Drizzled Public API Documentation

xtrabackup.cc
1 /******************************************************
2 XtraBackup: The another hot backup tool for InnoDB
3 (c) 2009 Percona Inc.
4 (C) 2011 Stewart Smith
5 Created 3/3/2009 Yasufumi Kinoshita
6 
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; version 2 of the License.
10 
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15 
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 
20 *******************************************************/
21 
22 #ifndef XTRABACKUP_VERSION
23 #define XTRABACKUP_VERSION "undefined"
24 #endif
25 #ifndef XTRABACKUP_REVISION
26 #define XTRABACKUP_REVISION "undefined"
27 #endif
28 
29 #include <config.h>
30 #include <string>
31 #include <drizzled/internal/my_sys.h>
32 #include <drizzled/charset.h>
33 #include <drizzled/gettext.h>
34 #include <drizzled/constrained_value.h>
35 #include <drizzled/configmake.h>
36 #include <drizzled/error/priority_t.h>
37 
38 #include "ha_prototypes.h"
39  //#define XTRABACKUP_TARGET_IS_PLUGIN
40 #include <boost/program_options.hpp>
41 #include <boost/scoped_array.hpp>
42 #include <boost/scoped_ptr.hpp>
43 
45 
46 #define my_progname "xtrabackup"
47 
48 #define MYSQL_VERSION_ID 50507 /* Drizzle is much greater */
49 
50 #include <univ.i>
51 #include <os0file.h>
52 #include <os0thread.h>
53 #include <srv0start.h>
54 #include <srv0srv.h>
55 #include <trx0roll.h>
56 #include <trx0trx.h>
57 #include <trx0sys.h>
58 #include <mtr0mtr.h>
59 #include <row0ins.h>
60 #include <row0mysql.h>
61 #include <row0sel.h>
62 #include <row0upd.h>
63 #include <log0log.h>
64 #include <log0recv.h>
65 #include <lock0lock.h>
66 #include <dict0crea.h>
67 #include <btr0cur.h>
68 #include <btr0btr.h>
69 #include <btr0sea.h>
70 #include <fsp0fsp.h>
71 #include <sync0sync.h>
72 #include <fil0fil.h>
73 #include <trx0xa.h>
74 
75 #ifdef INNODB_VERSION_SHORT
76 #include <ibuf0ibuf.h>
77 #else
78 #error ENOCOOL
79 #endif
80 
81 #define IB_INT64 ib_int64_t
82 #define LSN64 ib_uint64_t
83 #define MACH_READ_64 mach_read_from_8
84 #define MACH_WRITE_64 mach_write_to_8
85 #define OS_MUTEX_CREATE() os_mutex_create()
86 #define ut_dulint_zero 0
87 #define ut_dulint_cmp(A, B) (A > B ? 1 : (A == B ? 0 : -1))
88 #define ut_dulint_add(A, B) (A + B)
89 #define ut_dulint_minus(A, B) (A - B)
90 #define ut_dulint_align_down(A, B) (A & ~((ib_int64_t)B - 1))
91 #define ut_dulint_align_up(A, B) ((A + B - 1) & ~((ib_int64_t)B - 1))
92 
93 #ifdef __WIN__
94 #define SRV_PATH_SEPARATOR '\\'
95 #define SRV_PATH_SEPARATOR_STR "\\"
96 #else
97 #define SRV_PATH_SEPARATOR '/'
98 #define SRV_PATH_SEPARATOR_STR "/"
99 #endif
100 
101 #ifndef UNIV_PAGE_SIZE_MAX
102 #define UNIV_PAGE_SIZE_MAX UNIV_PAGE_SIZE
103 #endif
104 #ifndef UNIV_PAGE_SIZE_SHIFT_MAX
105 #define UNIV_PAGE_SIZE_SHIFT_MAX UNIV_PAGE_SIZE_SHIFT
106 #endif
107 
108 using namespace drizzled;
109 namespace po=boost::program_options;
110 
111 namespace drizzled {
112  bool errmsg_printf (error::priority_t, char const *format, ...);
113 
114  bool errmsg_printf (error::priority_t, char const *format, ...)
115  {
116  bool rv;
117  va_list args;
118  va_start(args, format);
119  rv= vfprintf(stderr, format, args);
120  va_end(args);
121  fprintf(stderr, "\n");
122  return rv;
123  }
124 
125 }
126 
127 #include "xtrabackup_api.h"
128 
129  #include <fcntl.h>
130  #include <regex.h>
131 
132  #ifdef POSIX_FADV_NORMAL
133  #define USE_POSIX_FADVISE
134  #endif
135 
136  /* ==start === definition at fil0fil.c === */
137  // ##################################################################
138  // NOTE: We should check the following definitions fit to the source.
139  // ##################################################################
140 
141  //Plugin ?
143  struct fil_node_struct {
144  fil_space_t* space;
146  char* name;
147  ibool open;
148  os_file_t handle;
149  ibool is_raw_disk;
151  ulint size;
154  ulint n_pending;
158  ulint n_pending_flushes;
162  ib_int64_t modification_counter;
164  ib_int64_t flush_counter;
167  UT_LIST_NODE_T(fil_node_t) chain;
171  ulint magic_n;
172  };
173 
174  struct fil_space_struct {
175  char* name;
177  ulint id;
178  ib_int64_t tablespace_version;
184  ibool mark;
188  ibool stop_ios;
192  ibool stop_ibuf_merges;
195  ibool is_being_deleted;
202  ulint purpose;
206  ulint size;
210  ulint flags;
211  ulint n_reserved_extents;
214  ulint n_pending_flushes;
217  ulint n_pending_ibuf_merges;
223  hash_node_t hash;
224  hash_node_t name_hash;
225  #ifndef UNIV_HOTBACKUP
226  rw_lock_t latch;
228  #endif /* !UNIV_HOTBACKUP */
229  UT_LIST_NODE_T(fil_space_t) unflushed_spaces;
232  ibool is_in_unflushed_spaces;
234  #ifdef XTRADB_BASED
235  ibool is_corrupt;
236  #endif
237  UT_LIST_NODE_T(fil_space_t) space_list;
239  ulint magic_n;
240  };
241 
242  typedef struct fil_system_struct fil_system_t;
243 
244  struct fil_system_struct {
245  #ifndef UNIV_HOTBACKUP
246  mutex_t mutex;
247  #ifdef XTRADB55
248  mutex_t file_extend_mutex;
249  #endif
250  #endif /* !UNIV_HOTBACKUP */
251  hash_table_t* spaces;
254  hash_table_t* name_hash;
267  UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces;
273  ulint n_open;
274  ulint max_n_open;
276  ib_int64_t modification_counter;
278  ulint max_assigned_id;
284  ib_int64_t tablespace_version;
292  UT_LIST_BASE_NODE_T(fil_space_t) space_list;
294  };
295 
296  typedef struct {
297  ulint page_size;
298  } xb_delta_info_t;
299 
300  extern fil_system_t* fil_system;
301 
302  /* ==end=== definition at fil0fil.c === */
303 
304 
305  bool innodb_inited= 0;
306 
307  /* === xtrabackup specific options === */
308  char xtrabackup_real_target_dir[FN_REFLEN] = "./xtrabackup_backupfiles/";
309  const char *xtrabackup_target_dir= xtrabackup_real_target_dir;
310  bool xtrabackup_backup = false;
311  bool xtrabackup_stats = false;
312  bool xtrabackup_prepare = false;
313  bool xtrabackup_print_param = false;
314 
315  bool xtrabackup_export = false;
316  bool xtrabackup_apply_log_only = false;
317 
318  bool xtrabackup_suspend_at_end = false;
319  uint64_t xtrabackup_use_memory = 100*1024*1024L;
320  bool xtrabackup_create_ib_logfile = false;
321 
322  long xtrabackup_throttle = 0; /* 0:unlimited */
323  lint io_ticket;
324  os_event_t wait_throttle = NULL;
325 
326  bool xtrabackup_stream = false;
327 const char *xtrabackup_incremental = NULL;
328  LSN64 incremental_lsn;
329  LSN64 incremental_to_lsn;
330  LSN64 incremental_last_lsn;
331  byte* incremental_buffer = NULL;
332  byte* incremental_buffer_base = NULL;
333 
334 const char *xtrabackup_incremental_basedir = NULL; /* for --backup */
335 const char *xtrabackup_extra_lsndir = NULL; /* for --backup with --extra-lsndir */
336 char *xtrabackup_incremental_dir = NULL; /* for --prepare */
337 
338  char *xtrabackup_tables = NULL;
339  int tables_regex_num;
340  regex_t *tables_regex;
341  regmatch_t tables_regmatch[1];
342 
343 const char *xtrabackup_tables_file = NULL;
344  hash_table_t* tables_hash;
345 
347  char* name;
348  hash_node_t name_hash;
349  };
351 
352  #ifdef XTRADB_BASED
353  static ulint thread_nr[SRV_MAX_N_IO_THREADS + 6 + 64];
354  static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 6 + 64];
355  #else
356  static ulint thread_nr[SRV_MAX_N_IO_THREADS + 6];
357  static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 6];
358  #endif
359 
360  LSN64 checkpoint_lsn_start;
361  LSN64 checkpoint_no_start;
362  LSN64 log_copy_scanned_lsn;
363  IB_INT64 log_copy_offset = 0;
364  ibool log_copying = TRUE;
365  ibool log_copying_running = FALSE;
366  ibool log_copying_succeed = FALSE;
367 
368  ibool xtrabackup_logfile_is_renamed = FALSE;
369 
370  uint parallel;
371 
372  /* === metadata of backup === */
373  #define XTRABACKUP_METADATA_FILENAME "xtrabackup_checkpoints"
374  char metadata_type[30] = ""; /*[full-backuped|full-prepared|incremental]*/
375 
376  ib_uint64_t metadata_from_lsn = 0;
377  ib_uint64_t metadata_to_lsn = 0;
378  ib_uint64_t metadata_last_lsn = 0;
379 
380  #define XB_DELTA_INFO_SUFFIX ".meta"
381 
382  /* === sharing with thread === */
383  os_file_t dst_log = -1;
384  char dst_log_path[FN_REFLEN];
385 
386  /* === some variables from mysqld === */
387  char mysql_real_data_home[FN_REFLEN] = "./";
388  char *mysql_data_home= mysql_real_data_home;
389 std::string mysql_data_home_arg;
390  static char mysql_data_home_buff[2];
391 
392 const char *opt_mysql_tmpdir = NULL;
393 
394 /* === static parameters in ha_innodb.cc */
395 
396 #define HA_INNOBASE_ROWS_IN_TABLE 10000 /* to get optimization right */
397 #define HA_INNOBASE_RANGE_COUNT 100
398 
399 ulong innobase_large_page_size = 0;
400 
401 /* The default values for the following, type long or longlong, start-up
402 parameters are declared in mysqld.cc: */
403 
404 long innobase_additional_mem_pool_size = 1*1024*1024L;
405 long innobase_buffer_pool_awe_mem_mb = 0;
406 long innobase_file_io_threads = 4;
407 long innobase_read_io_threads = 4;
408 long innobase_write_io_threads = 4;
409 long innobase_force_recovery = 0;
410 long innobase_lock_wait_timeout = 50;
411 long innobase_log_buffer_size = 1024*1024L;
412 long innobase_log_files_in_group = 2;
413 long innobase_log_files_in_group_backup;
414 long innobase_mirrored_log_groups = 1;
415 long innobase_open_files = 300L;
416 
417 long innobase_page_size = (1 << 14); /* 16KB */
418 static ulong innobase_log_block_size = 512;
419 bool innobase_fast_checksum = false;
420 bool innobase_extra_undoslots = false;
421 char* innobase_doublewrite_file = NULL;
422 
423 uint64_t innobase_buffer_pool_size = 8*1024*1024L;
424 
426 static log_file_constraint innobase_log_file_size;
427 
428 uint64_t innobase_log_file_size_backup;
429 
430 /* The default values for the following char* start-up parameters
431 are determined in innobase_init below: */
432 
433 char* innobase_data_home_dir = NULL;
434 const char* innobase_data_file_path = NULL;
435 char* innobase_log_group_home_dir = NULL;
436 char* innobase_log_group_home_dir_backup = NULL;
437 char* innobase_log_arch_dir = NULL;/* unused */
438 /* The following has a misleading name: starting from 4.0.5, this also
439 affects Windows: */
440 char* innobase_unix_file_flush_method = NULL;
441 
442 /* Below we have boolean-valued start-up parameters, and their default
443 values */
444 
445 ulong innobase_fast_shutdown = 1;
446 bool innobase_log_archive = FALSE;/* unused */
447 bool innobase_use_doublewrite = TRUE;
448 bool innobase_use_checksums = TRUE;
449 bool innobase_use_large_pages = FALSE;
450 bool innobase_file_per_table = FALSE;
451 bool innobase_locks_unsafe_for_binlog = FALSE;
452 bool innobase_rollback_on_timeout = FALSE;
453 bool innobase_create_status_file = FALSE;
454 bool innobase_adaptive_hash_index = TRUE;
455 
456 static char *internal_innobase_data_file_path = NULL;
457 
458 /* The following counter is used to convey information to InnoDB
459 about server activity: in selects it is not sensible to call
460 srv_active_wake_master_thread after each fetch or search, we only do
461 it every INNOBASE_WAKE_INTERVAL'th step. */
462 
463 #define INNOBASE_WAKE_INTERVAL 32
464 ulong innobase_active_counter = 0;
465 
466 UNIV_INTERN
467 bool
468 innobase_isspace(
469  const void *cs,
470  char char_to_test)
471 {
472  return static_cast<const CHARSET_INFO*>(cs)->isspace(char_to_test);
473 }
474 
475 /******************************************************************/
478 const char*
480 /*==============*/
481  const char* path_name)
482 {
483  const char* name = path_name + drizzled::internal::dirname_length(path_name);
484 
485  return((name) ? name : "null");
486 }
487 
488 UNIV_INTERN
489 void
491  Table* ,
492  const rec_t* ,
493  const dict_index_t* ,
494  const ulint* );
495 
496 UNIV_INTERN
497 void
499 /*==================*/
500  Table* ,
501  const rec_t* ,
502  const dict_index_t* ,
503  const ulint* )
505 {
506  fprintf(stderr, "ERROR: innobase_rec_to_mysql called\n");
507  return;
508 }
509 
510 UNIV_INTERN
511 void
513 
514 UNIV_INTERN
515 void
517 /*===============*/
518  Table* )
519 {
520  fprintf(stderr, "ERROR: innobase_rec_reset called\n");
521  return;
522 }
523 
524 UNIV_INTERN
525 void
527 /*===================*/
529  ulint )
530 {
531  return;
532 }
533 
534 
535 
536 /* ======== Datafiles iterator ======== */
537 typedef struct {
538  fil_system_t *system;
539  fil_space_t *space;
540  fil_node_t *node;
541  ibool started;
542  os_mutex_t mutex;
544 
545 static
547 datafiles_iter_new(fil_system_t *f_system)
548 {
549  datafiles_iter_t *it;
550 
552  it->mutex = OS_MUTEX_CREATE();
553 
554  it->system = f_system;
555  it->space = NULL;
556  it->node = NULL;
557  it->started = FALSE;
558 
559  return it;
560 }
561 
562 static
563 fil_node_t *
564 datafiles_iter_next(datafiles_iter_t *it, ibool *space_changed)
565 {
566  os_mutex_enter(it->mutex);
567 
568  *space_changed = FALSE;
569 
570  if (it->node == NULL) {
571  if (it->started)
572  goto end;
573  it->started = TRUE;
574  } else {
575  it->node = UT_LIST_GET_NEXT(chain, it->node);
576  if (it->node != NULL)
577  goto end;
578  }
579 
580  it->space = (it->space == NULL) ?
581  UT_LIST_GET_FIRST(it->system->space_list) :
582  UT_LIST_GET_NEXT(space_list, it->space);
583 
584  while (it->space != NULL &&
585  (it->space->purpose != FIL_TABLESPACE ||
586  UT_LIST_GET_LEN(it->space->chain) == 0))
587  it->space = UT_LIST_GET_NEXT(space_list, it->space);
588  if (it->space == NULL)
589  goto end;
590  *space_changed = TRUE;
591 
592  it->node = UT_LIST_GET_FIRST(it->space->chain);
593 
594 end:
595  os_mutex_exit(it->mutex);
596 
597  return it->node;
598 }
599 
600 static
601 void
602 datafiles_iter_free(datafiles_iter_t *it)
603 {
604  os_mutex_free(it->mutex);
605  ut_free(it);
606 }
607 
608 /* ======== Date copying thread context ======== */
609 
610 typedef struct {
611  datafiles_iter_t *it;
612  uint num;
613  uint *count;
614  os_mutex_t count_mutex;
615  os_thread_id_t id;
617 
618 static void print_version(void)
619 {
620  printf("%s Ver %s Rev %s for %s %s (%s)\n" ,my_progname,
621  XTRABACKUP_VERSION, XTRABACKUP_REVISION, "Drizzle",
622  TARGET_OS, TARGET_CPU);
623 }
624 
625 static void usage(void)
626 {
627  puts("Open source backup tool for InnoDB and XtraDB\n\
628 \n\
629 Copyright (C) 2009 Percona Inc.\n\
630 \n\
631 This program is free software; you can redistribute it and/or\n\
632 modify it under the terms of the GNU General Public License\n\
633 as published by the Free Software Foundation version 2\n\
634 of the License.\n\
635 \n\
636 This program is distributed in the hope that it will be useful,\n\
637 but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
638 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
639 GNU General Public License for more details.\n\
640 \n\
641 You can download full text of the license on http://www.gnu.org/licenses/gpl-2.0.txt\n");
642 
643  printf("Usage: [%s [--defaults-file=#] --backup | %s [--defaults-file=#] --prepare] [OPTIONS]\n",my_progname,my_progname);
644  // FIXME: print what variables we have
645 }
646 
647 /* ================ Dummys =================== */
648 
649 UNIV_INTERN
650 ibool
652 /*============================*/
654 {
655  fprintf(stderr, "xtrabackup: thd_is_replication_slave_thread() is called\n");
656  return(FALSE);
657 }
658 
659 UNIV_INTERN
660 ibool
662 /*===========================*/
664 {
665  fprintf(stderr, "xtrabackup: thd_has_edited_nontrans_tables() is called\n");
666  return(FALSE);
667 }
668 
669 UNIV_INTERN
670 ibool
672 /*==========*/
673  const drizzled::Session *)
674 {
675  fprintf(stderr, "xtrabackup: thd_is_select() is called\n");
676  return(false);
677 }
678 
679 UNIV_INTERN
680 void
682  FILE*,
684  uint)
685 {
686  fprintf(stderr, "xtrabackup: innobase_mysql_print_thd() is called\n");
687 }
688 
689 void
691  ulint cset,
692  ulint* mbminlen,
693  ulint* mbmaxlen)
694 {
695  CHARSET_INFO* cs;
696  ut_ad(cset < 256);
697  ut_ad(mbminlen);
698  ut_ad(mbmaxlen);
699 
700  cs = all_charsets[cset];
701  if (cs) {
702  *mbminlen = cs->mbminlen;
703  *mbmaxlen = cs->mbmaxlen;
704  } else {
705  ut_a(cset == 0);
706  *mbminlen = *mbmaxlen = 0;
707  }
708 }
709 
710 UNIV_INTERN
711 void
713 /*===========================*/
714  const void*,
715  char* ,
716  const char* ,
717  ulint )
718 {
719  fprintf(stderr, "xtrabackup: innobase_convert_from_table_id() is called\n");
720 }
721 
722 UNIV_INTERN
723 void
725 /*=====================*/
726  const void*,
727  char* ,
728  const char* ,
729  ulint )
730 {
731  fprintf(stderr, "xtrabackup: innobase_convert_from_id() is called\n");
732 }
733 
734 int
736  const char* a,
737  const char* b)
738 {
739  return my_charset_utf8_general_ci.strcasecmp(a, b);
740 }
741 
742 void
744  char* a)
745 {
746  my_charset_utf8_general_ci.casedn_str(a);
747 }
748 
749 UNIV_INTERN
750 const char*
752 /*==============*/
754  size_t* )
755 {
756  fprintf(stderr, "xtrabackup: innobase_get_stmt() is called\n");
757  return("nothing");
758 }
759 
760 int
762 {
763  char filename[FN_REFLEN];
764  int fd2 = -1;
765  int fd = internal::create_temp_file(filename, opt_mysql_tmpdir,
766  "ib",
767 #ifdef __WIN__
768  O_BINARY | O_TRUNC | O_SEQUENTIAL |
769  O_TEMPORARY | O_SHORT_LIVED |
770 #endif /* __WIN__ */
771  O_CREAT | O_EXCL | O_RDWR);
772  if (fd >= 0) {
773 #ifndef __WIN__
774  /* On Windows, open files cannot be removed, but files can be
775  created with the O_TEMPORARY flag to the same effect
776  ("delete on close"). */
777  unlink(filename);
778 #endif /* !__WIN__ */
779  /* Copy the file descriptor, so that the additional resources
780  allocated by create_temp_file() can be freed by invoking
781  my_close().
782 
783  Because the file descriptor returned by this function
784  will be passed to fdopen(), it will be closed by invoking
785  fclose(), which in turn will invoke close() instead of
786  my_close(). */
787  fd2 = dup(fd);
788  if (fd2 < 0) {
789  fprintf(stderr, "xtrabackup: Got error %d on dup\n",fd2);
790  }
791  close(fd);
792  }
793  return(fd2);
794 }
795 
796 void
798  trx_t* ,
799  const char* ,
800  ulint )
801 {
802  /* do nothing */
803 }
804 
805 /*****************************************************************/
809 static
810 char*
812 /*========================*/
813  char* buf,
814  ulint buflen,
815  const char* id,
816  ulint idlen,
817  void* ,
818  ibool )
820 {
821  const char* s = id;
822  int q;
823 
824  /* See if the identifier needs to be quoted. */
825  q = '"';
826 
827  if (q == EOF) {
828  if (UNIV_UNLIKELY(idlen > buflen)) {
829  idlen = buflen;
830  }
831  memcpy(buf, s, idlen);
832  return(buf + idlen);
833  }
834 
835  /* Quote the identifier. */
836  if (buflen < 2) {
837  return(buf);
838  }
839 
840  *buf++ = q;
841  buflen--;
842 
843  for (; idlen; idlen--) {
844  int c = *s++;
845  if (UNIV_UNLIKELY(c == q)) {
846  if (UNIV_UNLIKELY(buflen < 3)) {
847  break;
848  }
849 
850  *buf++ = c;
851  *buf++ = c;
852  buflen -= 2;
853  } else {
854  if (UNIV_UNLIKELY(buflen < 2)) {
855  break;
856  }
857 
858  *buf++ = c;
859  buflen--;
860  }
861  }
862 
863  *buf++ = q;
864  return(buf);
865 }
866 
867 /*****************************************************************/
871 UNIV_INTERN
872 char*
874 /*==================*/
875  char* buf,
876  ulint buflen,
877  const char* id,
878  ulint idlen,
879  drizzled::Session *session,
880  ibool table_id)
882 {
883  char* s = buf;
884  const char* bufend = buf + buflen;
885 
886  if (table_id) {
887  const char* slash = (const char*) memchr(id, '/', idlen);
888  if (!slash) {
889 
890  goto no_db_name;
891  }
892 
893  /* Print the database name and table name separately. */
894  s = innobase_convert_identifier(s, bufend - s, id, slash - id,
895  session, TRUE);
896  if (UNIV_LIKELY(s < bufend)) {
897  *s++ = '.';
898  s = innobase_convert_identifier(s, bufend - s,
899  slash + 1, idlen
900  - (slash - id) - 1,
901  session, TRUE);
902  }
903  } else if (UNIV_UNLIKELY(*id == TEMP_INDEX_PREFIX)) {
904  /* Temporary index name (smart ALTER TABLE) */
905  const char temp_index_suffix[]= "--temporary--";
906 
907  s = innobase_convert_identifier(buf, buflen, id + 1, idlen - 1,
908  session, FALSE);
909  if (s - buf + (sizeof temp_index_suffix - 1) < buflen) {
910  memcpy(s, temp_index_suffix,
911  sizeof temp_index_suffix - 1);
912  s += sizeof temp_index_suffix - 1;
913  }
914  } else {
915 no_db_name:
916  s = innobase_convert_identifier(buf, buflen, id, idlen,
917  session, table_id);
918  }
919 
920  return(s);
921 
922 }
923 
924 ibool
926  trx_t* )
927 {
928  /* There are no mysql_thd */
929  return(FALSE);
930 }
931 
932 UNIV_INTERN int
934 /*===============*/
935  int mysql_type,
936  uint charset_number,
937  const unsigned char* a,
938  unsigned int a_length,
940  const unsigned char* b, /* in: data field */
941  unsigned int b_length); /* in: data field length,
942  not UNIV_SQL_NULL */
943 
944 int
946 /*===============*/
947  /* out: 1, 0, -1, if a is greater, equal, less than b, respectively */
948  int mysql_type, /* in: MySQL type */
949  uint charset_number, /* in: number of the charset */
950  const unsigned char* a, /* in: data field */
951  unsigned int a_length, /* in: data field length, not UNIV_SQL_NULL */
952  const unsigned char* b, /* in: data field */
953  unsigned int b_length) /* in: data field length, not UNIV_SQL_NULL */
954 {
955  const CHARSET_INFO* charset;
956  enum_field_types mysql_tp;
957  int ret;
958 
959  assert(a_length != UNIV_SQL_NULL);
960  assert(b_length != UNIV_SQL_NULL);
961 
962  mysql_tp = (enum_field_types) mysql_type;
963 
964  switch (mysql_tp) {
965 
966  case DRIZZLE_TYPE_BLOB:
967  case DRIZZLE_TYPE_VARCHAR:
968  /* Use the charset number to pick the right charset struct for
969  the comparison. Since the MySQL function get_charset may be
970  slow before Bar removes the mutex operation there, we first
971  look at 2 common charsets directly. */
972 
973  if (charset_number == default_charset_info->number) {
974  charset = default_charset_info;
975  } else {
976  charset = get_charset(charset_number);
977 
978  if (charset == NULL) {
979  fprintf(stderr, "xtrabackup needs charset %lu for doing "
980  "a comparison, but MySQL cannot "
981  "find that charset.",
982  (ulong) charset_number);
983  ut_a(0);
984  }
985  }
986 
987  /* Starting from 4.1.3, we use strnncollsp() in comparisons of
988  non-latin1_swedish_ci strings. NOTE that the collation order
989  changes then: 'b\0\0...' is ordered BEFORE 'b ...'. Users
990  having indexes on such data need to rebuild their tables! */
991 
992  ret = charset->coll->strnncollsp(charset,
993  a, a_length,
994  b, b_length, 0);
995  if (ret < 0) {
996  return(-1);
997  } else if (ret > 0) {
998  return(1);
999  } else {
1000  return(0);
1001  }
1002  default:
1003  ut_error;
1004  }
1005 
1006  return(0);
1007 }
1008 
1009 ulint
1011  ulint charset_id,
1012  ulint prefix_len,
1013  ulint data_len,
1014  const char* str)
1015 {
1016  ulint char_length; /* character length in bytes */
1017  ulint n_chars; /* number of characters in prefix */
1018  const CHARSET_INFO* charset; /* charset used in the field */
1019 
1020  charset = get_charset((uint) charset_id);
1021 
1022  ut_ad(charset);
1023  ut_ad(charset->mbmaxlen);
1024 
1025  /* Calculate how many characters at most the prefix index contains */
1026 
1027  n_chars = prefix_len / charset->mbmaxlen;
1028 
1029  /* If the charset is multi-byte, then we must find the length of the
1030  first at most n chars in the string. If the string contains less
1031  characters than n, then we return the length to the end of the last
1032  character. */
1033 
1034  if (charset->mbmaxlen > 1) {
1035  /* my_charpos() returns the byte length of the first n_chars
1036  characters, or a value bigger than the length of str, if
1037  there were not enough full characters in str.
1038 
1039  Why does the code below work:
1040  Suppose that we are looking for n UTF-8 characters.
1041 
1042  1) If the string is long enough, then the prefix contains at
1043  least n complete UTF-8 characters + maybe some extra
1044  characters + an incomplete UTF-8 character. No problem in
1045  this case. The function returns the pointer to the
1046  end of the nth character.
1047 
1048  2) If the string is not long enough, then the string contains
1049  the complete value of a column, that is, only complete UTF-8
1050  characters, and we can store in the column prefix index the
1051  whole string. */
1052 
1053  char_length = my_charpos(charset, str,
1054  str + data_len, (int) n_chars);
1055  if (char_length > data_len) {
1056  char_length = data_len;
1057  }
1058  } else {
1059  if (data_len < prefix_len) {
1060  char_length = data_len;
1061  } else {
1062  char_length = prefix_len;
1063  }
1064  }
1065 
1066  return(char_length);
1067 }
1068 
1069 UNIV_INTERN
1070 ulint
1072 /*================*/
1073  const char* ,
1074  ulint ,
1076  ulint ,
1077  char* ,
1078  ulint )
1080 {
1081  fprintf(stderr, "xtrabackup: innobase_raw_format() is called\n");
1082  return(0);
1083 }
1084 
1085 UNIV_INTERN
1086 ulong
1088 /*==================*/
1091 {
1092  return(innobase_lock_wait_timeout);
1093 }
1094 
1095 UNIV_INTERN
1096 ibool
1098 /*============*/
1099  drizzled::Session* )
1101 {
1102  return(FALSE);
1103 }
1104 
1105 ibool
1107 /*==========*/
1108  trx_t*)
1109 {
1110  return(FALSE);
1111 }
1112 
1113 #ifdef XTRADB_BASED
1114 trx_t*
1115 innobase_get_trx()
1116 {
1117  return(NULL);
1118 }
1119 
1120 ibool
1121 innobase_get_slow_log()
1122 {
1123  return(FALSE);
1124 }
1125 #endif
1126 
1127 /***********************************************************************
1128 Computes bit shift for a given value. If the argument is not a power
1129 of 2, returns 0.*/
1130 UNIV_INLINE
1131 ulint
1132 get_bit_shift(ulint value)
1133 {
1134  ulint shift;
1135 
1136  if (value == 0)
1137  return 0;
1138 
1139  for (shift = 0; !(value & 1UL); shift++) {
1140  value >>= 1;
1141  }
1142  return (value >> 1) ? 0 : shift;
1143 }
1144 
1145 static bool
1146 innodb_init_param(void)
1147 {
1148  /* innobase_init */
1149  static char current_dir[3]; /* Set if using current lib */
1150  bool ret;
1151  char *default_path;
1152 
1153  /* dummy for initialize all_charsets[] */
1154  get_charset_name(0);
1155 
1156 #ifdef XTRADB_BASED
1157  srv_page_size = 0;
1158  srv_page_size_shift = 0;
1159 
1160  if (innobase_page_size != (1 << 14)) {
1161  int n_shift = get_bit_shift(innobase_page_size);
1162 
1163  if (n_shift >= 12 && n_shift <= UNIV_PAGE_SIZE_SHIFT_MAX) {
1164  fprintf(stderr,
1165  "InnoDB: Warning: innodb_page_size has been "
1166  "changed from default value 16384.\n");
1167  srv_page_size_shift = n_shift;
1168  srv_page_size = 1 << n_shift;
1169  fprintf(stderr,
1170  "InnoDB: The universal page size of the "
1171  "database is set to %lu.\n", srv_page_size);
1172  } else {
1173  fprintf(stderr, "InnoDB: Error: invalid value of "
1174  "innobase_page_size: %lu", innobase_page_size);
1175  exit(EXIT_FAILURE);
1176  }
1177  } else {
1178  srv_page_size_shift = 14;
1179  srv_page_size = (1 << srv_page_size_shift);
1180  }
1181 
1182  srv_log_block_size = 0;
1183  if (innobase_log_block_size != 512) {
1184  uint n_shift = get_bit_shift(innobase_log_block_size);;
1185 
1186  fprintf(stderr,
1187  "InnoDB: Warning: innodb_log_block_size has "
1188  "been changed from its default value. "
1189  "(###EXPERIMENTAL### operation)\n");
1190  if (n_shift > 0) {
1191  srv_log_block_size = (1 << n_shift);
1192  fprintf(stderr,
1193  "InnoDB: The log block size is set to %lu.\n",
1194  srv_log_block_size);
1195  }
1196  } else {
1197  srv_log_block_size = 512;
1198  }
1199 
1200  if (!srv_log_block_size) {
1201  fprintf(stderr,
1202  "InnoDB: Error: %lu is not valid value for "
1203  "innodb_log_block_size.\n", innobase_log_block_size);
1204  goto error;
1205  }
1206 
1207  srv_fast_checksum = (ibool) innobase_fast_checksum;
1208 #endif
1209 
1210  /* Check that values don't overflow on 32-bit systems. */
1211  if (sizeof(ulint) == 4) {
1212  if (xtrabackup_use_memory > UINT32_MAX) {
1213  fprintf(stderr,
1214  "xtrabackup: use-memory can't be over 4GB"
1215  " on 32-bit systems\n");
1216  }
1217 
1218  if (innobase_buffer_pool_size > UINT32_MAX) {
1219  fprintf(stderr,
1220  "xtrabackup: innobase_buffer_pool_size can't be over 4GB"
1221  " on 32-bit systems\n");
1222 
1223  goto error;
1224  }
1225 
1226  if (innobase_log_file_size > UINT32_MAX) {
1227  fprintf(stderr,
1228  "xtrabackup: innobase_log_file_size can't be over 4GB"
1229  " on 32-bit systemsi\n");
1230 
1231  goto error;
1232  }
1233  }
1234 
1235  os_innodb_umask = (ulint)0664;
1236 
1237  /* First calculate the default path for innodb_data_home_dir etc.,
1238  in case the user has not given any value.
1239 
1240  Note that when using the embedded server, the datadirectory is not
1241  necessarily the current directory of this program. */
1242 
1243  /* It's better to use current lib, to keep paths short */
1244  current_dir[0] = FN_CURLIB;
1245  current_dir[1] = FN_LIBCHAR;
1246  current_dir[2] = 0;
1247  default_path = current_dir;
1248 
1249  ut_a(default_path);
1250 
1251  /* Set InnoDB initialization parameters according to the values
1252  read from MySQL .cnf file */
1253 
1254  if (xtrabackup_backup || xtrabackup_stats) {
1255  fprintf(stderr, "xtrabackup: Target instance is assumed as followings.\n");
1256  } else {
1257  fprintf(stderr, "xtrabackup: Temporary instance for recovery is set as followings.\n");
1258  }
1259 
1260  /*--------------- Data files -------------------------*/
1261 
1262  /* The default dir for data files is the datadir of MySQL */
1263 
1264  srv_data_home = ((xtrabackup_backup || xtrabackup_stats) && innobase_data_home_dir
1265  ? innobase_data_home_dir : default_path);
1266  fprintf(stderr, "xtrabackup: innodb_data_home_dir = %s\n", srv_data_home);
1267 
1268  /* Set default InnoDB data file size to 10 MB and let it be
1269  auto-extending. Thus users can use InnoDB in >= 4.0 without having
1270  to specify any startup options. */
1271 
1272  if (!innobase_data_file_path) {
1273  innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
1274  }
1275  fprintf(stderr, "xtrabackup: innodb_data_file_path = %s\n",
1276  innobase_data_file_path);
1277 
1278  /* Since InnoDB edits the argument in the next call, we make another
1279  copy of it: */
1280 
1281  internal_innobase_data_file_path = strdup(innobase_data_file_path);
1282 
1284  internal_innobase_data_file_path);
1285  if (ret == FALSE) {
1286  fprintf(stderr,
1287  "xtrabackup: syntax error in innodb_data_file_path\n");
1288 mem_free_and_error:
1289  free(internal_innobase_data_file_path);
1290  goto error;
1291  }
1292 
1293  if (xtrabackup_prepare) {
1294  /* "--prepare" needs filenames only */
1295  ulint i;
1296 
1297  for (i=0; i < srv_n_data_files; i++) {
1298  char *p;
1299 
1300  p = srv_data_file_names[i];
1301  while ((p = strstr(p, SRV_PATH_SEPARATOR_STR)) != NULL)
1302  {
1303  p++;
1304  srv_data_file_names[i] = p;
1305  }
1306  }
1307  }
1308 
1309 #ifdef XTRADB_BASED
1310  srv_doublewrite_file = innobase_doublewrite_file;
1311 #ifndef XTRADB55
1312  srv_extra_undoslots = (ibool) innobase_extra_undoslots;
1313 #endif
1314 #endif
1315 
1316  /* -------------- Log files ---------------------------*/
1317 
1318  /* The default dir for log files is the datadir of MySQL */
1319 
1320  if (!((xtrabackup_backup || xtrabackup_stats) && innobase_log_group_home_dir)) {
1321  innobase_log_group_home_dir = default_path;
1322  }
1323  if (xtrabackup_prepare && xtrabackup_incremental_dir) {
1324  innobase_log_group_home_dir = xtrabackup_incremental_dir;
1325  }
1326  fprintf(stderr, "xtrabackup: innodb_log_group_home_dir = %s\n",
1327  innobase_log_group_home_dir);
1328 
1329 #ifdef UNIV_LOG_ARCHIVE
1330  /* Since innodb_log_arch_dir has no relevance under MySQL,
1331  starting from 4.0.6 we always set it the same as
1332  innodb_log_group_home_dir: */
1333 
1334  innobase_log_arch_dir = innobase_log_group_home_dir;
1335 
1336  srv_arch_dir = innobase_log_arch_dir;
1337 #endif /* UNIG_LOG_ARCHIVE */
1338 
1339  ret = (bool)
1340  srv_parse_log_group_home_dirs(innobase_log_group_home_dir);
1341 
1342  if (ret == FALSE || innobase_mirrored_log_groups != 1) {
1343  fprintf(stderr, "xtrabackup: syntax error in innodb_log_group_home_dir, or a "
1344  "wrong number of mirrored log groups\n");
1345 
1346  goto mem_free_and_error;
1347  }
1348 
1349  srv_adaptive_flushing = FALSE;
1350  srv_use_sys_malloc = TRUE;
1351  srv_file_format = 1; /* Barracuda */
1353 
1354  /* --------------------------------------------------*/
1355 
1356  srv_file_flush_method_str = innobase_unix_file_flush_method;
1357 
1358  srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
1359  srv_n_log_files = (ulint) innobase_log_files_in_group;
1360  srv_log_file_size = (ulint) innobase_log_file_size;
1361  fprintf(stderr, "xtrabackup: innodb_log_files_in_group = %ld\n",
1362  srv_n_log_files);
1363  fprintf(stderr, "xtrabackup: innodb_log_file_size = %ld\n",
1364  srv_log_file_size);
1365 
1366 #ifdef UNIV_LOG_ARCHIVE
1367  srv_log_archive_on = (ulint) innobase_log_archive;
1368 #endif /* UNIV_LOG_ARCHIVE */
1369  srv_log_buffer_size = (ulint) innobase_log_buffer_size;
1370 
1371  /* We set srv_pool_size here in units of 1 kB. InnoDB internally
1372  changes the value so that it becomes the number of database pages. */
1373 
1374  //srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
1375  srv_buf_pool_size = (ulint) xtrabackup_use_memory;
1376 
1377  srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
1378 
1379  srv_n_file_io_threads = (ulint) innobase_file_io_threads;
1380 
1381  srv_n_read_io_threads = (ulint) innobase_read_io_threads;
1382  srv_n_write_io_threads = (ulint) innobase_write_io_threads;
1383 
1384  srv_force_recovery = (ulint) innobase_force_recovery;
1385 
1386  srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
1387  srv_use_checksums = (ibool) innobase_use_checksums;
1388 
1389  btr_search_enabled = innobase_adaptive_hash_index ? true : false;
1390 
1391  os_use_large_pages = (ibool) innobase_use_large_pages;
1392  os_large_page_size = (ulint) innobase_large_page_size;
1393 
1394  row_rollback_on_timeout = (ibool) innobase_rollback_on_timeout;
1395 
1396  srv_file_per_table = innobase_file_per_table ? true : false;
1397 
1398  srv_locks_unsafe_for_binlog = (ibool) innobase_locks_unsafe_for_binlog;
1399 
1400  srv_max_n_open_files = (ulint) innobase_open_files;
1401  srv_innodb_status = (ibool) innobase_create_status_file;
1402 
1403  srv_print_verbose_log = 1;
1404 
1405  /* Store the default charset-collation number of this MySQL
1406  installation */
1407 
1408  /* We cannot treat characterset here for now!! */
1409  data_mysql_default_charset_coll = (ulint)default_charset_info->number;
1410 
1411  ut_a(DATA_MYSQL_BINARY_CHARSET_COLL == my_charset_bin.number);
1412 
1413  //innobase_commit_concurrency_init_default();
1414 
1415  /* Since we in this module access directly the fields of a trx
1416  struct, and due to different headers and flags it might happen that
1417  mutex_t has a different size in this module and in InnoDB
1418  modules, we check at run time that the size is the same in
1419  these compilation modules. */
1420 
1421 
1422  /* On 5.5 srv_use_native_aio is TRUE by default. It is later reset
1423  if it is not supported by the platform in
1424  innobase_start_or_create_for_mysql(). As we don't call it in xtrabackup,
1425  we have to duplicate checks from that function here. */
1426 
1427 #ifdef __WIN__
1428  switch (os_get_os_version()) {
1429  case OS_WIN95:
1430  case OS_WIN31:
1431  case OS_WINNT:
1432  /* On Win 95, 98, ME, Win32 subsystem for Windows 3.1,
1433  and NT use simulated aio. In NT Windows provides async i/o,
1434  but when run in conjunction with InnoDB Hot Backup, it seemed
1435  to corrupt the data files. */
1436 
1437  srv_use_native_aio = FALSE;
1438  break;
1439 
1440  case OS_WIN2000:
1441  case OS_WINXP:
1442  /* On 2000 and XP, async IO is available. */
1443  srv_use_native_aio = TRUE;
1444  break;
1445 
1446  default:
1447  /* Vista and later have both async IO and condition variables */
1448  srv_use_native_aio = TRUE;
1449  srv_use_native_conditions = TRUE;
1450  break;
1451  }
1452 
1453 #elif defined(LINUX_NATIVE_AIO)
1454 
1455  if (srv_use_native_aio) {
1456  ut_print_timestamp(stderr);
1457  fprintf(stderr,
1458  " InnoDB: Using Linux native AIO\n");
1459  }
1460 #else
1461  /* Currently native AIO is supported only on windows and linux
1462  and that also when the support is compiled in. In all other
1463  cases, we ignore the setting of innodb_use_native_aio. */
1464  srv_use_native_aio = FALSE;
1465 
1466 #endif
1467 
1468  return(FALSE);
1469 
1470 error:
1471  fprintf(stderr, "xtrabackup: innodb_init_param(): Error occured.\n");
1472  return(TRUE);
1473 }
1474 
1475 static bool
1476 innodb_init(void)
1477 {
1478  int err;
1479 
1481 
1482  if (err != DB_SUCCESS) {
1483  free(internal_innobase_data_file_path);
1484  goto error;
1485  }
1486 
1487  /* They may not be needed for now */
1488 // (void) hash_init(&innobase_open_tables,system_charset_info, 32, 0, 0,
1489 // (hash_get_key) innobase_get_key, 0, 0);
1490 // pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
1491 // pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
1492 // pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
1493 // pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
1494 // pthread_cond_init(&commit_cond, NULL);
1495 
1496  innodb_inited= 1;
1497 
1498  return(FALSE);
1499 
1500 error:
1501  fprintf(stderr, "xtrabackup: innodb_init(): Error occured.\n");
1502  return(TRUE);
1503 }
1504 
1505 static bool
1506 innodb_end(void)
1507 {
1508  srv_fast_shutdown = (ulint) innobase_fast_shutdown;
1509  innodb_inited = 0;
1510 
1511  fprintf(stderr, "xtrabackup: starting shutdown with innodb_fast_shutdown = %lu\n",
1512  srv_fast_shutdown);
1513 
1514  if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
1515  goto error;
1516  }
1517  free(internal_innobase_data_file_path);
1518 
1519  /* They may not be needed for now */
1520 // hash_free(&innobase_open_tables);
1521 // pthread_mutex_destroy(&innobase_share_mutex);
1522 // pthread_mutex_destroy(&prepare_commit_mutex);
1523 // pthread_mutex_destroy(&commit_threads_m);
1524 // pthread_mutex_destroy(&commit_cond_m);
1525 // pthread_cond_destroy(&commit_cond);
1526 
1527  return(FALSE);
1528 
1529 error:
1530  fprintf(stderr, "xtrabackup: innodb_end(): Error occured.\n");
1531  return(TRUE);
1532 }
1533 
1534 /* ================= common ================= */
1535 static bool
1536 xtrabackup_read_metadata(char *filename)
1537 {
1538  FILE *fp;
1539 
1540  fp = fopen(filename,"r");
1541  if(!fp) {
1542  fprintf(stderr, "xtrabackup: Error: cannot open %s\n", filename);
1543  return(TRUE);
1544  }
1545 
1546  if (fscanf(fp, "backup_type = %29s\n", metadata_type)
1547  != 1)
1548  return(TRUE);
1549  if (fscanf(fp, "from_lsn = %"PRIu64"\n", &metadata_from_lsn)
1550  != 1)
1551  return(TRUE);
1552  if (fscanf(fp, "to_lsn = %"PRIu64"\n", &metadata_to_lsn)
1553  != 1)
1554  return(TRUE);
1555  if (fscanf(fp, "last_lsn = %"PRIu64"\n", &metadata_last_lsn)
1556  != 1) {
1557  metadata_last_lsn = 0;
1558  }
1559 
1560  fclose(fp);
1561 
1562  return(FALSE);
1563 }
1564 
1565 static bool
1566 xtrabackup_write_metadata(char *filename)
1567 {
1568  FILE *fp;
1569 
1570  fp = fopen(filename,"w");
1571  if(!fp) {
1572  fprintf(stderr, "xtrabackup: Error: cannot open %s\n", filename);
1573  return(TRUE);
1574  }
1575 
1576  if (fprintf(fp, "backup_type = %s\n", metadata_type)
1577  < 0)
1578  return(TRUE);
1579  if (fprintf(fp, "from_lsn = %"PRIu64"\n", metadata_from_lsn)
1580  < 0)
1581  return(TRUE);
1582  if (fprintf(fp, "to_lsn = %"PRIu64"\n", metadata_to_lsn)
1583  < 0)
1584  return(TRUE);
1585  if (fprintf(fp, "last_lsn = %"PRIu64"\n", metadata_last_lsn)
1586  < 0)
1587  return(TRUE);
1588 
1589  fclose(fp);
1590 
1591  return(FALSE);
1592 }
1593 
1594 /***********************************************************************
1595 Read meta info for an incremental delta.
1596 @return TRUE on success, FALSE on failure. */
1597 static bool
1598 xb_read_delta_metadata(const char *filepath, xb_delta_info_t *info)
1599 {
1600  FILE *fp;
1601 
1602  memset(info, 0, sizeof(xb_delta_info_t));
1603 
1604  fp = fopen(filepath, "r");
1605  if (!fp) {
1606  /* Meta files for incremental deltas are optional */
1607  return(TRUE);
1608  }
1609 
1610  if (fscanf(fp, "page_size = %lu\n", &info->page_size) != 1)
1611  return(FALSE);
1612 
1613  fclose(fp);
1614 
1615  return(TRUE);
1616 }
1617 
1618 /***********************************************************************
1619 Write meta info for an incremental delta.
1620 @return TRUE on success, FALSE on failure. */
1621 static bool
1622 xb_write_delta_metadata(const char *filepath, const xb_delta_info_t *info)
1623 {
1624  FILE *fp;
1625 
1626  fp = fopen(filepath, "w");
1627  if (!fp) {
1628  fprintf(stderr, "xtrabackup: Error: cannot open %s\n", filepath);
1629  return(FALSE);
1630  }
1631 
1632  if (fprintf(fp, "page_size = %lu\n", info->page_size) < 0)
1633  return(FALSE);
1634 
1635  fclose(fp);
1636 
1637  return(TRUE);
1638 }
1639 
1640 /* ================= backup ================= */
1641 static void
1642 xtrabackup_io_throttling(void)
1643 {
1644  if (xtrabackup_throttle && (io_ticket--) < 0) {
1645  os_event_reset(wait_throttle);
1646  os_event_wait(wait_throttle);
1647  }
1648 }
1649 
1650 
1651 /* TODO: We may tune the behavior (e.g. by fil_aio)*/
1652 #define COPY_CHUNK 64
1653 
1654 static bool
1655 xtrabackup_copy_datafile(fil_node_t* node, uint thread_n)
1656 {
1657  os_file_t src_file = -1;
1658  os_file_t dst_file = -1;
1659  char dst_path[FN_REFLEN];
1660  char meta_path[FN_REFLEN];
1661  ibool success;
1662  byte* page;
1663  byte* buf2 = NULL;
1664  IB_INT64 file_size;
1665  IB_INT64 offset;
1666  ulint page_in_buffer= 0;
1667  ulint incremental_buffers = 0;
1668  ulint page_size;
1669  ulint page_size_shift;
1670  ulint zip_size;
1671  xb_delta_info_t info;
1672 
1673  info.page_size = 0;
1674 
1675 #ifdef XTRADB_BASED
1676  if (xtrabackup_tables && (!trx_sys_sys_space(node->space->id)))
1677 #else
1678  if (xtrabackup_tables && (node->space->id != 0))
1679 #endif
1680  { /* must backup id==0 */
1681  char *p;
1682  int p_len, regres= 0;
1683  char *next, *prev;
1684  char tmp;
1685  int i;
1686 
1687  p = node->name;
1688  prev = NULL;
1689  while ((next = strstr(p, SRV_PATH_SEPARATOR_STR)) != NULL)
1690  {
1691  prev = p;
1692  p = next + 1;
1693  }
1694  p_len = strlen(p) - strlen(".ibd");
1695 
1696  if (p_len < 1) {
1697  /* unknown situation: skip filtering */
1698  goto skip_filter;
1699  }
1700 
1701  /* TODO: Fix this lazy implementation... */
1702  tmp = p[p_len];
1703  p[p_len] = 0;
1704  *(p - 1) = '.';
1705 
1706  for (i = 0; i < tables_regex_num; i++) {
1707  regres = regexec(&tables_regex[i], prev, 1, tables_regmatch, 0);
1708  if (regres != REG_NOMATCH)
1709  break;
1710  }
1711 
1712  p[p_len] = tmp;
1713  *(p - 1) = SRV_PATH_SEPARATOR;
1714 
1715  if ( regres == REG_NOMATCH ) {
1716  printf("[%02u] Copying %s is skipped.\n",
1717  thread_n, node->name);
1718  return(FALSE);
1719  }
1720  }
1721 
1722 #ifdef XTRADB_BASED
1723  if (xtrabackup_tables_file && (!trx_sys_sys_space(node->space->id)))
1724 #else
1725  if (xtrabackup_tables_file && (node->space->id != 0))
1726 #endif
1727  { /* must backup id==0 */
1728  xtrabackup_tables_t* table;
1729  char *p;
1730  int p_len;
1731  char *next, *prev;
1732  char tmp;
1733 
1734  p = node->name;
1735  prev = NULL;
1736  while ((next = strstr(p, SRV_PATH_SEPARATOR_STR)) != NULL)
1737  {
1738  prev = p;
1739  p = next + 1;
1740  }
1741  p_len = strlen(p) - strlen(".ibd");
1742 
1743  if (p_len < 1) {
1744  /* unknown situation: skip filtering */
1745  goto skip_filter;
1746  }
1747 
1748  /* TODO: Fix this lazy implementation... */
1749  tmp = p[p_len];
1750  p[p_len] = 0;
1751 
1752  HASH_SEARCH(name_hash, tables_hash, ut_fold_string(prev),
1754  table,
1755  ut_ad(table->name),
1756  !strcmp(table->name, prev));
1757 
1758  p[p_len] = tmp;
1759 
1760  if (!table) {
1761  printf("[%02u] Copying %s is skipped.\n",
1762  thread_n, node->name);
1763  return(FALSE);
1764  }
1765  }
1766 
1767 skip_filter:
1768  zip_size = fil_space_get_zip_size(node->space->id);
1769  if (zip_size == ULINT_UNDEFINED) {
1770  fprintf(stderr, "[%02u] xtrabackup: Warning: "
1771  "Failed to determine page size for %s.\n"
1772  "[%02u] xtrabackup: Warning: We assume the table was "
1773  "dropped during xtrabackup execution and ignore the "
1774  "file.\n", thread_n, node->name, thread_n);
1775  goto skip;
1776  } else if (zip_size) {
1777  page_size = zip_size;
1778  page_size_shift = get_bit_shift(page_size);
1779  fprintf(stderr, "[%02u] %s is compressed with page size = "
1780  "%lu bytes\n", thread_n, node->name, page_size);
1781  if (page_size_shift < 10 || page_size_shift > 14) {
1782  fprintf(stderr, "[%02u] xtrabackup: Error: Invalid "
1783  "page size.\n", thread_n);
1784  ut_error;
1785  }
1786  } else {
1787  page_size = UNIV_PAGE_SIZE;
1788  page_size_shift = UNIV_PAGE_SIZE_SHIFT;
1789  }
1790 
1791 #ifdef XTRADB_BASED
1792  if (trx_sys_sys_space(node->space->id))
1793 #else
1794  if (node->space->id == 0)
1795 #endif
1796  {
1797  char *next, *p;
1798  /* system datafile "/fullpath/datafilename.ibd" or "./datafilename.ibd" */
1799  p = node->name;
1800  while ((next = strstr(p, SRV_PATH_SEPARATOR_STR)) != NULL)
1801  {
1802  p = next + 1;
1803  }
1804  sprintf(dst_path, "%s/%s", xtrabackup_target_dir, p);
1805  } else {
1806  /* file per table style "./database/table.ibd" */
1807  sprintf(dst_path, "%s%s", xtrabackup_target_dir, strstr(node->name, SRV_PATH_SEPARATOR_STR));
1808  }
1809 
1810  if (xtrabackup_incremental) {
1811  snprintf(meta_path, sizeof(meta_path),
1812  "%s%s", dst_path, XB_DELTA_INFO_SUFFIX);
1813  strcat(dst_path, ".delta");
1814 
1815  /* clear buffer */
1816  bzero(incremental_buffer, (page_size/4) * page_size);
1817  page_in_buffer = 0;
1818  mach_write_to_4(incremental_buffer, 0x78747261UL);/*"xtra"*/
1819  page_in_buffer++;
1820 
1821  info.page_size = page_size;
1822  }
1823 
1824  /* open src_file*/
1825  if (!node->open) {
1826  src_file = os_file_create_simple_no_error_handling(
1827  0 /* dummy of innodb_file_data_key */,
1828  node->name, OS_FILE_OPEN,
1829  OS_FILE_READ_ONLY, &success);
1830  if (!success) {
1831  /* The following call prints an error message */
1832  os_file_get_last_error(TRUE);
1833 
1834  fprintf(stderr,
1835  "[%02u] xtrabackup: Warning: cannot open %s\n"
1836  "[%02u] xtrabackup: Warning: We assume the "
1837  "table was dropped during xtrabackup execution "
1838  "and ignore the file.\n",
1839  thread_n, node->name, thread_n);
1840  goto skip;
1841  }
1842 
1843  if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
1844  os_file_set_nocache(src_file, node->name, "OPEN");
1845  }
1846  } else {
1847  src_file = node->handle;
1848  }
1849 
1850 #ifdef USE_POSIX_FADVISE
1851  posix_fadvise(src_file, 0, 0, POSIX_FADV_SEQUENTIAL);
1852  posix_fadvise(src_file, 0, 0, POSIX_FADV_DONTNEED);
1853 #endif
1854 
1855  /* open dst_file */
1856  /* os_file_create reads srv_unix_file_flush_method */
1857  dst_file = os_file_create(
1858  0 /* dummy of innodb_file_data_key */,
1859  dst_path, OS_FILE_CREATE,
1860  OS_FILE_NORMAL, OS_DATA_FILE, &success);
1861  if (!success) {
1862  /* The following call prints an error message */
1863  os_file_get_last_error(TRUE);
1864 
1865  fprintf(stderr,"[%02u] xtrabackup: error: "
1866  "cannot open %s\n", thread_n, dst_path);
1867  goto error;
1868  }
1869 
1870 #ifdef USE_POSIX_FADVISE
1871  posix_fadvise(dst_file, 0, 0, POSIX_FADV_DONTNEED);
1872 #endif
1873 
1874  /* copy : TODO: tune later */
1875  printf("[%02u] Copying %s \n to %s\n", thread_n,
1876  node->name, dst_path);
1877 
1878  buf2 = (unsigned char*) ut_malloc(COPY_CHUNK * page_size + UNIV_PAGE_SIZE);
1879  page = (unsigned char*) ut_align(buf2, UNIV_PAGE_SIZE);
1880 
1881  success = os_file_read(src_file, page, 0, 0, UNIV_PAGE_SIZE);
1882  if (!success) {
1883  goto error;
1884  }
1885 
1886  file_size = os_file_get_size_as_iblonglong(src_file);
1887 
1888  for (offset = 0; offset < file_size; offset += COPY_CHUNK * page_size) {
1889  ulint chunk;
1890  ulint chunk_offset;
1891  ulint retry_count = 10;
1892 //copy_loop:
1893  if ((ulint)(file_size - offset) > COPY_CHUNK * page_size) {
1894  chunk = COPY_CHUNK * page_size;
1895  } else {
1896  chunk = (ulint)(file_size - offset);
1897  }
1898 
1899 read_retry:
1900  xtrabackup_io_throttling();
1901 
1902  success = os_file_read(src_file, page,
1903  (ulint)(offset & 0xFFFFFFFFUL),
1904  (ulint)(offset >> 32), chunk);
1905  if (!success) {
1906  goto error;
1907  }
1908 
1909  /* check corruption and retry */
1910  for (chunk_offset = 0; chunk_offset < chunk; chunk_offset += page_size) {
1911  if (buf_page_is_corrupted(page + chunk_offset, zip_size))
1912  {
1913  if (
1914 #ifdef XTRADB_BASED
1915  trx_sys_sys_space(node->space->id)
1916 #else
1917  node->space->id == 0
1918 #endif
1919  && ((offset + (IB_INT64)chunk_offset) >> page_size_shift)
1920  >= FSP_EXTENT_SIZE
1921  && ((offset + (IB_INT64)chunk_offset) >> page_size_shift)
1922  < FSP_EXTENT_SIZE * 3) {
1923  /* double write buffer may have old data in the end
1924  or it may contain the other format page like COMPRESSED.
1925  So, we can pass the check of double write buffer.*/
1926  ut_a(page_size == UNIV_PAGE_SIZE);
1927  fprintf(stderr, "[%02u] xtrabackup: "
1928  "Page %lu seems double write "
1929  "buffer. passing the check.\n",
1930  thread_n,
1931  (ulint)((offset +
1932  (IB_INT64)chunk_offset) >>
1933  page_size_shift));
1934  } else {
1935  retry_count--;
1936  if (retry_count == 0) {
1937  fprintf(stderr,
1938  "[%02u] xtrabackup: "
1939  "Error: 10 retries "
1940  "resulted in fail. This"
1941  "file seems to be "
1942  "corrupted.\n",
1943  thread_n);
1944  goto error;
1945  }
1946  fprintf(stderr, "[%02u] xtrabackup: "
1947  "Database page corruption "
1948  "detected at page %lu. "
1949  "retrying...\n",
1950  thread_n,
1951  (ulint)((offset +
1952  (IB_INT64)chunk_offset)
1953  >> page_size_shift));
1954  goto read_retry;
1955  }
1956  }
1957  }
1958 
1959  if (xtrabackup_incremental) {
1960  for (chunk_offset = 0; chunk_offset < chunk; chunk_offset += page_size) {
1961  /* newer page */
1962  /* This condition may be OK for header, ibuf and fsp */
1963  if (ut_dulint_cmp(incremental_lsn,
1964  MACH_READ_64(page + chunk_offset + FIL_PAGE_LSN)) < 0) {
1965  /* ========================================= */
1966  IB_INT64 offset_on_page;
1967 
1968  if (page_in_buffer == page_size/4) {
1969  /* flush buffer */
1970  success = os_file_write(dst_path, dst_file, incremental_buffer,
1971  ((incremental_buffers * (page_size/4))
1972  << page_size_shift) & 0xFFFFFFFFUL,
1973  (incremental_buffers * (page_size/4))
1974  >> (32 - page_size_shift),
1975  page_in_buffer * page_size);
1976  if (!success) {
1977  goto error;
1978  }
1979 
1980  incremental_buffers++;
1981 
1982  /* clear buffer */
1983  bzero(incremental_buffer, (page_size/4) * page_size);
1984  page_in_buffer = 0;
1985  mach_write_to_4(incremental_buffer, 0x78747261UL);/*"xtra"*/
1986  page_in_buffer++;
1987  }
1988 
1989  offset_on_page = ((offset + (IB_INT64)chunk_offset) >> page_size_shift);
1990  ut_a(offset_on_page >> 32 == 0);
1991 
1992  mach_write_to_4(incremental_buffer + page_in_buffer * 4, (ulint)offset_on_page);
1993  memcpy(incremental_buffer + page_in_buffer * page_size,
1994  page + chunk_offset, page_size);
1995 
1996  page_in_buffer++;
1997  /* ========================================= */
1998  }
1999  }
2000  } else {
2001  success = os_file_write(dst_path, dst_file, page,
2002  (ulint)(offset & 0xFFFFFFFFUL),
2003  (ulint)(offset >> 32), chunk);
2004  if (!success) {
2005  goto error;
2006  }
2007  }
2008 
2009  }
2010 
2011  if (xtrabackup_incremental) {
2012  /* termination */
2013  if (page_in_buffer != page_size/4) {
2014  mach_write_to_4(incremental_buffer + page_in_buffer * 4, 0xFFFFFFFFUL);
2015  }
2016 
2017  mach_write_to_4(incremental_buffer, 0x58545241UL);/*"XTRA"*/
2018 
2019  /* flush buffer */
2020  success = os_file_write(dst_path, dst_file, incremental_buffer,
2021  ((incremental_buffers * (page_size/4))
2022  << page_size_shift) & 0xFFFFFFFFUL,
2023  (incremental_buffers * (page_size/4))
2024  >> (32 - page_size_shift),
2025  page_in_buffer * page_size);
2026  if (!success) {
2027  goto error;
2028  }
2029  if (!xb_write_delta_metadata(meta_path, &info)) {
2030  fprintf(stderr, "[%02u] xtrabackup: Error: "
2031  "failed to write meta info for %s\n",
2032  thread_n, dst_path);
2033  goto error;
2034  }
2035  }
2036 
2037  success = os_file_flush(dst_file);
2038  if (!success) {
2039  goto error;
2040  }
2041 
2042 
2043  /* check size again */
2044  /* TODO: but is it needed ?? */
2045 // if (file_size < os_file_get_size_as_iblonglong(src_file)) {
2046 // offset -= COPY_CHUNK * page_size;
2047 // file_size = os_file_get_size_as_iblonglong(src_file);
2048 // goto copy_loop;
2049 // }
2050 
2051  /* TODO: How should we treat double_write_buffer here? */
2052  /* (currently, don't care about. Because,
2053  the blocks is newer than the last checkpoint anyway.) */
2054 
2055  /* close */
2056  printf("[%02u] ...done\n", thread_n);
2057  if (!node->open) {
2058  os_file_close(src_file);
2059  }
2060  os_file_close(dst_file);
2061  ut_free(buf2);
2062  return(FALSE);
2063 error:
2064  if (src_file != -1 && !node->open)
2065  os_file_close(src_file);
2066  if (dst_file != -1)
2067  os_file_close(dst_file);
2068  if (buf2)
2069  ut_free(buf2);
2070  fprintf(stderr, "[%02u] xtrabackup: Error: "
2071  "xtrabackup_copy_datafile() failed.\n", thread_n);
2072  return(TRUE); /*ERROR*/
2073 
2074 skip:
2075  if (src_file != -1 && !node->open)
2076  os_file_close(src_file);
2077  if (dst_file != -1)
2078  os_file_close(dst_file);
2079  if (buf2)
2080  ut_free(buf2);
2081  fprintf(stderr, "[%02u] xtrabackup: Warning: skipping file %s.\n",
2082  thread_n, node->name);
2083  return(FALSE);
2084 }
2085 
2086 static bool
2087 xtrabackup_copy_logfile(LSN64 from_lsn, bool is_last)
2088 {
2089  /* definition from recv_recovery_from_checkpoint_start() */
2090  log_group_t* group;
2091  LSN64 group_scanned_lsn;
2092  LSN64 contiguous_lsn;
2093 
2094  ibool success;
2095 
2096  if (!xtrabackup_stream)
2097  ut_a(dst_log != -1);
2098 
2099  /* read from checkpoint_lsn_start to current */
2100  contiguous_lsn = ut_dulint_align_down(from_lsn,
2102 
2103  /* TODO: We must check the contiguous_lsn still exists in log file.. */
2104 
2105  group = UT_LIST_GET_FIRST(log_sys->log_groups);
2106 
2107  while (group) {
2108  ibool finished;
2109  LSN64 start_lsn;
2110  LSN64 end_lsn;
2111 
2112 
2113  /* reference recv_group_scan_log_recs() */
2114  finished = FALSE;
2115 
2116  start_lsn = contiguous_lsn;
2117 
2118  while (!finished) {
2119  end_lsn = ut_dulint_add(start_lsn, RECV_SCAN_SIZE);
2120 
2121  xtrabackup_io_throttling();
2122 
2123  log_group_read_log_seg(LOG_RECOVER, log_sys->buf,
2124  group, start_lsn, end_lsn);
2125 
2126  //printf("log read from (%lu %lu) to (%lu %lu)\n",
2127  // start_lsn.high, start_lsn.low, end_lsn.high, end_lsn.low);
2128 
2129  /* reference recv_scan_log_recs() */
2130  {
2131  byte* log_block;
2132  ulint no;
2133  LSN64 scanned_lsn;
2134  ulint data_len;
2135 
2136  ulint scanned_checkpoint_no = 0;
2137 
2138  finished = FALSE;
2139 
2140  log_block = log_sys->buf;
2141  scanned_lsn = start_lsn;
2142 
2143  while (log_block < log_sys->buf + RECV_SCAN_SIZE && !finished) {
2144 
2145  no = log_block_get_hdr_no(log_block);
2146 
2147  if (no != log_block_convert_lsn_to_no(scanned_lsn)
2148  || !log_block_checksum_is_ok_or_old_format(log_block)) {
2149 
2150  if (no > log_block_convert_lsn_to_no(scanned_lsn)
2151  && log_block_checksum_is_ok_or_old_format(log_block)) {
2152  fprintf(stderr,
2153 ">> ###Warning###: The copying transaction log migh be overtaken already by the target.\n"
2154 ">> : Waiting log block no %lu, but the bumber is already %lu.\n"
2155 ">> : If the number equals %lu + n * %lu, it should be overtaken already.\n",
2156  (ulong) log_block_convert_lsn_to_no(scanned_lsn),
2157  (ulong) no,
2158  (ulong) log_block_convert_lsn_to_no(scanned_lsn),
2159  (ulong) (log_block_convert_lsn_to_no(
2160  log_group_get_capacity(group)
2161  ) - 1));
2162 
2163  } else if (no == log_block_convert_lsn_to_no(scanned_lsn)
2164  && !log_block_checksum_is_ok_or_old_format(
2165  log_block)) {
2166  fprintf(stderr,
2167 "xtrabackup: Log block no %lu at lsn %"PRIu64" has\n"
2168 "xtrabackup: ok header, but checksum field contains %lu, should be %lu\n",
2169  (ulong) no,
2170  scanned_lsn,
2171  (ulong) log_block_get_checksum(log_block),
2172  (ulong) log_block_calc_checksum(log_block));
2173  }
2174 
2175  /* Garbage or an incompletely written log block */
2176 
2177  finished = TRUE;
2178 
2179  break;
2180  }
2181 
2182  if (log_block_get_flush_bit(log_block)) {
2183  /* This block was a start of a log flush operation:
2184  we know that the previous flush operation must have
2185  been completed for all log groups before this block
2186  can have been flushed to any of the groups. Therefore,
2187  we know that log data is contiguous up to scanned_lsn
2188  in all non-corrupt log groups. */
2189 
2190  if (ut_dulint_cmp(scanned_lsn, contiguous_lsn) > 0) {
2191  contiguous_lsn = scanned_lsn;
2192  }
2193  }
2194 
2195  data_len = log_block_get_data_len(log_block);
2196 
2197  if (
2198  (scanned_checkpoint_no > 0)
2199  && (log_block_get_checkpoint_no(log_block)
2200  < scanned_checkpoint_no)
2201  && (scanned_checkpoint_no
2202  - log_block_get_checkpoint_no(log_block)
2203  > 0x80000000UL)) {
2204 
2205  /* Garbage from a log buffer flush which was made
2206  before the most recent database recovery */
2207 
2208  finished = TRUE;
2209  break;
2210  }
2211 
2212  scanned_lsn = ut_dulint_add(scanned_lsn, data_len);
2213  scanned_checkpoint_no = log_block_get_checkpoint_no(log_block);
2214 
2215  if (data_len < OS_FILE_LOG_BLOCK_SIZE) {
2216  /* Log data for this group ends here */
2217 
2218  finished = TRUE;
2219  } else {
2220  log_block += OS_FILE_LOG_BLOCK_SIZE;
2221  }
2222  } /* while (log_block < log_sys->buf + RECV_SCAN_SIZE && !finished) */
2223 
2224  group_scanned_lsn = scanned_lsn;
2225 
2226 
2227 
2228  }
2229 
2230  /* ===== write log to 'xtrabackup_logfile' ====== */
2231  {
2232  ulint write_size;
2233 
2234  if (!finished) {
2235  write_size = RECV_SCAN_SIZE;
2236  } else {
2237  write_size = ut_dulint_minus(
2238  ut_dulint_align_up(group_scanned_lsn, OS_FILE_LOG_BLOCK_SIZE),
2239  start_lsn);
2240  }
2241 
2242  //printf("Wrinting offset= %lld, size= %lu\n", log_copy_offset, write_size);
2243 
2244  if (!xtrabackup_stream) {
2245  success = os_file_write(dst_log_path, dst_log, log_sys->buf,
2246  (ulint)(log_copy_offset & 0xFFFFFFFFUL),
2247  (ulint)(log_copy_offset >> 32), write_size);
2248  } else {
2249  ulint ret;
2250  ulint stdout_write_size = write_size;
2251  if (finished && !is_last
2252  && group_scanned_lsn % OS_FILE_LOG_BLOCK_SIZE
2253  )
2254  stdout_write_size -= OS_FILE_LOG_BLOCK_SIZE;
2255  if (stdout_write_size) {
2256  ret = write(fileno(stdout), log_sys->buf, stdout_write_size);
2257  if (ret == stdout_write_size) {
2258  success = TRUE;
2259  } else {
2260  fprintf(stderr, "write: %lu > %lu\n", stdout_write_size, ret);
2261  success = FALSE;
2262  }
2263  } else {
2264  success = TRUE; /* do nothing */
2265  }
2266  }
2267 
2268  log_copy_offset += write_size;
2269 
2270  if (finished && group_scanned_lsn % OS_FILE_LOG_BLOCK_SIZE)
2271  {
2272  /* if continue, it will start from align_down(group_scanned_lsn) */
2273  log_copy_offset -= OS_FILE_LOG_BLOCK_SIZE;
2274  }
2275 
2276  if(!success) {
2277  if (!xtrabackup_stream) {
2278  fprintf(stderr, "xtrabackup: Error: os_file_write to %s\n", dst_log_path);
2279  } else {
2280  fprintf(stderr, "xtrabackup: Error: write to stdout\n");
2281  }
2282  goto error;
2283  }
2284 
2285 
2286  }
2287 
2288 
2289 
2290 
2291 
2292  start_lsn = end_lsn;
2293  }
2294 
2295 
2296 
2297  group->scanned_lsn = group_scanned_lsn;
2298 
2299 
2300  fprintf(stderr, ">> log scanned up to (%"PRIu64")\n",group->scanned_lsn);
2301 
2302  group = UT_LIST_GET_NEXT(log_groups, group);
2303 
2304  /* update global variable*/
2305  log_copy_scanned_lsn = group_scanned_lsn;
2306 
2307  /* innodb_mirrored_log_groups must be 1, no other groups */
2308  ut_a(group == NULL);
2309  }
2310 
2311 
2312  if (!xtrabackup_stream) {
2313  success = os_file_flush(dst_log);
2314  } else {
2315  fflush(stdout);
2316  success = TRUE;
2317  }
2318 
2319  if(!success) {
2320  goto error;
2321  }
2322 
2323  return(FALSE);
2324 
2325 error:
2326  if (!xtrabackup_stream)
2327  os_file_close(dst_log);
2328  fprintf(stderr, "xtrabackup: Error: xtrabackup_copy_logfile() failed.\n");
2329  return(TRUE);
2330 }
2331 
2332 /* copying logfile in background */
2333 #define SLEEPING_PERIOD 5
2334 
2335 static
2336 #ifndef __WIN__
2337 void*
2338 #else
2339 ulint
2340 #endif
2341 log_copying_thread(
2342  void* )
2343 {
2344  ulint counter = 0;
2345 
2346  if (!xtrabackup_stream)
2347  ut_a(dst_log != -1);
2348 
2349  log_copying_running = TRUE;
2350 
2351  while(log_copying) {
2352  os_thread_sleep(200000); /*0.2 sec*/
2353 
2354  counter++;
2355  if(counter >= SLEEPING_PERIOD * 5) {
2356  if(xtrabackup_copy_logfile(log_copy_scanned_lsn, FALSE))
2357  goto end;
2358  counter = 0;
2359  }
2360  }
2361 
2362  /* last copying */
2363  if(xtrabackup_copy_logfile(log_copy_scanned_lsn, TRUE))
2364  goto end;
2365 
2366  log_copying_succeed = TRUE;
2367 end:
2368  log_copying_running = FALSE;
2369  os_thread_exit(NULL);
2370 
2371  return(0);
2372 }
2373 
2374 /* io throttle watching (rough) */
2375 static
2376 #ifndef __WIN__
2377 void*
2378 #else
2379 ulint
2380 #endif
2381 io_watching_thread(
2382  void* )
2383 {
2384  /* currently, for --backup only */
2385  ut_a(xtrabackup_backup);
2386 
2387  while (log_copying) {
2388  os_thread_sleep(1000000); /*1 sec*/
2389 
2390  //for DEBUG
2391  //if (io_ticket == xtrabackup_throttle) {
2392  // fprintf(stderr, "There seem to be no IO...?\n");
2393  //}
2394 
2395  io_ticket = xtrabackup_throttle;
2396  os_event_set(wait_throttle);
2397  }
2398 
2399  /* stop io throttle */
2400  xtrabackup_throttle = 0;
2401  os_event_set(wait_throttle);
2402 
2403  os_thread_exit(NULL);
2404 
2405  return(0);
2406 }
2407 
2408 /************************************************************************
2409 I/o-handler thread function. */
2410 static
2411 
2412 #ifndef __WIN__
2413 void*
2414 #else
2415 ulint
2416 #endif
2417 io_handler_thread(
2418 /*==============*/
2419  void* arg)
2420 {
2421  ulint segment;
2422  ulint i;
2423 
2424  segment = *((ulint*)arg);
2425 
2426  for (i = 0;; i++) {
2427  fil_aio_wait(segment);
2428  }
2429 
2430  /* We count the number of threads in os_thread_exit(). A created
2431  thread should always use that to exit and not use return() to exit.
2432  The thread actually never comes here because it is exited in an
2433  os_event_wait(). */
2434 
2435  os_thread_exit(NULL);
2436 
2437 #ifndef __WIN__
2438  return(NULL); /* Not reached */
2439 #else
2440  return(0);
2441 #endif
2442 }
2443 
2444 /***************************************************************************
2445 Creates an output directory for a given tablespace, if it does not exist */
2446 static
2447 int
2448 xtrabackup_create_output_dir(
2449 /*==========================*/
2450  /* out: 0 if succes, -1 if failure */
2451  fil_space_t *space) /* in: tablespace */
2452 {
2453  char path[FN_REFLEN];
2454  char *ptr1, *ptr2;
2455 
2456  /* mkdir if not exist */
2457  ptr1 = strstr(space->name, SRV_PATH_SEPARATOR_STR);
2458  if (ptr1) {
2459  ptr2 = strstr(ptr1 + 1, SRV_PATH_SEPARATOR_STR);
2460  } else {
2461  ptr2 = NULL;
2462  }
2463 #ifdef XTRADB_BASED
2464  if(!trx_sys_sys_space(space->id) && ptr2)
2465 #else
2466  if(space->id && ptr2)
2467 #endif
2468  {
2469  /* single table space */
2470  *ptr2 = 0; /* temporary (it's my lazy..)*/
2471  snprintf(path, sizeof(path), "%s%s", xtrabackup_target_dir,
2472  ptr1);
2473  *ptr2 = SRV_PATH_SEPARATOR;
2474 
2475  if (mkdir(path, 0777) != 0 && errno != EEXIST) {
2476  fprintf(stderr,
2477  "xtrabackup: Error: cannot mkdir %d: %s\n",
2478  errno, path);
2479  return -1;
2480  }
2481  }
2482  return 0;
2483 }
2484 
2485 /**************************************************************************
2486 Datafiles copying thread.*/
2487 static
2488 os_thread_ret_t
2489 data_copy_thread_func(
2490 /*==================*/
2491  void *arg) /* thread context */
2492 {
2493  data_thread_ctxt_t *ctxt = (data_thread_ctxt_t *) arg;
2494  uint num = ctxt->num;
2495  fil_space_t* space;
2496  ibool space_changed;
2497  fil_node_t* node;
2498 
2499  while ((node = datafiles_iter_next(ctxt->it, &space_changed)) != NULL) {
2500  space = node->space;
2501 
2502  if (space_changed && xtrabackup_create_output_dir(space))
2503  exit(EXIT_FAILURE);
2504 
2505  /* copy the datafile */
2506  if(xtrabackup_copy_datafile(node, num)) {
2507  fprintf(stderr, "[%02u] xtrabackup: Error: "
2508  "failed to copy datafile.\n",
2509  num);
2510  exit(EXIT_FAILURE);
2511  }
2512  }
2513 
2514  os_mutex_enter(ctxt->count_mutex);
2515  (*ctxt->count)--;
2516  os_mutex_exit(ctxt->count_mutex);
2517 
2518  os_thread_exit(NULL);
2519  OS_THREAD_DUMMY_RETURN;
2520 }
2521 
2522 /* CAUTION(?): Don't rename file_per_table during backup */
2523 static void
2524 xtrabackup_backup_func(void)
2525 {
2526  struct stat stat_info;
2527  LSN64 latest_cp;
2528 
2529 #ifdef USE_POSIX_FADVISE
2530  fprintf(stderr, "xtrabackup: uses posix_fadvise().\n");
2531 #endif
2532 
2533  /* cd to datadir */
2534 
2535  if (chdir(mysql_real_data_home) != 0)
2536  {
2537  fprintf(stderr, "xtrabackup: cannot my_setwd %s\n", mysql_real_data_home);
2538  exit(EXIT_FAILURE);
2539  }
2540  fprintf(stderr, "xtrabackup: cd to %s\n", mysql_real_data_home);
2541 
2542  mysql_data_home= mysql_data_home_buff;
2543  mysql_data_home[0]=FN_CURLIB; // all paths are relative from here
2544  mysql_data_home[1]=0;
2545 
2546  /* set read only */
2547  srv_read_only = TRUE;
2548 
2549  /* initialize components */
2550  if(innodb_init_param())
2551  exit(EXIT_FAILURE);
2552 
2553  if (srv_file_flush_method_str == NULL) {
2554  /* These are the default options */
2555  srv_unix_file_flush_method = SRV_UNIX_FSYNC;
2556 
2557  srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
2558 #ifndef __WIN__
2559  } else if (0 == ut_strcmp(srv_file_flush_method_str, "fsync")) {
2560  srv_unix_file_flush_method = SRV_UNIX_FSYNC;
2561 
2562  } else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DSYNC")) {
2563  srv_unix_file_flush_method = SRV_UNIX_O_DSYNC;
2564 
2565  } else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DIRECT")) {
2566  srv_unix_file_flush_method = SRV_UNIX_O_DIRECT;
2567  fprintf(stderr,"xtrabackup: use O_DIRECT\n");
2568  } else if (0 == ut_strcmp(srv_file_flush_method_str, "littlesync")) {
2569  srv_unix_file_flush_method = SRV_UNIX_LITTLESYNC;
2570 
2571  } else if (0 == ut_strcmp(srv_file_flush_method_str, "nosync")) {
2572  srv_unix_file_flush_method = SRV_UNIX_NOSYNC;
2573 #else
2574  } else if (0 == ut_strcmp(srv_file_flush_method_str, "normal")) {
2575  srv_win_file_flush_method = SRV_WIN_IO_NORMAL;
2576  os_aio_use_native_aio = FALSE;
2577 
2578  } else if (0 == ut_strcmp(srv_file_flush_method_str, "unbuffered")) {
2579  srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
2580  os_aio_use_native_aio = FALSE;
2581 
2582  } else if (0 == ut_strcmp(srv_file_flush_method_str,
2583  "async_unbuffered")) {
2584  srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
2585 #endif
2586  } else {
2587  fprintf(stderr,
2588  "xtrabackup: Unrecognized value %s for innodb_flush_method\n",
2589  srv_file_flush_method_str);
2590  exit(EXIT_FAILURE);
2591  }
2592 
2593  if (srv_buf_pool_size >= 1000 * 1024 * 1024) {
2594  /* Here we still have srv_pool_size counted
2595  in kilobytes (in 4.0 this was in bytes)
2596  srv_boot() converts the value to
2597  pages; if buffer pool is less than 1000 MB,
2598  assume fewer threads. */
2599  srv_max_n_threads = 50000;
2600 
2601 
2602  } else if (srv_buf_pool_size >= 8 * 1024 * 1024) {
2603 
2604  srv_max_n_threads = 10000;
2605  } else {
2606  srv_max_n_threads = 1000; /* saves several MB of memory,
2607  especially in 64-bit
2608  computers */
2609  }
2610 
2611  {
2612  ulint nr;
2613  ulint i;
2614 
2615  nr = srv_n_data_files;
2616 
2617  for (i = 0; i < nr; i++) {
2618  srv_data_file_sizes[i] = srv_data_file_sizes[i]
2619  * ((1024 * 1024) / UNIV_PAGE_SIZE);
2620  }
2621 
2622  srv_last_file_size_max = srv_last_file_size_max
2623  * ((1024 * 1024) / UNIV_PAGE_SIZE);
2624 
2625  srv_log_file_size = srv_log_file_size / UNIV_PAGE_SIZE;
2626 
2627  srv_log_buffer_size = srv_log_buffer_size / UNIV_PAGE_SIZE;
2628 
2629  srv_lock_table_size = 5 * (srv_buf_pool_size / UNIV_PAGE_SIZE);
2630  }
2631 
2632  os_sync_mutex = NULL;
2633  srv_general_init();
2634 
2635  {
2636  ibool create_new_db;
2637 #ifdef XTRADB_BASED
2638  ibool create_new_doublewrite_file;
2639 #endif
2640  ibool log_file_created;
2641  ibool log_created = FALSE;
2642  ibool log_opened = FALSE;
2643  LSN64 min_flushed_lsn;
2644  LSN64 max_flushed_lsn;
2645  ulint sum_of_new_sizes;
2646  ulint err;
2647  ulint i;
2648 
2649 
2650 
2651 
2652 #define SRV_N_PENDING_IOS_PER_THREAD OS_AIO_N_PENDING_IOS_PER_THREAD
2653 #define SRV_MAX_N_PENDING_SYNC_IOS 100
2654 
2655  srv_n_file_io_threads = 2 + srv_n_read_io_threads + srv_n_write_io_threads;
2656 
2657  os_aio_init(8 * SRV_N_PENDING_IOS_PER_THREAD,
2658  srv_n_read_io_threads,
2659  srv_n_write_io_threads,
2660  SRV_MAX_N_PENDING_SYNC_IOS);
2661 
2662  fil_init(srv_file_per_table ? 50000 : 5000,
2663  srv_max_n_open_files);
2664 
2665  fsp_init();
2666  log_init();
2667 
2668  lock_sys_create(srv_lock_table_size);
2669 
2670  for (i = 0; i < srv_n_file_io_threads; i++) {
2671  thread_nr[i] = i;
2672 
2673  os_thread_create(io_handler_thread, thread_nr + i, thread_ids + i);
2674  }
2675 
2676  os_thread_sleep(200000); /*0.2 sec*/
2677 
2678  err = open_or_create_data_files(&create_new_db,
2679 #ifdef XTRADB_BASED
2680  &create_new_doublewrite_file,
2681 #endif
2682  &min_flushed_lsn, &max_flushed_lsn,
2683  &sum_of_new_sizes);
2684  if (err != DB_SUCCESS) {
2685  fprintf(stderr,
2686 "xtrabackup: Could not open or create data files.\n"
2687 "xtrabackup: If you tried to add new data files, and it failed here,\n"
2688 "xtrabackup: you should now edit innodb_data_file_path in my.cnf back\n"
2689 "xtrabackup: to what it was, and remove the new ibdata files InnoDB created\n"
2690 "xtrabackup: in this failed attempt. InnoDB only wrote those files full of\n"
2691 "xtrabackup: zeros, but did not yet use them in any way. But be careful: do not\n"
2692 "xtrabackup: remove old data files which contain your precious data!\n");
2693 
2694  //return((int) err);
2695  exit(EXIT_FAILURE);
2696  }
2697 
2698  /* create_new_db must not be TRUE.. */
2699  if (create_new_db) {
2700  fprintf(stderr, "xtrabackup: Something wrong with source files...\n");
2701  exit(EXIT_FAILURE);
2702  }
2703 
2704  for (i = 0; i < srv_n_log_files; i++) {
2705  err = open_or_create_log_file(create_new_db, &log_file_created,
2706  log_opened, 0, i);
2707  if (err != DB_SUCCESS) {
2708 
2709  //return((int) err);
2710  exit(EXIT_FAILURE);
2711  }
2712 
2713  if (log_file_created) {
2714  log_created = TRUE;
2715  } else {
2716  log_opened = TRUE;
2717  }
2718  if ((log_opened && create_new_db)
2719  || (log_opened && log_created)) {
2720  fprintf(stderr,
2721  "xtrabackup: Error: all log files must be created at the same time.\n"
2722  "xtrabackup: All log files must be created also in database creation.\n"
2723  "xtrabackup: If you want bigger or smaller log files, shut down the\n"
2724  "xtrabackup: database and make sure there were no errors in shutdown.\n"
2725  "xtrabackup: Then delete the existing log files. Edit the .cnf file\n"
2726  "xtrabackup: and start the database again.\n");
2727 
2728  //return(DB_ERROR);
2729  exit(EXIT_FAILURE);
2730  }
2731  }
2732 
2733  /* log_file_created must not be TRUE, if online */
2734  if (log_file_created) {
2735  fprintf(stderr, "xtrabackup: Something wrong with source files...\n");
2736  exit(EXIT_FAILURE);
2737  }
2738 
2740 
2741  }
2742 
2743  /* create extra LSN dir if it does not exist. */
2744  if (xtrabackup_extra_lsndir
2745  && (stat(xtrabackup_extra_lsndir,&stat_info) != 0)
2746  && (mkdir(xtrabackup_extra_lsndir,0777) != 0)){
2747  fprintf(stderr,"xtrabackup: Error: cannot mkdir %d: %s\n",errno,xtrabackup_extra_lsndir);
2748  exit(EXIT_FAILURE);
2749  }
2750 
2751 
2752  if (!xtrabackup_stream) {
2753 
2754  /* create target dir if not exist */
2755  if (stat(xtrabackup_target_dir,&stat_info) != 0
2756  && (mkdir(xtrabackup_target_dir,0777) != 0)){
2757  fprintf(stderr,"xtrabackup: Error: cannot mkdir %d: %s\n",errno,xtrabackup_target_dir);
2758  exit(EXIT_FAILURE);
2759  }
2760 
2761  } else {
2762  fprintf(stderr,"xtrabackup: Stream mode.\n");
2763  /* stdout can treat binary at Linux */
2764  //setmode(fileno(stdout), O_BINARY);
2765  }
2766 
2767  {
2768  fil_system_t* f_system = fil_system;
2769 
2770  /* definition from recv_recovery_from_checkpoint_start() */
2771  log_group_t* max_cp_group;
2772  ulint max_cp_field;
2773  byte* buf;
2774  boost::scoped_array<byte> log_hdr_buf_(
2775  new byte[LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE]);
2776  byte* log_hdr_buf;
2777  ulint err;
2778 
2779  ibool success;
2780 
2781  /* start back ground thread to copy newer log */
2782  os_thread_id_t log_copying_thread_id;
2783  datafiles_iter_t *it;
2784 
2785  log_hdr_buf = (byte*)ut_align(log_hdr_buf_.get(),
2787 
2788  /* log space */
2789  //space = UT_LIST_GET_NEXT(space_list, UT_LIST_GET_FIRST(f_system->space_list));
2790  //printf("space: name=%s, id=%d, purpose=%d, size=%d\n",
2791  // space->name, space->id, space->purpose, space->size);
2792 
2793  /* get current checkpoint_lsn */
2794  /* Look for the latest checkpoint from any of the log groups */
2795 
2796  err = recv_find_max_checkpoint(&max_cp_group, &max_cp_field);
2797 
2798  if (err != DB_SUCCESS) {
2799 
2800  exit(EXIT_FAILURE);
2801  }
2802 
2803  log_group_read_checkpoint_info(max_cp_group, max_cp_field);
2804  buf = log_sys->checkpoint_buf;
2805 
2806  checkpoint_lsn_start = MACH_READ_64(buf + LOG_CHECKPOINT_LSN);
2807  checkpoint_no_start = MACH_READ_64(buf + LOG_CHECKPOINT_NO);
2808 
2809 reread_log_header:
2810  fil_io(OS_FILE_READ | OS_FILE_LOG, TRUE, max_cp_group->space_id,
2811  0,
2812  0, 0, LOG_FILE_HDR_SIZE,
2813  log_hdr_buf, max_cp_group);
2814 
2815  /* check consistency of log file header to copy */
2816  err = recv_find_max_checkpoint(&max_cp_group, &max_cp_field);
2817 
2818  if (err != DB_SUCCESS) {
2819 
2820  exit(EXIT_FAILURE);
2821  }
2822 
2823  log_group_read_checkpoint_info(max_cp_group, max_cp_field);
2824  buf = log_sys->checkpoint_buf;
2825 
2826  if(ut_dulint_cmp(checkpoint_no_start,
2827  MACH_READ_64(buf + LOG_CHECKPOINT_NO)) != 0) {
2828  checkpoint_lsn_start = MACH_READ_64(buf + LOG_CHECKPOINT_LSN);
2829  checkpoint_no_start = MACH_READ_64(buf + LOG_CHECKPOINT_NO);
2830  goto reread_log_header;
2831  }
2832 
2833  if (!xtrabackup_stream) {
2834 
2835  /* open 'xtrabackup_logfile' */
2836  sprintf(dst_log_path, "%s%s", xtrabackup_target_dir, "/xtrabackup_logfile");
2837  srv_normalize_path_for_win(dst_log_path);
2838  /* os_file_create reads srv_unix_file_flush_method for OS_DATA_FILE*/
2839  dst_log = os_file_create(
2840  0 /* dummy of innodb_file_data_key */,
2841  dst_log_path, OS_FILE_CREATE,
2842  OS_FILE_NORMAL, OS_DATA_FILE, &success);
2843 
2844  if (!success) {
2845  /* The following call prints an error message */
2846  os_file_get_last_error(TRUE);
2847 
2848  fprintf(stderr,
2849 "xtrabackup: error: cannot open %s\n",
2850  dst_log_path);
2851  exit(EXIT_FAILURE);
2852  }
2853 
2854 #ifdef USE_POSIX_FADVISE
2855  posix_fadvise(dst_log, 0, 0, POSIX_FADV_DONTNEED);
2856 #endif
2857 
2858  }
2859 
2860  /* label it */
2861  strcpy((char*) log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
2862  "xtrabkup ");
2864  (char*) log_hdr_buf + (LOG_FILE_WAS_CREATED_BY_HOT_BACKUP
2865  + (sizeof "xtrabkup ") - 1));
2866 
2867  if (!xtrabackup_stream) {
2868  success = os_file_write(dst_log_path, dst_log, log_hdr_buf,
2869  0, 0, LOG_FILE_HDR_SIZE);
2870  } else {
2871  /* Stream */
2872  if ((write(fileno(stdout), log_hdr_buf, LOG_FILE_HDR_SIZE)
2873  - LOG_FILE_HDR_SIZE) == 0)
2874  {
2875  success = TRUE;
2876  } else {
2877  success = FALSE;
2878  }
2879  }
2880 
2881  log_copy_offset += LOG_FILE_HDR_SIZE;
2882  if (!success) {
2883  if (dst_log != -1)
2884  os_file_close(dst_log);
2885  exit(EXIT_FAILURE);
2886  }
2887 
2888  /* start flag */
2889  log_copying = TRUE;
2890 
2891  /* start io throttle */
2892  if(xtrabackup_throttle) {
2893  os_thread_id_t io_watching_thread_id;
2894 
2895  io_ticket = xtrabackup_throttle;
2896  wait_throttle = os_event_create(NULL);
2897 
2898  os_thread_create(io_watching_thread, NULL, &io_watching_thread_id);
2899  }
2900 
2901 
2902  /* copy log file by current position */
2903  if(xtrabackup_copy_logfile(checkpoint_lsn_start, FALSE))
2904  exit(EXIT_FAILURE);
2905 
2906 
2907  os_thread_create(log_copying_thread, NULL, &log_copying_thread_id);
2908 
2909 
2910 
2911  if (!xtrabackup_stream) { /* stream mode is transaction log only */
2912  uint i;
2913  uint count;
2914  os_mutex_t count_mutex;
2915  data_thread_ctxt_t *data_threads;
2916 
2917  ut_a(parallel > 0);
2918 
2919  if (parallel > 1)
2920  printf("xtrabackup: Starting %u threads for parallel "
2921  "data files transfer\n", parallel);
2922 
2923  it = datafiles_iter_new(f_system);
2924  if (it == NULL) {
2925  fprintf(stderr,
2926  "xtrabackup: Error: "
2927  "datafiles_iter_new() failed.\n");
2928  exit(EXIT_FAILURE);
2929  }
2930 
2931  /* Create data copying threads */
2932  ut_a(parallel > 0);
2933 
2934  data_threads = (data_thread_ctxt_t *)
2935  ut_malloc(sizeof(data_thread_ctxt_t) * parallel);
2936  count = parallel;
2937  count_mutex = OS_MUTEX_CREATE();
2938 
2939  for (i = 0; i < parallel; i++) {
2940  data_threads[i].it = it;
2941  data_threads[i].num = i+1;
2942  data_threads[i].count = &count;
2943  data_threads[i].count_mutex = count_mutex;
2944  os_thread_create(data_copy_thread_func,
2945  data_threads + i,
2946  &data_threads[i].id);
2947  }
2948 
2949  /* Wait for threads to exit */
2950  while (1) {
2951  os_thread_sleep(1000000);
2952  os_mutex_enter(count_mutex);
2953  if (count == 0) {
2954  os_mutex_exit(count_mutex);
2955  break;
2956  }
2957  os_mutex_exit(count_mutex);
2958  }
2959  /* NOTE: It may not needed at "--backup" for now */
2960  /* mutex_enter(&(f_system->mutex)); */
2961 
2962  os_mutex_free(count_mutex);
2963  datafiles_iter_free(it);
2964 
2965  } //if (!xtrabackup_stream)
2966 
2967  //mutex_exit(&(f_system->mutex));
2968  }
2969 
2970 
2971  /* suspend-at-end */
2972  if (xtrabackup_suspend_at_end) {
2973  os_file_t suspend_file = -1;
2974  char suspend_path[FN_REFLEN];
2975  ibool success, exists;
2976  os_file_type_t type;
2977 
2978  sprintf(suspend_path, "%s%s", xtrabackup_target_dir,
2979  "/xtrabackup_suspended");
2980 
2981  srv_normalize_path_for_win(suspend_path);
2982  /* os_file_create reads srv_unix_file_flush_method */
2983  suspend_file = os_file_create(
2984  0 /* dummy of innodb_file_data_key */,
2985  suspend_path, OS_FILE_OVERWRITE,
2986  OS_FILE_NORMAL, OS_DATA_FILE, &success);
2987 
2988  if (!success) {
2989  fprintf(stderr, "xtrabackup: Error: failed to create file 'xtrabackup_suspended'\n");
2990  }
2991 
2992  if (suspend_file != -1)
2993  os_file_close(suspend_file);
2994 
2995  exists = TRUE;
2996  while (exists) {
2997  os_thread_sleep(200000); /*0.2 sec*/
2998  success = os_file_status(suspend_path, &exists, &type);
2999  if (!success)
3000  break;
3001  }
3002  xtrabackup_suspend_at_end = FALSE; /* suspend is 1 time */
3003  }
3004 
3005  /* read the latest checkpoint lsn */
3006  latest_cp = ut_dulint_zero;
3007  {
3008  log_group_t* max_cp_group;
3009  ulint max_cp_field;
3010  ulint err;
3011 
3012  err = recv_find_max_checkpoint(&max_cp_group, &max_cp_field);
3013 
3014  if (err != DB_SUCCESS) {
3015  fprintf(stderr, "xtrabackup: Error: recv_find_max_checkpoint() failed.\n");
3016  goto skip_last_cp;
3017  }
3018 
3019  log_group_read_checkpoint_info(max_cp_group, max_cp_field);
3020 
3021  latest_cp = MACH_READ_64(log_sys->checkpoint_buf + LOG_CHECKPOINT_LSN);
3022 
3023  if (!xtrabackup_stream) {
3024  printf("xtrabackup: The latest check point (for incremental): '%"PRIu64"'\n",
3025  latest_cp);
3026  } else {
3027  fprintf(stderr, "xtrabackup: The latest check point (for incremental): '%"PRIu64"'\n",
3028  latest_cp);
3029  }
3030  }
3031 skip_last_cp:
3032  /* stop log_copying_thread */
3033  log_copying = FALSE;
3034  if (!xtrabackup_stream) {
3035  printf("xtrabackup: Stopping log copying thread");
3036  while (log_copying_running) {
3037  printf(".");
3038  os_thread_sleep(200000); /*0.2 sec*/
3039  }
3040  printf("\n");
3041  } else {
3042  while (log_copying_running)
3043  os_thread_sleep(200000); /*0.2 sec*/
3044  }
3045 
3046  /* output to metadata file */
3047  {
3048  char filename[FN_REFLEN];
3049 
3050  if(!xtrabackup_incremental) {
3051  strcpy(metadata_type, "full-backuped");
3052  metadata_from_lsn = ut_dulint_zero;
3053  } else {
3054  strcpy(metadata_type, "incremental");
3055  metadata_from_lsn = incremental_lsn;
3056  }
3057  metadata_to_lsn = latest_cp;
3058  metadata_last_lsn = log_copy_scanned_lsn;
3059 
3060  sprintf(filename, "%s/%s", xtrabackup_target_dir, XTRABACKUP_METADATA_FILENAME);
3061  if (xtrabackup_write_metadata(filename))
3062  fprintf(stderr, "xtrabackup: error: xtrabackup_write_metadata(xtrabackup_target_dir)\n");
3063 
3064  if(xtrabackup_extra_lsndir) {
3065  sprintf(filename, "%s/%s", xtrabackup_extra_lsndir, XTRABACKUP_METADATA_FILENAME);
3066  if (xtrabackup_write_metadata(filename))
3067  fprintf(stderr, "xtrabackup: error: xtrabackup_write_metadata(xtrabackup_extra_lsndir)\n");
3068  }
3069  }
3070 
3071  if (!log_copying_succeed) {
3072  fprintf(stderr, "xtrabackup: Error: log_copying_thread failed.\n");
3073  exit(EXIT_FAILURE);
3074  }
3075 
3076  if (!xtrabackup_stream)
3077  os_file_close(dst_log);
3078 
3079  if (wait_throttle)
3080  os_event_free(wait_throttle);
3081 
3082  if (!xtrabackup_stream) {
3083  printf("xtrabackup: Transaction log of lsn (%"PRIu64") to (%"PRIu64") was copied.\n",
3084  checkpoint_lsn_start, log_copy_scanned_lsn);
3085  } else {
3086  fprintf(stderr, "xtrabackup: Transaction log of lsn (%"PRIu64") to (%"PRIu64") was copied.\n",
3087  checkpoint_lsn_start, log_copy_scanned_lsn);
3088  if(xtrabackup_extra_lsndir) {
3089  char filename[FN_REFLEN];
3090  sprintf(filename, "%s/%s", xtrabackup_extra_lsndir, XTRABACKUP_METADATA_FILENAME);
3091  if (xtrabackup_write_metadata(filename))
3092  fprintf(stderr, "xtrabackup: error: xtrabackup_write_metadata(xtrabackup_extra_lsndir)\n");
3093  }
3094  }
3095 }
3096 
3097 /* ================= stats ================= */
3098 static bool
3099 xtrabackup_stats_level(
3100  dict_index_t* index,
3101  ulint level)
3102 {
3103  ulint space;
3104  page_t* page;
3105 
3106  rec_t* node_ptr;
3107 
3108  ulint right_page_no;
3109 
3110  page_cur_t cursor;
3111 
3112  mtr_t mtr;
3113  mem_heap_t* heap = mem_heap_create(256);
3114 
3115  ulint* offsets = NULL;
3116 
3117  uint64_t n_pages, n_pages_extern;
3118  uint64_t sum_data, sum_data_extern;
3119  uint64_t n_recs;
3120  ulint page_size;
3121 
3122  n_pages = sum_data = n_recs = 0;
3123  n_pages_extern = sum_data_extern = 0;
3124 
3125  buf_block_t* block;
3126  ulint zip_size;
3127 
3128  if (level == 0)
3129  fprintf(stdout, " leaf pages: ");
3130  else
3131  fprintf(stdout, " level %lu pages: ", level);
3132 
3133  mtr_start(&mtr);
3134 
3135  mtr_x_lock(&(index->lock), &mtr);
3136  block = btr_root_block_get(index, &mtr);
3137  page = buf_block_get_frame(block);
3138 
3139  space = page_get_space_id(page);
3140  zip_size = fil_space_get_zip_size(space);
3141 
3142  while (level != btr_page_get_level(page, &mtr)) {
3143 
3144  ut_a(space == buf_block_get_space(block));
3145  ut_a(space == page_get_space_id(page));
3146  ut_a(!page_is_leaf(page));
3147 
3148  page_cur_set_before_first(block, &cursor);
3149  page_cur_move_to_next(&cursor);
3150 
3151  node_ptr = page_cur_get_rec(&cursor);
3152  offsets = rec_get_offsets(node_ptr, index, offsets,
3153  ULINT_UNDEFINED, &heap);
3154 
3155  block = btr_node_ptr_get_child(node_ptr, index, offsets, &mtr);
3156  page = buf_block_get_frame(block);
3157  }
3158 
3159 loop:
3160  mem_heap_empty(heap);
3161  offsets = NULL;
3162  mtr_x_lock(&(index->lock), &mtr);
3163 
3164  right_page_no = btr_page_get_next(page, &mtr);
3165 
3166 
3167  /*=================================*/
3168  //fprintf(stdout, "%lu ", (ulint) buf_frame_get_page_no(page));
3169 
3170  n_pages++;
3171  sum_data += page_get_data_size(page);
3172  n_recs += page_get_n_recs(page);
3173 
3174 
3175  if (level == 0) {
3176  page_cur_t cur;
3177  ulint n_fields;
3178  ulint i;
3179  mem_heap_t* local_heap = NULL;
3180  ulint offsets_[REC_OFFS_NORMAL_SIZE];
3181  ulint* local_offsets = offsets_;
3182 
3183  *offsets_ = (sizeof offsets_) / sizeof *offsets_;
3184 
3185  page_cur_set_before_first(block, &cur);
3186 
3187  page_cur_move_to_next(&cur);
3188 
3189  for (;;) {
3190  if (page_cur_is_after_last(&cur)) {
3191  break;
3192  }
3193 
3194  local_offsets = rec_get_offsets(cur.rec, index, local_offsets,
3195  ULINT_UNDEFINED, &local_heap);
3196  n_fields = rec_offs_n_fields(local_offsets);
3197 
3198  for (i = 0; i < n_fields; i++) {
3199  if (rec_offs_nth_extern(local_offsets, i)) {
3200  page_t* local_page;
3201  ulint space_id;
3202  ulint page_no;
3203  ulint offset;
3204  byte* blob_header;
3205  ulint part_len;
3206  mtr_t local_mtr;
3207  ulint local_len;
3208  byte* data;
3209  buf_block_t* local_block;
3210 
3211  data = rec_get_nth_field(cur.rec, local_offsets, i, &local_len);
3212 
3213  ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
3214  local_len -= BTR_EXTERN_FIELD_REF_SIZE;
3215 
3216  space_id = mach_read_from_4(data + local_len + BTR_EXTERN_SPACE_ID);
3217  page_no = mach_read_from_4(data + local_len + BTR_EXTERN_PAGE_NO);
3218  offset = mach_read_from_4(data + local_len + BTR_EXTERN_OFFSET);
3219 
3220  if (offset != FIL_PAGE_DATA)
3221  fprintf(stderr, "\nWarning: several record may share same external page.\n");
3222 
3223  for (;;) {
3224  mtr_start(&local_mtr);
3225 
3226  local_block = btr_block_get(space_id, zip_size, page_no, RW_S_LATCH, &local_mtr);
3227  local_page = buf_block_get_frame(local_block);
3228 
3229  blob_header = local_page + offset;
3230 #define BTR_BLOB_HDR_PART_LEN 0
3231 #define BTR_BLOB_HDR_NEXT_PAGE_NO 4
3232  //part_len = btr_blob_get_part_len(blob_header);
3233  part_len = mach_read_from_4(blob_header + BTR_BLOB_HDR_PART_LEN);
3234 
3235  //page_no = btr_blob_get_next_page_no(blob_header);
3236  page_no = mach_read_from_4(blob_header + BTR_BLOB_HDR_NEXT_PAGE_NO);
3237 
3238  offset = FIL_PAGE_DATA;
3239 
3240 
3241 
3242 
3243  /*=================================*/
3244  //fprintf(stdout, "[%lu] ", (ulint) buf_frame_get_page_no(page));
3245 
3246  n_pages_extern++;
3247  sum_data_extern += part_len;
3248 
3249 
3250  mtr_commit(&local_mtr);
3251 
3252  if (page_no == FIL_NULL)
3253  break;
3254  }
3255  }
3256  }
3257 
3258  page_cur_move_to_next(&cur);
3259  }
3260  }
3261 
3262 
3263 
3264 
3265  mtr_commit(&mtr);
3266  if (right_page_no != FIL_NULL) {
3267  mtr_start(&mtr);
3268  block = btr_block_get(space, zip_size, right_page_no, RW_X_LATCH, &mtr);
3269  page = buf_block_get_frame(block);
3270  goto loop;
3271  }
3272  mem_heap_free(heap);
3273 
3274  if (zip_size) {
3275  page_size = zip_size;
3276  } else {
3277  page_size = UNIV_PAGE_SIZE;
3278  }
3279 
3280  if (level == 0)
3281  fprintf(stdout, "recs=%"PRIu64", ", n_recs);
3282 
3283  fprintf(stdout, "pages=%"PRIu64", data=%"PRIu64" bytes, data/pages=%"PRIu64"%%",
3284  n_pages, sum_data,
3285  ((sum_data * 100)/ page_size)/n_pages);
3286 
3287 
3288  if (level == 0 && n_pages_extern) {
3289  putc('\n', stdout);
3290  /* also scan blob pages*/
3291  fprintf(stdout, " external pages: ");
3292 
3293  fprintf(stdout, "pages=%"PRIu64", data=%"PRIu64" bytes, data/pages=%"PRIu64"%%",
3294  n_pages_extern, sum_data_extern,
3295  ((sum_data_extern * 100)/ page_size)/n_pages_extern);
3296  }
3297 
3298  putc('\n', stdout);
3299 
3300  if (level > 0) {
3301  xtrabackup_stats_level(index, level - 1);
3302  }
3303 
3304  return(TRUE);
3305 }
3306 
3307 static void
3308 xtrabackup_stats_func(void)
3309 {
3310  ulint n;
3311 
3312  /* cd to datadir */
3313 
3314  if (chdir(mysql_real_data_home) != 0)
3315  {
3316  fprintf(stderr, "xtrabackup: cannot my_setwd %s\n", mysql_real_data_home);
3317  exit(EXIT_FAILURE);
3318  }
3319  fprintf(stderr, "xtrabackup: cd to %s\n", mysql_real_data_home);
3320 
3321  mysql_data_home= mysql_data_home_buff;
3322  mysql_data_home[0]=FN_CURLIB; // all paths are relative from here
3323  mysql_data_home[1]=0;
3324 
3325  /* set read only */
3326  srv_read_only = TRUE;
3327  srv_fake_write = TRUE;
3328 
3329  /* initialize components */
3330  if(innodb_init_param())
3331  exit(EXIT_FAILURE);
3332 
3333  /* Check if the log files have been created, otherwise innodb_init()
3334  will crash when called with srv_read_only == TRUE */
3335  for (n = 0; n < srv_n_log_files; n++) {
3336  char logname[FN_REFLEN];
3337  ibool exists;
3338  os_file_type_t type;
3339 
3340  sprintf(logname, "ib_logfile%lu", (ulong) n);
3341  if (!os_file_status(logname, &exists, &type) || !exists ||
3342  type != OS_FILE_TYPE_FILE) {
3343  fprintf(stderr, "xtrabackup: Error: "
3344  "Cannot find log file %s.\n", logname);
3345  fprintf(stderr, "xtrabackup: Error: "
3346  "to use the statistics feature, you need a "
3347  "clean copy of the database including "
3348  "correctly sized log files, so you need to "
3349  "execute with --prepare twice to use this "
3350  "functionality on a backup.\n");
3351  exit(EXIT_FAILURE);
3352  }
3353  }
3354 
3355  fprintf(stderr, "xtrabackup: Starting 'read-only' InnoDB instance to gather index statistics.\n"
3356  "xtrabackup: Using %"PRIu64" bytes for buffer pool (set by --use-memory parameter)\n",
3357  xtrabackup_use_memory);
3358 
3359  if(innodb_init())
3360  exit(EXIT_FAILURE);
3361 
3362  fprintf(stdout, "\n\n<INDEX STATISTICS>\n");
3363 
3364  /* gather stats */
3365 
3366  {
3367  dict_table_t* sys_tables;
3368  dict_index_t* sys_index;
3369  dict_table_t* table;
3370  btr_pcur_t pcur;
3371  rec_t* rec;
3372  byte* field;
3373  ulint len;
3374  mtr_t mtr;
3375 
3376  /* Enlarge the fatal semaphore wait timeout during the InnoDB table
3377  monitor printout */
3378 
3379  mutex_enter(&kernel_mutex);
3380  srv_fatal_semaphore_wait_threshold += 72000; /* 20 hours */
3381  mutex_exit(&kernel_mutex);
3382 
3383  mutex_enter(&(dict_sys->mutex));
3384 
3385  mtr_start(&mtr);
3386 
3387  sys_tables = dict_table_get_low("SYS_TABLES");
3388  sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
3389 
3390  btr_pcur_open_at_index_side(TRUE, sys_index, BTR_SEARCH_LEAF, &pcur,
3391  TRUE, &mtr);
3392 loop:
3393  btr_pcur_move_to_next_user_rec(&pcur, &mtr);
3394 
3395  rec = btr_pcur_get_rec(&pcur);
3396 
3397  if (!btr_pcur_is_on_user_rec(&pcur))
3398  {
3399  /* end of index */
3400 
3401  btr_pcur_close(&pcur);
3402  mtr_commit(&mtr);
3403 
3404  mutex_exit(&(dict_sys->mutex));
3405 
3406  /* Restore the fatal semaphore wait timeout */
3407 
3408  mutex_enter(&kernel_mutex);
3409  srv_fatal_semaphore_wait_threshold -= 72000; /* 20 hours */
3410  mutex_exit(&kernel_mutex);
3411 
3412  goto end;
3413  }
3414 
3415  field = rec_get_nth_field_old(rec, 0, &len);
3416 
3417  if (!rec_get_deleted_flag(rec, 0))
3418  {
3419 
3420  /* We found one */
3421 
3422  char* table_name = mem_strdupl((char*) field, len);
3423 
3424  btr_pcur_store_position(&pcur, &mtr);
3425 
3426  mtr_commit(&mtr);
3427 
3428  table = dict_table_get_low(table_name);
3429  mem_free(table_name);
3430 
3431 
3432  if (xtrabackup_tables) {
3433  char *p;
3434  int regres= 0;
3435  int i;
3436 
3437  p = strstr(table->name, SRV_PATH_SEPARATOR_STR);
3438 
3439  if (p)
3440  *p = '.';
3441 
3442  for (i = 0; i < tables_regex_num; i++) {
3443  regres = regexec(&tables_regex[i], table->name, 1, tables_regmatch, 0);
3444  if (regres != REG_NOMATCH)
3445  break;
3446  }
3447 
3448  if (p)
3449  *p = SRV_PATH_SEPARATOR;
3450 
3451  if ( regres == REG_NOMATCH )
3452  goto skip;
3453  }
3454 
3455  if (xtrabackup_tables_file) {
3456  xtrabackup_tables_t* xtable;
3457 
3458  HASH_SEARCH(name_hash, tables_hash, ut_fold_string(table->name),
3460  xtable,
3461  ut_ad(xtable->name),
3462  !strcmp(xtable->name, table->name));
3463 
3464  if (!xtable)
3465  goto skip;
3466  }
3467 
3468 
3469  if (table == NULL) {
3470  fputs("InnoDB: Failed to load table ", stderr);
3471  ut_print_namel(stderr, NULL, TRUE, (char*) field, len);
3472  putc('\n', stderr);
3473  } else {
3474  dict_index_t* index;
3475 
3476  /* The table definition was corrupt if there
3477  is no index */
3478 
3479  if (dict_table_get_first_index(table)) {
3480 #ifdef XTRADB_BASED
3481  dict_update_statistics(table, TRUE, FALSE);
3482 #elif defined(INNODB_VERSION_SHORT)
3483  dict_update_statistics(table, TRUE);
3484 #else
3485  dict_update_statistics_low(table, TRUE);
3486 #endif
3487  }
3488 
3489  //dict_table_print_low(table);
3490 
3491  index = UT_LIST_GET_FIRST(table->indexes);
3492  while (index != NULL) {
3493 {
3494  IB_INT64 n_vals;
3495 
3496  if (index->n_user_defined_cols > 0) {
3497  n_vals = index->stat_n_diff_key_vals[
3498  index->n_user_defined_cols];
3499  } else {
3500  n_vals = index->stat_n_diff_key_vals[1];
3501  }
3502 
3503  fprintf(stdout,
3504  " table: %s, index: %s, space id: %lu, root page: %lu"
3505  ", zip size: %lu"
3506  "\n estimated statistics in dictionary:\n"
3507  " key vals: %lu, leaf pages: %lu, size pages: %lu\n"
3508  " real statistics:\n",
3509  table->name, index->name,
3510  (ulong) index->space,
3511  (ulong) index->page,
3512  (ulong) fil_space_get_zip_size(index->space),
3513  (ulong) n_vals,
3514  (ulong) index->stat_n_leaf_pages,
3515  (ulong) index->stat_index_size);
3516 
3517  {
3518  mtr_t local_mtr;
3519  page_t* root;
3520  ulint page_level;
3521 
3522  mtr_start(&local_mtr);
3523 
3524  mtr_x_lock(&(index->lock), &local_mtr);
3525  root = btr_root_get(index, &local_mtr);
3526 
3527  page_level = btr_page_get_level(root, &local_mtr);
3528 
3529  xtrabackup_stats_level(index, page_level);
3530 
3531  mtr_commit(&local_mtr);
3532  }
3533 
3534  putc('\n', stdout);
3535 }
3536  index = UT_LIST_GET_NEXT(indexes, index);
3537  }
3538  }
3539 
3540 skip:
3541  mtr_start(&mtr);
3542 
3543  btr_pcur_restore_position(BTR_SEARCH_LEAF, &pcur, &mtr);
3544  }
3545 
3546  goto loop;
3547  }
3548 
3549 end:
3550  putc('\n', stdout);
3551 
3552  /* shutdown InnoDB */
3553  if(innodb_end())
3554  exit(EXIT_FAILURE);
3555 }
3556 
3557 /* ================= prepare ================= */
3558 
3559 static bool
3560 xtrabackup_init_temp_log(void)
3561 {
3562  os_file_t src_file = -1;
3563  char src_path[FN_REFLEN];
3564  char dst_path[FN_REFLEN];
3565  ibool success;
3566 
3567  ulint field;
3568  byte* log_buf;
3569  byte* log_buf_ = NULL;
3570 
3571  IB_INT64 file_size;
3572 
3573  LSN64 max_no;
3574  LSN64 max_lsn= 0;
3575  LSN64 checkpoint_no;
3576 
3577  ulint fold;
3578 
3579  max_no = ut_dulint_zero;
3580 
3581  if(!xtrabackup_incremental_dir) {
3582  sprintf(dst_path, "%s%s", xtrabackup_target_dir, "/ib_logfile0");
3583  sprintf(src_path, "%s%s", xtrabackup_target_dir, "/xtrabackup_logfile");
3584  } else {
3585  sprintf(dst_path, "%s%s", xtrabackup_incremental_dir, "/ib_logfile0");
3586  sprintf(src_path, "%s%s", xtrabackup_incremental_dir, "/xtrabackup_logfile");
3587  }
3588 
3589  srv_normalize_path_for_win(dst_path);
3590  srv_normalize_path_for_win(src_path);
3591 retry:
3592  src_file = os_file_create_simple_no_error_handling(
3593  0 /* dummy of innodb_file_data_key */,
3594  src_path, OS_FILE_OPEN,
3595  OS_FILE_READ_WRITE /* OS_FILE_READ_ONLY */, &success);
3596  if (!success) {
3597  /* The following call prints an error message */
3598  os_file_get_last_error(TRUE);
3599 
3600  fprintf(stderr,
3601 "xtrabackup: Warning: cannot open %s. will try to find.\n",
3602  src_path);
3603 
3604  /* check if ib_logfile0 may be xtrabackup_logfile */
3605  src_file = os_file_create_simple_no_error_handling(
3606  0 /* dummy of innodb_file_data_key */,
3607  dst_path, OS_FILE_OPEN,
3608  OS_FILE_READ_WRITE /* OS_FILE_READ_ONLY */, &success);
3609  if (!success) {
3610  os_file_get_last_error(TRUE);
3611  fprintf(stderr,
3612 " xtrabackup: Fatal error: cannot find %s.\n",
3613  src_path);
3614 
3615  goto error;
3616  }
3617 
3618  log_buf_ = (unsigned char*) ut_malloc(LOG_FILE_HDR_SIZE * 2);
3619  log_buf = (unsigned char*) ut_align(log_buf_, LOG_FILE_HDR_SIZE);
3620 
3621  success = os_file_read(src_file, log_buf, 0, 0, LOG_FILE_HDR_SIZE);
3622  if (!success) {
3623  goto error;
3624  }
3625 
3626  if ( ut_memcmp(log_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
3627  (byte*)"xtrabkup", (sizeof "xtrabkup") - 1) == 0) {
3628  fprintf(stderr,
3629 " xtrabackup: 'ib_logfile0' seems to be 'xtrabackup_logfile'. will retry.\n");
3630 
3631  ut_free(log_buf_);
3632  log_buf_ = NULL;
3633 
3634  os_file_close(src_file);
3635  src_file = -1;
3636 
3637  /* rename and try again */
3638  success = os_file_rename(
3639  0 /* dummy of innodb_file_data_key */,
3640  dst_path, src_path);
3641  if (!success) {
3642  goto error;
3643  }
3644 
3645  goto retry;
3646  }
3647 
3648  fprintf(stderr,
3649 " xtrabackup: Fatal error: cannot find %s.\n",
3650  src_path);
3651 
3652  ut_free(log_buf_);
3653  log_buf_ = NULL;
3654 
3655  os_file_close(src_file);
3656  src_file = -1;
3657 
3658  goto error;
3659  }
3660 
3661 #ifdef USE_POSIX_FADVISE
3662  posix_fadvise(src_file, 0, 0, POSIX_FADV_SEQUENTIAL);
3663  posix_fadvise(src_file, 0, 0, POSIX_FADV_DONTNEED);
3664 #endif
3665 
3666  if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
3667  os_file_set_nocache(src_file, src_path, "OPEN");
3668  }
3669 
3670  file_size = os_file_get_size_as_iblonglong(src_file);
3671 
3672 
3673  /* TODO: We should skip the following modifies, if it is not the first time. */
3674  log_buf_ = (unsigned char*) ut_malloc(UNIV_PAGE_SIZE * 129);
3675  log_buf = (unsigned char*) ut_align(log_buf_, UNIV_PAGE_SIZE);
3676 
3677  /* read log file header */
3678  success = os_file_read(src_file, log_buf, 0, 0, LOG_FILE_HDR_SIZE);
3679  if (!success) {
3680  goto error;
3681  }
3682 
3683  if ( ut_memcmp(log_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
3684  (byte*)"xtrabkup", (sizeof "xtrabkup") - 1) != 0 ) {
3685  printf("xtrabackup: notice: xtrabackup_logfile was already used to '--prepare'.\n");
3686  goto skip_modify;
3687  } else {
3688  /* clear it later */
3689  //memset(log_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
3690  // ' ', 4);
3691  }
3692 
3693  /* read last checkpoint lsn */
3694  for (field = LOG_CHECKPOINT_1; field <= LOG_CHECKPOINT_2;
3695  field += LOG_CHECKPOINT_2 - LOG_CHECKPOINT_1) {
3696  if (!recv_check_cp_is_consistent(log_buf + field))
3697  goto not_consistent;
3698 
3699  checkpoint_no = MACH_READ_64(log_buf + field + LOG_CHECKPOINT_NO);
3700 
3701  if (ut_dulint_cmp(checkpoint_no, max_no) >= 0) {
3702  max_no = checkpoint_no;
3703  max_lsn = MACH_READ_64(log_buf + field + LOG_CHECKPOINT_LSN);
3704 /*
3705  mach_write_to_4(log_buf + field + LOG_CHECKPOINT_OFFSET,
3706  LOG_FILE_HDR_SIZE + ut_dulint_minus(max_lsn,
3707  ut_dulint_align_down(max_lsn,OS_FILE_LOG_BLOCK_SIZE)));
3708 
3709  ulint fold;
3710  fold = ut_fold_binary(log_buf + field, LOG_CHECKPOINT_CHECKSUM_1);
3711  mach_write_to_4(log_buf + field + LOG_CHECKPOINT_CHECKSUM_1, fold);
3712 
3713  fold = ut_fold_binary(log_buf + field + LOG_CHECKPOINT_LSN,
3714  LOG_CHECKPOINT_CHECKSUM_2 - LOG_CHECKPOINT_LSN);
3715  mach_write_to_4(log_buf + field + LOG_CHECKPOINT_CHECKSUM_2, fold);
3716 */
3717  }
3718 not_consistent:
3719  ;
3720  }
3721 
3722  if (ut_dulint_cmp(max_no, ut_dulint_zero) == 0) {
3723  fprintf(stderr, "xtrabackup: No valid checkpoint found.\n");
3724  goto error;
3725  }
3726 
3727 
3728  /* It seems to be needed to overwrite the both checkpoint area. */
3729  MACH_WRITE_64(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_LSN, max_lsn);
3730  mach_write_to_4(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_OFFSET,
3731  LOG_FILE_HDR_SIZE + ut_dulint_minus(max_lsn,
3732  ut_dulint_align_down(max_lsn,OS_FILE_LOG_BLOCK_SIZE)));
3733 #ifdef XTRADB_BASED
3734  MACH_WRITE_64(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_ARCHIVED_LSN,
3735  (ib_uint64_t)(LOG_FILE_HDR_SIZE + ut_dulint_minus(max_lsn,
3736  ut_dulint_align_down(max_lsn,OS_FILE_LOG_BLOCK_SIZE))));
3737 #endif
3738  fold = ut_fold_binary(log_buf + LOG_CHECKPOINT_1, LOG_CHECKPOINT_CHECKSUM_1);
3739  mach_write_to_4(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_CHECKSUM_1, fold);
3740 
3741  fold = ut_fold_binary(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_LSN,
3742  LOG_CHECKPOINT_CHECKSUM_2 - LOG_CHECKPOINT_LSN);
3743  mach_write_to_4(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_CHECKSUM_2, fold);
3744 
3745  MACH_WRITE_64(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_LSN, max_lsn);
3746  mach_write_to_4(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_OFFSET,
3747  LOG_FILE_HDR_SIZE + ut_dulint_minus(max_lsn,
3748  ut_dulint_align_down(max_lsn,OS_FILE_LOG_BLOCK_SIZE)));
3749 #ifdef XTRADB_BASED
3750  MACH_WRITE_64(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_ARCHIVED_LSN,
3751  (ib_uint64_t)(LOG_FILE_HDR_SIZE + ut_dulint_minus(max_lsn,
3752  ut_dulint_align_down(max_lsn,OS_FILE_LOG_BLOCK_SIZE))));
3753 #endif
3754  fold = ut_fold_binary(log_buf + LOG_CHECKPOINT_2, LOG_CHECKPOINT_CHECKSUM_1);
3755  mach_write_to_4(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_CHECKSUM_1, fold);
3756 
3757  fold = ut_fold_binary(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_LSN,
3758  LOG_CHECKPOINT_CHECKSUM_2 - LOG_CHECKPOINT_LSN);
3759  mach_write_to_4(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_CHECKSUM_2, fold);
3760 
3761 
3762  success = os_file_write(src_path, src_file, log_buf, 0, 0, LOG_FILE_HDR_SIZE);
3763  if (!success) {
3764  goto error;
3765  }
3766 
3767  /* expand file size (9/8) and align to UNIV_PAGE_SIZE */
3768 
3769  if (file_size % UNIV_PAGE_SIZE) {
3770  memset(log_buf, 0, UNIV_PAGE_SIZE);
3771  success = os_file_write(src_path, src_file, log_buf,
3772  (ulint)(file_size & 0xFFFFFFFFUL),
3773  (ulint)(file_size >> 32),
3774  UNIV_PAGE_SIZE - (file_size % UNIV_PAGE_SIZE));
3775  if (!success) {
3776  goto error;
3777  }
3778 
3779  file_size = os_file_get_size_as_iblonglong(src_file);
3780  }
3781 
3782  /* TODO: We should judge whether the file is already expanded or not... */
3783  {
3784  ulint expand;
3785 
3786  memset(log_buf, 0, UNIV_PAGE_SIZE * 128);
3787  expand = file_size / UNIV_PAGE_SIZE / 8;
3788 
3789  for (; expand > 128; expand -= 128) {
3790  success = os_file_write(src_path, src_file, log_buf,
3791  (ulint)(file_size & 0xFFFFFFFFUL),
3792  (ulint)(file_size >> 32),
3793  UNIV_PAGE_SIZE * 128);
3794  if (!success) {
3795  goto error;
3796  }
3797  file_size += UNIV_PAGE_SIZE * 128;
3798  }
3799 
3800  if (expand) {
3801  success = os_file_write(src_path, src_file, log_buf,
3802  (ulint)(file_size & 0xFFFFFFFFUL),
3803  (ulint)(file_size >> 32),
3804  expand * UNIV_PAGE_SIZE);
3805  if (!success) {
3806  goto error;
3807  }
3808  file_size += UNIV_PAGE_SIZE * expand;
3809  }
3810  }
3811 
3812  /* make larger than 2MB */
3813  if (file_size < 2*1024*1024L) {
3814  memset(log_buf, 0, UNIV_PAGE_SIZE);
3815  while (file_size < 2*1024*1024L) {
3816  success = os_file_write(src_path, src_file, log_buf,
3817  (ulint)(file_size & 0xFFFFFFFFUL),
3818  (ulint)(file_size >> 32),
3819  UNIV_PAGE_SIZE);
3820  if (!success) {
3821  goto error;
3822  }
3823  file_size += UNIV_PAGE_SIZE;
3824  }
3825  file_size = os_file_get_size_as_iblonglong(src_file);
3826  }
3827 
3828  printf("xtrabackup: xtrabackup_logfile detected: size=%"PRIu64", start_lsn=(%"PRIu64")\n",
3829  file_size, max_lsn);
3830 
3831  os_file_close(src_file);
3832  src_file = -1;
3833 
3834  /* Backup log parameters */
3835  innobase_log_group_home_dir_backup = innobase_log_group_home_dir;
3836  innobase_log_file_size_backup = innobase_log_file_size;
3837  innobase_log_files_in_group_backup = innobase_log_files_in_group;
3838 
3839  /* fake InnoDB */
3840  innobase_log_group_home_dir = NULL;
3841  innobase_log_file_size = file_size;
3842  innobase_log_files_in_group = 1;
3843 
3844  srv_thread_concurrency = 0;
3845 
3846  /* rename 'xtrabackup_logfile' to 'ib_logfile0' */
3847  success = os_file_rename(
3848  0 /* dummy of innodb_file_data_key */,
3849  src_path, dst_path);
3850  if (!success) {
3851  goto error;
3852  }
3853  xtrabackup_logfile_is_renamed = TRUE;
3854 
3855  ut_free(log_buf_);
3856 
3857  return(FALSE);
3858 
3859 skip_modify:
3860  os_file_close(src_file);
3861  src_file = -1;
3862  ut_free(log_buf_);
3863  return(FALSE);
3864 
3865 error:
3866  if (src_file != -1)
3867  os_file_close(src_file);
3868  if (log_buf_)
3869  ut_free(log_buf_);
3870  fprintf(stderr, "xtrabackup: Error: xtrabackup_init_temp_log() failed.\n");
3871  return(TRUE); /*ERROR*/
3872 }
3873 
3874 /***********************************************************************
3875 Generates path to the meta file path from a given path to an incremental .delta
3876 by replacing trailing ".delta" with ".meta", or returns error if 'delta_path'
3877 does not end with the ".delta" character sequence.
3878 @return TRUE on success, FALSE on error. */
3879 static
3880 ibool
3881 get_meta_path(
3882  const char *delta_path, /* in: path to a .delta file */
3883  char *meta_path) /* out: path to the corresponding .meta
3884  file */
3885 {
3886  size_t len = strlen(delta_path);
3887 
3888  if (len <= 6 || strcmp(delta_path + len - 6, ".delta")) {
3889  return FALSE;
3890  }
3891  memcpy(meta_path, delta_path, len - 6);
3892  strcpy(meta_path + len - 6, XB_DELTA_INFO_SUFFIX);
3893 
3894  return TRUE;
3895 }
3896 
3897 static void
3898 xtrabackup_apply_delta(
3899  const char* dirname, /* in: dir name of incremental */
3900  const char* dbname, /* in: database name (ibdata: NULL) */
3901  const char* filename, /* in: file name (not a path),
3902  including the .delta extension */
3903  bool )
3904 {
3905  os_file_t src_file = -1;
3906  os_file_t dst_file = -1;
3907  char src_path[FN_REFLEN];
3908  char dst_path[FN_REFLEN];
3909  char meta_path[FN_REFLEN];
3910  ibool success;
3911 
3912  ibool last_buffer = FALSE;
3913  ulint page_in_buffer;
3914  ulint incremental_buffers = 0;
3915 
3916  xb_delta_info_t info;
3917  ulint page_size;
3918  ulint page_size_shift;
3919 
3920  ut_a(xtrabackup_incremental);
3921 
3922  if (dbname) {
3923  snprintf(src_path, sizeof(src_path), "%s/%s/%s",
3924  dirname, dbname, filename);
3925  snprintf(dst_path, sizeof(dst_path), "%s/%s/%s",
3926  xtrabackup_real_target_dir, dbname, filename);
3927  } else {
3928  snprintf(src_path, sizeof(src_path), "%s/%s",
3929  dirname, filename);
3930  snprintf(dst_path, sizeof(dst_path), "%s/%s",
3931  xtrabackup_real_target_dir, filename);
3932  }
3933  dst_path[strlen(dst_path) - 6] = '\0';
3934 
3935  if (!get_meta_path(src_path, meta_path)) {
3936  goto error;
3937  }
3938 
3939  srv_normalize_path_for_win(dst_path);
3940  srv_normalize_path_for_win(src_path);
3941  srv_normalize_path_for_win(meta_path);
3942 
3943  if (!xb_read_delta_metadata(meta_path, &info)) {
3944  goto error;
3945  }
3946 
3947  page_size = info.page_size;
3948  page_size_shift = get_bit_shift(page_size);
3949  fprintf(stderr, "xtrabackup: page size for %s is %lu bytes\n",
3950  src_path, page_size);
3951  if (page_size_shift < 10 ||
3952  page_size_shift > UNIV_PAGE_SIZE_SHIFT_MAX) {
3953  fprintf(stderr,
3954  "xtrabackup: error: invalid value of page_size "
3955  "(%lu bytes) read from %s\n", page_size, meta_path);
3956  goto error;
3957  }
3958 
3959  src_file = os_file_create_simple_no_error_handling(
3960  0 /* dummy of innodb_file_data_key */,
3961  src_path, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success);
3962  if (!success) {
3963  os_file_get_last_error(TRUE);
3964  fprintf(stderr,
3965  "xtrabackup: error: cannot open %s\n",
3966  src_path);
3967  goto error;
3968  }
3969 
3970 #ifdef USE_POSIX_FADVISE
3971  posix_fadvise(src_file, 0, 0, POSIX_FADV_SEQUENTIAL);
3972  posix_fadvise(src_file, 0, 0, POSIX_FADV_DONTNEED);
3973 #endif
3974 
3975  if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
3976  os_file_set_nocache(src_file, src_path, "OPEN");
3977  }
3978 
3979  dst_file = os_file_create_simple_no_error_handling(
3980  0 /* dummy of innodb_file_data_key */,
3981  dst_path, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success);
3982  if (!success) {
3983  os_file_get_last_error(TRUE);
3984  fprintf(stderr,
3985  "xtrabackup: error: cannot open %s\n",
3986  dst_path);
3987  goto error;
3988  }
3989 
3990 #ifdef USE_POSIX_FADVISE
3991  posix_fadvise(dst_file, 0, 0, POSIX_FADV_DONTNEED);
3992 #endif
3993 
3994  if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
3995  os_file_set_nocache(dst_file, dst_path, "OPEN");
3996  }
3997 
3998  printf("Applying %s ...\n", src_path);
3999 
4000  while (!last_buffer) {
4001  ulint cluster_header;
4002 
4003  /* read to buffer */
4004  /* first block of block cluster */
4005  success = os_file_read(src_file, incremental_buffer,
4006  ((incremental_buffers * (page_size / 4))
4007  << page_size_shift) & 0xFFFFFFFFUL,
4008  (incremental_buffers * (page_size / 4))
4009  >> (32 - page_size_shift),
4010  page_size);
4011  if (!success) {
4012  goto error;
4013  }
4014 
4015  cluster_header = mach_read_from_4(incremental_buffer);
4016  switch(cluster_header) {
4017  case 0x78747261UL: /*"xtra"*/
4018  break;
4019  case 0x58545241UL: /*"XTRA"*/
4020  last_buffer = TRUE;
4021  break;
4022  default:
4023  fprintf(stderr,
4024  "xtrabackup: error: %s seems not .delta file.\n",
4025  src_path);
4026  goto error;
4027  }
4028 
4029  for (page_in_buffer = 1; page_in_buffer < page_size / 4;
4030  page_in_buffer++) {
4031  if (mach_read_from_4(incremental_buffer + page_in_buffer * 4)
4032  == 0xFFFFFFFFUL)
4033  break;
4034  }
4035 
4036  ut_a(last_buffer || page_in_buffer == page_size / 4);
4037 
4038  /* read whole of the cluster */
4039  success = os_file_read(src_file, incremental_buffer,
4040  ((incremental_buffers * (page_size / 4))
4041  << page_size_shift) & 0xFFFFFFFFUL,
4042  (incremental_buffers * (page_size / 4))
4043  >> (32 - page_size_shift),
4044  page_in_buffer * page_size);
4045  if (!success) {
4046  goto error;
4047  }
4048 
4049  for (page_in_buffer = 1; page_in_buffer < page_size / 4;
4050  page_in_buffer++) {
4051  ulint offset_on_page;
4052 
4053  offset_on_page = mach_read_from_4(incremental_buffer + page_in_buffer * 4);
4054 
4055  if (offset_on_page == 0xFFFFFFFFUL)
4056  break;
4057 
4058  /* apply blocks in the cluster */
4059 // if (ut_dulint_cmp(incremental_lsn,
4060 // MACH_READ_64(incremental_buffer
4061 // + page_in_buffer * page_size
4062 // + FIL_PAGE_LSN)) >= 0)
4063 // continue;
4064 
4065  success = os_file_write(dst_path, dst_file,
4066  incremental_buffer +
4067  page_in_buffer * page_size,
4068  (offset_on_page << page_size_shift) &
4069  0xFFFFFFFFUL,
4070  offset_on_page >> (32 - page_size_shift),
4071  page_size);
4072  if (!success) {
4073  goto error;
4074  }
4075  }
4076 
4077  incremental_buffers++;
4078  }
4079 
4080  if (src_file != -1)
4081  os_file_close(src_file);
4082  if (dst_file != -1)
4083  os_file_close(dst_file);
4084  return;
4085 
4086 error:
4087  if (src_file != -1)
4088  os_file_close(src_file);
4089  if (dst_file != -1)
4090  os_file_close(dst_file);
4091  fprintf(stderr, "xtrabackup: Error: xtrabackup_apply_delta() failed.\n");
4092  return;
4093 }
4094 
4095 static void
4096 xtrabackup_apply_deltas(bool check_newer)
4097 {
4098  int ret;
4099  char dbpath[FN_REFLEN];
4100  os_file_dir_t dir;
4101  os_file_dir_t dbdir;
4102  os_file_stat_t dbinfo;
4103  os_file_stat_t fileinfo;
4104  ulint err = DB_SUCCESS;
4105  static char current_dir[2];
4106 
4107  current_dir[0] = FN_CURLIB;
4108  current_dir[1] = 0;
4109  srv_data_home = current_dir;
4110 
4111  /* datafile */
4112  dbdir = os_file_opendir(xtrabackup_incremental_dir, FALSE);
4113 
4114  if (dbdir != NULL) {
4115  ret = fil_file_readdir_next_file(&err, xtrabackup_incremental_dir, dbdir,
4116  &fileinfo);
4117  while (ret == 0) {
4118  if (fileinfo.type == OS_FILE_TYPE_DIR) {
4119  goto next_file_item_1;
4120  }
4121 
4122  if (strlen(fileinfo.name) > 6
4123  && 0 == strcmp(fileinfo.name +
4124  strlen(fileinfo.name) - 6,
4125  ".delta")) {
4126  xtrabackup_apply_delta(
4127  xtrabackup_incremental_dir, NULL,
4128  fileinfo.name, check_newer);
4129  }
4130 next_file_item_1:
4131  ret = fil_file_readdir_next_file(&err,
4132  xtrabackup_incremental_dir, dbdir,
4133  &fileinfo);
4134  }
4135 
4136  os_file_closedir(dbdir);
4137  } else {
4138  fprintf(stderr, "xtrabackup: Cannot open dir %s\n", xtrabackup_incremental_dir);
4139  }
4140 
4141  /* single table tablespaces */
4142  dir = os_file_opendir(xtrabackup_incremental_dir, FALSE);
4143 
4144  if (dir == NULL) {
4145  fprintf(stderr, "xtrabackup: Cannot open dir %s\n", xtrabackup_incremental_dir);
4146  }
4147 
4148  ret = fil_file_readdir_next_file(&err, xtrabackup_incremental_dir, dir,
4149  &dbinfo);
4150  while (ret == 0) {
4151  if (dbinfo.type == OS_FILE_TYPE_FILE
4152  || dbinfo.type == OS_FILE_TYPE_UNKNOWN) {
4153 
4154  goto next_datadir_item;
4155  }
4156 
4157  sprintf(dbpath, "%s/%s", xtrabackup_incremental_dir,
4158  dbinfo.name);
4160 
4161  dbdir = os_file_opendir(dbpath, FALSE);
4162 
4163  if (dbdir != NULL) {
4164 
4165  ret = fil_file_readdir_next_file(&err, dbpath, dbdir,
4166  &fileinfo);
4167  while (ret == 0) {
4168 
4169  if (fileinfo.type == OS_FILE_TYPE_DIR) {
4170 
4171  goto next_file_item_2;
4172  }
4173 
4174  if (strlen(fileinfo.name) > 6
4175  && 0 == strcmp(fileinfo.name +
4176  strlen(fileinfo.name) - 6,
4177  ".delta")) {
4178  /* The name ends in .delta; try opening
4179  the file */
4180  xtrabackup_apply_delta(
4181  xtrabackup_incremental_dir, dbinfo.name,
4182  fileinfo.name, check_newer);
4183  }
4184 next_file_item_2:
4185  ret = fil_file_readdir_next_file(&err,
4186  dbpath, dbdir,
4187  &fileinfo);
4188  }
4189 
4190  os_file_closedir(dbdir);
4191  }
4192 next_datadir_item:
4193  ret = fil_file_readdir_next_file(&err,
4194  xtrabackup_incremental_dir,
4195  dir, &dbinfo);
4196  }
4197 
4198  os_file_closedir(dir);
4199 
4200 }
4201 
4202 static bool
4203 xtrabackup_close_temp_log(bool clear_flag)
4204 {
4205  os_file_t src_file = -1;
4206  char src_path[FN_REFLEN];
4207  char dst_path[FN_REFLEN];
4208  ibool success;
4209 
4210  byte* log_buf;
4211  byte* log_buf_ = NULL;
4212 
4213 
4214  if (!xtrabackup_logfile_is_renamed)
4215  return(FALSE);
4216 
4217  /* Restore log parameters */
4218  innobase_log_group_home_dir = innobase_log_group_home_dir_backup;
4219  innobase_log_file_size = innobase_log_file_size_backup;
4220  innobase_log_files_in_group = innobase_log_files_in_group_backup;
4221 
4222  /* rename 'ib_logfile0' to 'xtrabackup_logfile' */
4223  if(!xtrabackup_incremental_dir) {
4224  sprintf(dst_path, "%s%s", xtrabackup_target_dir, "/ib_logfile0");
4225  sprintf(src_path, "%s%s", xtrabackup_target_dir, "/xtrabackup_logfile");
4226  } else {
4227  sprintf(dst_path, "%s%s", xtrabackup_incremental_dir, "/ib_logfile0");
4228  sprintf(src_path, "%s%s", xtrabackup_incremental_dir, "/xtrabackup_logfile");
4229  }
4230 
4231  srv_normalize_path_for_win(dst_path);
4232  srv_normalize_path_for_win(src_path);
4233 
4234  success = os_file_rename(
4235  0 /* dummy of innodb_file_data_key */,
4236  dst_path, src_path);
4237  if (!success) {
4238  goto error;
4239  }
4240  xtrabackup_logfile_is_renamed = FALSE;
4241 
4242  if (!clear_flag)
4243  return(FALSE);
4244 
4245  /* clear LOG_FILE_WAS_CREATED_BY_HOT_BACKUP field */
4246  src_file = os_file_create_simple_no_error_handling(
4247  0 /* dummy of innodb_file_data_key */,
4248  src_path, OS_FILE_OPEN,
4249  OS_FILE_READ_WRITE, &success);
4250  if (!success) {
4251  goto error;
4252  }
4253 
4254 #ifdef USE_POSIX_FADVISE
4255  posix_fadvise(src_file, 0, 0, POSIX_FADV_DONTNEED);
4256 #endif
4257 
4258  if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
4259  os_file_set_nocache(src_file, src_path, "OPEN");
4260  }
4261 
4262  log_buf_ = (unsigned char*) ut_malloc(LOG_FILE_HDR_SIZE * 2);
4263  log_buf = (unsigned char*) ut_align(log_buf_, LOG_FILE_HDR_SIZE);
4264 
4265  success = os_file_read(src_file, log_buf, 0, 0, LOG_FILE_HDR_SIZE);
4266  if (!success) {
4267  goto error;
4268  }
4269 
4270  memset(log_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, ' ', 4);
4271 
4272  success = os_file_write(src_path, src_file, log_buf, 0, 0, LOG_FILE_HDR_SIZE);
4273  if (!success) {
4274  goto error;
4275  }
4276 
4277  os_file_close(src_file);
4278  src_file = -1;
4279 
4280  return(FALSE);
4281 error:
4282  if (src_file != -1)
4283  os_file_close(src_file);
4284  if (log_buf_)
4285  ut_free(log_buf_);
4286  fprintf(stderr, "xtrabackup: Error: xtrabackup_close_temp_log() failed.\n");
4287  return(TRUE); /*ERROR*/
4288 }
4289 
4290 static void
4291 xtrabackup_prepare_func(void)
4292 {
4293  /* cd to target-dir */
4294 
4295  if (chdir(xtrabackup_real_target_dir) != 0)
4296  {
4297  fprintf(stderr, "xtrabackup: cannot my_setwd %s\n", xtrabackup_real_target_dir);
4298  exit(EXIT_FAILURE);
4299  }
4300  fprintf(stderr, "xtrabackup: cd to %s\n", xtrabackup_real_target_dir);
4301 
4302  xtrabackup_target_dir= mysql_data_home_buff;
4303  mysql_data_home_buff[0]=FN_CURLIB; // all paths are relative from here
4304  mysql_data_home_buff[1]=0;
4305 
4306  /* read metadata of target */
4307  {
4308  char filename[FN_REFLEN];
4309 
4310  sprintf(filename, "%s/%s", xtrabackup_target_dir, XTRABACKUP_METADATA_FILENAME);
4311 
4312  if (xtrabackup_read_metadata(filename))
4313  fprintf(stderr, "xtrabackup: error: xtrabackup_read_metadata()\n");
4314 
4315  if (!strcmp(metadata_type, "full-backuped")) {
4316  fprintf(stderr, "xtrabackup: This target seems to be not prepared yet.\n");
4317  } else if (!strcmp(metadata_type, "full-prepared")) {
4318  fprintf(stderr, "xtrabackup: This target seems to be already prepared.\n");
4319  goto skip_check;
4320  } else {
4321  fprintf(stderr, "xtrabackup: This target seems not to have correct metadata...\n");
4322  }
4323 
4324  if (xtrabackup_incremental) {
4325  fprintf(stderr,
4326  "xtrabackup: error: applying incremental backup needs target prepared.\n");
4327  exit(EXIT_FAILURE);
4328  }
4329 skip_check:
4330  if (xtrabackup_incremental
4331  && ut_dulint_cmp(metadata_to_lsn, incremental_lsn) != 0) {
4332  fprintf(stderr,
4333  "xtrabackup: error: This incremental backup seems not to be proper for the target.\n"
4334  "xtrabackup: Check 'to_lsn' of the target and 'from_lsn' of the incremental.\n");
4335  exit(EXIT_FAILURE);
4336  }
4337  }
4338 
4339  /* Create logfiles for recovery from 'xtrabackup_logfile', before start InnoDB */
4340  srv_max_n_threads = 1000;
4341  os_sync_mutex = NULL;
4342  ut_mem_init();
4343 #ifdef XTRADB_BASED
4344  /* temporally dummy value to avoid crash */
4345  srv_page_size_shift = 14;
4346  srv_page_size = (1 << srv_page_size_shift);
4347 #endif
4348  os_sync_init();
4349  sync_init();
4351  if(xtrabackup_init_temp_log())
4352  goto error;
4353 
4354  if(xtrabackup_incremental)
4355  xtrabackup_apply_deltas(TRUE);
4356 
4357  sync_close();
4358  sync_initialized = FALSE;
4359  os_sync_free();
4360  os_sync_mutex = NULL;
4361  ut_free_all_mem();
4362 
4363  /* check the accessibility of target-dir */
4364  /* ############# TODO ##################### */
4365 
4366  if(innodb_init_param())
4367  goto error;
4368 
4369  srv_apply_log_only = (ibool) xtrabackup_apply_log_only;
4370 
4371  /* increase IO threads */
4372  if(srv_n_file_io_threads < 10) {
4373  srv_n_file_io_threads = 10;
4374  }
4375 
4376  fprintf(stderr, "xtrabackup: Starting InnoDB instance for recovery.\n"
4377  "xtrabackup: Using %"PRIu64" bytes for buffer pool (set by --use-memory parameter)\n",
4378  xtrabackup_use_memory);
4379 
4380  if(innodb_init())
4381  goto error;
4382 
4383  //printf("Hello InnoDB world!\n");
4384 
4385  /* TEST: innodb status*/
4386 /*
4387  ulint trx_list_start = ULINT_UNDEFINED;
4388  ulint trx_list_end = ULINT_UNDEFINED;
4389  srv_printf_innodb_monitor(stdout, &trx_list_start, &trx_list_end);
4390 */
4391  /* TEST: list of datafiles and transaction log files and LSN*/
4392 /*
4393  {
4394  fil_system_t* f_system = fil_system;
4395  fil_space_t* space;
4396  fil_node_t* node;
4397 
4398  mutex_enter(&(f_system->mutex));
4399 
4400  space = UT_LIST_GET_FIRST(f_system->space_list);
4401 
4402  while (space != NULL) {
4403  printf("space: name=%s, id=%d, purpose=%d, size=%d\n",
4404  space->name, space->id, space->purpose, space->size);
4405 
4406  node = UT_LIST_GET_FIRST(space->chain);
4407 
4408  while (node != NULL) {
4409  printf("node: name=%s, open=%d, size=%d\n",
4410  node->name, node->open, node->size);
4411 
4412  node = UT_LIST_GET_NEXT(chain, node);
4413  }
4414  space = UT_LIST_GET_NEXT(space_list, space);
4415  }
4416 
4417  mutex_exit(&(f_system->mutex));
4418  }
4419 */
4420  /* align space sizes along with fsp header */
4421  {
4422  fil_system_t* f_system = fil_system;
4423  fil_space_t* space;
4424 
4425  mutex_enter(&(f_system->mutex));
4426  space = UT_LIST_GET_FIRST(f_system->space_list);
4427 
4428  while (space != NULL) {
4429  byte* header;
4430  ulint size;
4431  ulint actual_size;
4432  mtr_t mtr;
4433  buf_block_t* block;
4434  ulint flags;
4435 
4436  if (space->purpose == FIL_TABLESPACE) {
4437  mutex_exit(&(f_system->mutex));
4438 
4439  mtr_start(&mtr);
4440 
4441  mtr_s_lock(fil_space_get_latch(space->id, &flags), &mtr);
4442 
4443  block = buf_page_get(space->id,
4445  0, RW_S_LATCH, &mtr);
4446  header = FIL_PAGE_DATA /*FSP_HEADER_OFFSET*/
4447  + buf_block_get_frame(block);
4448 
4449  size = mtr_read_ulint(header + 8 /* FSP_SIZE */, MLOG_4BYTES, &mtr);
4450 
4451  mtr_commit(&mtr);
4452 
4453  //printf("%d, %d\n", space->id, size);
4454 
4455  fil_extend_space_to_desired_size(&actual_size, space->id, size);
4456 
4457  mutex_enter(&(f_system->mutex));
4458  }
4459 
4460  space = UT_LIST_GET_NEXT(space_list, space);
4461  }
4462 
4463  mutex_exit(&(f_system->mutex));
4464  }
4465 
4466 
4467 
4468  if (xtrabackup_export) {
4469  printf("xtrabackup: export option is specified.\n");
4470  if (innobase_file_per_table) {
4471  fil_system_t* f_system = fil_system;
4472  fil_space_t* space;
4473  fil_node_t* node;
4474  os_file_t info_file = -1;
4475  char info_file_path[FN_REFLEN];
4476  ibool success;
4477  char table_name[FN_REFLEN];
4478 
4479  byte* page;
4480  byte* buf = NULL;
4481 
4482  buf = (byte*) ut_malloc(UNIV_PAGE_SIZE * 2);
4483  page = (byte*) ut_align(buf, UNIV_PAGE_SIZE);
4484 
4485  /* flush insert buffer at shutdwon */
4486  innobase_fast_shutdown = 0;
4487 
4488  mutex_enter(&(f_system->mutex));
4489 
4490  space = UT_LIST_GET_FIRST(f_system->space_list);
4491  while (space != NULL) {
4492  /* treat file_per_table only */
4493  if (space->purpose != FIL_TABLESPACE
4494 #ifdef XTRADB_BASED
4495  || trx_sys_sys_space(space->id)
4496 #else
4497  || space->id == 0
4498 #endif
4499  )
4500  {
4501  space = UT_LIST_GET_NEXT(space_list, space);
4502  continue;
4503  }
4504 
4505  node = UT_LIST_GET_FIRST(space->chain);
4506  while (node != NULL) {
4507  int len;
4508  char *next, *prev, *p;
4509  dict_table_t* table;
4510  dict_index_t* index;
4511  ulint n_index;
4512 
4513  /* node exist == file exist, here */
4514  strncpy(info_file_path, node->name, FN_REFLEN);
4515  len = strlen(info_file_path);
4516  info_file_path[len - 3] = 'e';
4517  info_file_path[len - 2] = 'x';
4518  info_file_path[len - 1] = 'p';
4519 
4520  p = info_file_path;
4521  prev = NULL;
4522  while ((next = strstr(p, SRV_PATH_SEPARATOR_STR)) != NULL)
4523  {
4524  prev = p;
4525  p = next + 1;
4526  }
4527  info_file_path[len - 4] = 0;
4528  strncpy(table_name, prev, FN_REFLEN);
4529 
4530  info_file_path[len - 4] = '.';
4531 
4532  mutex_exit(&(f_system->mutex));
4533  mutex_enter(&(dict_sys->mutex));
4534 
4535  table = dict_table_get_low(table_name);
4536  if (!table) {
4537  fprintf(stderr,
4538 "xtrabackup: error: cannot find dictionary record of table %s\n", table_name);
4539  goto next_node;
4540  }
4541  index = dict_table_get_first_index(table);
4542  n_index = UT_LIST_GET_LEN(table->indexes);
4543  if (n_index > 31) {
4544  fprintf(stderr,
4545 "xtrabackup: error: sorry, cannot export over 31 indexes for now.\n");
4546  goto next_node;
4547  }
4548 
4549  /* init exp file */
4550  bzero(page, UNIV_PAGE_SIZE);
4551  mach_write_to_4(page , 0x78706f72UL);
4552  mach_write_to_4(page + 4, 0x74696e66UL);/*"xportinf"*/
4553  mach_write_to_4(page + 8, n_index);
4554  strncpy((char*)page + 12, table_name, 500);
4555 
4556  printf(
4557 "xtrabackup: export metadata of table '%s' to file `%s` (%lu indexes)\n",
4558  table_name, info_file_path, n_index);
4559 
4560  n_index = 1;
4561  while (index) {
4562  mach_write_to_8(page + n_index * 512, index->id);
4563  mach_write_to_4(page + n_index * 512 + 8,
4564  index->page);
4565 
4566  strncpy((char*)page + n_index * 512 + 12, index->name, 500);
4567 
4568  printf(
4569 "xtrabackup: name=%s, id.low=%lu, page=%lu\n",
4570  index->name,
4571  (ulint)(index->id & 0xFFFFFFFFUL),
4572 
4573  (ulint) index->page);
4574 
4575  index = dict_table_get_next_index(index);
4576  n_index++;
4577  }
4578 
4579  srv_normalize_path_for_win(info_file_path);
4580  info_file = os_file_create(
4581  0 /* dummy of innodb_file_data_key */,
4582  info_file_path, OS_FILE_OVERWRITE,
4583  OS_FILE_NORMAL, OS_DATA_FILE, &success);
4584  if (!success) {
4585  os_file_get_last_error(TRUE);
4586  goto next_node;
4587  }
4588  success = os_file_write(info_file_path, info_file, page,
4589  0, 0, UNIV_PAGE_SIZE);
4590  if (!success) {
4591  os_file_get_last_error(TRUE);
4592  goto next_node;
4593  }
4594  success = os_file_flush(info_file);
4595  if (!success) {
4596  os_file_get_last_error(TRUE);
4597  goto next_node;
4598  }
4599 next_node:
4600  if (info_file != -1) {
4601  os_file_close(info_file);
4602  info_file = -1;
4603  }
4604  mutex_exit(&(dict_sys->mutex));
4605  mutex_enter(&(f_system->mutex));
4606 
4607  node = UT_LIST_GET_NEXT(chain, node);
4608  }
4609 
4610  space = UT_LIST_GET_NEXT(space_list, space);
4611  }
4612  mutex_exit(&(f_system->mutex));
4613 
4614  ut_free(buf);
4615  } else {
4616  printf("xtrabackup: export option is for file_per_table only, disabled.\n");
4617  }
4618  }
4619 
4620  /* print binlog position (again?) */
4621  printf("\n[notice (again)]\n"
4622  " If you use binary log and don't use any hack of group commit,\n"
4623  " the binary log position seems to be:\n");
4624 // FIXME: trx_sys_print_mysql_binlog_offset();
4625  printf("\n");
4626 
4627  /* output to xtrabackup_binlog_pos_innodb */
4628  if (false) {
4629 //FIXME if (*trx_sys_mysql_bin_log_name != '\0') {
4630  FILE *fp;
4631 
4632  fp = fopen("xtrabackup_binlog_pos_innodb", "w");
4633  if (fp) {
4634  fprintf(fp, "%s\t%llu\n",
4635  "none", 0ULL);
4636  /* FIXME
4637  trx_sys_mysql_bin_log_name,
4638  trx_sys_mysql_bin_log_pos);*/
4639  fclose(fp);
4640  } else {
4641  printf("xtrabackup: failed to open 'xtrabackup_binlog_pos_innodb'\n");
4642  }
4643  }
4644 
4645  /* Check whether the log is applied enough or not. */
4646  if ((xtrabackup_incremental
4647  && ut_dulint_cmp(srv_start_lsn, incremental_last_lsn) < 0)
4648  ||(!xtrabackup_incremental
4649  && ut_dulint_cmp(srv_start_lsn, metadata_last_lsn) < 0)) {
4650  printf( "xtrabackup: ########################################################\n"
4651  "xtrabackup: # !!WARNING!! #\n"
4652  "xtrabackup: # The transaction log file should be wrong or corrupt. #\n"
4653  "xtrabackup: # The log was not applied to the intended LSN! #\n"
4654  "xtrabackup: ########################################################\n");
4655  if (xtrabackup_incremental) {
4656  printf("xtrabackup: The intended lsn is %"PRIu64"\n",
4657  incremental_last_lsn);
4658  } else {
4659  printf("xtrabackup: The intended lsn is %"PRIu64"\n",
4660  metadata_last_lsn);
4661  }
4662  }
4663 
4664  if(innodb_end())
4665  goto error;
4666 
4667  sync_initialized = FALSE;
4668  os_sync_mutex = NULL;
4669 
4670  /* re-init necessary components */
4671  ut_mem_init();
4672 
4673  os_sync_init();
4674  sync_init();
4676 
4677  if(xtrabackup_close_temp_log(TRUE))
4678  exit(EXIT_FAILURE);
4679 
4680  /* output to metadata file */
4681  {
4682  char filename[FN_REFLEN];
4683 
4684  strcpy(metadata_type, "full-prepared");
4685 
4686  if(xtrabackup_incremental
4687  && ut_dulint_cmp(metadata_to_lsn, incremental_to_lsn) < 0)
4688  {
4689  metadata_to_lsn = incremental_to_lsn;
4690  metadata_last_lsn = incremental_last_lsn;
4691  }
4692 
4693  sprintf(filename, "%s/%s", xtrabackup_target_dir, XTRABACKUP_METADATA_FILENAME);
4694  if (xtrabackup_write_metadata(filename))
4695  fprintf(stderr, "xtrabackup: error: xtrabackup_write_metadata(xtrabackup_target_dir)\n");
4696 
4697  if(xtrabackup_extra_lsndir) {
4698  sprintf(filename, "%s/%s", xtrabackup_extra_lsndir, XTRABACKUP_METADATA_FILENAME);
4699  if (xtrabackup_write_metadata(filename))
4700  fprintf(stderr, "xtrabackup: error: xtrabackup_write_metadata(xtrabackup_extra_lsndir)\n");
4701  }
4702  }
4703 
4704  if(!xtrabackup_create_ib_logfile)
4705  return;
4706 
4707  /* TODO: make more smart */
4708 
4709  printf("\n[notice]\nWe cannot call InnoDB second time during the process lifetime.\n");
4710  printf("Please re-execte to create ib_logfile*. Sorry.\n");
4711 /*
4712  printf("Restart InnoDB to create ib_logfile*.\n");
4713 
4714  if(innodb_init_param())
4715  goto error;
4716 
4717  if(innodb_init())
4718  goto error;
4719 
4720  if(innodb_end())
4721  goto error;
4722 */
4723 
4724  return;
4725 
4726 error:
4727  xtrabackup_close_temp_log(FALSE);
4728 
4729  exit(EXIT_FAILURE);
4730 }
4731 
4732 /* ================= main =================== */
4733 
4734 int main(int argc, char **argv)
4735 {
4736  po::options_description commandline_options(_("Options used only in command line"));
4737  commandline_options.add_options()
4738  ("target-dir", po::value<std::string>(), _("destination directory"))
4739  ("backup", po::value<bool>(&xtrabackup_backup)->default_value(false)->zero_tokens(), _("take backup to target-dir"))
4740  ("stats", po::value<bool>(&xtrabackup_stats)->default_value(false)->zero_tokens(), _("calc statistic of datadir (offline mysqld is recommended)"))
4741  ("prepare", po::value<bool>(&xtrabackup_prepare)->default_value(false)->zero_tokens(), _("prepare a backup for starting mysql server on the backup."))
4742  ("export", po::value<bool>(&xtrabackup_export)->default_value(false)->zero_tokens(), _("create files to import to another database when prepare."))
4743  ("apply-log-only", po::value<bool>(&xtrabackup_apply_log_only)->default_value(false)->zero_tokens(), _("stop recovery process not to progress LSN after applying log when prepare."))
4744  ("print-param", po::value<bool>(&xtrabackup_print_param)->default_value(false)->zero_tokens(), _("print parameter of mysqld needed for copyback."))
4745  ("use-memory", po::value<uint64_t>(&xtrabackup_use_memory)->default_value(100*1024*1024), _("The value is used instead of buffer_pool_size"))
4746  ("suspend-at-end", po::value<bool>(&xtrabackup_suspend_at_end)->default_value(false)->zero_tokens(), _("creates a file 'xtrabackup_suspended' and waits until the user deletes that file at the end of '--backup'"))
4747  ("throttle", po::value<long>(&xtrabackup_throttle), _("limit count of IO operations (pairs of read&write) per second to IOS values (for '--backup')"))
4748  ("log-stream", po::value<bool>(&xtrabackup_stream)->default_value(false)->zero_tokens(), _("outputs the contents of 'xtrabackup_logfile' to stdout only until the file 'xtrabackup_suspended' deleted (for '--backup')."))
4749  ("extra-lsndir", po::value<std::string>(), _("(for --backup): save an extra copy of the xtrabackup_checkpoints file in this directory."))
4750  ("incremental-lsn", po::value<std::string>(), _("(for --backup): copy only .ibd pages newer than specified LSN 'high:low'. ##ATTENTION##: checkpoint lsn must be used. anyone can detect your mistake. be carefully!"))
4751  ("incremental-basedir", po::value<std::string>(), _("(for --backup): copy only .ibd pages newer than backup at specified directory."))
4752  ("incremental-dir", po::value<std::string>(), _("(for --prepare): apply .delta files and logfile in the specified directory."))
4753  ("tables", po::value<std::string>(), _("filtering by regexp for table names."))
4754  ("tables-file", po::value<std::string>(), _("filtering by list of the exact database.table name in the file."))
4755  ("create-ib-logfile", po::value<bool>(&xtrabackup_create_ib_logfile), _("** not work for now** creates ib_logfile* also after '--prepare'. ### If you want create ib_logfile*, only re-execute this command in same options. ###"))
4756  ("datadir,h", po::value<std::string>(), _("Path to the database root."))
4757  ("tmpdir,t", po::value<std::string>(), _("Path for temporary files. Several paths may be specified, separated by a colon (:), in this case they are used in a round-robin fashion."))
4758  ("parallel", po::value<uint32_t>(&parallel)->default_value(1), _("Number of threads to use for parallel datafiles transfer. Does not have any effect in the stream mode. The default value is 1."))
4759  ("innodb-adaptive-hash-index", po::value<bool>(&innobase_adaptive_hash_index)->default_value(true), _("Enable InnoDB adaptive hash index (enabled by default). Disable with --skip-innodb-adaptive-hash-index."))
4760  ("innodb-additional-mem-pool-size", po::value<long>(&innobase_additional_mem_pool_size)->default_value(1*1024*1024), _("Size of a memory pool InnoDB uses to store data dictionary information and other internal data structures."))
4761  ("innodb-autoextend-increment", po::value<uint32_t>(&srv_auto_extend_increment)->default_value(8), _("Data file autoextend increment in megabytes"))
4762  ("innodb-buffer-pool-size", po::value<uint64_t>(&innobase_buffer_pool_size)->default_value(8*1024*1024), _("The size of the memory buffer InnoDB uses to cache data and indexes of its tables."))
4763  ("innodb-checksums", po::value<bool>(&innobase_use_checksums)->default_value(true), _("Enable InnoDB checksums validation (enabled by default). Disable with --skip-innodb-checksums."))
4764  ("innodb-data-file-path", po::value<std::string>(), _("Path to individual files and their sizes."))
4765  ("innodb-data-home-dir", po::value<std::string>(), _("The common part for InnoDB table spaces."))
4766  ("innodb-doublewrite", po::value<bool>(&innobase_use_doublewrite)->default_value(true), _("Enable InnoDB doublewrite buffer (enabled by default). Disable with --skip-innodb-doublewrite."))
4767  ("innodb-file-io-threads", po::value<long>(&innobase_file_io_threads)->default_value(4), _("Number of file I/O threads in InnoDB."))
4768  ("innodb-file-per-table", po::value<bool>(&innobase_file_per_table), _("Stores each InnoDB table to an .ibd file in the database dir."))
4769  ("innodb-flush-log-at-trx-commit", po::value<ulong>(&srv_flush_log_at_trx_commit)->default_value(1), _("Set to 0 (write and flush once per second), 1 (write and flush at each commit) or 2 (write at commit, flush once per second)."))
4770  ("innodb-flush-method", po::value<std::string>(), _("With which method to flush data."))
4771 /* ####### Should we use this option? ####### */
4772  ("innodb-force-recovery", po::value<long>(&innobase_force_recovery)->default_value(0), _("Helps to save your data in case the disk image of the database becomes corrupt."))
4773  ("innodb-lock-wait-timeout", po::value<long>(&innobase_lock_wait_timeout)->default_value(50), _("Timeout in seconds an InnoDB transaction may wait for a lock before being rolled back."))
4774  ("innodb-log-buffer-size", po::value<long>(&innobase_log_buffer_size)->default_value(1024*1024), _("The size of the buffer which InnoDB uses to write log to the log files on disk."))
4775  ("innodb-log-file-size", po::value<log_file_constraint>(&innobase_log_file_size)->default_value(20*1024*1024L), _("Size of each log file in a log group."))
4776  ("innodb-log-files-in-group", po::value<long>(&innobase_log_files_in_group)->default_value(2), _("Number of log files in the log group. InnoDB writes to the files in a circular fashion. Value 3 is recommended here."))
4777  ("innodb-log-group-home-dir", po::value<std::string>(), _("Path to InnoDB log files."))
4778  ("innodb-max_dirty-pages-pct", po::value<ulong>(&srv_max_buf_pool_modified_pct)->default_value(90), _("Percentage of dirty pages allowed in bufferpool."))
4779  ("innodb-open-files", po::value<long>(&innobase_open_files)->default_value(300), _("How many files at the maximum InnoDB keeps open at the same time."))
4780 #ifdef XTRADB_BASED
4781  ("innodb-page-size", po::value<uint32_t>(&innobase_page_size)->default_value(1 << 14), _("The universal page size of the database."))
4782  ("innodb-log-block-size", po::value<uint32_t>(&innobase_log_block_size)->default_value(512), _("###EXPERIMENTAL###: The log block size of the transaction log file. Changing for created log file is not supported. Use on your own risk!"))
4783  ("innodb-fast-checksum", po::value<bool>(&innobase_fast_checksum), _("Change the algorithm of checksum for the whole of datapage to 4-bytes word based."))
4784  ("innodb-extra-undoslots", po::value<bool>(&innobase_extra_undoslots), _("Enable to use about 4000 undo slots instead of default 1024. Not recommended to use, Because it is not change back to disable, once it is used."))
4785  ("innodb-doublewrite-file", po::value<char *>(&innobase_doublewrite_file), _("Path to special datafile for doublewrite buffer. (default is "": not used)"))
4786 #endif
4787  ;
4788 
4789  po::variables_map vm;
4790  // Disable allow_guessing, it is evil and broken
4791  int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
4792  po::store(po::command_line_parser(argc, argv).options(commandline_options).style(style).run(), vm);
4793  po::notify(vm);
4794 
4795  if (vm.count("target-dir"))
4796  xtrabackup_target_dir= vm["target-dir"].as<std::string>().c_str();
4797 
4798  if (vm.count("extra-lsndir"))
4799  xtrabackup_extra_lsndir= vm["extra-lsndir"].as<std::string>().c_str();
4800 
4801  if (vm.count("incremental-lsn"))
4802  xtrabackup_incremental= vm["incremental-lsn"].as<std::string>().c_str();
4803 
4804  if (vm.count("incremental-basedir"))
4805  xtrabackup_incremental_basedir= vm["incremental-basedir"].as<std::string>().c_str();
4806 
4807  boost::scoped_ptr<char> xtrabackup_tables_autoptr(new char[(vm.count("tables")) ? vm["tables"].as<std::string>().length() + 1: 0]);
4808  if (vm.count("tables"))
4809  {
4810  xtrabackup_tables= xtrabackup_tables_autoptr.get();
4811  strcpy(xtrabackup_tables, vm["tables"].as<std::string>().c_str());
4812  }
4813 
4814  if (vm.count("tables-file"))
4815  xtrabackup_tables_file= vm["tables-file"].as<std::string>().c_str();
4816 
4817  if (vm.count("tmpdir"))
4818  opt_mysql_tmpdir= vm["tmpdir"].as<std::string>().c_str();
4819 
4820  if (vm.count("innodb-data-file-path"))
4821  innobase_data_file_path= vm["innodb-data-file-path"].as<std::string>().c_str();
4822 
4823  boost::scoped_ptr<char> xtrabackup_incremental_dir_autoptr(new char[(vm.count("incremental-dir")) ? vm["incremental-dir"].as<std::string>().length() + 1: 0]);
4824  if (vm.count("incremental-dir"))
4825  {
4826  xtrabackup_incremental_dir= xtrabackup_incremental_dir_autoptr.get();
4827  strcpy(xtrabackup_incremental_dir, vm["incremental-dir"].as<std::string>().c_str());
4828  }
4829 
4830  boost::scoped_ptr<char> innobase_data_home_dir_autoptr(new char[(vm.count("innodb-data-home-dir")) ? vm["innodb-data-home-dir"].as<std::string>().length() + 1 : 0]);
4831  if (vm.count("innodb-data-home-dir"))
4832  {
4833  innobase_data_home_dir= innobase_data_home_dir_autoptr.get();
4834  strcpy(innobase_data_home_dir, vm["innodb-data-home-dir"].as<std::string>().c_str());
4835  }
4836 
4837  boost::scoped_ptr<char> innobase_flush_method_autoptr(new char[(vm.count("innodb-flush-method")) ? vm["innodb-flush-method"].as<std::string>().length() + 1 : 0]);
4838  if (vm.count("innodb-flush-method"))
4839  {
4840  innobase_unix_file_flush_method= innobase_flush_method_autoptr.get();
4841  strcpy(innobase_unix_file_flush_method, vm["innodb-flush-method"].as<std::string>().c_str());
4842  }
4843 
4844  boost::scoped_ptr<char> innobase_log_group_home_dir_autoptr(new char[(vm.count("innodb-log-group-home-dir")) ? vm["innodb-log-group-home-dir"].as<std::string>().length() + 1: 0]);
4845 
4846  if (vm.count("innodb-log-group-home-dir"))
4847  {
4848  innobase_log_group_home_dir= innobase_log_group_home_dir_autoptr.get();
4849  strcpy(innobase_log_group_home_dir, vm["innodb-log-group-home-dir"].as<std::string>().c_str());
4850  }
4851 
4852  xtrabackup_use_memory-= xtrabackup_use_memory % (1024*1024);
4853  if (xtrabackup_use_memory < (1024*1024)) {
4854  fprintf(stderr, "xtrabackup: use-memory out of range\n");
4855  exit(EXIT_FAILURE);
4856  }
4857 
4858  if (parallel < 1) {
4859  fprintf(stderr, "xtrabackup: parallel needs to be greater than 0\n");
4860  exit(EXIT_FAILURE);
4861  }
4862 
4863  innobase_additional_mem_pool_size-= innobase_additional_mem_pool_size % 1024;
4864  if (innobase_additional_mem_pool_size < (512*1024)) {
4865  fprintf(stderr, "xtrabackup: innodb-additional-mem-pool-size out of range\n");
4866  exit(EXIT_FAILURE);
4867  }
4868 
4869  if ((srv_auto_extend_increment < 1) || (srv_auto_extend_increment > 8)) {
4870  fprintf(stderr, "xtrabackup: innodb-auto-extend-increment out of range\n");
4871  exit(EXIT_FAILURE);
4872  }
4873 
4874  innobase_buffer_pool_size-= innobase_buffer_pool_size % (1024*1024);
4875  if (innobase_buffer_pool_size < (1024*1024)) {
4876  fprintf(stderr, "xtrabackup: innodb-buffer-pool-size out of range\n");
4877  exit(EXIT_FAILURE);
4878  }
4879 
4880  if ((innobase_file_io_threads < 4) || (innobase_file_io_threads > 64)) {
4881  fprintf(stderr, "xtrabackup: innodb-file-io-threads out of range\n");
4882  exit(EXIT_FAILURE);
4883  }
4884 
4885  if (srv_flush_log_at_trx_commit > 2) {
4886  fprintf(stderr, "xtrabackup: innodb-flush-log-at-trx-commit out of range\n");
4887  exit(EXIT_FAILURE);
4888  }
4889 
4890  if (innobase_force_recovery > 6) {
4891  fprintf(stderr, "xtrabackup: innodb-force-recovery out of range\n");
4892  exit(EXIT_FAILURE);
4893  }
4894 
4895  if ((innobase_lock_wait_timeout < 1) || (innobase_lock_wait_timeout > (1024*1024*1024))) {
4896  fprintf(stderr, "xtrabackup: innodb-lock-wait-timeout out of range\n");
4897  exit(EXIT_FAILURE);
4898  }
4899 
4900  innobase_log_buffer_size-= innobase_log_buffer_size % 1024;
4901  if (innobase_additional_mem_pool_size < (256*1024)) {
4902  fprintf(stderr, "xtrabackup: innodb-log-buffer-size out of range\n");
4903  exit(EXIT_FAILURE);
4904  }
4905 
4906  if (innobase_additional_mem_pool_size < (1024*1024)) {
4907  fprintf(stderr, "xtrabackup: innodb-log-file-size out of range\n");
4908  exit(EXIT_FAILURE);
4909  }
4910 
4911  if ((innobase_log_files_in_group < 2) || (innobase_log_files_in_group > (100))) {
4912  fprintf(stderr, "xtrabackup: innodb-log-files-in-group out of range\n");
4913  exit(EXIT_FAILURE);
4914  }
4915 
4916  if (srv_max_buf_pool_modified_pct > 100) {
4917  fprintf(stderr, "xtrabackup: innodb-max-buf-pool-modified-pct out of range\n");
4918  exit(EXIT_FAILURE);
4919  }
4920 
4921  if (innobase_open_files < 10) {
4922  fprintf(stderr, "xtrabackup: innodb-open-files out of range\n");
4923  exit(EXIT_FAILURE);
4924  }
4925 
4926  if ((innobase_page_size < (1 << 12)) || (innobase_page_size > (1 << UNIV_PAGE_SIZE_SHIFT_MAX))) {
4927  fprintf(stderr, "xtrabackup: innodb-page-size out of range\n");
4928  exit(EXIT_FAILURE);
4929  }
4930 
4931  if ((innobase_log_block_size < (512)) || (innobase_log_block_size > (1 << UNIV_PAGE_SIZE_SHIFT_MAX))) {
4932  fprintf(stderr, "xtrabackup: innodb-log-block-size out of range\n");
4933  exit(EXIT_FAILURE);
4934  }
4935 
4936  if (vm.count("datadir"))
4937  {
4938  mysql_data_home_arg.assign(vm["datadir"].as<std::string>());
4939  }
4940  else
4941  {
4942  mysql_data_home_arg.assign(LOCALSTATEDIR);
4943  }
4944 
4945  mysql_data_home= (char*)malloc(mysql_data_home_arg.length());
4946  strcpy(mysql_data_home, mysql_data_home_arg.c_str());
4947 
4948  if ((!xtrabackup_prepare) && (strcmp(mysql_data_home, "./") == 0)) {
4949  if (!xtrabackup_print_param)
4950  usage();
4951  printf("\nxtrabackup: Error: Please set parameter 'datadir'\n");
4952  exit(EXIT_FAILURE);
4953  }
4954 
4955  if (xtrabackup_tables) {
4956  /* init regexp */
4957  char *p, *next;
4958  int i;
4959  char errbuf[100];
4960 
4961  tables_regex_num = 1;
4962 
4963  p = xtrabackup_tables;
4964  while ((p = strchr(p, ',')) != NULL) {
4965  p++;
4966  tables_regex_num++;
4967  }
4968 
4969  tables_regex = (regex_t*) ut_malloc(sizeof(regex_t) * tables_regex_num);
4970 
4971  p = xtrabackup_tables;
4972  for (i=0; i < tables_regex_num; i++) {
4973  next = strchr(p, ',');
4974  ut_a(next || i == tables_regex_num - 1);
4975 
4976  next++;
4977  if (i != tables_regex_num - 1)
4978  *(next - 1) = '\0';
4979 
4980  regerror(regcomp(&tables_regex[i],p,REG_EXTENDED),
4981  &tables_regex[i],errbuf,sizeof(errbuf));
4982  fprintf(stderr, "xtrabackup: tables regcomp(%s): %s\n",p,errbuf);
4983 
4984  if (i != tables_regex_num - 1)
4985  *(next - 1) = ',';
4986  p = next;
4987  }
4988  }
4989 
4990  if (xtrabackup_tables_file) {
4991  char name_buf[NAME_LEN*2+2];
4992  FILE *fp;
4993 
4994  if (xtrabackup_stream) {
4995  fprintf(stderr, "xtrabackup: Warning: --tables_file option doesn't affect with --stream.\n");
4996  xtrabackup_tables_file = NULL;
4997  goto skip_tables_file_register;
4998  }
4999 
5000  name_buf[NAME_LEN*2+1] = '\0';
5001 
5002  /* init tables_hash */
5003  tables_hash = hash_create(1000);
5004 
5005  /* read and store the filenames */
5006  fp = fopen(xtrabackup_tables_file,"r");
5007  if (!fp) {
5008  fprintf(stderr, "xtrabackup: cannot open %s\n", xtrabackup_tables_file);
5009  exit(EXIT_FAILURE);
5010  }
5011  for (;;) {
5012  xtrabackup_tables_t* table;
5013  char* p = name_buf;
5014 
5015  if ( fgets(name_buf, NAME_LEN*2+1, fp) == 0 ) {
5016  break;
5017  }
5018 
5019  while (*p != '\0') {
5020  if (*p == '.') {
5021  *p = '/';
5022  }
5023  p++;
5024  }
5025  p = strchr(name_buf, '\n');
5026  if (p)
5027  {
5028  *p = '\0';
5029  }
5030 
5031  table = (xtrabackup_tables_t*) malloc(sizeof(xtrabackup_tables_t) + strlen(name_buf) + 1);
5032  memset(table, '\0', sizeof(xtrabackup_tables_t) + strlen(name_buf) + 1);
5033  table->name = ((char*)table) + sizeof(xtrabackup_tables_t);
5034  strcpy(table->name, name_buf);
5035 
5036  HASH_INSERT(xtrabackup_tables_t, name_hash, tables_hash,
5037  ut_fold_string(table->name), table);
5038 
5039  printf("xtrabackup: table '%s' is registered to the list.\n", table->name);
5040  }
5041  }
5042 skip_tables_file_register:
5043 
5044 #ifdef XTRADB_BASED
5045  /* temporary setting of enough size */
5046  srv_page_size_shift = UNIV_PAGE_SIZE_SHIFT_MAX;
5047  srv_page_size = UNIV_PAGE_SIZE_MAX;
5048  srv_log_block_size = 512;
5049 #endif
5050  if (xtrabackup_backup && xtrabackup_incremental) {
5051  /* direct specification is only for --backup */
5052  /* and the lsn is prior to the other option */
5053 
5054  char* endchar;
5055  int error = 0;
5056 
5057  incremental_lsn = strtoll(xtrabackup_incremental, &endchar, 10);
5058  if (*endchar != '\0')
5059  error = 1;
5060 
5061  if (error) {
5062  fprintf(stderr, "xtrabackup: value '%s' may be wrong format for incremental option.\n",
5063  xtrabackup_incremental);
5064  exit(EXIT_FAILURE);
5065  }
5066 
5067  /* allocate buffer for incremental backup (4096 pages) */
5068  incremental_buffer_base = (byte*) malloc((UNIV_PAGE_SIZE_MAX / 4 + 1) *
5069  UNIV_PAGE_SIZE_MAX);
5070  incremental_buffer = (byte*) ut_align(incremental_buffer_base,
5071  UNIV_PAGE_SIZE_MAX);
5072  } else if (xtrabackup_backup && xtrabackup_incremental_basedir) {
5073  char filename[FN_REFLEN];
5074 
5075  sprintf(filename, "%s/%s", xtrabackup_incremental_basedir, XTRABACKUP_METADATA_FILENAME);
5076 
5077  if (xtrabackup_read_metadata(filename)) {
5078  fprintf(stderr,
5079  "xtrabackup: error: failed to read metadata from %s\n",
5080  filename);
5081  exit(EXIT_FAILURE);
5082  }
5083 
5084  incremental_lsn = metadata_to_lsn;
5085  xtrabackup_incremental = xtrabackup_incremental_basedir; //dummy
5086 
5087  /* allocate buffer for incremental backup (4096 pages) */
5088  incremental_buffer_base = (byte*) malloc((UNIV_PAGE_SIZE_MAX / 4 + 1) *
5089  UNIV_PAGE_SIZE_MAX);
5090  incremental_buffer = (byte*) ut_align(incremental_buffer_base,
5091  UNIV_PAGE_SIZE_MAX);
5092  } else if (xtrabackup_prepare && xtrabackup_incremental_dir) {
5093  char filename[FN_REFLEN];
5094 
5095  sprintf(filename, "%s/%s", xtrabackup_incremental_dir, XTRABACKUP_METADATA_FILENAME);
5096 
5097  if (xtrabackup_read_metadata(filename)) {
5098  fprintf(stderr,
5099  "xtrabackup: error: failed to read metadata from %s\n",
5100  filename);
5101  exit(EXIT_FAILURE);
5102  }
5103 
5104  incremental_lsn = metadata_from_lsn;
5105  incremental_to_lsn = metadata_to_lsn;
5106  incremental_last_lsn = metadata_last_lsn;
5107  xtrabackup_incremental = xtrabackup_incremental_dir; //dummy
5108 
5109  /* allocate buffer for incremental backup (4096 pages) */
5110  incremental_buffer_base = (byte*) malloc((UNIV_PAGE_SIZE / 4 + 1) *
5111  UNIV_PAGE_SIZE);
5112  incremental_buffer = (byte*) ut_align(incremental_buffer_base,
5113  UNIV_PAGE_SIZE);
5114  } else {
5115  /* allocate buffer for applying incremental (for header page only) */
5116  incremental_buffer_base = (byte*) malloc((1 + 1) * UNIV_PAGE_SIZE_MAX);
5117  incremental_buffer = (byte*) ut_align(incremental_buffer_base,
5118  UNIV_PAGE_SIZE_MAX);
5119 
5120  xtrabackup_incremental = NULL;
5121  }
5122 
5123  /* --print-param */
5124  if (xtrabackup_print_param) {
5125  printf("# This MySQL options file was generated by XtraBackup.\n");
5126  printf("[mysqld]\n");
5127  printf("datadir = \"%s\"\n", mysql_data_home);
5128  printf("tmpdir = \"%s\"\n", opt_mysql_tmpdir);
5129  printf("innodb_data_home_dir = \"%s\"\n",
5130  innobase_data_home_dir ? innobase_data_home_dir : mysql_data_home);
5131  printf("innodb_data_file_path = \"%s\"\n",
5132  innobase_data_file_path ? innobase_data_file_path : "ibdata1:10M:autoextend");
5133  printf("innodb_log_group_home_dir = \"%s\"\n",
5134  innobase_log_group_home_dir ? innobase_log_group_home_dir : mysql_data_home);
5135  printf("innodb_log_files_in_group = %ld\n", innobase_log_files_in_group);
5136  printf("innodb_log_file_size = %"PRIu64"\n", (uint64_t)innobase_log_file_size);
5137  printf("innodb_flush_method = \"%s\"\n",
5138  (innobase_unix_file_flush_method != NULL) ?
5139  innobase_unix_file_flush_method : "");
5140  exit(EXIT_SUCCESS);
5141  }
5142 
5143  if (!xtrabackup_stream) {
5144  print_version();
5145  if (xtrabackup_incremental) {
5146  printf("incremental backup from %"PRIu64" is enabled.\n",
5147  incremental_lsn);
5148  }
5149  } else {
5150  if (xtrabackup_backup) {
5151  xtrabackup_suspend_at_end = TRUE;
5152  fprintf(stderr, "xtrabackup: suspend-at-end is enabled.\n");
5153  }
5154  }
5155 
5156  /* cannot execute both for now */
5157  {
5158  int num = 0;
5159 
5160  if (xtrabackup_backup) num++;
5161  if (xtrabackup_stats) num++;
5162  if (xtrabackup_prepare) num++;
5163  if (num != 1) { /* !XOR (for now) */
5164  usage();
5165  exit(EXIT_FAILURE);
5166  }
5167  }
5168 
5169  /* --backup */
5170  if (xtrabackup_backup)
5171  xtrabackup_backup_func();
5172 
5173  /* --stats */
5174  if (xtrabackup_stats)
5175  xtrabackup_stats_func();
5176 
5177  /* --prepare */
5178  if (xtrabackup_prepare)
5179  xtrabackup_prepare_func();
5180 
5181  free(incremental_buffer_base);
5182 
5183  if (xtrabackup_tables) {
5184  /* free regexp */
5185  int i;
5186 
5187  for (i = 0; i < tables_regex_num; i++) {
5188  regfree(&tables_regex[i]);
5189  }
5190  ut_free(tables_regex);
5191  }
5192 
5193  if (xtrabackup_tables_file) {
5194  ulint i;
5195 
5196  /* free the hash elements */
5197  for (i = 0; i < hash_get_n_cells(tables_hash); i++) {
5198  xtrabackup_tables_t* table;
5199 
5200  table = (xtrabackup_tables_t*)
5201  HASH_GET_FIRST(tables_hash, i);
5202 
5203  while (table) {
5204  xtrabackup_tables_t* prev_table = table;
5205 
5206  table = (xtrabackup_tables_t*)
5207  HASH_GET_NEXT(name_hash, prev_table);
5208 
5209  HASH_DELETE(xtrabackup_tables_t, name_hash, tables_hash,
5210  ut_fold_string(prev_table->name), prev_table);
5211  free(prev_table);
5212  }
5213  }
5214 
5215  /* free tables_hash */
5216  hash_table_free(tables_hash);
5217  }
5218 
5219  exit(EXIT_SUCCESS);
5220 }
#define UT_LIST_GET_LEN(BASE)
Definition: ut0lst.h:217
int os_file_t
Definition: os0file.h:87
UNIV_INTERN ibool thd_is_select(const drizzled::Session *session)
Definition: ha_innodb.cc:973
ibool srv_locks_unsafe_for_binlog
Definition: srv0srv.cc:138
UNIV_INTERN ibool fil_extend_space_to_desired_size(ulint *actual_size, ulint space_id, ulint size_after_extend)
Definition: fil0fil.cc:3886
UNIV_INTERN const char * innobase_get_stmt(drizzled::Session *mysql_thd, size_t *length) __attribute__((nonnull))
Definition: xtrabackup.cc:751
const char * name
Definition: dict0mem.h:339
ulint stat_index_size
Definition: dict0mem.h:392
#define UT_LIST_GET_NEXT(NAME, N)
Definition: ut0lst.h:201
UNIV_INTERN void innobase_convert_from_table_id(const void *, char *to, const char *from, ulint len)
Definition: ha_innodb.cc:1316
UNIV_INLINE ulint page_get_space_id(const page_t *page)
UNIV_INTERN ulint fil_io(ulint type, ibool sync, ulint space_id, ulint zip_size, ulint block_offset, ulint byte_offset, ulint len, void *buf, void *message)
Definition: fil0fil.cc:4287
UNIV_INLINE ibool btr_pcur_is_on_user_rec(const btr_pcur_t *cursor)
UNIV_INTERN void fsp_init(void)
Definition: fsp0fsp.cc:914
UNIV_INLINE ibool log_block_get_flush_bit(const byte *log_block)
UNIV_INTERN void innobase_rec_to_mysql(Table *table, const rec_t *rec, const dict_index_t *index, const ulint *offsets)
UNIV_INTERN ibool srv_parse_log_group_home_dirs(char *str)
Definition: srv0start.cc:379
UNIV_INLINE void mach_write_to_4(byte *b, ulint n)
unsigned space
Definition: dict0mem.h:343
UNIV_INTERN int innobase_start_or_create_for_mysql(void)
Definition: srv0start.cc:971
UNIV_INTERN void os_mutex_free(os_mutex_t mutex)
Definition: os0sync.cc:840
UNIV_INTERN void sync_close(void)
Definition: sync0sync.cc:1510
UNIV_INTERN void os_file_set_nocache(int fd, const char *file_name, const char *operation_name)
Definition: os0file.cc:1340
UNIV_INLINE ulint log_block_get_checkpoint_no(const byte *log_block)
UNIV_INTERN void log_group_read_checkpoint_info(log_group_t *group, ulint field)
Definition: log0log.cc:1971
UNIV_INTERN page_t * btr_root_get(dict_index_t *index, mtr_t *mtr)
Definition: btr0btr.cc:715
#define mtr_s_lock(B, MTR)
Definition: mtr0mtr.h:336
UNIV_INTERN ib_int64_t os_file_get_size_as_iblonglong(os_file_t file)
Definition: os0file.cc:1943
UNIV_INTERN void ut_print_namel(FILE *f, struct trx_struct *trx, ibool table_id, const char *name, ulint namelen)
Definition: ut0ut.cc:546
UNIV_INTERN void os_io_init_simple(void)
Definition: os0file.cc:711
UNIV_INLINE ulint page_get_n_recs(const page_t *page)
UNIV_INTERN os_thread_t os_thread_create(os_posix_f_t start_f, void *arg, os_thread_id_t *thread_id)
Definition: os0thread.cc:110
#define mem_free(PTR)
Definition: mem0mem.h:249
UNIV_INTERN void log_init(void)
Definition: log0log.cc:803
#define RECV_SCAN_SIZE
Definition: log0recv.h:486
UNIV_INTERN void log_group_read_log_seg(ulint type, byte *buf, log_group_t *group, ib_uint64_t start_lsn, ib_uint64_t end_lsn)
Definition: log0log.cc:2231
TODO: Rename this file - func.h is stupid.
UNIV_INLINE ulint page_get_data_size(const page_t *page)
ibool row_rollback_on_timeout
Definition: row0mysql.cc:58
UNIV_INTERN os_event_t os_event_create(const char *name)
Definition: os0sync.cc:365
UNIV_INTERN int innobase_shutdown_for_mysql(void)
Definition: srv0start.cc:1878
UNIV_INTERN void * ut_malloc(ulint n)
Definition: ut0mem.cc:235
UNIV_INLINE ulint rec_offs_nth_extern(const ulint *offsets, ulint n)
UNIV_INLINE void mach_write_to_8(byte *b, ib_uint64_t n)
UNIV_INTERN void thd_set_lock_wait_time(drizzled::Session *in_session, ulint value)
Definition: ha_innodb.cc:1015
#define OS_WIN31
Definition: os0file.h:193
UNIV_INTERN void innobase_rec_reset(Table *table)
UNIV_INTERN void ut_free_all_mem(void)
Definition: ut0mem.cc:411
os_file_type_t type
Definition: os0file.h:384
#define OS_WIN95
Definition: os0file.h:194
UNIV_INTERN void srv_general_init(void)
Definition: srv0srv.cc:1192
UNIV_INLINE ulint log_block_convert_lsn_to_no(ib_uint64_t lsn)
#define DICT_TF_FORMAT_51
Definition: dict0mem.h:87
UNIV_INLINE ulint dict_table_flags_to_zip_size(ulint flags) __attribute__((const ))
UNIV_INTERN hash_table_t * hash_create(ulint n)
Definition: hash0hash.cc:102
UNIV_INTERN ibool buf_page_is_corrupted(const byte *read_buf, ulint zip_size)
Definition: buf0buf.cc:503
UNIV_INTERN ulint fil_space_get_zip_size(ulint id)
Definition: fil0fil.cc:1535
UNIV_INTERN void innobase_mysql_print_thd(FILE *f, drizzled::Session *in_session, uint)
Definition: ha_innodb.cc:1264
UNIV_INTERN void sync_init(void)
Definition: sync0sync.cc:1431
UNIV_INLINE void page_cur_set_before_first(const buf_block_t *block, page_cur_t *cur)
UNIV_INTERN ulong thd_lock_wait_timeout(drizzled::Session *)
Definition: ha_innodb.cc:1000
fil_space_t * space
Definition: fil0fil.cc:137
UNIV_INTERN ibool thd_is_replication_slave_thread(drizzled::Session *)
Definition: ha_innodb.cc:887
UNIV_INTERN void os_mutex_enter(os_mutex_t mutex)
Definition: os0sync.cc:809
#define mem_heap_free(heap)
Definition: mem0mem.h:117
#define btr_block_get(space, zip_size, page_no, mode, mtr)
Definition: btr0btr.h:212
UNIV_INTERN ibool thd_supports_xa(drizzled::Session *)
Definition: ha_innodb.cc:986
#define OS_FILE_READ
Definition: os0file.h:144
UNIV_INTERN void dict_update_statistics(dict_table_t *table, ibool only_calc_if_missing_stats)
Definition: dict0dict.cc:4268
unsigned page
Definition: dict0mem.h:345
UNIV_INLINE dict_table_t * dict_table_get_low(const char *table_name)
#define HASH_INSERT(TYPE, NAME, TABLE, FOLD, DATA)
Definition: hash0hash.h:101
unsigned n_user_defined_cols
Definition: dict0mem.h:353
UNIV_INLINE ulint btr_page_get_level(const page_t *page, mtr_t *mtr)
ibool sync_initialized
Definition: sync0sync.cc:190
UNIV_INTERN rw_lock_t * fil_space_get_latch(ulint id, ulint *zip_size)
Definition: fil0fil.cc:515
#define FIL_TABLESPACE
Definition: fil0fil.h:190
UNIV_INLINE ulint btr_page_get_next(const page_t *page, mtr_t *mtr)
UNIV_INTERN os_file_dir_t os_file_opendir(const char *dirname, ibool error_is_fatal)
Definition: os0file.cc:761
ib_uint64_t scanned_lsn
Definition: log0log.h:749
UNIV_INLINE void btr_pcur_close(btr_pcur_t *cursor)
UNIV_INTERN ibool trx_is_interrupted(trx_t *trx)
Definition: ha_innodb.cc:1882
#define BTR_EXTERN_OFFSET
Definition: btr0cur.h:790
#define HASH_GET_NEXT(NAME, DATA)
Definition: hash0hash.h:172
UNIV_INTERN void hash_table_free(hash_table_t *table)
Definition: hash0hash.cc:139
typedef UT_LIST_BASE_NODE_T(mutex_t) ut_list_base_node_t
UNIV_INLINE ulint rec_get_deleted_flag(const rec_t *rec, ulint comp)
UNIV_INTERN void mtr_commit(mtr_t *mtr) __attribute__((nonnull))
Definition: mtr0mtr.cc:247
#define OS_FILE_LOG_BLOCK_SIZE
Definition: os0file.h:104
UNIV_INLINE ulint log_block_get_data_len(const byte *log_block)
UNIV_INTERN ulint mtr_read_ulint(const byte *ptr, ulint type, mtr_t *mtr)
Definition: mtr0mtr.cc:362
UNIV_INTERN void fil_init(ulint hash_size, ulint max_n_open)
Definition: fil0fil.cc:1574
#define OS_WINNT
Definition: os0file.h:195
ulint space_id
Definition: log0log.h:714
const char * innobase_basename(const char *path_name)
Definition: ha_innodb.cc:1357
static char * innobase_convert_identifier(char *buf, ulint buflen, const char *id, ulint idlen, drizzled::Session *session, ibool file_id)
Definition: ha_innodb.cc:1734
UNIV_INTERN ibool trx_is_strict(trx_t *trx)
Definition: ha_innodb.cc:1894
UNIV_INLINE ibool page_is_leaf(const page_t *page) __attribute__((nonnull
ulint innobase_get_at_most_n_mbchars(ulint charset_id, ulint prefix_len, ulint data_len, const char *str)
Definition: ha_innodb.cc:9109
UNIV_INTERN ulint innobase_raw_format(const char *data, ulint data_len, ulint, char *buf, ulint buf_size)
Definition: ha_innodb.cc:1518
UNIV_INTERN void os_sync_init(void)
Definition: os0sync.cc:304
#define UT_LIST_NODE_T(TYPE)
Definition: ut0lst.h:73
os_mutex_t os_sync_mutex
Definition: os0sync.cc:59
UNIV_INLINE ibool page_cur_is_after_last(const page_cur_t *cur)
UNIV_INLINE void * ut_align(const void *ptr, ulint align_no)
#define HASH_GET_FIRST(TABLE, HASH_VAL)
Definition: hash0hash.h:166
UNIV_INTERN void os_mutex_exit(os_mutex_t mutex)
Definition: os0sync.cc:824
UNIV_INTERN void os_event_set(os_event_t event)
Definition: os0sync.cc:434
ib_int64_t * stat_n_diff_key_vals
Definition: dict0mem.h:379
UNIV_INTERN int os_file_closedir(os_file_dir_t dir)
Definition: os0file.cc:817
UNIV_INTERN void os_thread_sleep(ulint tm)
Definition: os0thread.cc:265
UNIV_INTERN ib_int64_t os_event_reset(os_event_t event)
Definition: os0sync.cc:472
UNIV_INTERN void btr_pcur_store_position(btr_pcur_t *cursor, mtr_t *mtr)
Definition: btr0pcur.cc:89
#define ut_a(EXPR)
Definition: ut0dbg.h:105
UNIV_INLINE void page_cur_move_to_next(page_cur_t *cur)
ib_uint64_t srv_start_lsn
Definition: srv0start.cc:99
UNIV_INLINE ulint log_block_get_checksum(const byte *log_block)
#define mem_heap_create(N)
Definition: mem0mem.h:97
UNIV_INTERN int innobase_mysql_cmp(int mysql_type, uint charset_number, const unsigned char *a, unsigned int a_length, const unsigned char *b, unsigned int b_length)
Definition: ha_innodb.cc:3941
UNIV_INTERN ulint os_file_get_last_error(ibool report_all_errors)
Definition: os0file.cc:385
UNIV_INTERN void srv_normalize_path_for_win(char *str)
Definition: srv0start.cc:513
#define OS_WIN2000
Definition: os0file.h:196
UNIV_INTERN int innobase_mysql_tmpfile(void)
Definition: ha_innodb.cc:1479
#define UT_LIST_GET_FIRST(BASE)
Definition: ut0lst.h:224
UNIV_INLINE ulint rec_offs_n_fields(const ulint *offsets)
bool btr_search_enabled
Definition: btr0sea.cc:48
my_bool srv_file_per_table
Definition: srv0srv.cc:125
UNIV_INTERN void ut_mem_init(void)
Definition: ut0mem.cc:77
#define MLOG_4BYTES
Definition: mtr0mtr.h:75
UNIV_INLINE void mem_heap_empty(mem_heap_t *heap)
UNIV_INTERN ulint log_group_get_capacity(const log_group_t *group)
Definition: log0log.cc:529
#define BTR_EXTERN_SPACE_ID
Definition: btr0cur.h:788
UNIV_INLINE ulint ut_fold_binary(const byte *str, ulint len) __attribute__((pure))
dict_sys_t * dict_sys
Definition: dict0dict.cc:63
#define OS_DATA_FILE
Definition: os0file.h:125
byte * checkpoint_buf
Definition: log0log.h:927
ulint srv_max_file_format_at_startup
Definition: srv0srv.cc:131
UNIV_INTERN ibool thd_has_edited_nontrans_tables(drizzled::Session *session)
Definition: ha_innodb.cc:961
index_id_t id
Definition: dict0mem.h:337
#define ut_ad(EXPR)
Definition: ut0dbg.h:127
os_thread_t os_thread_id_t
Definition: os0thread.h:53
#define mtr_x_lock(B, MTR)
Definition: mtr0mtr.h:340
#define HASH_SEARCH(NAME, TABLE, FOLD, TYPE, DATA, ASSERTION, TEST)
Definition: hash0hash.h:176
UNIV_INTERN void ut_free(void *ptr)
Definition: ut0mem.cc:294
#define ut_error
Definition: ut0dbg.h:115
UNIV_INTERN char * innobase_convert_name(char *buf, ulint buflen, const char *id, ulint idlen, drizzled::Session *session, ibool table_id)
Definition: ha_innodb.cc:1820
UNIV_INLINE ulint ut_fold_string(const char *str) __attribute__((pure))
UNIV_INTERN void ut_sprintf_timestamp(char *buf)
Definition: ut0ut.cc:290
UNIV_INTERN int innobase_strcasecmp(const char *a, const char *b)
Definition: ha_innodb.cc:1345
UNIV_INLINE char * mem_strdupl(const char *str, ulint len)
#define BTR_EXTERN_FIELD_REF_SIZE
Definition: btr0types.h:170
#define FIL_NULL
Definition: fil0fil.h:48
byte * buf
Definition: log0log.h:780
UNIV_INLINE ulint buf_block_get_space(const buf_block_t *block) __attribute__((pure))
UNIV_INTERN void os_event_free(os_event_t event)
Definition: os0sync.cc:535
UNIV_INTERN void innobase_casedn_str(char *a)
Definition: ha_innodb.cc:1370
DIR * os_file_dir_t
Definition: os0file.h:395
ulint os_innodb_umask
Definition: os0file.cc:71
UNIV_INLINE ulint mach_read_from_4(const byte *b) __attribute__((nonnull
UNIV_INTERN void innobase_get_cset_width(ulint cset, ulint *mbminlen, ulint *mbmaxlen)
Definition: ha_innodb.cc:1289
UNIV_INTERN void ut_print_timestamp(FILE *file)
Definition: ut0ut.cc:247
#define OS_FILE_OPEN
Definition: os0file.h:107
#define FIL_PAGE_DATA
Definition: fil0fil.h:159
#define OS_WINXP
Definition: os0file.h:197
byte page_t
Definition: page0types.h:37
#define BTR_EXTERN_PAGE_NO
Definition: btr0cur.h:789
UNIV_INTERN void fil_aio_wait(ulint segment)
Definition: fil0fil.cc:4570
UNIV_INTERN void os_thread_exit(void *exit_value)
Definition: os0thread.cc:199
UNIV_INTERN void os_sync_free(void)
Definition: os0sync.cc:325
UNIV_INLINE void mtr_start(mtr_t *mtr) __attribute__((nonnull))
UNIV_INLINE ulint log_block_calc_checksum(const byte *block)
rw_lock_t lock
Definition: dict0mem.h:399
UNIV_INLINE ibool btr_pcur_move_to_next_user_rec(btr_pcur_t *cursor, mtr_t *mtr)
#define HASH_DELETE(TYPE, NAME, TABLE, FOLD, DATA)
Definition: hash0hash.h:137
ulint srv_file_format
Definition: srv0srv.cc:127
UNIV_INLINE ulint log_block_get_hdr_no(const byte *log_block)
UNIV_INTERN ibool os_file_status(const char *path, ibool *exists, os_file_type_t *type)
Definition: os0file.cc:2903
os_file_t handle
Definition: fil0fil.cc:141
UNIV_INTERN ibool srv_parse_data_file_paths_and_sizes(char *str)
Definition: srv0start.cc:195
UNIV_INTERN void innobase_invalidate_query_cache(trx_t *trx, const char *full_name, ulint full_name_len)
Definition: xtrabackup.cc:797
UNIV_INTERN void lock_sys_create(ulint n_cells)
Definition: lock0lock.cc:565
char name[OS_FILE_MAX_PATH]
Definition: os0file.h:383
UNIV_INTERN void innobase_convert_from_id(const void *, char *to, const char *from, ulint len)
Definition: ha_innodb.cc:1330
ulint srv_buf_pool_size
Definition: srv0srv.cc:253
UNIV_INLINE void btr_pcur_open_at_index_side(ibool from_left, dict_index_t *index, ulint latch_mode, btr_pcur_t *pcur, ibool do_init, mtr_t *mtr)
UNIV_INLINE int ut_memcmp(const void *str1, const void *str2, ulint n)
ulint stat_n_leaf_pages
Definition: dict0mem.h:395
#define FIL_PAGE_LSN
Definition: fil0fil.h:115
#define TEMP_INDEX_PREFIX
Definition: ut0ut.h:51
UNIV_INLINE int ut_strcmp(const char *str1, const char *str2)
UNIV_INLINE ulint hash_get_n_cells(hash_table_t *table)
UNIV_INTERN ulint fil_load_single_table_tablespaces(void)
Definition: fil0fil.cc:3522
#define buf_page_get(SP, ZS, OF, LA, MTR)
Definition: buf0buf.h:316