CUBRID Engine  latest
log_writer.c
Go to the documentation of this file.
1 /*
2  * Copyright 2008 Search Solution Corporation
3  * Copyright 2016 CUBRID Corporation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */
18 
19 /*
20  * log_writer.c -
21  */
22 
23 #ident "$Id$"
24 
25 #include "config.h"
26 
27 #include <assert.h>
28 #include <errno.h>
29 #if !defined(WINDOWS)
30 #include <dirent.h>
31 #ifdef UNSTABLE_TDE_FOR_REPLICATION_LOG
32 #include "sys/socket.h"
33 #include "sys/un.h"
34 #endif /* UNSTABLE_TDE_FOR_REPLICATION_LOG */
35 #endif /* !WINDOWNS */
36 #include <signal.h>
37 
38 #include "log_writer.h"
39 
40 #include "error_manager.h"
41 #include "message_catalog.h"
42 #include "msgcat_set_log.hpp"
43 #include "object_representation.h"
44 #include "system_parameter.h"
45 #include "connection_support.h"
46 #include "log_applier.h"
47 #include "log_storage.hpp"
48 #include "log_volids.hpp"
49 #include "crypt_opfunc.h"
50 #ifdef UNSTABLE_TDE_FOR_REPLICATION_LOG
51 #include "tde.h"
52 #endif /* UNSTABLE_TDE_FOR_REPLICATION_LOG */
53 #if defined(SERVER_MODE)
54 #include "log_append.hpp"
55 #include "log_manager.h"
56 #include "server_support.h"
57 #include "network_interface_sr.h"
58 #else /* !defined(SERVER_MODE) */
59 #include "network_interface_cl.h"
60 #endif /* !defined(SERVER_MODE) */
61 #if !defined(WINDOWS)
62 #include "heartbeat.h"
63 #endif
64 #include "string_buffer.hpp"
65 
66 #define LOGWR_THREAD_SUSPEND_TIMEOUT 10
67 
68 #define LOGWR_COPY_LOG_BUFFER_NPAGES LOGPB_BUFFER_NPAGES_LOWER
69 
71 static bool logwr_need_shutdown = false;
72 
75 { /* Background log archive header information */
77 
78  INT32 dummy;
79  INT64 db_creation;
80 
84 };
85 
87 {
90 };
91 
92 #define logwr_er_log(...) if (prm_get_bool_value (PRM_ID_DEBUG_LOGWR)) _er_log_debug (ARG_FILE_LINE, __VA_ARGS__)
93 
94 static int logwr_check_page_checksum (THREAD_ENTRY * thread_p, LOG_PAGE * log_pgptr);
95 
96 #if defined(CS_MODE)
97 static log_header
98 init_cs_logwr_header ()
99 {
100  log_header hdr;
101  hdr.next_trid = NULL_TRANID;
104  hdr.nxarv_num = -1;
106  hdr.last_deleted_arv_num = -1;
107  return hdr;
108 }
109 
110 // *INDENT-OFF*
111 LOGWR_GLOBAL logwr_Gl = {
112  /* log header */
113  init_cs_logwr_header (),
114  /* loghdr_pgptr */
115  NULL,
116  /* db_name */
117  {'0'},
118  /* hostname */
119  NULL,
120  /* log_path */
121  {'0'},
122  /* loginf_path */
123  {'0'},
124  /* active_name */
125  {'0'},
126  /* append_vdes */
127  NULL_VOLDES,
128  /* logpg_area */
129  NULL,
130  /* logpg_area_size */
131  0,
132  /* logpg_fill_size */
133  0,
134  /* toflush */
135  NULL,
136  /* max_toflush */
137  0,
138  /* num_toflush */
139  0,
140  /* mode */
142  /* action */
143  LOGWR_ACTION_NONE,
144  /* last_chkpt_pageid */
145  NULL_PAGEID,
146  /* last_recv_pageid */
147  NULL_PAGEID,
148  /* last_arv_fpageid */
149  NULL_PAGEID,
150  /* last_arv_lpageid */
151  NULL_PAGEID,
152  /* last_arv_num */
153  -1,
154  /* force_flush */
155  false,
156  /* last_flush_time */
157  {0, 0},
158  /* background archiving info */
160  /* bg_archive_name */
161  {'0'},
162  /* ori_nxarv_pageid */
163  NULL_PAGEID,
164  /* start_pageid */
165  -2,
166  /* reinit_copylog */
167  false
168 };
169 // *INDENT-ON*
170 
171 static int logwr_fetch_header_page (LOG_PAGE * log_pgptr, int vol_fd, HEADER_FETCH_MODE mode = NORMAL_FETCH_MODE);
172 static int logwr_read_log_header (void);
173 static int logwr_read_bgarv_log_header (void);
174 static int logwr_initialize (const char *db_name, const char *log_path, int mode, LOG_PAGEID start_pageid);
175 static void logwr_finalize (void);
176 static LOG_PAGE **logwr_writev_append_pages (LOG_PAGE ** to_flush, DKNPAGES npages);
177 static int logwr_flush_all_append_pages (void);
178 static int logwr_archive_active_log (void);
179 static int logwr_flush_bgarv_header_page (void);
180 static void logwr_reinit_copylog (void);
181 #ifdef UNSTABLE_TDE_FOR_REPLICATION_LOG
182 static int logwr_load_tde (void);
183 #endif /* UNSTABLE_TDE_FOR_REPLICATION_LOG */
184 
185 /*
186  * logwr_to_physical_pageid -
187  *
188  * return:
189  * logical_pageid(in):
190  * Note:
191  */
193 logwr_to_physical_pageid (LOG_PAGEID logical_pageid)
194 {
195  LOG_PHY_PAGEID phy_pageid;
196 
197  if (logical_pageid == LOGPB_HEADER_PAGE_ID)
198  {
199  phy_pageid = 0;
200  }
201  else
202  {
203  LOG_PAGEID tmp_pageid;
204 
205  tmp_pageid = logical_pageid - logwr_Gl.hdr.fpageid;
206 
207  if (tmp_pageid >= logwr_Gl.hdr.npages)
208  {
209  tmp_pageid %= logwr_Gl.hdr.npages;
210  }
211  else if (tmp_pageid < 0)
212  {
213  tmp_pageid = (logwr_Gl.hdr.npages - ((-tmp_pageid) % logwr_Gl.hdr.npages));
214  }
215  tmp_pageid++;
216  if (tmp_pageid > logwr_Gl.hdr.npages)
217  {
218  tmp_pageid %= logwr_Gl.hdr.npages;
219  }
220 
221  assert (tmp_pageid <= PAGEID_MAX);
222  phy_pageid = (LOG_PHY_PAGEID) tmp_pageid;
223  }
224 
225  return phy_pageid;
226 }
227 
228 /*
229  * logwr_fetch_header_page -
230  *
231  * return:
232  * log_pgptr(out):
233  * vol_fd(in):
234  * mode(in):
235  *
236  * Note: if page contents are unexpected :
237  * - if is just formatted and mode is CHECK_FORMATTED_PAGE, error code ER_DISK_INCONSISTENT_VOL_HEADER
238  * is returned (no error is set);
239  * - otherwise ER_LOG_PAGE_CORRUPTED is returned and error is set
240  *
241  */
242 static int
243 logwr_fetch_header_page (LOG_PAGE * log_pgptr, int vol_fd, HEADER_FETCH_MODE mode)
244 {
245  LOG_PAGEID pageid;
246  LOG_PHY_PAGEID phy_pageid;
247 
248  assert (log_pgptr != NULL);
249 
250  /*
251  * Page is contained in the active log.
252  * Find the corresponding physical page and read the page form disk.
253  */
254  pageid = LOGPB_HEADER_PAGE_ID;
255  phy_pageid = logwr_to_physical_pageid (pageid);
256 
257  if (fileio_read (NULL, vol_fd, log_pgptr, phy_pageid, LOG_PAGESIZE) == NULL)
258  {
259  er_set (ER_FATAL_ERROR_SEVERITY, ARG_FILE_LINE, ER_LOG_READ, 3, pageid, phy_pageid, logwr_Gl.active_name);
260  return ER_LOG_READ;
261  }
262  else
263  {
264  if (log_pgptr->hdr.logical_pageid != pageid)
265  {
266  if (mode == CHECK_FORMATTED_PAGE && fileio_is_formatted_page (NULL, (char *) log_pgptr))
267  {
268  /* set error outside this function */
270  }
272  return ER_LOG_PAGE_CORRUPTED;
273  }
274  }
275 
276  return NO_ERROR;
277 }
278 
279 /*
280  * logwr_read_log_header -
281  *
282  * return:
283  * Note:
284  */
285 static int
286 logwr_read_log_header (void)
287 {
288  char log_pgbuf[IO_MAX_PAGE_SIZE + MAX_ALIGNMENT];
289  char *aligned_log_pgbuf;
290  LOG_PAGE *log_pgptr;
291  int error = NO_ERROR;
292 
293  aligned_log_pgbuf = PTR_ALIGN (log_pgbuf, MAX_ALIGNMENT);
294  log_pgptr = (LOG_PAGE *) aligned_log_pgbuf;
295 
296  if (!fileio_is_volume_exist (logwr_Gl.active_name))
297  {
298  /* Delay to create a new log file until it gets the log header page from server because we need to know the
299  * npages to create an log file */
300  ;
301  }
302  else
303  {
304  /* Mount the active log and read the log header */
305  logwr_Gl.append_vdes =
306  fileio_mount (NULL, logwr_Gl.db_name, logwr_Gl.active_name, LOG_DBLOG_ACTIVE_VOLID, true, false);
307  if (logwr_Gl.append_vdes == NULL_VOLDES)
308  {
309  /* Unable to mount the active log */
310  return ER_IO_MOUNT_FAIL;
311  }
312  else
313  {
314  error = logwr_fetch_header_page (log_pgptr, logwr_Gl.append_vdes, CHECK_FORMATTED_PAGE);
315  if (error == ER_DISK_INCONSISTENT_VOL_HEADER)
316  {
317  /* the page appears to be just formatted (previous instance of log writter was stopped before appending
318  * expected data; in this case just notify and delete the volume:
319  * the behavior will be the same as `if (!fileio_is_volume_exist (logwr_Gl.active_name)) branch` */
321  logwr_Gl.active_name);
322 
324  fileio_unformat (NULL, logwr_Gl.active_name);
325  er_clear ();
326  return NO_ERROR;
327  }
328 
329  if (error != NO_ERROR)
330  {
331  return error;
332  }
333 
334  memcpy (&logwr_Gl.hdr, log_pgptr->area, sizeof (LOG_HEADER));
335 
337  assert (log_pgptr->hdr.offset == NULL_OFFSET);
338  }
339  }
340 
341  return NO_ERROR;
342 }
343 
344 /*
345  * logwr_read_bgarv_log_header -
346  *
347  * return:
348  * Note:
349  */
350 static int
351 logwr_read_bgarv_log_header (void)
352 {
353  char log_pgbuf[IO_MAX_PAGE_SIZE + MAX_ALIGNMENT];
354  char *aligned_log_pgbuf;
355  LOG_PAGE *log_pgptr;
356  LOG_BGARV_HEADER *bgarv_header;
357  BACKGROUND_ARCHIVING_INFO *bg_arv_info;
358  int error = NO_ERROR;
359 
360  bg_arv_info = &logwr_Gl.bg_archive_info;
361 
362  aligned_log_pgbuf = PTR_ALIGN (log_pgbuf, MAX_ALIGNMENT);
363  log_pgptr = (LOG_PAGE *) aligned_log_pgbuf;
364 
365  assert (bg_arv_info->vdes != NULL_VOLDES);
366 
367  error = logwr_fetch_header_page (log_pgptr, bg_arv_info->vdes);
368  if (error != NO_ERROR)
369  {
370  return error;
371  }
372 
374  assert (log_pgptr->hdr.offset = NULL_OFFSET);
375 
376  bgarv_header = (LOG_BGARV_HEADER *) log_pgptr->area;
377 
378  if (strncmp (bgarv_header->magic, CUBRID_MAGIC_LOG_ARCHIVE, CUBRID_MAGIC_MAX_LENGTH) != 0)
379  {
380  /* magic is different */
382  }
383 
384  bg_arv_info->start_page_id = bgarv_header->start_page_id;
385  bg_arv_info->current_page_id = bgarv_header->current_page_id;
386  bg_arv_info->last_sync_pageid = bgarv_header->last_sync_pageid;
387 
388  return NO_ERROR;
389 }
390 
391 /*
392  * la_shutdown_by_signal() - When the process catches the SIGTERM signal,
393  * it does the shutdown process.
394  * return: none
395  *
396  * Note:
397  * set the "logwr_need_shutdown" flag as true, then each threads would
398  * process "shutdown"
399  */
400 static void
401 logwr_shutdown_by_signal (int)
402 {
403  logwr_need_shutdown = true;
404 
405  return;
406 }
407 
408 bool
410 {
411  return (logwr_need_shutdown) ? true : false;
412 }
413 
414 /*
415  * logwr_initialize - Initialize logwr_Gl structure
416  *
417  * return:
418  *
419  * db_name(in):
420  * log_path(in):
421  * mode(in):
422  *
423  * Note:
424  */
425 static int
426 logwr_initialize (const char *db_name, const char *log_path, int mode, LOG_PAGEID start_pageid)
427 {
428  int log_nbuffers;
429  int error;
430  char *at_char = NULL;
431 
432  /* signal processing */
433 #if defined(WINDOWS)
434  (void) os_set_signal_handler (SIGABRT, logwr_shutdown_by_signal);
435  (void) os_set_signal_handler (SIGINT, logwr_shutdown_by_signal);
436  (void) os_set_signal_handler (SIGTERM, logwr_shutdown_by_signal);
437 #else /* ! WINDOWS */
438  (void) os_set_signal_handler (SIGSTOP, logwr_shutdown_by_signal);
439  (void) os_set_signal_handler (SIGTERM, logwr_shutdown_by_signal);
440  (void) os_set_signal_handler (SIGPIPE, SIG_IGN);
441 #endif /* ! WINDOWS */
442 
443  /* set the db name and log path */
444  strncpy (logwr_Gl.db_name, db_name, PATH_MAX - 1);
445  if ((at_char = strchr (logwr_Gl.db_name, '@')) != NULL)
446  {
447  *at_char = '\0';
448  logwr_Gl.hostname = at_char + 1;
449  }
450  strncpy (logwr_Gl.log_path, log_path, PATH_MAX - 1);
451  /* set the mode */
452  logwr_Gl.mode = (LOGWR_MODE) mode;
453 
454  /* set the active log file path */
455  fileio_make_log_active_name (logwr_Gl.active_name, log_path, logwr_Gl.db_name);
456  /* set the log info file path */
457  fileio_make_log_info_name (logwr_Gl.loginf_path, log_path, logwr_Gl.db_name);
458  /* background archive file path */
459  fileio_make_log_archive_temp_name (logwr_Gl.bg_archive_name, log_path, logwr_Gl.db_name);
460  log_nbuffers = LOGWR_COPY_LOG_BUFFER_NPAGES + 1;
461 
462  if (logwr_Gl.logpg_area == NULL)
463  {
464  logwr_Gl.logpg_area_size = log_nbuffers * LOG_PAGESIZE;
465  logwr_Gl.logpg_area = (char *) malloc (logwr_Gl.logpg_area_size);
466  if (logwr_Gl.logpg_area == NULL)
467  {
468  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, (size_t) logwr_Gl.logpg_area_size);
469  logwr_Gl.logpg_area_size = 0;
471  }
472  }
473 
474  if (logwr_Gl.toflush == NULL)
475  {
476  int i;
477 
478  logwr_Gl.max_toflush = log_nbuffers - 1;
479  logwr_Gl.toflush = (LOG_PAGE **) calloc (logwr_Gl.max_toflush, sizeof (logwr_Gl.toflush));
480  if (logwr_Gl.toflush == NULL)
481  {
483  logwr_Gl.max_toflush * sizeof (logwr_Gl.toflush));
484  logwr_Gl.max_toflush = 0;
486  }
487  for (i = 0; i < logwr_Gl.max_toflush; i++)
488  {
489  logwr_Gl.toflush[i] = NULL;
490  }
491  }
492 
493  error = logwr_read_log_header ();
494  if (error != NO_ERROR)
495  {
496  return error;
497  }
498 
499  logwr_Gl.start_pageid = start_pageid;
500  if (logwr_Gl.start_pageid >= NULL_PAGEID && logwr_Gl.hdr.nxarv_pageid != NULL_PAGEID)
501  {
502  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_HA_GENERIC_ERROR, 1, "Replication transaction log already exist");
503  return ER_HA_GENERIC_ERROR;
504  }
505 
506  logwr_Gl.action = LOGWR_ACTION_NONE;
507 
508  logwr_Gl.last_arv_fpageid = logwr_Gl.hdr.nxarv_pageid;
509  logwr_Gl.last_arv_num = logwr_Gl.hdr.nxarv_num;
510 
511  logwr_Gl.force_flush = false;
512  logwr_Gl.last_flush_time.tv_sec = 0;
513  logwr_Gl.last_flush_time.tv_usec = 0;
514 
515  logwr_Gl.ori_nxarv_pageid = NULL_PAGEID;
516 
518  {
519  BACKGROUND_ARCHIVING_INFO *bg_arv_info;
520  bg_arv_info = &logwr_Gl.bg_archive_info;
521 
522  if (fileio_is_volume_exist (logwr_Gl.bg_archive_name) == true)
523  {
524  bg_arv_info->vdes =
525  fileio_mount (NULL, logwr_Gl.bg_archive_name, logwr_Gl.bg_archive_name, LOG_DBLOG_ARCHIVE_VOLID, true,
526  false);
527  if (bg_arv_info->vdes == NULL_VOLDES)
528  {
529  return ER_IO_MOUNT_FAIL;
530  }
531 
532  error = logwr_read_bgarv_log_header ();
533  if (error != NO_ERROR)
534  {
535  if (error == ER_LOG_INCOMPATIBLE_DATABASE)
536  {
537  /* Considering the case of upgrading, if it read magic from bg archive file which is not include
538  * magic, make new bg archive file. */
539  fileio_dismount (NULL, bg_arv_info->vdes);
540  fileio_unformat (NULL, logwr_Gl.bg_archive_name);
541 
542  bg_arv_info->vdes = NULL_VOLDES;
543  }
544  else
545  {
546  return error;
547  }
548  }
549  }
550 
551  /* if bg archive file does not exist or magic is diff, */
552  /* create new bg archive file */
553  if (bg_arv_info->vdes == NULL_VOLDES)
554  {
555  bg_arv_info->vdes =
556  fileio_format (NULL, logwr_Gl.db_name, logwr_Gl.bg_archive_name, LOG_DBLOG_BG_ARCHIVE_VOLID,
557  logwr_Gl.hdr.npages + 1, false, false, false, LOG_PAGESIZE, 0, false);
558  if (bg_arv_info->vdes == NULL_VOLDES)
559  {
561  "Unable to create temporary archive log");
562  return ER_HA_GENERIC_ERROR;
563  }
564 
565  bg_arv_info->start_page_id = logwr_Gl.hdr.nxarv_pageid;
566  bg_arv_info->current_page_id = NULL_PAGEID;
567  bg_arv_info->last_sync_pageid = logwr_Gl.hdr.nxarv_pageid;
568 
569  error = logwr_flush_bgarv_header_page ();
570  if (error != NO_ERROR)
571  {
572  return error;
573  }
574  }
575  }
576 
577  return NO_ERROR;
578 }
579 
580 /*
581  * logwr_finalize -
582  *
583  * return:
584  * Note:
585  */
586 static void
587 logwr_finalize (void)
588 {
589  if (logwr_Gl.logpg_area != NULL)
590  {
591  free_and_init (logwr_Gl.logpg_area);
592  logwr_Gl.logpg_area_size = 0;
593  logwr_Gl.logpg_fill_size = 0;
594  logwr_Gl.loghdr_pgptr = NULL;
595  }
596  if (logwr_Gl.toflush != NULL)
597  {
598  free_and_init (logwr_Gl.toflush);
599  logwr_Gl.max_toflush = 0;
600  logwr_Gl.num_toflush = 0;
601  }
602  if (logwr_Gl.append_vdes != NULL_VOLDES)
603  {
604  fileio_dismount (NULL, logwr_Gl.append_vdes);
605  logwr_Gl.append_vdes = NULL_VOLDES;
606  }
607  logwr_Gl.last_recv_pageid = NULL_PAGEID;
608  logwr_Gl.mode = LOGWR_MODE_ASYNC;
609  logwr_Gl.action = LOGWR_ACTION_NONE;
610 
611  logwr_Gl.force_flush = false;
612  logwr_Gl.last_flush_time.tv_sec = 0;
613  logwr_Gl.last_flush_time.tv_usec = 0;
614 
615  logwr_Gl.ori_nxarv_pageid = NULL_PAGEID;
616  logwr_Gl.start_pageid = -2;
617 
619  {
620  if (logwr_Gl.bg_archive_info.vdes != NULL_VOLDES)
621  {
622  fileio_dismount (NULL, logwr_Gl.bg_archive_info.vdes);
623  logwr_Gl.bg_archive_info.vdes = NULL_VOLDES;
624  }
625  }
626 
627  logwr_Gl.reinit_copylog = false;
628 }
629 
630 /*
631  * logwr_set_hdr_and_flush_info -
632  *
633  * return:
634  * Note:
635  */
636 int
637 logwr_set_hdr_and_flush_info (void)
638 {
639  LOG_PAGE *log_pgptr = NULL, *last_pgptr;
640  char *p;
641  int num_toflush = 0;
642 
643  /* Set the flush information */
644  p = logwr_Gl.logpg_area + LOG_PAGESIZE;
645  while (p < (logwr_Gl.logpg_area + logwr_Gl.logpg_fill_size))
646  {
647  log_pgptr = (LOG_PAGE *) p;
648  logwr_Gl.toflush[num_toflush++] = log_pgptr;
649  p += LOG_PAGESIZE;
650  }
651 
652  last_pgptr = log_pgptr;
653  logwr_Gl.num_toflush = num_toflush;
654 
655  /* get original next archive pageid */
656  logwr_Gl.ori_nxarv_pageid = logwr_Gl.hdr.nxarv_pageid;
657 
658  /* Set the header and action information */
659  if (num_toflush > 0)
660  {
661  log_pgptr = (LOG_PAGE *) logwr_Gl.logpg_area;
662  memcpy (&logwr_Gl.hdr, log_pgptr->area, sizeof (LOG_HEADER));
663  logwr_Gl.loghdr_pgptr = log_pgptr;
664 
665  /* Initialize archive info if it is not set */
666  if (logwr_Gl.last_arv_fpageid == NULL_PAGEID || logwr_Gl.last_arv_num < 0)
667  {
668  logwr_Gl.last_arv_fpageid = logwr_Gl.hdr.nxarv_pageid;
669  logwr_Gl.last_arv_num = logwr_Gl.hdr.nxarv_num;
671  {
672  logwr_Gl.bg_archive_info.start_page_id = logwr_Gl.last_arv_fpageid;
673  }
674  }
675 
676  /* Check if it need archiving */
677  if (((logwr_Gl.last_arv_num + 1 < logwr_Gl.hdr.nxarv_num)
678  && (logwr_Gl.hdr.ha_file_status == LOG_HA_FILESTAT_ARCHIVED))
679  && (logwr_Gl.last_arv_fpageid <= logwr_Gl.last_recv_pageid))
680  {
681  /* Do delayed archiving */
682  logwr_Gl.action = (LOGWR_ACTION) (logwr_Gl.action | LOGWR_ACTION_ARCHIVING);
683  logwr_Gl.last_arv_lpageid = logwr_Gl.last_recv_pageid;
684  }
685  else if ((logwr_Gl.last_arv_num + 1 == logwr_Gl.hdr.nxarv_num)
686  && (last_pgptr->hdr.logical_pageid >= logwr_Gl.hdr.nxarv_pageid))
687  {
688  logwr_Gl.action = (LOGWR_ACTION) (logwr_Gl.action | LOGWR_ACTION_ARCHIVING);
689  logwr_Gl.last_arv_lpageid = logwr_Gl.hdr.nxarv_pageid - 1;
690  }
691 
692  if (last_pgptr != NULL && last_pgptr->hdr.logical_pageid < logwr_Gl.hdr.eof_lsa.pageid)
693  {
694  /* There are left several pages to get from the server */
695  logwr_Gl.last_recv_pageid = last_pgptr->hdr.logical_pageid;
696  logwr_Gl.action = (LOGWR_ACTION) (logwr_Gl.action | LOGWR_ACTION_DELAYED_WRITE);
697  }
698  else
699  {
700  logwr_Gl.last_recv_pageid = logwr_Gl.hdr.eof_lsa.pageid;
701 
702  if (logwr_Gl.action & LOGWR_ACTION_DELAYED_WRITE)
703  {
704  /* In case that it finishes delay write */
705  logwr_Gl.action = (LOGWR_ACTION) (logwr_Gl.action & ~LOGWR_ACTION_DELAYED_WRITE);
706  }
707  }
708  }
709  else
710  {
711  /* If it gets only the header page, compares both of the headers. There is no update for the header information */
712  LOG_HEADER hdr;
713  log_pgptr = (LOG_PAGE *) logwr_Gl.logpg_area;
714  memcpy (&hdr, log_pgptr->area, sizeof (LOG_HEADER));
715 
718  && (hdr.ha_promotion_time == 0 || difftime64 (hdr.ha_promotion_time, logwr_Gl.hdr.ha_promotion_time) == 0)
719  && difftime64 (hdr.db_restore_time, logwr_Gl.hdr.db_restore_time) != 0)
720  {
721  logwr_Gl.reinit_copylog = true;
722 
723  logwr_Gl.loghdr_pgptr = (LOG_PAGE *) logwr_Gl.logpg_area;
724 
727  }
728 
729  if (difftime64 (hdr.db_creation, logwr_Gl.hdr.db_creation) != 0)
730  {
733  }
734 
735  if (logwr_Gl.hdr.ha_file_status != LOG_HA_FILESTAT_SYNCHRONIZED)
736  {
737  /* In case of delayed write, get last_recv_pageid from the append lsa of the local log header */
738  logwr_Gl.last_recv_pageid = logwr_Gl.hdr.append_lsa.pageid - 1;
739  }
740  else
741  {
742  /* To get the last page again, decrease last pageid */
743  logwr_Gl.last_recv_pageid = logwr_Gl.hdr.eof_lsa.pageid - 1;
744  }
745  }
746  if (logwr_Gl.hdr.ha_file_status != LOG_HA_FILESTAT_SYNCHRONIZED)
747  {
748  /* In case of delayed write, save the append lsa of the log to be written locally */
749  logwr_Gl.hdr.append_lsa.pageid = logwr_Gl.last_recv_pageid;
750  logwr_Gl.hdr.append_lsa.offset = NULL_OFFSET;
751  }
752  return NO_ERROR;
753 }
754 
755 
756 /*
757  * logwr_copy_necessary_log -
758 
759  * return:
760  * to_pageid(in): page id
761  *
762  * Note: copy active log to background archive file.
763  * (from bg_arv_info.current to to_pageid)
764  */
765 
766 static int
767 logwr_copy_necessary_log (LOG_PAGEID to_pageid)
768 {
769  char log_pgbuf[IO_MAX_PAGE_SIZE * LOGPB_IO_NPAGES + MAX_ALIGNMENT];
770  char *aligned_log_pgbuf = NULL;
771  LOG_PAGEID pageid = NULL_PAGEID;
772  LOG_PHY_PAGEID phy_pageid = NULL_PAGEID;
773  LOG_PHY_PAGEID ar_phy_pageid = NULL_PAGEID;
774  LOG_PAGE *log_pgptr = NULL;
775  int num_pages = 0;
776  BACKGROUND_ARCHIVING_INFO *bg_arv_info = NULL;
777 
778  bg_arv_info = &logwr_Gl.bg_archive_info;
779  aligned_log_pgbuf = PTR_ALIGN (log_pgbuf, MAX_ALIGNMENT);
780 
781  pageid = bg_arv_info->current_page_id;
782  if (pageid == NULL_PAGEID)
783  {
784  pageid = bg_arv_info->start_page_id;
785  }
786 
787  ar_phy_pageid = (LOG_PHY_PAGEID) (pageid - bg_arv_info->start_page_id + 1);
788 
789  log_pgptr = (LOG_PAGE *) aligned_log_pgbuf;
790 
791  assert (logwr_Gl.last_arv_fpageid <= pageid && pageid <= logwr_Gl.hdr.append_lsa.pageid);
792  assert (logwr_Gl.last_arv_fpageid <= to_pageid && to_pageid <= logwr_Gl.hdr.append_lsa.pageid);
793 
794  for (; pageid < to_pageid; pageid += num_pages, ar_phy_pageid += num_pages)
795  {
796  num_pages = MIN (LOGPB_IO_NPAGES, (int) (to_pageid - pageid));
797  phy_pageid = logwr_to_physical_pageid (pageid);
798  num_pages = MIN (num_pages, logwr_Gl.hdr.npages - phy_pageid + 1);
799 
800  if (fileio_read_pages (NULL, logwr_Gl.append_vdes, (char *) log_pgptr, phy_pageid, num_pages, LOG_PAGESIZE) ==
801  NULL)
802  {
803  er_set (ER_FATAL_ERROR_SEVERITY, ARG_FILE_LINE, ER_LOG_READ, 3, pageid, phy_pageid, logwr_Gl.active_name);
804  return ER_LOG_READ;
805  }
806  else
807  {
808  if (log_pgptr->hdr.logical_pageid != pageid)
809  {
811  return ER_LOG_PAGE_CORRUPTED;
812  }
813  }
814  /* no need to encrypt, it is read as not decrypted (TDE) if encrypted */
815  if (fileio_write_pages (NULL, bg_arv_info->vdes, (char *) log_pgptr, ar_phy_pageid, num_pages, LOG_PAGESIZE,
817  {
818  er_set (ER_FATAL_ERROR_SEVERITY, ARG_FILE_LINE, ER_LOG_WRITE, 3, pageid, ar_phy_pageid,
819  logwr_Gl.bg_archive_name);
820  return ER_LOG_WRITE;
821  }
822  }
823 
824  return NO_ERROR;
825 }
826 
827 /*
828  * logwr_fetch_append_pages -
829  *
830  * return:
831  * to_flush(in):
832  * npages(in):
833  * Note:
834  */
835 static LOG_PAGE **
836 logwr_writev_append_pages (LOG_PAGE ** to_flush, DKNPAGES npages)
837 {
838  char log_pgbuf[IO_MAX_PAGE_SIZE * LOGPB_IO_NPAGES + MAX_ALIGNMENT];
839  LOG_PAGEID fpageid;
840  LOG_PHY_PAGEID phy_pageid;
841  BACKGROUND_ARCHIVING_INFO *bg_arv_info = NULL;
842  LOG_PAGE *log_pgptr = NULL;
843 #ifdef UNSTABLE_TDE_FOR_REPLICATION_LOG
844  LOG_PAGE *buf_pgptr = NULL;
845 #endif /* UNSTABLE_TDE_FOR_REPLICATION_LOG */
848  int error = NO_ERROR;
849  int i;
850  int tde_load_retries = 3;
851 
852 #if !defined (CS_MODE)
854 #endif
855 
856 #ifdef UNSTABLE_TDE_FOR_REPLICATION_LOG
857  buf_pgptr = (LOG_PAGE *) PTR_ALIGN (log_pgbuf, MAX_ALIGNMENT);
858 #endif /* UNSTABLE_TDE_FOR_REPLICATION_LOG */
859 
860  if (npages > 0)
861  {
862  fpageid = to_flush[0]->hdr.logical_pageid;
863 
864  (void) logwr_check_page_checksum (NULL, *to_flush);
865 
866  /* 1. archive temp write */
868  {
869  bg_arv_info = &logwr_Gl.bg_archive_info;
870  /* check archive temp descriptor */
871  if (bg_arv_info->vdes == NULL_VOLDES)
872  {
873  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_HA_GENERIC_ERROR, 1, "invalid temporary archive log file");
874  to_flush = NULL;
875  return to_flush;
876  }
877 
878  /* If there exist empty page between current_page_id and (fpageid-1) copy missing logs to background archive
879  * log file */
880  if (bg_arv_info->current_page_id < fpageid - 1 || bg_arv_info->current_page_id == NULL_PAGEID)
881  {
882  if (logwr_copy_necessary_log (fpageid) != NO_ERROR)
883  {
884  to_flush = NULL;
885  return to_flush;
886  }
887  }
888 
889  phy_pageid = (LOG_PHY_PAGEID) (fpageid - bg_arv_info->start_page_id + 1);
890  for (i = 0; i < npages; i++)
891  {
892  log_pgptr = to_flush[i];
893 #ifdef UNSTABLE_TDE_FOR_REPLICATION_LOG
894  if (LOG_IS_PAGE_TDE_ENCRYPTED (log_pgptr))
895  {
896  logwr_set_tde_algorithm (NULL, log_pgptr, tde_algo);
897 
898  while (!tde_Cipher.is_loaded)
899  {
900  error = logwr_load_tde ();
901  if (error != NO_ERROR)
902  {
903  ASSERT_ERROR ();
904  if (tde_load_retries-- > 0)
905  {
907  sleep (1);
908  er_clear ();
909  continue;
910  }
911  return NULL;
912  }
913  }
914 
915  if (tde_encrypt_log_page (log_pgptr, tde_algo, buf_pgptr) != NO_ERROR)
916  {
917  return NULL;
918  }
919  log_pgptr = buf_pgptr;
920  }
921 #endif /* UNSTABLE_TDE_FOR_REPLICATION_LOG */
922  if (fileio_write (NULL, bg_arv_info->vdes, log_pgptr, phy_pageid + i, LOG_PAGESIZE, write_mode) == NULL)
923  {
925  {
927  logwr_Gl.bg_archive_name, logwr_Gl.hdr.db_logpagesize);
928  }
929  else
930  {
932  logwr_Gl.bg_archive_name);
933  }
934  to_flush = NULL;
935  return to_flush;
936  }
937  }
938 
939  bg_arv_info->current_page_id = fpageid + (npages - 1);
940  logwr_er_log ("background archiving current_page_id[%lld], fpageid[%lld], npages[%d]",
941  bg_arv_info->current_page_id, fpageid, npages);
942 
943  error = logwr_flush_bgarv_header_page ();
944  if (error != NO_ERROR)
945  {
946  to_flush = NULL;
947  return to_flush;
948  }
949  }
950 
951  tde_load_retries = 3;
952 
953  /* 2. active write */
954  phy_pageid = logwr_to_physical_pageid (fpageid);
955  for (i = 0; i < npages; i++)
956  {
957  log_pgptr = to_flush[i];
958 #ifdef UNSTABLE_TDE_FOR_REPLICATION_LOG
959  if (LOG_IS_PAGE_TDE_ENCRYPTED (log_pgptr))
960  {
961  logwr_set_tde_algorithm (NULL, log_pgptr, tde_algo);
962 
963  while (!tde_Cipher.is_loaded)
964  {
965  error = logwr_load_tde ();
966  if (error != NO_ERROR)
967  {
968  ASSERT_ERROR ();
969  if (tde_load_retries-- > 0)
970  {
972  sleep (1);
973  er_clear ();
974  continue;
975  }
976  return NULL;
977  }
978  }
979 
980  if (tde_encrypt_log_page (log_pgptr, tde_algo, buf_pgptr) != NO_ERROR)
981  {
982  return NULL;
983  }
984  log_pgptr = buf_pgptr;
985  }
986 #endif /* UNSTABLE_TDE_FOR_REPLICATION_LOG */
987  if (fileio_write (NULL, logwr_Gl.append_vdes, log_pgptr, phy_pageid + i, LOG_PAGESIZE, write_mode) == NULL)
988  {
990  {
992  logwr_Gl.active_name, logwr_Gl.hdr.db_logpagesize);
993  }
994  else
995  {
997  logwr_Gl.active_name);
998  }
999  to_flush = NULL;
1000  return to_flush;
1001  }
1002  }
1003  }
1004  return to_flush;
1005 }
1006 
1007 /*
1008  * logwr_flush_all_append_pages -
1009  *
1010  * return:
1011  * Note:
1012  */
1013 static int
1014 logwr_flush_all_append_pages (void)
1015 {
1016  LOG_PAGE *pgptr, *prv_pgptr;
1017  LOG_PAGEID pageid, prv_pageid;
1018  int idxflush;
1019  bool need_sync;
1020  int flush_page_count;
1021  int i;
1022 
1023  idxflush = -1;
1024  prv_pgptr = NULL;
1025  need_sync = false;
1026  flush_page_count = 0;
1027 
1028  for (i = 0; i < logwr_Gl.num_toflush; i++)
1029  {
1030  pgptr = logwr_Gl.toflush[i];
1031 
1032  if (idxflush != -1 && prv_pgptr != NULL)
1033  {
1034  /*
1035  * This append log page should be dirty and contiguous to previous
1036  * append page. If it is not, we need to flush the accumulated pages
1037  * up to this point, and then start accumulating pages again.
1038  */
1039  pageid = pgptr->hdr.logical_pageid;
1040  prv_pageid = prv_pgptr->hdr.logical_pageid;
1041 
1042  if ((pageid != prv_pageid + 1)
1043  || (logwr_to_physical_pageid (pageid) != logwr_to_physical_pageid (prv_pageid) + 1))
1044  {
1045  /*
1046  * This page is not contiguous.
1047  *
1048  * Flush the accumulated contiguous pages
1049  */
1050  if (logwr_writev_append_pages (&logwr_Gl.toflush[idxflush], i - idxflush) == NULL)
1051  {
1052  assert (er_errid () != NO_ERROR);
1053  return er_errid ();
1054  }
1055  else
1056  {
1057  need_sync = true;
1058 
1059  /*
1060  * Start over the accumulation of pages
1061  */
1062 
1063  flush_page_count += i - idxflush;
1064  idxflush = -1;
1065  }
1066  }
1067  }
1068 
1069  if (idxflush == -1)
1070  {
1071  /*
1072  * This page should be included in the flush
1073  */
1074  idxflush = i;
1075  }
1076 
1077  /* prv_pgptr was not pgptr's previous buffer. prv_pgptr was the first buffer to flush, so only 2 continous pages
1078  * always were flushed together. */
1079  prv_pgptr = pgptr;
1080  }
1081 
1082  /*
1083  * If there are any accumulated pages, flush them at this point
1084  */
1085 
1086  if (idxflush != -1)
1087  {
1088  int page_toflush = logwr_Gl.num_toflush - idxflush;
1089 
1090  /* last countious pages */
1091  if (logwr_writev_append_pages (&logwr_Gl.toflush[idxflush], page_toflush) == NULL)
1092  {
1093  assert (er_errid () != NO_ERROR);
1094  return er_errid ();
1095  }
1096  else
1097  {
1098  need_sync = true;
1099  flush_page_count += page_toflush;
1100  pgptr = logwr_Gl.toflush[idxflush + page_toflush - 1];
1101  }
1102  }
1103 
1104  /*
1105  * Make sure that all of the above log writes are synchronized with any
1106  * future log writes. That is, the pages should be stored on physical disk.
1107  */
1108  if (need_sync == true
1109  && fileio_synchronize (NULL, logwr_Gl.append_vdes, logwr_Gl.active_name, FILEIO_SYNC_ONLY) == NULL_VOLDES)
1110  {
1111  assert (er_errid () != NO_ERROR);
1112  return er_errid ();
1113  }
1114 
1115  /* It's for dual write. */
1116  if (need_sync == true && prm_get_bool_value (PRM_ID_LOG_BACKGROUND_ARCHIVING))
1117  {
1118  if (fileio_synchronize (NULL, logwr_Gl.bg_archive_info.vdes, logwr_Gl.bg_archive_name,
1120  {
1121  assert (er_errid () != NO_ERROR);
1122  return er_errid ();
1123  }
1124  }
1125 
1126  /* Initialize flush info */
1127  for (i = 0; i < logwr_Gl.num_toflush; i++)
1128  {
1129  logwr_Gl.toflush[i] = NULL;
1130  }
1131  logwr_Gl.num_toflush = 0;
1132 
1133  logwr_er_log ("logwr_write_log_pages, flush_page_count(%d)\n", flush_page_count);
1134 
1135  return NO_ERROR;
1136 }
1137 
1138 /*
1139  * logwr_flush_bgarv_header_page -
1140  *
1141  * return:
1142  * Note:
1143  */
1144 int
1145 logwr_flush_bgarv_header_page (void)
1146 {
1147  char log_pgbuf[IO_MAX_PAGE_SIZE + MAX_ALIGNMENT];
1148  char *aligned_log_pgbuf;
1149  LOG_PAGE *log_pgptr;
1150  BACKGROUND_ARCHIVING_INFO *bg_arv_info = NULL;
1151  LOG_BGARV_HEADER *bgarvhdr = NULL;
1152  LOG_PAGEID logical_pageid;
1153  LOG_PHY_PAGEID phy_pageid;
1154  int error_code = NO_ERROR;
1155 
1156  bg_arv_info = &logwr_Gl.bg_archive_info;
1157 
1159  assert (bg_arv_info->vdes != NULL_VOLDES);
1160 
1161  aligned_log_pgbuf = PTR_ALIGN (log_pgbuf, MAX_ALIGNMENT);
1162  log_pgptr = (LOG_PAGE *) aligned_log_pgbuf;
1163 
1165  log_pgptr->hdr.offset = NULL_OFFSET;
1166  logical_pageid = LOGPB_HEADER_PAGE_ID;
1167 
1168  /* Construct the bg archive log header */
1169  bgarvhdr = (LOG_BGARV_HEADER *) log_pgptr->area;
1171  bgarvhdr->db_creation = logwr_Gl.hdr.db_creation;
1172  bgarvhdr->start_page_id = bg_arv_info->start_page_id;
1173  bgarvhdr->current_page_id = bg_arv_info->current_page_id;
1174  bgarvhdr->last_sync_pageid = bg_arv_info->last_sync_pageid;
1175 
1176  phy_pageid = logwr_to_physical_pageid (log_pgptr->hdr.logical_pageid);
1177 
1178  if (fileio_write (NULL, bg_arv_info->vdes, log_pgptr, phy_pageid, LOG_PAGESIZE,
1180  || fileio_synchronize (NULL, bg_arv_info->vdes, logwr_Gl.bg_archive_name, FILEIO_SYNC_ONLY) == NULL_VOLDES)
1181  {
1183  {
1184  error_code = ER_LOG_WRITE_OUT_OF_SPACE;
1185  er_set (ER_FATAL_ERROR_SEVERITY, ARG_FILE_LINE, ER_LOG_WRITE_OUT_OF_SPACE, 4, logical_pageid, phy_pageid,
1186  logwr_Gl.bg_archive_name, LOG_PAGESIZE);
1187  }
1188  else
1189  {
1190  error_code = ER_LOG_WRITE;
1191  er_set_with_oserror (ER_FATAL_ERROR_SEVERITY, ARG_FILE_LINE, ER_LOG_WRITE, 3, logical_pageid, phy_pageid,
1192  logwr_Gl.bg_archive_name);
1193  }
1194  return error_code;
1195  }
1196 
1197  return NO_ERROR;
1198 }
1199 
1200 /*
1201  * logwr_flush_header_page -
1202  *
1203  * return:
1204  * Note:
1205  */
1206 void
1207 logwr_flush_header_page (void)
1208 {
1209  LOG_PAGEID logical_pageid;
1210  LOG_PHY_PAGEID phy_pageid;
1211  int nbytes;
1212 
1213  if (logwr_Gl.loghdr_pgptr == NULL)
1214  {
1215  return;
1216  }
1217 
1218  logwr_Gl.hdr.is_shutdown = true;
1219 
1220  /* flush current archiving status */
1221  logwr_Gl.hdr.nxarv_num = logwr_Gl.last_arv_num;
1222  logwr_Gl.hdr.nxarv_pageid = logwr_Gl.last_arv_fpageid;
1223  logwr_Gl.hdr.nxarv_phy_pageid = logwr_to_physical_pageid (logwr_Gl.last_arv_fpageid);
1224 
1225  memcpy (logwr_Gl.loghdr_pgptr->area, &logwr_Gl.hdr, sizeof (logwr_Gl.hdr));
1226 
1227  logical_pageid = LOGPB_HEADER_PAGE_ID;
1228  phy_pageid = logwr_to_physical_pageid (logical_pageid);
1229 
1230  /* logwr_Gl.append_vdes is only changed while starting or finishing or recovering server. So, log cs is not needed. */
1231  if (fileio_write (NULL, logwr_Gl.append_vdes, logwr_Gl.loghdr_pgptr, phy_pageid, LOG_PAGESIZE,
1233  || fileio_synchronize (NULL, logwr_Gl.append_vdes, logwr_Gl.active_name, FILEIO_SYNC_ONLY) == NULL_VOLDES)
1234  {
1235 
1237  {
1238  nbytes = logwr_Gl.hdr.db_logpagesize;
1239  er_set (ER_FATAL_ERROR_SEVERITY, ARG_FILE_LINE, ER_LOG_WRITE_OUT_OF_SPACE, 4, logical_pageid, phy_pageid,
1240  logwr_Gl.active_name, nbytes);
1241  }
1242  else
1243  {
1244  er_set_with_oserror (ER_FATAL_ERROR_SEVERITY, ARG_FILE_LINE, ER_LOG_WRITE, 3, logical_pageid, phy_pageid,
1245  logwr_Gl.active_name);
1246  }
1247  }
1248 
1249  /* save last checkpoint pageid */
1250  logwr_Gl.last_chkpt_pageid = logwr_Gl.hdr.chkpt_lsa.pageid;
1251 
1252  if (prev_ha_server_state != logwr_Gl.hdr.ha_server_state)
1253  {
1254  string_buffer error_msg;
1255  error_msg ("change the state of HA server (%s@%s) from '%s' to '%s'", logwr_Gl.db_name,
1256  (logwr_Gl.hostname != NULL) ? logwr_Gl.hostname : "unknown",
1258  css_ha_server_state_string ((HA_SERVER_STATE) logwr_Gl.hdr.ha_server_state));
1260  }
1261  prev_ha_server_state = logwr_Gl.hdr.ha_server_state;
1262 
1263  logwr_er_log ("logwr_flush_header_page, ha_server_state=%s, ha_file_status=%s\n",
1264  css_ha_server_state_string ((HA_SERVER_STATE) logwr_Gl.hdr.ha_server_state),
1265  logwr_log_ha_filestat_to_string ((LOG_HA_FILESTAT) logwr_Gl.hdr.ha_file_status));
1266 }
1267 
1268 /*
1269  * logwr_archive_active_log -
1270  *
1271  * return:
1272  * Note:
1273  */
1274 static int
1275 logwr_archive_active_log (void)
1276 {
1277  char archive_name[PATH_MAX] = { '\0' };
1278  LOG_ARV_HEADER *arvhdr;
1279  char log_pgbuf[IO_MAX_PAGE_SIZE * LOGPB_IO_NPAGES + MAX_ALIGNMENT];
1280  char *aligned_log_pgbuf;
1281  LOG_PAGE *log_pgptr = NULL;
1282  LOG_PAGE *malloc_arv_hdr_pgptr = NULL;
1283  LOG_PAGEID pageid;
1284  LOG_LSA saved_append_lsa;
1285  LOG_PHY_PAGEID ar_phy_pageid = NULL_PAGEID, phy_pageid = NULL_PAGEID;
1286  int vdes = NULL_VOLDES;
1287  int error_code = NO_ERROR;
1288  int num_pages = 0;
1289  const char *catmsg;
1290  char buffer[LINE_MAX];
1291  BACKGROUND_ARCHIVING_INFO *bg_arv_info;
1292 
1293  aligned_log_pgbuf = PTR_ALIGN (log_pgbuf, MAX_ALIGNMENT);
1294 
1295  /* Create the archive header page */
1296  malloc_arv_hdr_pgptr = (LOG_PAGE *) malloc (LOG_PAGESIZE);
1297  if (malloc_arv_hdr_pgptr == NULL)
1298  {
1299  error_code = ER_OUT_OF_VIRTUAL_MEMORY;
1300  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_OUT_OF_VIRTUAL_MEMORY, 1, (size_t) LOG_PAGESIZE);
1301  goto error;
1302  }
1303 
1304  malloc_arv_hdr_pgptr->hdr.logical_pageid = LOGPB_HEADER_PAGE_ID;
1305  malloc_arv_hdr_pgptr->hdr.offset = NULL_OFFSET;
1306 
1307  /* Construct the archive log header */
1308  arvhdr = (LOG_ARV_HEADER *) malloc_arv_hdr_pgptr->area;
1310  arvhdr->db_creation = logwr_Gl.hdr.db_creation;
1311  arvhdr->next_trid = NULL_TRANID;
1312  arvhdr->fpageid = logwr_Gl.last_arv_fpageid;
1313  arvhdr->arv_num = logwr_Gl.last_arv_num;
1314  arvhdr->npages = (DKNPAGES) (logwr_Gl.last_arv_lpageid - arvhdr->fpageid + 1);
1315 
1316  /*
1317  * Now create the archive and start copying pages
1318  */
1319 
1320  snprintf (buffer, sizeof (buffer), "log archiving started for archive %03d", arvhdr->arv_num);
1322 
1323  fileio_make_log_archive_name (archive_name, logwr_Gl.log_path, logwr_Gl.db_name, arvhdr->arv_num);
1324  bg_arv_info = &logwr_Gl.bg_archive_info;
1326  {
1327  if (bg_arv_info->vdes == NULL_VOLDES)
1328  {
1329  error_code = ER_HA_GENERIC_ERROR;
1331  "invalid temporary archive log file");
1332  goto error;
1333  }
1334  vdes = bg_arv_info->vdes;
1335  }
1336  else
1337  {
1338  if (fileio_is_volume_exist (archive_name) == true)
1339  {
1340  vdes = fileio_mount (NULL, archive_name, archive_name, LOG_DBLOG_ARCHIVE_VOLID, true, false);
1341  if (vdes == NULL_VOLDES)
1342  {
1343  error_code = ER_IO_MOUNT_FAIL;
1344  goto error;
1345  }
1346  }
1347  else
1348  {
1349  vdes =
1350  fileio_format (NULL, logwr_Gl.db_name, archive_name, LOG_DBLOG_ARCHIVE_VOLID, arvhdr->npages + 1, false,
1351  false, false, LOG_PAGESIZE, 0, false);
1352  if (vdes == NULL_VOLDES)
1353  {
1354  /* Unable to create archive log to archive */
1355  error_code = ER_LOG_CREATE_LOGARCHIVE_FAIL;
1357  arvhdr->fpageid, arvhdr->fpageid + arvhdr->npages - 1);
1358  goto error;
1359  }
1360  }
1361  }
1362 
1363  if (fileio_write (NULL, vdes, malloc_arv_hdr_pgptr, 0, LOG_PAGESIZE, FILEIO_WRITE_NO_COMPENSATE_WRITE) == NULL)
1364  {
1365  /* Error archiving header page into archive */
1366  error_code = ER_LOG_WRITE;
1367  er_set (ER_FATAL_ERROR_SEVERITY, ARG_FILE_LINE, ER_LOG_WRITE, 3, 0LL, 0LL, archive_name);
1368  goto error;
1369  }
1370 
1372  && logwr_Gl.last_arv_fpageid == bg_arv_info->start_page_id)
1373  {
1374  pageid = bg_arv_info->current_page_id;
1375  ar_phy_pageid = (LOG_PHY_PAGEID) (bg_arv_info->current_page_id - bg_arv_info->start_page_id + 1);
1376  }
1377  else
1378  {
1379  pageid = logwr_Gl.last_arv_fpageid;
1380  ar_phy_pageid = 1;
1381  }
1382 
1383  log_pgptr = (LOG_PAGE *) aligned_log_pgbuf;
1384 
1385  /* Now start dumping the current active pages to archive */
1386  for (; pageid <= logwr_Gl.last_arv_lpageid; pageid += num_pages, ar_phy_pageid += num_pages)
1387  {
1388  /*
1389  * Page is contained in the active log.
1390  * Find the corresponding physical page and read the page form disk.
1391  */
1392  num_pages = MIN (LOGPB_IO_NPAGES, (int) (logwr_Gl.last_arv_lpageid - pageid + 1));
1393 
1394  phy_pageid = logwr_to_physical_pageid (pageid);
1395  num_pages = MIN (num_pages, logwr_Gl.hdr.npages - phy_pageid + 1);
1396 
1397  if (fileio_read_pages (NULL, logwr_Gl.append_vdes, (char *) log_pgptr, phy_pageid, num_pages, LOG_PAGESIZE) ==
1398  NULL)
1399  {
1400  error_code = ER_LOG_READ;
1401  er_set (ER_FATAL_ERROR_SEVERITY, ARG_FILE_LINE, ER_LOG_READ, 3, pageid, phy_pageid, logwr_Gl.active_name);
1402  goto error;
1403  }
1404  else
1405  {
1406  if (log_pgptr->hdr.logical_pageid != pageid)
1407  {
1408  /* Clean the buffer... since it may be corrupted */
1409  error_code = ER_LOG_PAGE_CORRUPTED;
1411  goto error;
1412  }
1413  }
1414  /* no need to encrypt, it is read as not decrypted (TDE) if encrypted */
1415  if (fileio_write_pages (NULL, vdes, (char *) log_pgptr, ar_phy_pageid, num_pages, LOG_PAGESIZE,
1417  {
1418  error_code = ER_LOG_WRITE;
1419  er_set (ER_FATAL_ERROR_SEVERITY, ARG_FILE_LINE, ER_LOG_WRITE, 3, pageid, ar_phy_pageid, archive_name);
1420  goto error;
1421  }
1422  }
1423 
1424  fileio_dismount (NULL, vdes);
1425  vdes = NULL_VOLDES;
1426 
1428  {
1429  bg_arv_info->vdes = NULL_VOLDES;
1430  if (fileio_rename (NULL_VOLID, logwr_Gl.bg_archive_name, archive_name) == NULL)
1431  {
1432  goto error;
1433  }
1434  bg_arv_info->vdes =
1435  fileio_format (NULL, logwr_Gl.db_name, logwr_Gl.bg_archive_name, LOG_DBLOG_BG_ARCHIVE_VOLID,
1436  logwr_Gl.hdr.npages, false, false, false, LOG_PAGESIZE, 0, false);
1437  if (bg_arv_info->vdes != NULL_VOLDES)
1438  {
1439  bg_arv_info->start_page_id = logwr_Gl.last_arv_lpageid + 1;
1440  bg_arv_info->current_page_id = NULL_PAGEID;
1441  }
1442  else
1443  {
1444  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_HA_GENERIC_ERROR, 1, "Unable to create temporary archive log");
1445  return ER_HA_GENERIC_ERROR;
1446  }
1447  error_code = logwr_flush_bgarv_header_page ();
1448  if (error_code != NO_ERROR)
1449  {
1450  goto error;
1451  }
1452  }
1453 
1454  /* Update archive info */
1455  logwr_Gl.last_arv_num++;
1456  logwr_Gl.last_arv_fpageid = logwr_Gl.last_arv_lpageid + 1;
1457 
1458  /* set append lsa as last archive logical pageid */
1459  /* in order to prevent log applier reading an immature active log page. */
1460  LSA_COPY (&saved_append_lsa, &logwr_Gl.hdr.append_lsa);
1461  logwr_Gl.hdr.append_lsa.pageid = logwr_Gl.last_arv_lpageid;
1462  logwr_Gl.hdr.append_lsa.offset = NULL_OFFSET;
1463 
1464  /* Flush the log header to reflect the archive */
1465  logwr_flush_header_page ();
1466 
1467  /* restore append lsa */
1468  LSA_COPY (&logwr_Gl.hdr.append_lsa, &saved_append_lsa);
1469 
1471  arvhdr->fpageid + arvhdr->npages - 1);
1472 
1474  if (catmsg == NULL)
1475  {
1476  catmsg = "ARCHIVE: %d %s %lld %lld\n";
1477  }
1478  error_code =
1479  log_dump_log_info (logwr_Gl.loginf_path, false, catmsg, arvhdr->arv_num, archive_name, arvhdr->fpageid,
1480  arvhdr->fpageid + arvhdr->npages - 1);
1481  logwr_er_log ("logwr_archive_active_log, arv_num(%d), fpageid(%lld) lpageid(%lld)\n", arvhdr->arv_num,
1482  arvhdr->fpageid, arvhdr->fpageid + arvhdr->npages - 1);
1483 
1484  free_and_init (malloc_arv_hdr_pgptr);
1485 
1486  return NO_ERROR;
1487 
1488 error:
1489 
1490  if (malloc_arv_hdr_pgptr != NULL)
1491  {
1492  free_and_init (malloc_arv_hdr_pgptr);
1493  }
1494 
1495  if (vdes != NULL_VOLDES)
1496  {
1497  fileio_dismount (NULL, vdes);
1498  fileio_unformat (NULL, archive_name);
1499  }
1500 
1501  return error_code;
1502 }
1503 
1504 /*
1505  * logwr_write_log_pages -
1506  *
1507  * return:
1508  * Note:
1509  */
1510 int
1511 logwr_write_log_pages (void)
1512 {
1513  int error;
1514  struct timeval curtime;
1515  int diff_msec;
1516 
1517  if (logwr_Gl.num_toflush <= 0)
1518  return NO_ERROR;
1519 
1520  if (logwr_Gl.mode == LOGWR_MODE_SEMISYNC)
1521  {
1522  gettimeofday (&curtime, NULL);
1523  diff_msec =
1524  (((curtime.tv_sec - logwr_Gl.last_flush_time.tv_sec) * 1000) +
1525  ((curtime.tv_usec - logwr_Gl.last_flush_time.tv_usec) / 1000));
1526 
1527  if (logwr_Gl.force_flush == false && !LOGWR_AT_SERVER_ARCHIVING ()
1528  && (logwr_Gl.hdr.eof_lsa.pageid <= logwr_Gl.toflush[0]->hdr.logical_pageid) && (diff_msec < 1000))
1529  {
1530  return NO_ERROR;
1531  }
1532 
1533  logwr_Gl.force_flush = false;
1534  }
1535 
1536  if (logwr_Gl.append_vdes == NULL_VOLDES && !fileio_is_volume_exist (logwr_Gl.active_name))
1537  {
1538  /* Create a new active log */
1539  logwr_Gl.append_vdes =
1540  fileio_format (NULL, logwr_Gl.db_name, logwr_Gl.active_name, LOG_DBLOG_ACTIVE_VOLID, (logwr_Gl.hdr.npages + 1),
1541  prm_get_bool_value (PRM_ID_LOG_SWEEP_CLEAN), true, false, LOG_PAGESIZE, 0, false);
1542  if (logwr_Gl.append_vdes == NULL_VOLDES)
1543  {
1544  /* Unable to create an active log */
1545  return ER_IO_FORMAT_FAIL;
1546  }
1547  }
1548 
1549  /*
1550  * LWT sets the archiving flag at the time when it sends new active page
1551  * after archiving finished, so that logwr_archive_active_log() should
1552  * be executed before logwr_flush_all_append_pages().
1553  */
1554  if (logwr_Gl.action & LOGWR_ACTION_ARCHIVING)
1555  {
1556  error = logwr_archive_active_log ();
1557  if (error != NO_ERROR)
1558  {
1559  return error;
1560  }
1561  }
1562 
1563  error = logwr_flush_all_append_pages ();
1564  if (error != NO_ERROR)
1565  {
1566  return error;
1567  }
1568 
1569  logwr_flush_header_page ();
1570 
1571  gettimeofday (&logwr_Gl.last_flush_time, NULL);
1572 
1573  return NO_ERROR;
1574 }
1575 
1576 #if !defined(WINDOWS)
1577 /*
1578  * logwr_copy_log_header_check
1579  * return:
1580  *
1581  * master_eof_lsa(OUT): record eof_lsa to calculate replication delay
1582  *
1583  * note:
1584  */
1585 int
1586 logwr_copy_log_header_check (const char *db_name, bool verbose, LOG_LSA * master_eof_lsa)
1587 {
1588  int error = NO_ERROR;
1589  LOGWR_CONTEXT ctx = { -1, 0, false };
1590  OR_ALIGNED_BUF (OR_INT_SIZE * 2 + OR_INT64_SIZE) a_request;
1591  OR_ALIGNED_BUF (OR_INT_SIZE * 2) a_reply;
1592  char *request, *reply;
1593  char *ptr;
1594  char *logpg_area = NULL;
1595  LOG_PAGE *loghdr_pgptr;
1596  LOG_HEADER hdr;
1597  char *atchar;
1598 
1599  atchar = (char *) strchr (db_name, '@');
1600  if (atchar)
1601  {
1602  *atchar = '\0';
1603  }
1604 
1605  request = OR_ALIGNED_BUF_START (a_request);
1606  reply = OR_ALIGNED_BUF_START (a_reply);
1607 
1608  /* HEADER PAGE REQUEST */
1609  ptr = or_pack_int64 (request, LOGPB_HEADER_PAGE_ID);
1610  ptr = or_pack_int (ptr, LOGWR_MODE_ASYNC);
1611  ptr = or_pack_int (ptr, NO_ERROR);
1612 
1613  error =
1614  net_client_check_log_header (&ctx, request, OR_ALIGNED_BUF_SIZE (a_request), reply, OR_ALIGNED_BUF_SIZE (a_reply),
1615  (char **) &logpg_area, verbose);
1616  if (error != NO_ERROR)
1617  {
1618  return error;
1619  }
1620  else
1621  {
1622 
1623  loghdr_pgptr = (LOG_PAGE *) logpg_area;
1624  memcpy (&hdr, loghdr_pgptr->area, sizeof (LOG_HEADER));
1625 
1626  *master_eof_lsa = hdr.eof_lsa;
1627 
1628  printf ("\n *** Active Info. *** \n");
1629  la_print_log_header (db_name, &hdr, verbose);
1630 
1631  free_and_init (logpg_area);
1632  }
1633 
1634  /* END REQUEST */
1635  ptr = or_pack_int64 (request, LOGPB_HEADER_PAGE_ID);
1636  ptr = or_pack_int (ptr, LOGWR_MODE_ASYNC);
1637  /* send ER_GENERIC_ERROR to make LWT not wait for more page requests */
1638  ptr = or_pack_int (ptr, ER_GENERIC_ERROR);
1639 
1640  error =
1641  net_client_check_log_header (&ctx, request, OR_ALIGNED_BUF_SIZE (a_request), reply, OR_ALIGNED_BUF_SIZE (a_reply),
1642  (char **) &logpg_area, verbose);
1643  return error;
1644 }
1645 #endif /* !WINDOWS */
1646 
1647 /*
1648  * logwr_copy_log_file -
1649  *
1650  * return: NO_ERROR if successful, error_code otherwise
1651  *
1652  * db_name(in): database name to copy the log file
1653  * log_path(in): file pathname to copy the log file
1654  * mode(in): LOGWR_MODE_SYNC, LOGWR_MODE_ASYNC or LOGWR_MODE_SEMISYNC
1655  *
1656  * Note:
1657  */
1658 int
1659 logwr_copy_log_file (const char *db_name, const char *log_path, int mode, INT64 start_page_id)
1660 {
1661  LOGWR_CONTEXT ctx = { -1, 0, false };
1662  int error = NO_ERROR;
1663 
1664  if ((error = logwr_initialize (db_name, log_path, mode, start_page_id)) != NO_ERROR)
1665  {
1666  logwr_finalize ();
1667  return error;
1668  }
1669 
1671 
1672  while (!ctx.shutdown && !logwr_need_shutdown)
1673  {
1674  if ((error = logwr_get_log_pages (&ctx)) != NO_ERROR)
1675  {
1676  ctx.last_error = error;
1677 
1678  if (error == ER_HA_LW_FAILED_GET_LOG_PAGE)
1679  {
1680 #if !defined(WINDOWS)
1683  "Encountered an unrecoverable error and will shut itself down", "");
1684 #endif /* !WINDOWS */
1685  }
1686 
1687  if (logwr_Gl.reinit_copylog)
1688  {
1689  char error_str[LINE_MAX];
1690 
1691  sprintf (error_str,
1692  "Replication logs and catalog have been reinitialized "
1693  "due to rebuilt database on the peer node");
1695  error = ER_HA_GENERIC_ERROR;
1696 
1697  logwr_reinit_copylog ();
1698 
1699  goto end;
1700  }
1701  }
1702  else
1703  {
1704  if (logwr_Gl.action & LOGWR_ACTION_ASYNC_WRITE)
1705  {
1706  error = logwr_write_log_pages ();
1707  if (error != NO_ERROR)
1708  {
1709  ctx.last_error = error;
1710  }
1711  }
1712  }
1713  logwr_Gl.action = (LOGWR_ACTION) (logwr_Gl.action & LOGWR_ACTION_DELAYED_WRITE);
1714  }
1715 
1716 #if !defined(WINDOWS)
1717  if (hb_Proc_shutdown == true)
1718  {
1720  "Disconnected with the cub_master and will shut itself down", "");
1721  }
1722 #endif /* ! WINDOWS */
1723 
1724  /* SIGNAL caught and shutdown */
1725  if (logwr_need_shutdown)
1726  {
1727  if (logwr_Gl.mode == LOGWR_MODE_SEMISYNC)
1728  {
1729  logwr_Gl.force_flush = true;
1730  logwr_write_log_pages ();
1731  }
1732 
1735  }
1736 
1737 end:
1738  if (ctx.rc > 0)
1739  {
1740  if (logwr_Gl.start_pageid >= NULL_PAGEID && error == NO_ERROR)
1741  {
1742  /* to shutdown log writer thread of cub_server */
1744  }
1745  else
1746  {
1747  net_client_logwr_send_end_msg (ctx.rc, error);
1748  }
1749  }
1750 
1751  logwr_finalize ();
1752  return error;
1753 }
1754 
1755 static void
1756 logwr_reinit_copylog (void)
1757 {
1758 #if !defined(WINDOWS)
1759  DIR *dirp;
1760  struct dirent *dp;
1761  char log_archive_path[2 * PATH_MAX];
1762  char archive_log_prefix[2 * PATH_MAX];
1763  int archive_log_prefix_len;
1764  BACKGROUND_ARCHIVING_INFO *bg_arv_info = NULL;
1765 
1766  /* mark will be deleted */
1767  logwr_Gl.hdr.mark_will_del = true;
1768  logwr_flush_header_page ();
1769 
1770  /* remove background archive */
1772  {
1773  if (logwr_Gl.bg_archive_info.vdes != NULL_VOLDES)
1774  {
1775  bg_arv_info = &logwr_Gl.bg_archive_info;
1776 
1777  fileio_dismount (NULL, bg_arv_info->vdes);
1778  bg_arv_info->vdes = NULL_VOLDES;
1779  }
1780 
1781  fileio_unformat (NULL, logwr_Gl.bg_archive_name);
1782  }
1783 
1784  /* remove log info */
1785  fileio_unformat (NULL, logwr_Gl.loginf_path);
1786 
1787  /* remove archive logs */
1788  sprintf (archive_log_prefix, "%s%s", logwr_Gl.db_name, FILEIO_SUFFIX_LOGARCHIVE);
1789  archive_log_prefix_len = strlen (archive_log_prefix);
1790  dirp = opendir (logwr_Gl.log_path);
1791  if (dirp == NULL)
1792  {
1793  assert (false);
1794  return;
1795  }
1796 
1797  do
1798  {
1799  errno = 0;
1800  dp = readdir (dirp);
1801  if (dp == NULL)
1802  {
1803  if (errno != 0)
1804  {
1805  assert (false);
1806  }
1807  break;
1808  }
1809 
1810  if (strncmp (archive_log_prefix, dp->d_name, archive_log_prefix_len) == 0)
1811  {
1812  sprintf (log_archive_path, "%s%s%s", logwr_Gl.log_path, FILEIO_PATH_SEPARATOR (logwr_Gl.log_path),
1813  dp->d_name);
1814  fileio_unformat (NULL, log_archive_path);
1815  }
1816  }
1817  while (1);
1818  closedir (dirp);
1819 
1820  /* remove active log */
1821  if (logwr_Gl.append_vdes != NULL_VOLDES)
1822  {
1823  fileio_dismount (NULL, logwr_Gl.append_vdes);
1824  logwr_Gl.append_vdes = NULL_VOLDES;
1825  }
1826  fileio_unformat (NULL, logwr_Gl.active_name);
1827 
1828 #endif /* !WINDOWS */
1829  return;
1830 }
1831 
1832 #ifdef UNSTABLE_TDE_FOR_REPLICATION_LOG
1833 static int
1834 logwr_load_tde (void)
1835 {
1836  int client_len;
1837  int client_sockfd;
1838  char sock_path[PATH_MAX];
1839  TDE_DATA_KEY_SET dks;
1840  char *bufptr;
1841  int nbytes, len;
1842  int err_msg = NO_ERROR;
1843 
1844  struct sockaddr_un clientaddr;
1845 
1846  fileio_make_ha_sock_name (sock_path, logwr_Gl.log_path, TDE_HA_SOCK_NAME);
1847 
1848  client_sockfd = socket (AF_UNIX, SOCK_STREAM, 0);
1849  if (client_sockfd == -1)
1850  {
1851  er_set_with_oserror (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_TDE_DK_SHARING_SOCK_OPEN, 1, sock_path);
1852  return ER_TDE_DK_SHARING_SOCK_OPEN;
1853  }
1854 
1855  bzero (&clientaddr, sizeof (clientaddr));
1856  clientaddr.sun_family = AF_UNIX;
1857  strcpy (clientaddr.sun_path, sock_path);
1858  client_len = sizeof (clientaddr);
1859 
1860  if (connect (client_sockfd, (struct sockaddr *) &clientaddr, client_len) < 0)
1861  {
1862  er_set_with_oserror (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_TDE_DK_SHARING_SOCK_CONNECT, 0);
1863  return ER_TDE_DK_SHARING_SOCK_CONNECT;
1864  }
1865 
1866  bufptr = logwr_Gl.log_path;
1867  len = PATH_MAX;
1868  while (len > 0)
1869  {
1870  nbytes = write (client_sockfd, bufptr, len);
1871  if (nbytes < 0)
1872  {
1873  switch (errno)
1874  {
1875  case EINTR:
1876  case EAGAIN:
1877  continue;
1878  default:
1879  {
1880  close (client_sockfd);
1881  er_set_with_oserror (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_TDE_DK_SHARING_SOCK_WRITE, 0);
1882  return ER_TDE_DK_SHARING_SOCK_WRITE;
1883  }
1884  }
1885  }
1886  bufptr += nbytes;
1887  len -= nbytes;
1888  }
1889 
1890  /* read error message */
1891  bufptr = (char *) &err_msg;
1892  len = sizeof (err_msg);
1893  while (len > 0)
1894  {
1895  nbytes = read (client_sockfd, bufptr, len);
1896  if (nbytes < 0)
1897  {
1898  switch (errno)
1899  {
1900  case EINTR:
1901  case EAGAIN:
1902  continue;
1903  default:
1904  {
1905  close (client_sockfd);
1906  er_set_with_oserror (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_TDE_DK_SHARING_SOCK_READ, 0);
1907  return ER_TDE_DK_SHARING_SOCK_READ;
1908  }
1909  }
1910  }
1911  bufptr += nbytes;
1912  len -= nbytes;
1913  }
1914 
1915  if (err_msg != NO_ERROR)
1916  {
1917  close (client_sockfd);
1918  return err_msg;
1919  }
1920 
1921  /* read data keys */
1922 
1923  bufptr = (char *) &dks;
1924  len = sizeof (TDE_DATA_KEY_SET);
1925  while (len > 0)
1926  {
1927  nbytes = read (client_sockfd, bufptr, len);
1928  if (nbytes < 0)
1929  {
1930  switch (errno)
1931  {
1932  case EINTR:
1933  case EAGAIN:
1934  continue;
1935  default:
1936  {
1937  close (client_sockfd);
1938  er_set_with_oserror (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_TDE_DK_SHARING_SOCK_READ, 0);
1939  return ER_TDE_DK_SHARING_SOCK_READ;
1940  }
1941  }
1942  }
1943  bufptr += nbytes;
1944  len -= nbytes;
1945  }
1946 
1950 
1951  tde_Cipher.is_loaded = true;
1952 
1953  close (client_sockfd);
1954  return NO_ERROR;
1955 }
1956 #endif /* UNSTABLE_TDE_FOR_REPLICATION_LOG */
1957 
1958 #else /* CS_MODE */
1959 int
1960 logwr_copy_log_file (const char *db_name, const char *log_path, int mode, INT64 start_page_id)
1961 {
1962  return ER_FAILED;
1963 }
1964 #endif /* !CS_MODE */
1965 
1966 
1967 
1968 /*
1969  * logwr_compute_page_checksum - Computes log page checksum.
1970  * return: error code
1971  * thread_p (in) : thread entry
1972  * log_pgptr (in) : log page pointer
1973  * checksum_crc32(out): computed checksum
1974  * Note: Currently CRC32 is used as checksum.
1975  * Note: this is a copy of logpb_compute_page_checksum
1976  */
1977 static int
1979 {
1980  int error_code = NO_ERROR, saved_checksum_crc32;
1981  const int block_size = 4096;
1982  const int max_num_pages = IO_MAX_PAGE_SIZE / block_size;
1983  const int sample_nbytes = 16;
1984  int sampling_offset;
1985  char buf[max_num_pages * sample_nbytes * 2];
1986  const int num_pages = LOG_PAGESIZE / block_size;
1987  const size_t sizeof_buf = num_pages * sample_nbytes * 2;
1988  int checksum_crc32;
1989 
1990  assert (log_pgptr != NULL);
1991 
1992  /* Save the old page checksum. */
1993  saved_checksum_crc32 = log_pgptr->hdr.checksum;
1994  if (saved_checksum_crc32 == 0)
1995  {
1996  return NO_ERROR;
1997  }
1998 
1999  /* Resets checksum to not affect the new computation. */
2000  log_pgptr->hdr.checksum = 0;
2001 
2002  char *p = buf;
2003  for (int i = 0; i < num_pages; i++)
2004  {
2005  // first
2006  sampling_offset = (i * block_size);
2007  memcpy (p, ((char *) log_pgptr) + sampling_offset, sample_nbytes);
2008  p += sample_nbytes;
2009 
2010  // last
2011  sampling_offset = (i * block_size) + (block_size - sample_nbytes);
2012  memcpy (p, ((char *) log_pgptr) + sampling_offset, sample_nbytes);
2013  p += sample_nbytes;
2014  }
2015 
2016  crypt_crc32 ((char *) buf, (int) sizeof_buf, &checksum_crc32);
2017 
2018  /* Restores the saved checksum */
2019  log_pgptr->hdr.checksum = saved_checksum_crc32;
2020 
2021  if (checksum_crc32 != saved_checksum_crc32)
2022  {
2024  "logwr_check_page_checksum: log page %lld has checksum = %d, computed checksum = %d\n",
2025  (long long int) log_pgptr->hdr.logical_pageid, saved_checksum_crc32, checksum_crc32);
2026  assert (false);
2027  return ER_FAILED;
2028  }
2029 
2030  return error_code;
2031 }
2032 
2033 /*
2034  * logwr_log_ha_filestat_to_string() - return the string alias of enum value
2035  *
2036  * return: constant string
2037  *
2038  * val(in):
2039  */
2040 const char *
2042 {
2043  switch (val)
2044  {
2045  case LOG_HA_FILESTAT_CLEAR:
2046  return "CLEAR";
2048  return "ARCHIVED";
2050  return "SYNCHRONIZED";
2051  default:
2052  return "UNKNOWN";
2053  }
2054 }
2055 
2056 #ifdef UNSTABLE_TDE_FOR_REPLICATION_LOG
2058 logwr_get_tde_algorithm (const LOG_PAGE * log_pgptr)
2059 {
2060  /* exclusive */
2062  && (log_pgptr->hdr.flags & LOG_HDRPAGE_FLAG_ENCRYPTED_ARIA)));
2063 
2064  if (log_pgptr->hdr.flags & LOG_HDRPAGE_FLAG_ENCRYPTED_AES)
2065  {
2066  return TDE_ALGORITHM_AES;
2067  }
2068  else if (log_pgptr->hdr.flags & LOG_HDRPAGE_FLAG_ENCRYPTED_ARIA)
2069  {
2070  return TDE_ALGORITHM_ARIA;
2071  }
2072  else
2073  {
2074  return TDE_ALGORITHM_NONE;
2075  }
2076 }
2077 
2078 void
2079 logwr_set_tde_algorithm (THREAD_ENTRY * thread_p, LOG_PAGE * log_pgptr, const TDE_ALGORITHM tde_algo)
2080 {
2081  /* clear encrypted flag */
2082  log_pgptr->hdr.flags &= ~LOG_HDRPAGE_FLAG_ENCRYPTED_MASK;
2083 
2084  switch (tde_algo)
2085  {
2086  case TDE_ALGORITHM_AES:
2088  break;
2089  case TDE_ALGORITHM_ARIA:
2091  break;
2092  case TDE_ALGORITHM_NONE:
2093  /* already cleared */
2094  break;
2095  }
2096 }
2097 #endif /* UNSTABLE_TDE_FOR_REPLICATION_LOG */
2098 
2099 #if defined(SERVER_MODE)
2100 static int logwr_register_writer_entry (LOGWR_ENTRY ** wr_entry_p, THREAD_ENTRY * thread_p, LOG_PAGEID fpageid,
2101  int mode, bool copy_from_first_phy_page);
2102 static bool logwr_unregister_writer_entry (LOGWR_ENTRY * wr_entry, int status);
2103 static int logwr_pack_log_pages (THREAD_ENTRY * thread_p, char *logpg_area, int *logpg_used_size, int *status,
2104  LOGWR_ENTRY * entry, bool copy_from_file);
2105 static void logwr_cs_exit (THREAD_ENTRY * thread_p, bool * check_cs_own);
2106 static void logwr_write_end (THREAD_ENTRY * thread_p, LOGWR_INFO * writer_info, LOGWR_ENTRY * entry, int status);
2107 static void logwr_set_eof_lsa (THREAD_ENTRY * thread_p, LOGWR_ENTRY * entry);
2108 static bool logwr_is_delayed (THREAD_ENTRY * thread_p, LOGWR_ENTRY * entry);
2109 static void logwr_update_last_sent_eof_lsa (LOGWR_ENTRY * entry);
2110 
2111 /*
2112  * logwr_register_writer_entry -
2113  *
2114  * return:
2115  *
2116  * wr_entry_p(out):
2117  * id(in):
2118  * fpageid(in):
2119  * mode(in):
2120  *
2121  * Note:
2122  */
2123 static int
2124 logwr_register_writer_entry (LOGWR_ENTRY ** wr_entry_p, THREAD_ENTRY * thread_p, LOG_PAGEID fpageid, int mode,
2125  bool copy_from_first_phy_page)
2126 {
2127  LOGWR_ENTRY *entry;
2128  int rv;
2129  LOGWR_INFO *writer_info = log_Gl.writer_info;
2130 
2131  *wr_entry_p = NULL;
2132  rv = pthread_mutex_lock (&writer_info->wr_list_mutex);
2133 
2134  entry = writer_info->writer_list;
2135  while (entry)
2136  {
2137  if (entry->thread_p == thread_p)
2138  {
2139  break;
2140  }
2141  entry = entry->next;
2142  }
2143 
2144  if (entry == NULL)
2145  {
2146  entry = (LOGWR_ENTRY *) malloc (sizeof (LOGWR_ENTRY));
2147  if (entry == NULL)
2148  {
2149  pthread_mutex_unlock (&writer_info->wr_list_mutex);
2151  return ER_OUT_OF_VIRTUAL_MEMORY;
2152  }
2153 
2154  entry->thread_p = thread_p;
2155  entry->fpageid = fpageid;
2156  entry->mode = (LOGWR_MODE) mode;
2157  entry->start_copy_time = 0;
2158  entry->copy_from_first_phy_page = copy_from_first_phy_page;
2159 
2160  entry->status = LOGWR_STATUS_DELAY;
2161  LSA_SET_NULL (&entry->eof_lsa);
2162  LSA_SET_NULL (&entry->last_sent_eof_lsa);
2164 
2165  entry->next = writer_info->writer_list;
2166  writer_info->writer_list = entry;
2167  }
2168  else
2169  {
2170  entry->fpageid = fpageid;
2171  entry->mode = (LOGWR_MODE) mode;
2172  entry->copy_from_first_phy_page = copy_from_first_phy_page;
2173  if (entry->status != LOGWR_STATUS_DELAY)
2174  {
2175  entry->status = LOGWR_STATUS_WAIT;
2176  entry->start_copy_time = 0;
2177  }
2178  }
2179 
2180  pthread_mutex_unlock (&writer_info->wr_list_mutex);
2181  *wr_entry_p = entry;
2182 
2183  return NO_ERROR;
2184 }
2185 
2186 /*
2187  * logwr_unregister_writer_entry -
2188  *
2189  * return:
2190  *
2191  * wr_entry(in):
2192  * status(in):
2193  *
2194  * Note:
2195  */
2196 static bool
2197 logwr_unregister_writer_entry (LOGWR_ENTRY * wr_entry, int status)
2198 {
2199  LOGWR_ENTRY *entry;
2200  bool is_all_done;
2201  int rv;
2202  LOGWR_INFO *writer_info = log_Gl.writer_info;
2203 
2204  rv = pthread_mutex_lock (&writer_info->wr_list_mutex);
2205 
2206  wr_entry->status = (LOGWR_STATUS) status;
2207 
2208  entry = writer_info->writer_list;
2209  while (entry)
2210  {
2211  if (entry->status == LOGWR_STATUS_FETCH)
2212  {
2213  break;
2214  }
2215  entry = entry->next;
2216  }
2217 
2218  is_all_done = (entry == NULL) ? true : false;
2219 
2220  if (status == LOGWR_STATUS_ERROR)
2221  {
2222  LOGWR_ENTRY *prev_entry = NULL;
2223  entry = writer_info->writer_list;
2224  while (entry)
2225  {
2226  if (entry == wr_entry)
2227  {
2228  if (entry == writer_info->writer_list)
2229  {
2230  writer_info->writer_list = entry->next;
2231  }
2232  else
2233  {
2234  prev_entry->next = entry->next;
2235  }
2236  free_and_init (entry);
2237  break;
2238  }
2239  prev_entry = entry;
2240  entry = entry->next;
2241  }
2242  }
2243  pthread_mutex_unlock (&writer_info->wr_list_mutex);
2244 
2245  return is_all_done;
2246 }
2247 
2248 
2249 /*
2250  * logwr_pack_log_pages -
2251  *
2252  * return:
2253  *
2254  * thread_p(in):
2255  * logpg_area(in):
2256  * logpg_used_size(out):
2257  * status(out): LOGWR_STATUS_DONE, LOGWR_STATUS_DELAY or LOGWR_STATUS_ERROR
2258  * entry(in):
2259  *
2260  * Note:
2261  */
2262 static int
2263 logwr_pack_log_pages (THREAD_ENTRY * thread_p, char *logpg_area, int *logpg_used_size, int *status, LOGWR_ENTRY * entry,
2264  bool copy_from_file)
2265 {
2266  LOG_PAGEID fpageid, lpageid, pageid;
2267  char *p;
2268  LOG_PAGE *log_pgptr;
2269  UINT64 num_logpgs;
2270  LOG_LSA nxio_lsa = LSA_INITIALIZER;
2271  bool is_hdr_page_only;
2272  int ha_file_status;
2273  int error_code;
2274 
2275  LOG_ARV_HEADER arvhdr;
2276  LOG_HEADER *hdr_ptr;
2277  int nxarv_num = 0;
2278  LOG_PAGEID nxarv_pageid = NULL_PAGEID, nxarv_phy_pageid = NULL_PAGEID;
2279 
2280  LOG_LSA eof_lsa;
2281 
2282  fpageid = NULL_PAGEID;
2283  lpageid = NULL_PAGEID;
2284  ha_file_status = LOG_HA_FILESTAT_CLEAR;
2285 
2286  is_hdr_page_only = (entry->fpageid == LOGPB_HEADER_PAGE_ID);
2287 
2288  if (is_hdr_page_only == true && entry->copy_from_first_phy_page == true)
2289  {
2290  assert_release (false);
2291  error_code = ER_FAILED;
2292  goto error;
2293  }
2294 
2295  if (LSA_ISNULL (&entry->eof_lsa))
2296  {
2297  LSA_COPY (&eof_lsa, &log_Gl.hdr.eof_lsa);
2298  }
2299  else
2300  {
2301  LSA_COPY (&eof_lsa, &entry->eof_lsa);
2302  }
2303 
2304  if (entry->copy_from_first_phy_page == true)
2305  {
2306  fpageid = entry->fpageid;
2307  if (fpageid == NULL_PAGEID)
2308  {
2309  fpageid = logpb_find_oldest_available_page_id (thread_p);
2310  if (fpageid == NULL_PAGEID)
2311  {
2312  error_code = ER_FAILED;
2313  goto error;
2314  }
2315  }
2316 
2317  if (logpb_is_page_in_archive (fpageid) == true)
2318  {
2319  if (logpb_fetch_from_archive (thread_p, fpageid, NULL, NULL, &arvhdr, false) == NULL)
2320  {
2321  error_code = ER_FAILED;
2322  goto error;
2323  }
2324 
2325  nxarv_phy_pageid = 1; /* first physical page id */
2326  nxarv_pageid = arvhdr.fpageid;
2327  nxarv_num = arvhdr.arv_num;
2328  }
2329  else
2330  {
2331  nxarv_phy_pageid = log_Gl.hdr.nxarv_phy_pageid;
2332  nxarv_pageid = log_Gl.hdr.nxarv_pageid;
2333  nxarv_num = log_Gl.hdr.nxarv_num;
2334  }
2335 
2336  lpageid = nxarv_pageid;
2337  fpageid = nxarv_pageid;
2338  }
2339  else if (!is_hdr_page_only)
2340  {
2341  /* Find the first pageid to be packed */
2342  fpageid = entry->fpageid;
2343  if (fpageid == NULL_PAGEID)
2344  {
2345  /* In case of first request from the log writer, pack all active pages to be flushed until now */
2346  fpageid = log_Gl.hdr.nxarv_pageid;
2347  }
2348  else
2349  {
2350  nxio_lsa = log_Gl.append.get_nxio_lsa ();
2351  if (fpageid > nxio_lsa.pageid)
2352  {
2353  fpageid = nxio_lsa.pageid;
2354  }
2355  }
2356 
2357  /* Find the last pageid which is bounded by several limitations */
2358  if (!logpb_is_page_in_archive (fpageid))
2359  {
2360  lpageid = eof_lsa.pageid;
2361  }
2362  else
2363  {
2364  LOG_ARV_HEADER arvhdr;
2365 
2366  /* If the fpageid is in archive log, fetch the page and the header page in the archive */
2367  if (logpb_fetch_from_archive (thread_p, fpageid, NULL, NULL, &arvhdr, false) == NULL)
2368  {
2369  error_code = ER_FAILED;
2370  goto error;
2371  }
2372  /* Reset the lpageid with the last pageid in the archive */
2373  lpageid = arvhdr.fpageid + arvhdr.npages - 1;
2374  if (fpageid == arvhdr.fpageid)
2375  {
2376  ha_file_status = LOG_HA_FILESTAT_ARCHIVED;
2377  }
2378  }
2379  /* Pack the pages which can be in the page area of Log Writer */
2380  if (((size_t) (lpageid - fpageid + 1)) > (LOGWR_COPY_LOG_BUFFER_NPAGES - 1))
2381  {
2382  lpageid = fpageid + (LOGWR_COPY_LOG_BUFFER_NPAGES - 1) - 1;
2383  }
2384  if (lpageid == eof_lsa.pageid)
2385  {
2386  ha_file_status = LOG_HA_FILESTAT_SYNCHRONIZED;
2387  }
2388  }
2389 
2390  /* Set the server status on the header information */
2392  log_Gl.hdr.ha_file_status = ha_file_status;
2393 
2394  /* Allocate the log page area */
2395  num_logpgs = (is_hdr_page_only) ? 1 : (UINT64) ((lpageid - fpageid + 1) + 1);
2396 
2397  assert (lpageid >= fpageid);
2398  assert (num_logpgs <= LOGWR_COPY_LOG_BUFFER_NPAGES);
2399 
2400  p = logpg_area;
2401 
2402  /* Fill the header page */
2403  log_pgptr = (LOG_PAGE *) p;
2404  log_pgptr->hdr = log_Gl.loghdr_pgptr->hdr;
2405  memcpy (log_pgptr->area, &log_Gl.hdr, sizeof (log_Gl.hdr));
2406 
2407  hdr_ptr = (LOG_HEADER *) (log_pgptr->area);
2408  if (entry->copy_from_first_phy_page == true)
2409  {
2410  hdr_ptr->nxarv_phy_pageid = (LOG_PHY_PAGEID) nxarv_phy_pageid;
2411  hdr_ptr->nxarv_pageid = nxarv_pageid;
2412  hdr_ptr->nxarv_num = nxarv_num;
2413  }
2414  LSA_COPY (&hdr_ptr->eof_lsa, &eof_lsa);
2415 
2416  p += LOG_PAGESIZE;
2417 
2418  /* Fill the page array with the pages to send */
2419  if (!is_hdr_page_only)
2420  {
2421  for (pageid = fpageid; pageid >= 0 && pageid <= lpageid; pageid++)
2422  {
2423  log_pgptr = (LOG_PAGE *) p;
2424  if (copy_from_file == true)
2425  {
2426  if (logpb_copy_page_from_file (thread_p, pageid, log_pgptr) != NO_ERROR)
2427  {
2428  error_code = ER_FAILED;
2429  goto error;
2430  }
2431  }
2432  else
2433  {
2434  if (logpb_copy_page_from_log_buffer (thread_p, pageid, log_pgptr) != NO_ERROR)
2435  {
2436  error_code = ER_FAILED;
2437  goto error;
2438  }
2439  }
2440 
2441  if (pageid >= nxio_lsa.pageid)
2442  {
2443  /* page is not flushed yet, may be changed : update checksum before send */
2444  (void) logpb_set_page_checksum (thread_p, log_pgptr);
2445  }
2446  else
2447  {
2448  (void) logwr_check_page_checksum (thread_p, log_pgptr);
2449  }
2450 
2451  assert (pageid == (log_pgptr->hdr.logical_pageid));
2452  p += LOG_PAGESIZE;
2453  }
2454  }
2455 
2456  *logpg_used_size = (int) (p - logpg_area);
2457 
2458  /* In case that EOL exists at lpageid */
2459  if (!is_hdr_page_only && (lpageid >= eof_lsa.pageid))
2460  {
2461  *status = LOGWR_STATUS_DONE;
2462  LSA_COPY (&entry->tmp_last_sent_eof_lsa, &eof_lsa);
2463  }
2464  else
2465  {
2466  *status = LOGWR_STATUS_DELAY;
2467  entry->tmp_last_sent_eof_lsa.pageid = lpageid;
2469  }
2470 
2471  logwr_er_log ("logwr_pack_log_pages, fpageid(%lld), lpageid(%lld), num_pages(%lld),"
2472  "\n status(%d)\n", fpageid, lpageid, num_logpgs, entry->status);
2473 
2474  return NO_ERROR;
2475 
2476 error:
2477 
2478  *logpg_used_size = 0;
2479  *status = LOGWR_STATUS_ERROR;
2480 
2481  return error_code;
2482 }
2483 
2484 static void
2485 logwr_cs_exit (THREAD_ENTRY * thread_p, bool * check_cs_own)
2486 {
2487  if (*check_cs_own)
2488  {
2489  *check_cs_own = false;
2490  LOG_CS_EXIT (thread_p);
2491  }
2492  return;
2493 }
2494 
2495 static void
2496 logwr_write_end (THREAD_ENTRY * thread_p, LOGWR_INFO * writer_info, LOGWR_ENTRY * entry, int status)
2497 {
2498  int rv;
2499  int tran_index;
2500  int prev_status;
2501  INT64 saved_start_time;
2502 
2503  rv = pthread_mutex_lock (&writer_info->flush_end_mutex);
2504 
2505  prev_status = entry->status;
2506  saved_start_time = entry->start_copy_time;
2507 
2508  if (entry != NULL && logwr_unregister_writer_entry (entry, status))
2509  {
2510  if (prev_status == LOGWR_STATUS_FETCH && writer_info->trace_last_writer == true)
2511  {
2512  assert (saved_start_time > 0);
2513  writer_info->last_writer_elapsed_time = log_get_clock_msec () - saved_start_time;
2514 
2515  tran_index = LOG_FIND_THREAD_TRAN_INDEX (thread_p);
2516  logtb_get_client_ids (tran_index, &writer_info->last_writer_client_info);
2517  }
2518  pthread_cond_signal (&writer_info->flush_end_cond);
2519  }
2520  pthread_mutex_unlock (&writer_info->flush_end_mutex);
2521  return;
2522 }
2523 
2524 static void
2525 logwr_set_eof_lsa (THREAD_ENTRY * thread_p, LOGWR_ENTRY * entry)
2526 {
2527  if (LSA_ISNULL (&entry->eof_lsa))
2528  {
2529  LOG_CS_ENTER (thread_p);
2530  LSA_COPY (&entry->eof_lsa, &log_Gl.hdr.eof_lsa);
2531  LOG_CS_EXIT (thread_p);
2532  }
2533 
2534  return;
2535 }
2536 
2537 static bool
2538 logwr_is_delayed (THREAD_ENTRY * thread_p, LOGWR_ENTRY * entry)
2539 {
2540  logwr_set_eof_lsa (thread_p, entry);
2541 
2542  if (entry == NULL || LSA_ISNULL (&entry->last_sent_eof_lsa) || LSA_GE (&entry->last_sent_eof_lsa, &entry->eof_lsa))
2543  {
2544  return false;
2545  }
2546  return true;
2547 }
2548 
2549 static void
2550 logwr_update_last_sent_eof_lsa (LOGWR_ENTRY * entry)
2551 {
2552  if (entry)
2553  {
2555  }
2556  return;
2557 }
2558 
2559 /*
2560  * xlogwr_get_log_pages -
2561  *
2562  * return:
2563  *
2564  * thread_p(in):
2565  * first_pageid(in):
2566  * mode(in):
2567  *
2568  * Note:
2569  */
2570 int
2571 xlogwr_get_log_pages (THREAD_ENTRY * thread_p, LOG_PAGEID first_pageid, LOGWR_MODE mode)
2572 {
2573  LOGWR_ENTRY *entry;
2574  char *logpg_area;
2575  int logpg_used_size;
2576  LOG_PAGEID next_fpageid;
2577  LOGWR_MODE next_mode;
2578  LOGWR_MODE orig_mode = LOGWR_MODE_ASYNC;
2579  int status;
2580  int timeout;
2581  int rv;
2582  int error_code;
2583  bool check_cs_own = false;
2584  bool is_interrupted = false;
2585  bool copy_from_file = false;
2586  bool need_cs_exit_after_send = true;
2587  struct timespec to;
2588  LOGWR_INFO *writer_info = log_Gl.writer_info;
2589  bool copy_from_first_phy_page = false;
2590 
2591  logpg_used_size = 0;
2592  logpg_area = (char *) db_private_alloc (thread_p, (LOGWR_COPY_LOG_BUFFER_NPAGES * LOG_PAGESIZE));
2593  if (logpg_area == NULL)
2594  {
2595  return ER_OUT_OF_VIRTUAL_MEMORY;
2596  }
2597 
2598  if (thread_p->conn_entry)
2599  {
2600  thread_p->conn_entry->stop_phase = THREAD_STOP_LOGWR;
2601  }
2602 
2603  while (true)
2604  {
2606  {
2607  copy_from_first_phy_page = true;
2608  }
2609  else
2610  {
2611  copy_from_first_phy_page = false;
2612  }
2613  mode = (LOGWR_MODE) (mode & ~LOGWR_COPY_FROM_FIRST_PHY_PAGE_MASK);
2614 
2615  /* In case that a non-ASYNC mode client internally uses ASYNC mode */
2616  orig_mode = MAX (mode, orig_mode);
2617 
2618  logwr_er_log ("[tid:%ld] xlogwr_get_log_pages, fpageid(%lld), mode(%s)\n",
2619  thread_p->get_posix_id (), first_pageid,
2620  (mode == LOGWR_MODE_SYNC ? "sync" : (mode == LOGWR_MODE_ASYNC ? "async" : "semisync")));
2621 
2622  /* Register the writer at the list and wait until LFT start to work */
2623  rv = pthread_mutex_lock (&writer_info->flush_start_mutex);
2624  error_code = logwr_register_writer_entry (&entry, thread_p, first_pageid, mode, copy_from_first_phy_page);
2625  if (error_code != NO_ERROR)
2626  {
2627  pthread_mutex_unlock (&writer_info->flush_start_mutex);
2628  status = LOGWR_STATUS_ERROR;
2629  goto error;
2630  }
2631 
2632  if (entry->status == LOGWR_STATUS_WAIT)
2633  {
2634  bool continue_checking = true;
2635 
2636  if (mode == LOGWR_MODE_ASYNC)
2637  {
2638  timeout = LOGWR_THREAD_SUSPEND_TIMEOUT;
2639  to.tv_sec = time (NULL) + timeout;
2640  to.tv_nsec = 0;
2641  }
2642  else
2643  {
2644  timeout = INF_WAIT;
2645  to.tv_sec = to.tv_nsec = 0;
2646  }
2647 
2648  rv =
2649  thread_suspend_with_other_mutex (thread_p, &writer_info->flush_start_mutex, timeout, &to,
2651  if (rv == ER_CSS_PTHREAD_COND_TIMEDOUT)
2652  {
2653  pthread_mutex_unlock (&writer_info->flush_start_mutex);
2654 
2655  rv = pthread_mutex_lock (&writer_info->flush_end_mutex);
2656  if (logwr_unregister_writer_entry (entry, LOGWR_STATUS_DELAY))
2657  {
2658  pthread_cond_signal (&writer_info->flush_end_cond);
2659  }
2660  pthread_mutex_unlock (&writer_info->flush_end_mutex);
2661 
2662  continue;
2663  }
2665  || rv == ER_CSS_PTHREAD_COND_WAIT)
2666  {
2667  pthread_mutex_unlock (&writer_info->flush_start_mutex);
2668 
2669  error_code = ER_FAILED;
2670  status = LOGWR_STATUS_ERROR;
2671  goto error;
2672  }
2673 
2674  pthread_mutex_unlock (&writer_info->flush_start_mutex);
2675 
2676  if (logtb_is_interrupted (thread_p, false, &continue_checking))
2677  {
2678  /* interrupted, shutdown or connection has gone. */
2679  error_code = ER_INTERRUPTED;
2680  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 0);
2681  status = LOGWR_STATUS_ERROR;
2682  goto error;
2683  }
2684  else if (thread_p->resume_status == THREAD_RESUME_DUE_TO_INTERRUPT)
2685  {
2686  if (logwr_is_delayed (thread_p, entry))
2687  {
2688  is_interrupted = true;
2689  logwr_write_end (thread_p, writer_info, entry, LOGWR_STATUS_DELAY);
2690  continue;
2691  }
2692 
2693  error_code = ER_INTERRUPTED;
2694  status = LOGWR_STATUS_ERROR;
2695  goto error;
2696  }
2697  else if (thread_p->resume_status != THREAD_LOGWR_RESUMED)
2698  {
2699  error_code = ER_FAILED;
2700  status = LOGWR_STATUS_ERROR;
2701  goto error;
2702  }
2703  }
2704  else
2705  {
2706  assert (entry->status == LOGWR_STATUS_DELAY);
2707  pthread_mutex_unlock (&writer_info->flush_start_mutex);
2708  LOG_CS_ENTER (thread_p);
2709  check_cs_own = true;
2710  }
2711 
2712  if (thread_p->resume_status == THREAD_RESUME_DUE_TO_INTERRUPT)
2713  {
2714  logwr_set_eof_lsa (thread_p, entry);
2715  is_interrupted = true;
2716  }
2717 
2718  copy_from_file = (is_interrupted) ? true : false;
2719  /* Send the log pages to be flushed until now */
2720  error_code = logwr_pack_log_pages (thread_p, logpg_area, &logpg_used_size, &status, entry, copy_from_file);
2721  if (error_code != NO_ERROR)
2722  {
2723  error_code = ER_HA_LW_FAILED_GET_LOG_PAGE;
2724  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, error_code, 1, first_pageid);
2725 
2726  status = LOGWR_STATUS_ERROR;
2727  goto error;
2728  }
2729 
2730  /* wait until LFT finishes flushing */
2731  rv = pthread_mutex_lock (&writer_info->flush_wait_mutex);
2732 
2733  if (entry->status == LOGWR_STATUS_FETCH && writer_info->flush_completed == false)
2734  {
2735  rv = pthread_cond_wait (&writer_info->flush_wait_cond, &writer_info->flush_wait_mutex);
2736  assert_release (writer_info->flush_completed == true);
2737  }
2738  rv = pthread_mutex_unlock (&writer_info->flush_wait_mutex);
2739 
2740  if (entry->status == LOGWR_STATUS_FETCH)
2741  {
2742  rv = pthread_mutex_lock (&writer_info->wr_list_mutex);
2743  entry->start_copy_time = log_get_clock_msec ();
2744  pthread_mutex_unlock (&writer_info->wr_list_mutex);
2745  }
2746 
2747  /* In case of async mode, unregister the writer and wakeup LFT to finish */
2748  /*
2749  * The result mode is the following.
2750  *
2751  * transition \ req mode | req_sync req_async ----------------------------------------- delay -> delay | n/a
2752  * ASYNC delay -> done | n/a SYNC wait -> delay | SYNC ASYNC wait -> done | SYNC ASYNC */
2753 
2754  if (orig_mode == LOGWR_MODE_ASYNC
2755  || (mode == LOGWR_MODE_ASYNC && (entry->status != LOGWR_STATUS_DELAY || status != LOGWR_STATUS_DONE)))
2756  {
2757  logwr_cs_exit (thread_p, &check_cs_own);
2758  logwr_write_end (thread_p, writer_info, entry, status);
2759  need_cs_exit_after_send = false;
2760  }
2761 
2762  error_code = xlog_send_log_pages_to_client (thread_p, logpg_area, logpg_used_size, mode);
2763  if (error_code != NO_ERROR)
2764  {
2765  status = LOGWR_STATUS_ERROR;
2766  goto error;
2767  }
2768 
2769  /* Get the next request from the client and reset the arguments */
2770  if (need_cs_exit_after_send == true)
2771  {
2772  error_code =
2773  xlog_get_page_request_with_reply (thread_p, &next_fpageid, &next_mode,
2775  }
2776  else
2777  {
2778  error_code = xlog_get_page_request_with_reply (thread_p, &next_fpageid, &next_mode, -1);
2779  }
2780  if (error_code != NO_ERROR)
2781  {
2782  status = LOGWR_STATUS_ERROR;
2783  goto error;
2784  }
2785 
2786  logwr_update_last_sent_eof_lsa (entry);
2787 
2788  /* In case of sync mode, unregister the writer and wakeup LFT to finish */
2789  if (need_cs_exit_after_send)
2790  {
2791  logwr_cs_exit (thread_p, &check_cs_own);
2792  logwr_write_end (thread_p, writer_info, entry, status);
2793  }
2794 
2795  /* Reset the arguments for the next request */
2796  first_pageid = next_fpageid;
2797  mode = next_mode;
2798  need_cs_exit_after_send = true;
2799 
2800  if (mode & LOGWR_COPY_FROM_FIRST_PHY_PAGE_MASK)
2801  {
2802  assert_release (false);
2803 
2804  er_set (ER_ERROR_SEVERITY, ARG_FILE_LINE, ER_HA_GENERIC_ERROR, 1, "Unexpected copy mode from copylogdb");
2805  error_code = ER_HA_GENERIC_ERROR;
2806 
2807  status = LOGWR_STATUS_ERROR;
2808  goto error;
2809  }
2810  }
2811 
2812  db_private_free_and_init (thread_p, logpg_area);
2813 
2814  assert_release (false);
2815  return ER_FAILED;
2816 
2817 error:
2818 
2819  logwr_er_log ("[tid:%ld] xlogwr_get_log_pages, error(%d)\n", thread_p->get_posix_id (), error_code);
2820 
2821  logwr_cs_exit (thread_p, &check_cs_own);
2822  logwr_write_end (thread_p, writer_info, entry, status);
2823 
2824  db_private_free_and_init (thread_p, logpg_area);
2825 
2826  return error_code;
2827 }
2828 
2829 /*
2830  * logwr_get_min_copied_fpageid -
2831  *
2832  * return:
2833  *
2834  * Note:
2835  */
2836 LOG_PAGEID
2837 logwr_get_min_copied_fpageid (void)
2838 {
2839  LOGWR_INFO *writer_info = log_Gl.writer_info;
2840  LOGWR_ENTRY *entry;
2841  int num_entries = 0;
2842  LOG_PAGEID min_fpageid = LOGPAGEID_MAX;
2843  int rv;
2844 
2845  rv = pthread_mutex_lock (&writer_info->wr_list_mutex);
2846 
2847  entry = writer_info->writer_list;
2848  while (entry)
2849  {
2850  if (min_fpageid > entry->fpageid)
2851  {
2852  min_fpageid = entry->fpageid;
2853  }
2854  entry = entry->next;
2855  num_entries++;
2856  }
2857 
2858  pthread_mutex_unlock (&writer_info->wr_list_mutex);
2859 
2860  if (min_fpageid == LOGPAGEID_MAX || min_fpageid == LOGPB_HEADER_PAGE_ID)
2861  {
2862  min_fpageid = NULL_PAGEID;
2863  }
2864 
2865  return (min_fpageid);
2866 }
2867 
2868 #endif /* SERVER_MODE */
#define difftime64(time1, time2)
Definition: porting.h:394
void net_client_logwr_send_end_msg(int rc, int error)
Definition: network_cl.c:2487
THREAD_ENTRY * thread_p
Definition: log_writer.h:144
#define NO_ERROR
Definition: error_code.h:46
pthread_mutex_t flush_end_mutex
Definition: log_writer.h:166
LOG_PAGEID fpageid
Definition: log_writer.h:145
LOG_LSA tmp_last_sent_eof_lsa
Definition: log_writer.h:150
#define ASSERT_ERROR()
#define ER_CSS_PTHREAD_COND_TIMEDOUT
Definition: error_code.h:1428
void LSA_COPY(log_lsa *plsa1, const log_lsa *plsa2)
Definition: log_lsa.hpp:139
#define LOG_IS_PAGE_TDE_ENCRYPTED(log_page_p)
Definition: log_storage.hpp:47
PAGEID DKNPAGES
void * fileio_read(THREAD_ENTRY *thread_p, int vol_fd, void *io_page_p, PAGEID page_id, size_t page_size)
Definition: file_io.c:3950
#define ER_LOG_PAGE_CORRUPTED
Definition: error_code.h:140
int logpb_set_page_checksum(THREAD_ENTRY *thread_p, LOG_PAGE *log_pgptr)
INT64 last_writer_elapsed_time
Definition: log_writer.h:174
LOG_PAGEID logpb_find_oldest_available_page_id(THREAD_ENTRY *thread_p)
#define ER_FAILED
Definition: error_code.h:47
void fileio_dismount_without_fsync(THREAD_ENTRY *thread_p, int vol_fd)
Definition: file_io.c:3170
static bool logwr_need_shutdown
Definition: log_writer.c:71
#define LOG_HDRPAGE_FLAG_ENCRYPTED_MASK
Definition: log_storage.hpp:45
#define CUBRID_MAGIC_LOG_ARCHIVE
LOG_GLOBAL log_Gl
LOG_HEADER hdr
Definition: log_impl.h:653
#define NULL_TRANID
struct tde_data_key_set TDE_DATA_KEY_SET
#define pthread_mutex_unlock(a)
Definition: area_alloc.c:51
CLIENTIDS last_writer_client_info
Definition: log_writer.h:173
bool dwb_is_created(void)
int hb_deregister_from_master(void)
Definition: heartbeat.c:321
#define ER_HA_LW_STARTED
Definition: error_code.h:1296
LOG_HDRPAGE hdr
Definition: log_storage.hpp:84
void fileio_unformat(THREAD_ENTRY *thread_p, const char *vol_label_p)
Definition: file_io.c:2721
#define PAGEID_MAX
LOG_LSA eof_lsa
Definition: log_writer.h:148
const LOG_PAGEID LOGPB_HEADER_PAGE_ID
Definition: log_storage.hpp:51
PAGEID LOG_PHY_PAGEID
#define LSA_INITIALIZER
Definition: log_lsa.hpp:76
int xlog_send_log_pages_to_client(THREAD_ENTRY *thread_p, char *logpg_area, int area_size, LOGWR_MODE mode)
LOG_PAGE * loghdr_pgptr
Definition: log_impl.h:672
#define assert_release(e)
Definition: error_manager.h:96
pthread_mutex_t wr_list_mutex
Definition: log_writer.h:160
INT64 log_get_clock_msec(void)
void LOG_CS_ENTER(THREAD_ENTRY *thread_p)
#define logwr_er_log(...)
Definition: log_writer.c:92
#define ER_CSS_PTHREAD_MUTEX_LOCK
Definition: error_code.h:999
const VOLID LOG_DBLOG_ACTIVE_VOLID
Definition: log_volids.hpp:49
#define OR_ALIGNED_BUF(size)
LOG_PHY_PAGEID logwr_to_physical_pageid(LOG_PAGEID logical_pageid)
void fileio_make_log_archive_temp_name(char *log_archive_temp_name_p, const char *log_path_p, const char *db_name_p)
Definition: file_io.c:5793
LOG_PAGE * logpb_fetch_from_archive(THREAD_ENTRY *thread_p, LOG_PAGEID pageid, LOG_PAGE *log_pgptr, int *ret_arv_num, LOG_ARV_HEADER *arv_hdr, bool is_fatal)
int logwr_get_log_pages(LOGWR_CONTEXT *ctx_ptr)
#define OR_INT64_SIZE
bool fileio_is_volume_exist(const char *vol_label_p)
Definition: file_io.c:5094
LOG_PAGEID fpageid
int er_errid(void)
#define OR_ALIGNED_BUF_SIZE(abuf)
int xlog_get_page_request_with_reply(THREAD_ENTRY *thread_p, LOG_PAGEID *fpageid_ptr, LOGWR_MODE *mode_ptr, int timeout)
#define PTR_ALIGN(addr, boundary)
Definition: memory_alloc.h:77
void crypt_crc32(const char *src, int src_len, int *dest)
Definition: crypt_opfunc.c:672
LOGWR_MODE mode
Definition: log_writer.h:146
bool hb_Proc_shutdown
Definition: heartbeat.c:93
LOGWR_STATUS status
Definition: log_writer.h:147
void _er_log_debug(const char *file_name, const int line_no, const char *fmt,...)
#define NULL_VOLDES
Definition: file_io.h:44
#define MAX_ALIGNMENT
Definition: memory_alloc.h:70
const char * fileio_rename(VOLID vol_id, const char *old_label_p, const char *new_label_p)
Definition: file_io.c:5070
#define ER_CSS_PTHREAD_COND_WAIT
Definition: error_code.h:1008
int fileio_mount(THREAD_ENTRY *thread_p, const char *db_full_name_p, const char *vol_label_p, VOLID vol_id, int lock_wait, bool is_do_sync)
Definition: file_io.c:2957
void * fileio_read_pages(THREAD_ENTRY *thread_p, int vol_fd, char *io_pages_p, PAGEID page_id, int num_pages, size_t page_size)
Definition: file_io.c:4227
#define ER_IO_WRITE_OUT_OF_SPACE
Definition: error_code.h:64
#define LOGWR_THREAD_SUSPEND_TIMEOUT
Definition: log_writer.c:66
void THREAD_ENTRY
#define NULL_PAGEID
FILEIO_WRITE_MODE
Definition: file_io.h:164
#define OR_ALIGNED_BUF_START(abuf)
int logtb_get_client_ids(int tran_index, CLIENTIDS *client_info)
#define MSGCAT_SET_LOG
#define ER_LOG_READ
Definition: error_code.h:137
INT64 db_creation
char * or_pack_int64(char *ptr, INT64 number)
#define ER_IO_FORMAT_FAIL
Definition: error_code.h:57
#define MSGCAT_LOG_LOGINFO_ARCHIVE
void er_set(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
INT64 db_restore_time
const VOLID LOG_DBLOG_ARCHIVE_VOLID
Definition: log_volids.hpp:53
#define assert(x)
LOG_APPEND_INFO append
Definition: log_impl.h:651
Definition: log_writer.h:142
TDE_ALGORITHM
Definition: tde.h:71
int logpb_copy_page_from_file(THREAD_ENTRY *thread_p, LOG_PAGEID pageid, LOG_PAGE *log_pgptr)
int prm_get_integer_value(PARAM_ID prm_id)
#define ER_GENERIC_ERROR
Definition: error_code.h:49
INT64 start_copy_time
Definition: log_writer.h:151
#define TDE_DATA_KEY_LENGTH
Definition: tde.h:55
#define CUBRID_MAGIC_MAX_LENGTH
#define ER_OUT_OF_VIRTUAL_MEMORY
Definition: error_code.h:50
void LOG_CS_EXIT(THREAD_ENTRY *thread_p)
TDE_CIPHER tde_Cipher
Definition: tde.c:69
int last_deleted_arv_num
enum logwr_status LOGWR_STATUS
Definition: log_writer.h:139
int ha_server_state
char area[1]
Definition: log_storage.hpp:85
#define ER_LOG_WRITE_OUT_OF_SPACE
Definition: error_code.h:139
const char * css_ha_server_state_string(HA_SERVER_STATE state)
#define ER_HA_GENERIC_ERROR
Definition: error_code.h:1297
#define ER_HB_PROCESS_EVENT
Definition: error_code.h:1239
LOG_PAGEID logical_pageid
Definition: log_storage.hpp:65
LOG_HA_FILESTAT
#define LOGWR_COPY_LOG_BUFFER_NPAGES
Definition: log_writer.c:68
static enum scanner_mode mode
int ha_file_status
INT64 ha_promotion_time
unsigned char perm_key[TDE_DATA_KEY_LENGTH]
Definition: tde.h:87
#define LOGWR_COPY_FROM_FIRST_PHY_PAGE_MASK
Definition: log_writer.h:55
void fileio_dismount(THREAD_ENTRY *thread_p, int vol_fd)
Definition: file_io.c:3134
static int rv
Definition: area_alloc.c:52
std::int64_t pageid
Definition: log_lsa.hpp:36
LOG_PAGEID nxarv_pageid
INT64 LOG_PAGEID
#define NULL
Definition: freelistheap.h:34
LOGWR_ENTRY * writer_list
Definition: log_writer.h:159
#define ER_HA_LW_STOPPED_BY_SIGNAL
Definition: error_code.h:1294
#define LOG_HDRPAGE_FLAG_ENCRYPTED_AES
Definition: log_storage.hpp:42
if(extra_options)
Definition: dynamic_load.c:958
bool copy_from_first_phy_page
Definition: log_writer.h:152
#define ER_IO_MOUNT_FAIL
Definition: error_code.h:59
bool LSA_ISNULL(const log_lsa *lsa_ptr)
Definition: log_lsa.hpp:153
HEADER_FETCH_MODE
Definition: log_writer.c:86
#define LOG_HDRPAGE_FLAG_ENCRYPTED_ARIA
Definition: log_storage.hpp:43
#define db_private_free_and_init(thrd, ptr)
Definition: memory_alloc.h:141
int last_arv_num_for_syscrashes
pthread_cond_t flush_end_cond
Definition: log_writer.h:165
const char * get_buffer() const
PGLENGTH offset
Definition: log_storage.hpp:66
#define db_private_alloc(thrd, size)
Definition: memory_alloc.h:227
#define NULL_OFFSET
char * db_name
void er_set_with_oserror(int severity, const char *file_name, const int line_no, int err_id, int num_args,...)
#define MSGCAT_CATALOG_CUBRID
void fileio_make_log_active_name(char *log_active_name_p, const char *log_path_p, const char *db_name_p)
Definition: file_io.c:5707
LOG_PAGEID start_page_id
Definition: log_writer.c:81
#define ER_LOG_WRITE
Definition: error_code.h:138
void fileio_make_log_info_name(char *log_info_name_p, const char *log_path_p, const char *db_name_p)
Definition: file_io.c:5815
logwr_info * writer_info
Definition: log_impl.h:680
bool LSA_GE(const log_lsa *plsa1, const log_lsa *plsa2)
Definition: log_lsa.hpp:181
void fileio_make_log_archive_name(char *log_archive_name_p, const char *log_path_p, const char *db_name_p, int archive_number)
Definition: file_io.c:5758
bool logtb_is_interrupted(THREAD_ENTRY *thread_p, bool clear, bool *continue_checking)
static void error(const char *msg)
Definition: gencat.c:331
#define FILEIO_SUFFIX_LOGARCHIVE
Definition: file_io.h:83
LOG_PHY_PAGEID nxarv_phy_pageid
void * fileio_write(THREAD_ENTRY *thread_p, int vol_fd, void *io_page_p, PAGEID page_id, size_t page_size, FILEIO_WRITE_MODE write_mode)
Definition: file_io.c:4150
char * or_pack_int(char *ptr, int number)
#define ER_INTERRUPTED
Definition: error_code.h:51
LOG_PAGEID last_sync_pageid
Definition: log_writer.c:83
#define LOG_FIND_THREAD_TRAN_INDEX(thrd)
Definition: perf_monitor.h:158
#define ARG_FILE_LINE
Definition: error_manager.h:44
#define LOGPAGEID_MAX
const char * logwr_log_ha_filestat_to_string(enum LOG_HA_FILESTAT val)
Definition: log_writer.c:2041
unsigned char temp_key[TDE_DATA_KEY_LENGTH]
Definition: tde.h:88
LOG_PAGEID current_page_id
Definition: log_writer.c:82
int fileio_synchronize(THREAD_ENTRY *thread_p, int vol_fd, const char *vlabel, FILEIO_SYNC_OPTION sync_dwb)
Definition: file_io.c:4441
#define ER_LOG_CREATE_LOGARCHIVE_FAIL
Definition: error_code.h:157
#define free_and_init(ptr)
Definition: memory_alloc.h:147
#define strlen(s1)
Definition: intl_support.c:43
void LSA_SET_NULL(log_lsa *lsa_ptr)
Definition: log_lsa.hpp:146
static int logwr_check_page_checksum(THREAD_ENTRY *thread_p, LOG_PAGE *log_pgptr)
Definition: log_writer.c:1978
#define ER_HA_LW_FAILED_GET_LOG_PAGE
Definition: error_code.h:1281
int thread_suspend_with_other_mutex(cubthread::entry *thread_p, pthread_mutex_t *mutex_p, int timeout, struct timespec *to, thread_resume_suspend_status suspended_reason)
const VOLID LOG_DBLOG_BG_ARCHIVE_VOLID
Definition: log_volids.hpp:51
#define ER_LOG_ARCHIVE_CREATED
Definition: error_code.h:1215
bool logpb_is_page_in_archive(LOG_PAGEID pageid)
bool prm_get_bool_value(PARAM_ID prm_id)
#define ER_CSS_PTHREAD_MUTEX_UNLOCK
Definition: error_code.h:1001
bool is_loaded
Definition: tde.h:148
bool trace_last_writer
Definition: log_writer.h:172
#define ER_LOG_INCOMPATIBLE_DATABASE
Definition: error_code.h:145
HA_SERVER_STATE css_ha_server_state(void)
void er_clear(void)
enum logwr_mode LOGWR_MODE
Definition: log_writer.h:54
int fileio_format(THREAD_ENTRY *thread_p, const char *db_full_name_p, const char *vol_label_p, VOLID vol_id, DKNPAGES npages, bool is_sweep_clean, bool is_do_lock, bool is_do_sync, size_t page_size, int kbytes_to_be_written_per_sec, bool reuse_file)
Definition: file_io.c:2314
LOG_LSA last_sent_eof_lsa
Definition: log_writer.h:149
int i
Definition: dynamic_load.c:954
char * msgcat_message(int cat_id, int set_id, int msg_id)
#define ER_LOG_DOESNT_CORRESPOND_TO_DATABASE
Definition: error_code.h:148
TDE_DATA_KEY_SET data_keys
Definition: tde.h:149
bool logwr_force_shutdown(void)
LOG_LSA eof_lsa
void * fileio_write_pages(THREAD_ENTRY *thread_p, int vol_fd, char *io_pages_p, PAGEID page_id, int num_pages, size_t page_size, FILEIO_WRITE_MODE write_mode)
Definition: file_io.c:4314
#define ER_DISK_INCONSISTENT_VOL_HEADER
Definition: error_code.h:636
char magic[CUBRID_MAGIC_MAX_LENGTH]
Definition: log_writer.c:76
int log_dump_log_info(const char *logname_info, bool also_stdout, const char *fmt,...)
Definition: log_comm.c:205
char magic[CUBRID_MAGIC_MAX_LENGTH]
#define NULL_VOLID
#define FILEIO_PATH_SEPARATOR(path)
Definition: file_io.h:78
#define pthread_mutex_lock(a)
Definition: area_alloc.c:50
LOG_LSA get_nxio_lsa() const
Definition: log_append.cpp:106
#define IO_MAX_PAGE_SIZE
#define LOG_PAGESIZE
int net_client_check_log_header(LOGWR_CONTEXT *ctx_ptr, char *argbuf, int argsize, char *replybuf, int replysize, char **logpg_area_buf, bool verbose)
Definition: network_cl.c:2216
unsigned char log_key[TDE_DATA_KEY_LENGTH]
Definition: tde.h:89
enum ha_server_state HA_SERVER_STATE
Definition: boot.h:126
static int prev_ha_server_state
Definition: log_writer.c:70
TRANID next_trid
#define ER_TDE_CIPHER_LOAD_FAIL
Definition: error_code.h:1615
void la_print_log_header(const char *database_name, LOG_HEADER *hdr, bool verbose)
Definition: log_applier.c:6960
int logpb_copy_page_from_log_buffer(THREAD_ENTRY *thread_p, LOG_PAGEID pageid, LOG_PAGE *log_pgptr)
int logwr_copy_log_file(const char *db_name, const char *log_path, int mode, INT64 start_page_id)
Definition: log_writer.c:1960
const size_t LOGPB_IO_NPAGES
Definition: log_storage.hpp:55
bool fileio_is_formatted_page(THREAD_ENTRY *thread_p, const char *io_page)
Definition: file_io.c:11841
std::int64_t offset
Definition: log_lsa.hpp:37
SIGNAL_HANDLER_FUNCTION os_set_signal_handler(const int sig_no, SIGNAL_HANDLER_FUNCTION sig_handler)
Definition: porting.c:1333
const char ** p
Definition: dynamic_load.c:945
int tde_encrypt_log_page(const LOG_PAGE *logpage_plain, TDE_ALGORITHM tde_algo, LOG_PAGE *logpage_cipher)
Definition: tde.c:997
LOGWR_ENTRY * next
Definition: log_writer.h:153