1
/******************************************************
2
XtraBackup: The another hot backup tool for InnoDB
5
Created 3/3/2009 Yasufumi Kinoshita
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.
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.
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
20
*******************************************************/
22
#ifndef XTRABACKUP_VERSION
23
#define XTRABACKUP_VERSION "undefined"
25
#ifndef XTRABACKUP_REVISION
26
#define XTRABACKUP_REVISION "undefined"
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/level_t.h>
38
#include "ha_prototypes.h"
39
//#define XTRABACKUP_TARGET_IS_PLUGIN
40
#include <boost/program_options.hpp>
41
#include <boost/scoped_ptr.hpp>
43
typedef drizzled::charset_info_st CHARSET_INFO;
45
#define my_progname "xtrabackup"
47
#define MYSQL_VERSION_ID 50507 /* Drizzle is much greater */
51
#include <os0thread.h>
52
#include <srv0start.h>
59
#include <row0mysql.h>
64
#include <lock0lock.h>
65
#include <dict0crea.h>
70
#include <sync0sync.h>
74
#ifdef INNODB_VERSION_SHORT
75
#include <ibuf0ibuf.h>
80
#define IB_INT64 ib_int64_t
81
#define LSN64 ib_uint64_t
82
#define MACH_READ_64 mach_read_from_8
83
#define MACH_WRITE_64 mach_write_to_8
84
#define OS_MUTEX_CREATE() os_mutex_create()
85
#define ut_dulint_zero 0
86
#define ut_dulint_cmp(A, B) (A > B ? 1 : (A == B ? 0 : -1))
87
#define ut_dulint_add(A, B) (A + B)
88
#define ut_dulint_minus(A, B) (A - B)
89
#define ut_dulint_align_down(A, B) (A & ~((ib_int64_t)B - 1))
90
#define ut_dulint_align_up(A, B) ((A + B - 1) & ~((ib_int64_t)B - 1))
93
#define SRV_PATH_SEPARATOR '\\'
94
#define SRV_PATH_SEPARATOR_STR "\\"
96
#define SRV_PATH_SEPARATOR '/'
97
#define SRV_PATH_SEPARATOR_STR "/"
100
#ifndef UNIV_PAGE_SIZE_MAX
101
#define UNIV_PAGE_SIZE_MAX UNIV_PAGE_SIZE
103
#ifndef UNIV_PAGE_SIZE_SHIFT_MAX
104
#define UNIV_PAGE_SIZE_SHIFT_MAX UNIV_PAGE_SIZE_SHIFT
107
using namespace drizzled;
108
namespace po=boost::program_options;
111
bool errmsg_printf (error::level_t, char const *format, ...);
113
bool errmsg_printf (error::level_t, char const *format, ...)
117
va_start(args, format);
118
rv= vfprintf(stderr, format, args);
120
fprintf(stderr, "\n");
126
#include "xtrabackup_api.h"
128
/* prototypes for static functions in original */
131
recv_find_max_checkpoint(
132
/*=====================*/
133
/* out: error code or DB_SUCCESS */
134
log_group_t** max_group, /* out: max group */
135
ulint* max_field); /* out: LOG_CHECKPOINT_1 or
142
int fd, /* in: file descriptor to alter */
143
const char* file_name, /* in: used in the diagnostic message */
144
const char* operation_name); /* in: used in the diagnostic message,
145
we call os_file_set_nocache()
146
immediately after opening or creating
147
a file, so this is either "open" or
153
#ifdef POSIX_FADV_NORMAL
154
#define USE_POSIX_FADVISE
157
/* ==start === definition at fil0fil.c === */
158
// ##################################################################
159
// NOTE: We should check the following definitions fit to the source.
160
// ##################################################################
163
/** File node of a tablespace or the log data space */
164
struct fil_node_struct {
165
fil_space_t* space; /*!< backpointer to the space where this node
167
char* name; /*!< path to the file */
168
ibool open; /*!< TRUE if file open */
169
os_file_t handle; /*!< OS handle to the file, if file open */
170
ibool is_raw_disk;/*!< TRUE if the 'file' is actually a raw
171
device or a raw disk partition */
172
ulint size; /*!< size of the file in database pages, 0 if
173
not known yet; the possible last incomplete
174
megabyte may be ignored if space == 0 */
176
/*!< count of pending i/o's on this file;
177
closing of the file is not allowed if
179
ulint n_pending_flushes;
180
/*!< count of pending flushes on this file;
181
closing of the file is not allowed if
183
ib_int64_t modification_counter;/*!< when we write to the file we
184
increment this by one */
185
ib_int64_t flush_counter;/*!< up to what
186
modification_counter value we have
187
flushed the modifications to disk */
188
UT_LIST_NODE_T(fil_node_t) chain;
189
/*!< link field for the file chain */
190
UT_LIST_NODE_T(fil_node_t) LRU;
191
/*!< link field for the LRU list */
192
ulint magic_n;/*!< FIL_NODE_MAGIC_N */
195
struct fil_space_struct {
196
char* name; /*!< space name = the path to the first file in
198
ulint id; /*!< space id */
199
ib_int64_t tablespace_version;
200
/*!< in DISCARD/IMPORT this timestamp
201
is used to check if we should ignore
202
an insert buffer merge request for a
203
page because it actually was for the
204
previous incarnation of the space */
205
ibool mark; /*!< this is set to TRUE at database startup if
206
the space corresponds to a table in the InnoDB
207
data dictionary; so we can print a warning of
208
orphaned tablespaces */
209
ibool stop_ios;/*!< TRUE if we want to rename the
210
.ibd file of tablespace and want to
211
stop temporarily posting of new i/o
212
requests on the file */
213
ibool stop_ibuf_merges;
214
/*!< we set this TRUE when we start
215
deleting a single-table tablespace */
216
ibool is_being_deleted;
217
/*!< this is set to TRUE when we start
218
deleting a single-table tablespace and its
219
file; when this flag is set no further i/o
220
or flush requests can be placed on this space,
221
though there may be such requests still being
222
processed on this space */
223
ulint purpose;/*!< FIL_TABLESPACE, FIL_LOG, or
225
UT_LIST_BASE_NODE_T(fil_node_t) chain;
226
/*!< base node for the file chain */
227
ulint size; /*!< space size in pages; 0 if a single-table
228
tablespace whose size we do not know yet;
229
last incomplete megabytes in data files may be
230
ignored if space == 0 */
231
ulint flags; /*!< compressed page size and file format, or 0 */
232
ulint n_reserved_extents;
233
/*!< number of reserved free extents for
234
ongoing operations like B-tree page split */
235
ulint n_pending_flushes; /*!< this is positive when flushing
236
the tablespace to disk; dropping of the
237
tablespace is forbidden if this is positive */
238
ulint n_pending_ibuf_merges;/*!< this is positive
239
when merging insert buffer entries to
240
a page so that we may need to access
241
the ibuf bitmap page in the
242
tablespade: dropping of the tablespace
243
is forbidden if this is positive */
244
hash_node_t hash; /*!< hash chain node */
245
hash_node_t name_hash;/*!< hash chain the name_hash table */
246
#ifndef UNIV_HOTBACKUP
247
rw_lock_t latch; /*!< latch protecting the file space storage
249
#endif /* !UNIV_HOTBACKUP */
250
UT_LIST_NODE_T(fil_space_t) unflushed_spaces;
251
/*!< list of spaces with at least one unflushed
252
file we have written to */
253
ibool is_in_unflushed_spaces; /*!< TRUE if this space is
254
currently in unflushed_spaces */
258
UT_LIST_NODE_T(fil_space_t) space_list;
259
/*!< list of all spaces */
260
ulint magic_n;/*!< FIL_SPACE_MAGIC_N */
263
typedef struct fil_system_struct fil_system_t;
265
struct fil_system_struct {
266
#ifndef UNIV_HOTBACKUP
267
mutex_t mutex; /*!< The mutex protecting the cache */
269
mutex_t file_extend_mutex;
271
#endif /* !UNIV_HOTBACKUP */
272
hash_table_t* spaces; /*!< The hash table of spaces in the
273
system; they are hashed on the space
275
hash_table_t* name_hash; /*!< hash table based on the space
277
UT_LIST_BASE_NODE_T(fil_node_t) LRU;
278
/*!< base node for the LRU list of the
279
most recently used open files with no
280
pending i/o's; if we start an i/o on
281
the file, we first remove it from this
282
list, and return it to the start of
283
the list when the i/o ends;
284
log files and the system tablespace are
285
not put to this list: they are opened
286
after the startup, and kept open until
288
UT_LIST_BASE_NODE_T(fil_space_t) unflushed_spaces;
289
/*!< base node for the list of those
290
tablespaces whose files contain
291
unflushed writes; those spaces have
292
at least one file node where
293
modification_counter > flush_counter */
294
ulint n_open; /*!< number of files currently open */
295
ulint max_n_open; /*!< n_open is not allowed to exceed
297
ib_int64_t modification_counter;/*!< when we write to a file we
298
increment this by one */
299
ulint max_assigned_id;/*!< maximum space id in the existing
300
tables, or assigned during the time
301
mysqld has been up; at an InnoDB
302
startup we scan the data dictionary
303
and set here the maximum of the
304
space id's of the tables there */
305
ib_int64_t tablespace_version;
306
/*!< a counter which is incremented for
307
every space object memory creation;
308
every space mem object gets a
309
'timestamp' from this; in DISCARD/
310
IMPORT this is used to check if we
311
should ignore an insert buffer merge
313
UT_LIST_BASE_NODE_T(fil_space_t) space_list;
314
/*!< list of all file spaces */
321
extern fil_system_t* fil_system;
323
/* ==end=== definition at fil0fil.c === */
326
bool innodb_inited= 0;
328
/* === xtrabackup specific options === */
329
char xtrabackup_real_target_dir[FN_REFLEN] = "./xtrabackup_backupfiles/";
330
const char *xtrabackup_target_dir= xtrabackup_real_target_dir;
331
bool xtrabackup_backup = false;
332
bool xtrabackup_stats = false;
333
bool xtrabackup_prepare = false;
334
bool xtrabackup_print_param = false;
336
bool xtrabackup_export = false;
337
bool xtrabackup_apply_log_only = false;
339
bool xtrabackup_suspend_at_end = false;
340
uint64_t xtrabackup_use_memory = 100*1024*1024L;
341
bool xtrabackup_create_ib_logfile = false;
343
long xtrabackup_throttle = 0; /* 0:unlimited */
345
os_event_t wait_throttle = NULL;
347
bool xtrabackup_stream = false;
348
const char *xtrabackup_incremental = NULL;
349
LSN64 incremental_lsn;
350
LSN64 incremental_to_lsn;
351
LSN64 incremental_last_lsn;
352
byte* incremental_buffer = NULL;
353
byte* incremental_buffer_base = NULL;
355
const char *xtrabackup_incremental_basedir = NULL; /* for --backup */
356
const char *xtrabackup_extra_lsndir = NULL; /* for --backup with --extra-lsndir */
357
char *xtrabackup_incremental_dir = NULL; /* for --prepare */
359
char *xtrabackup_tables = NULL;
360
int tables_regex_num;
361
regex_t *tables_regex;
362
regmatch_t tables_regmatch[1];
364
const char *xtrabackup_tables_file = NULL;
365
hash_table_t* tables_hash;
367
struct xtrabackup_tables_struct{
369
hash_node_t name_hash;
371
typedef struct xtrabackup_tables_struct xtrabackup_tables_t;
374
static ulint thread_nr[SRV_MAX_N_IO_THREADS + 6 + 64];
375
static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 6 + 64];
377
static ulint thread_nr[SRV_MAX_N_IO_THREADS + 6];
378
static os_thread_id_t thread_ids[SRV_MAX_N_IO_THREADS + 6];
381
LSN64 checkpoint_lsn_start;
382
LSN64 checkpoint_no_start;
383
LSN64 log_copy_scanned_lsn;
384
IB_INT64 log_copy_offset = 0;
385
ibool log_copying = TRUE;
386
ibool log_copying_running = FALSE;
387
ibool log_copying_succeed = FALSE;
389
ibool xtrabackup_logfile_is_renamed = FALSE;
393
/* === metadata of backup === */
394
#define XTRABACKUP_METADATA_FILENAME "xtrabackup_checkpoints"
395
char metadata_type[30] = ""; /*[full-backuped|full-prepared|incremental]*/
397
ib_uint64_t metadata_from_lsn = 0;
398
ib_uint64_t metadata_to_lsn = 0;
399
ib_uint64_t metadata_last_lsn = 0;
401
#define XB_DELTA_INFO_SUFFIX ".meta"
403
/* === sharing with thread === */
404
os_file_t dst_log = -1;
405
char dst_log_path[FN_REFLEN];
407
/* === some variables from mysqld === */
408
char mysql_real_data_home[FN_REFLEN] = "./";
409
char *mysql_data_home= mysql_real_data_home;
410
std::string mysql_data_home_arg;
411
static char mysql_data_home_buff[2];
413
const char *opt_mysql_tmpdir = NULL;
415
/* === static parameters in ha_innodb.cc */
417
#define HA_INNOBASE_ROWS_IN_TABLE 10000 /* to get optimization right */
418
#define HA_INNOBASE_RANGE_COUNT 100
420
ulong innobase_large_page_size = 0;
422
/* The default values for the following, type long or longlong, start-up
423
parameters are declared in mysqld.cc: */
425
long innobase_additional_mem_pool_size = 1*1024*1024L;
426
long innobase_buffer_pool_awe_mem_mb = 0;
427
long innobase_file_io_threads = 4;
428
long innobase_read_io_threads = 4;
429
long innobase_write_io_threads = 4;
430
long innobase_force_recovery = 0;
431
long innobase_lock_wait_timeout = 50;
432
long innobase_log_buffer_size = 1024*1024L;
433
long innobase_log_files_in_group = 2;
434
long innobase_log_files_in_group_backup;
435
long innobase_mirrored_log_groups = 1;
436
long innobase_open_files = 300L;
438
long innobase_page_size = (1 << 14); /* 16KB */
439
static ulong innobase_log_block_size = 512;
440
bool innobase_fast_checksum = false;
441
bool innobase_extra_undoslots = false;
442
char* innobase_doublewrite_file = NULL;
444
uint64_t innobase_buffer_pool_size = 8*1024*1024L;
446
typedef constrained_check<int64_t, INT64_MAX, 1024*1024, 1024*1024> log_file_constraint;
447
static log_file_constraint innobase_log_file_size;
449
uint64_t innobase_log_file_size_backup;
451
/* The default values for the following char* start-up parameters
452
are determined in innobase_init below: */
454
char* innobase_data_home_dir = NULL;
455
const char* innobase_data_file_path = NULL;
456
char* innobase_log_group_home_dir = NULL;
457
char* innobase_log_group_home_dir_backup = NULL;
458
char* innobase_log_arch_dir = NULL;/* unused */
459
/* The following has a misleading name: starting from 4.0.5, this also
461
char* innobase_unix_file_flush_method = NULL;
463
/* Below we have boolean-valued start-up parameters, and their default
466
ulong innobase_fast_shutdown = 1;
467
bool innobase_log_archive = FALSE;/* unused */
468
bool innobase_use_doublewrite = TRUE;
469
bool innobase_use_checksums = TRUE;
470
bool innobase_use_large_pages = FALSE;
471
bool innobase_file_per_table = FALSE;
472
bool innobase_locks_unsafe_for_binlog = FALSE;
473
bool innobase_rollback_on_timeout = FALSE;
474
bool innobase_create_status_file = FALSE;
475
bool innobase_adaptive_hash_index = TRUE;
477
static char *internal_innobase_data_file_path = NULL;
479
/* The following counter is used to convey information to InnoDB
480
about server activity: in selects it is not sensible to call
481
srv_active_wake_master_thread after each fetch or search, we only do
482
it every INNOBASE_WAKE_INTERVAL'th step. */
484
#define INNOBASE_WAKE_INTERVAL 32
485
ulong innobase_active_counter = 0;
493
return my_isspace(static_cast<const CHARSET_INFO *>(cs), char_to_test);
498
innobase_rec_to_mysql(
501
const dict_index_t* ,
506
innobase_rec_to_mysql(
507
/*==================*/
508
Table* , /*!< in/out: MySQL table */
509
const rec_t* , /*!< in: record */
510
const dict_index_t* , /*!< in: index */
511
const ulint* ) /*!< in: rec_get_offsets(
514
fprintf(stderr, "ERROR: innobase_rec_to_mysql called\n");
520
innobase_rec_reset(Table*);
526
Table* ) /*!< in/out: MySQL table */
528
fprintf(stderr, "ERROR: innobase_rec_reset called\n");
534
thd_set_lock_wait_time(
535
/*===================*/
536
drizzled::Session* , /*!< in: thread handle (THD*) */
537
ulint ); /*!< in: time waited for the lock */
541
thd_set_lock_wait_time(
542
/*===================*/
543
drizzled::Session* , /*!< in: thread handle (THD*) */
544
ulint ) /*!< in: time waited for the lock */
551
/* ======== Datafiles iterator ======== */
553
fil_system_t *system;
562
datafiles_iter_new(fil_system_t *f_system)
564
datafiles_iter_t *it;
566
it = (datafiles_iter_t*) ut_malloc(sizeof(datafiles_iter_t));
567
it->mutex = OS_MUTEX_CREATE();
569
it->system = f_system;
579
datafiles_iter_next(datafiles_iter_t *it, ibool *space_changed)
581
os_mutex_enter(it->mutex);
583
*space_changed = FALSE;
585
if (it->node == NULL) {
590
it->node = UT_LIST_GET_NEXT(chain, it->node);
591
if (it->node != NULL)
595
it->space = (it->space == NULL) ?
596
UT_LIST_GET_FIRST(it->system->space_list) :
597
UT_LIST_GET_NEXT(space_list, it->space);
599
while (it->space != NULL &&
600
(it->space->purpose != FIL_TABLESPACE ||
601
UT_LIST_GET_LEN(it->space->chain) == 0))
602
it->space = UT_LIST_GET_NEXT(space_list, it->space);
603
if (it->space == NULL)
605
*space_changed = TRUE;
607
it->node = UT_LIST_GET_FIRST(it->space->chain);
610
os_mutex_exit(it->mutex);
617
datafiles_iter_free(datafiles_iter_t *it)
619
os_mutex_free(it->mutex);
623
/* ======== Date copying thread context ======== */
626
datafiles_iter_t *it;
629
os_mutex_t count_mutex;
631
} data_thread_ctxt_t;
633
static void print_version(void)
635
printf("%s Ver %s Rev %s for %s %s (%s)\n" ,my_progname,
636
XTRABACKUP_VERSION, XTRABACKUP_REVISION, "Drizzle7",
637
TARGET_OS, TARGET_CPU);
640
static void usage(void)
642
puts("Open source backup tool for InnoDB and XtraDB\n\
644
Copyright (C) 2009 Percona Inc.\n\
646
This program is free software; you can redistribute it and/or\n\
647
modify it under the terms of the GNU General Public License\n\
648
as published by the Free Software Foundation version 2\n\
651
This program is distributed in the hope that it will be useful,\n\
652
but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
653
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
654
GNU General Public License for more details.\n\
656
You can download full text of the license on http://www.gnu.org/licenses/gpl-2.0.txt\n");
658
printf("Usage: [%s [--defaults-file=#] --backup | %s [--defaults-file=#] --prepare] [OPTIONS]\n",my_progname,my_progname);
659
// FIXME: print what variables we have
662
/* ================ Dummys =================== */
666
thd_is_replication_slave_thread(
667
/*============================*/
668
drizzled::Session* ) /*!< in: thread handle (Session*) */
670
fprintf(stderr, "xtrabackup: thd_is_replication_slave_thread() is called\n");
676
thd_has_edited_nontrans_tables(
677
/*===========================*/
678
drizzled::Session *) /*!< in: thread handle (Session*) */
680
fprintf(stderr, "xtrabackup: thd_has_edited_nontrans_tables() is called\n");
688
const drizzled::Session *) /*!< in: thread handle (Session*) */
690
fprintf(stderr, "xtrabackup: thd_is_select() is called\n");
696
innobase_mysql_print_thd(
701
fprintf(stderr, "xtrabackup: innobase_mysql_print_thd() is called\n");
705
innobase_get_cset_width(
715
cs = all_charsets[cset];
717
*mbminlen = cs->mbminlen;
718
*mbmaxlen = cs->mbmaxlen;
721
*mbminlen = *mbmaxlen = 0;
727
innobase_convert_from_table_id(
728
/*===========================*/
729
const void*, /*!< in: the 'from' character set */
730
char* , /*!< out: converted identifier */
731
const char* , /*!< in: identifier to convert */
732
ulint ) /*!< in: length of 'to', in bytes */
734
fprintf(stderr, "xtrabackup: innobase_convert_from_table_id() is called\n");
739
innobase_convert_from_id(
740
/*=====================*/
741
const void*, /*!< in: the 'from' character set */
742
char* , /*!< out: converted identifier */
743
const char* , /*!< in: identifier to convert */
744
ulint ) /*!< in: length of 'to', in bytes */
746
fprintf(stderr, "xtrabackup: innobase_convert_from_id() is called\n");
754
return(my_strcasecmp(&my_charset_utf8_general_ci, a, b));
761
my_casedn_str(&my_charset_utf8_general_ci, a);
768
drizzled::Session *, /*!< in: MySQL thread handle */
769
size_t* ) /*!< out: length of the SQL statement */
771
fprintf(stderr, "xtrabackup: innobase_get_stmt() is called\n");
776
innobase_mysql_tmpfile(void)
778
char filename[FN_REFLEN];
780
int fd = internal::create_temp_file(filename, opt_mysql_tmpdir,
783
O_BINARY | O_TRUNC | O_SEQUENTIAL |
784
O_TEMPORARY | O_SHORT_LIVED |
786
O_CREAT | O_EXCL | O_RDWR);
789
/* On Windows, open files cannot be removed, but files can be
790
created with the O_TEMPORARY flag to the same effect
791
("delete on close"). */
793
#endif /* !__WIN__ */
794
/* Copy the file descriptor, so that the additional resources
795
allocated by create_temp_file() can be freed by invoking
798
Because the file descriptor returned by this function
799
will be passed to fdopen(), it will be closed by invoking
800
fclose(), which in turn will invoke close() instead of
804
fprintf(stderr, "xtrabackup: Got error %d on dup\n",fd2);
812
innobase_invalidate_query_cache(
820
/*****************************************************************//**
821
Convert an SQL identifier to the MySQL system_charset_info (UTF-8)
822
and quote it if needed.
823
@return pointer to the end of buf */
826
innobase_convert_identifier(
827
/*========================*/
828
char* buf, /*!< out: buffer for converted identifier */
829
ulint buflen, /*!< in: length of buf, in bytes */
830
const char* id, /*!< in: identifier to convert */
831
ulint idlen, /*!< in: length of id, in bytes */
832
void* , /*!< in: MySQL connection thread, or NULL */
833
ibool )/*!< in: TRUE=id is a table or database name;
834
FALSE=id is an UTF-8 string */
839
/* See if the identifier needs to be quoted. */
843
if (UNIV_UNLIKELY(idlen > buflen)) {
846
memcpy(buf, s, idlen);
850
/* Quote the identifier. */
858
for (; idlen; idlen--) {
860
if (UNIV_UNLIKELY(c == q)) {
861
if (UNIV_UNLIKELY(buflen < 3)) {
869
if (UNIV_UNLIKELY(buflen < 2)) {
882
/*****************************************************************//**
883
Convert a table or index name to the MySQL system_charset_info (UTF-8)
884
and quote it if needed.
885
@return pointer to the end of buf */
888
innobase_convert_name(
889
/*==================*/
890
char* buf, /*!< out: buffer for converted identifier */
891
ulint buflen, /*!< in: length of buf, in bytes */
892
const char* id, /*!< in: identifier to convert */
893
ulint idlen, /*!< in: length of id, in bytes */
894
drizzled::Session *session,/*!< in: MySQL connection thread, or NULL */
895
ibool table_id)/*!< in: TRUE=id is a table or database name;
896
FALSE=id is an index name */
899
const char* bufend = buf + buflen;
902
const char* slash = (const char*) memchr(id, '/', idlen);
908
/* Print the database name and table name separately. */
909
s = innobase_convert_identifier(s, bufend - s, id, slash - id,
911
if (UNIV_LIKELY(s < bufend)) {
913
s = innobase_convert_identifier(s, bufend - s,
918
} else if (UNIV_UNLIKELY(*id == TEMP_INDEX_PREFIX)) {
919
/* Temporary index name (smart ALTER TABLE) */
920
const char temp_index_suffix[]= "--temporary--";
922
s = innobase_convert_identifier(buf, buflen, id + 1, idlen - 1,
924
if (s - buf + (sizeof temp_index_suffix - 1) < buflen) {
925
memcpy(s, temp_index_suffix,
926
sizeof temp_index_suffix - 1);
927
s += sizeof temp_index_suffix - 1;
931
s = innobase_convert_identifier(buf, buflen, id, idlen,
943
/* There are no mysql_thd */
950
int mysql_type, /*!< in: MySQL type */
951
uint charset_number, /*!< in: number of the charset */
952
const unsigned char* a, /*!< in: data field */
953
unsigned int a_length, /*!< in: data field length,
955
const unsigned char* b, /* in: data field */
956
unsigned int b_length); /* in: data field length,
962
/* out: 1, 0, -1, if a is greater, equal, less than b, respectively */
963
int mysql_type, /* in: MySQL type */
964
uint charset_number, /* in: number of the charset */
965
const unsigned char* a, /* in: data field */
966
unsigned int a_length, /* in: data field length, not UNIV_SQL_NULL */
967
const unsigned char* b, /* in: data field */
968
unsigned int b_length) /* in: data field length, not UNIV_SQL_NULL */
970
const CHARSET_INFO* charset;
971
enum_field_types mysql_tp;
974
assert(a_length != UNIV_SQL_NULL);
975
assert(b_length != UNIV_SQL_NULL);
977
mysql_tp = (enum_field_types) mysql_type;
981
case DRIZZLE_TYPE_BLOB:
982
case DRIZZLE_TYPE_VARCHAR:
983
/* Use the charset number to pick the right charset struct for
984
the comparison. Since the MySQL function get_charset may be
985
slow before Bar removes the mutex operation there, we first
986
look at 2 common charsets directly. */
988
if (charset_number == default_charset_info->number) {
989
charset = default_charset_info;
991
charset = get_charset(charset_number);
993
if (charset == NULL) {
994
fprintf(stderr, "xtrabackup needs charset %lu for doing "
995
"a comparison, but MySQL cannot "
996
"find that charset.",
997
(ulong) charset_number);
1002
/* Starting from 4.1.3, we use strnncollsp() in comparisons of
1003
non-latin1_swedish_ci strings. NOTE that the collation order
1004
changes then: 'b\0\0...' is ordered BEFORE 'b ...'. Users
1005
having indexes on such data need to rebuild their tables! */
1007
ret = charset->coll->strnncollsp(charset,
1012
} else if (ret > 0) {
1025
innobase_get_at_most_n_mbchars(
1031
ulint char_length; /* character length in bytes */
1032
ulint n_chars; /* number of characters in prefix */
1033
const CHARSET_INFO* charset; /* charset used in the field */
1035
charset = get_charset((uint) charset_id);
1038
ut_ad(charset->mbmaxlen);
1040
/* Calculate how many characters at most the prefix index contains */
1042
n_chars = prefix_len / charset->mbmaxlen;
1044
/* If the charset is multi-byte, then we must find the length of the
1045
first at most n chars in the string. If the string contains less
1046
characters than n, then we return the length to the end of the last
1049
if (charset->mbmaxlen > 1) {
1050
/* my_charpos() returns the byte length of the first n_chars
1051
characters, or a value bigger than the length of str, if
1052
there were not enough full characters in str.
1054
Why does the code below work:
1055
Suppose that we are looking for n UTF-8 characters.
1057
1) If the string is long enough, then the prefix contains at
1058
least n complete UTF-8 characters + maybe some extra
1059
characters + an incomplete UTF-8 character. No problem in
1060
this case. The function returns the pointer to the
1061
end of the nth character.
1063
2) If the string is not long enough, then the string contains
1064
the complete value of a column, that is, only complete UTF-8
1065
characters, and we can store in the column prefix index the
1068
char_length = my_charpos(charset, str,
1069
str + data_len, (int) n_chars);
1070
if (char_length > data_len) {
1071
char_length = data_len;
1074
if (data_len < prefix_len) {
1075
char_length = data_len;
1077
char_length = prefix_len;
1081
return(char_length);
1086
innobase_raw_format(
1087
/*================*/
1088
const char* , /*!< in: raw data */
1089
ulint , /*!< in: raw data length
1091
ulint , /*!< in: charset collation */
1092
char* , /*!< out: output buffer */
1093
ulint ) /*!< in: output buffer size
1096
fprintf(stderr, "xtrabackup: innobase_raw_format() is called\n");
1102
thd_lock_wait_timeout(
1103
/*==================*/
1104
drizzled::Session*) /*!< in: thread handle (Session*), or NULL to query
1105
the global innodb_lock_wait_timeout */
1107
return(innobase_lock_wait_timeout);
1114
drizzled::Session* ) /*!< in: thread handle (Session*), or NULL to query
1115
the global innodb_supports_xa */
1123
trx_t*) /*!< in: transaction */
1136
innobase_get_slow_log()
1142
/***********************************************************************
1143
Computes bit shift for a given value. If the argument is not a power
1147
get_bit_shift(ulint value)
1154
for (shift = 0; !(value & 1UL); shift++) {
1157
return (value >> 1) ? 0 : shift;
1161
innodb_init_param(void)
1164
static char current_dir[3]; /* Set if using current lib */
1168
/* dummy for initialize all_charsets[] */
1169
get_charset_name(0);
1173
srv_page_size_shift = 0;
1175
if (innobase_page_size != (1 << 14)) {
1176
int n_shift = get_bit_shift(innobase_page_size);
1178
if (n_shift >= 12 && n_shift <= UNIV_PAGE_SIZE_SHIFT_MAX) {
1180
"InnoDB: Warning: innodb_page_size has been "
1181
"changed from default value 16384.\n");
1182
srv_page_size_shift = n_shift;
1183
srv_page_size = 1 << n_shift;
1185
"InnoDB: The universal page size of the "
1186
"database is set to %lu.\n", srv_page_size);
1188
fprintf(stderr, "InnoDB: Error: invalid value of "
1189
"innobase_page_size: %lu", innobase_page_size);
1193
srv_page_size_shift = 14;
1194
srv_page_size = (1 << srv_page_size_shift);
1197
srv_log_block_size = 0;
1198
if (innobase_log_block_size != 512) {
1199
uint n_shift = get_bit_shift(innobase_log_block_size);;
1202
"InnoDB: Warning: innodb_log_block_size has "
1203
"been changed from its default value. "
1204
"(###EXPERIMENTAL### operation)\n");
1206
srv_log_block_size = (1 << n_shift);
1208
"InnoDB: The log block size is set to %lu.\n",
1209
srv_log_block_size);
1212
srv_log_block_size = 512;
1215
if (!srv_log_block_size) {
1217
"InnoDB: Error: %lu is not valid value for "
1218
"innodb_log_block_size.\n", innobase_log_block_size);
1222
srv_fast_checksum = (ibool) innobase_fast_checksum;
1225
/* Check that values don't overflow on 32-bit systems. */
1226
if (sizeof(ulint) == 4) {
1227
if (xtrabackup_use_memory > UINT32_MAX) {
1229
"xtrabackup: use-memory can't be over 4GB"
1230
" on 32-bit systems\n");
1233
if (innobase_buffer_pool_size > UINT32_MAX) {
1235
"xtrabackup: innobase_buffer_pool_size can't be over 4GB"
1236
" on 32-bit systems\n");
1241
if (innobase_log_file_size > UINT32_MAX) {
1243
"xtrabackup: innobase_log_file_size can't be over 4GB"
1244
" on 32-bit systemsi\n");
1250
os_innodb_umask = (ulint)0664;
1252
/* First calculate the default path for innodb_data_home_dir etc.,
1253
in case the user has not given any value.
1255
Note that when using the embedded server, the datadirectory is not
1256
necessarily the current directory of this program. */
1258
/* It's better to use current lib, to keep paths short */
1259
current_dir[0] = FN_CURLIB;
1260
current_dir[1] = FN_LIBCHAR;
1262
default_path = current_dir;
1266
/* Set InnoDB initialization parameters according to the values
1267
read from MySQL .cnf file */
1269
if (xtrabackup_backup || xtrabackup_stats) {
1270
fprintf(stderr, "xtrabackup: Target instance is assumed as followings.\n");
1272
fprintf(stderr, "xtrabackup: Temporary instance for recovery is set as followings.\n");
1275
/*--------------- Data files -------------------------*/
1277
/* The default dir for data files is the datadir of MySQL */
1279
srv_data_home = ((xtrabackup_backup || xtrabackup_stats) && innobase_data_home_dir
1280
? innobase_data_home_dir : default_path);
1281
fprintf(stderr, "xtrabackup: innodb_data_home_dir = %s\n", srv_data_home);
1283
/* Set default InnoDB data file size to 10 MB and let it be
1284
auto-extending. Thus users can use InnoDB in >= 4.0 without having
1285
to specify any startup options. */
1287
if (!innobase_data_file_path) {
1288
innobase_data_file_path = (char*) "ibdata1:10M:autoextend";
1290
fprintf(stderr, "xtrabackup: innodb_data_file_path = %s\n",
1291
innobase_data_file_path);
1293
/* Since InnoDB edits the argument in the next call, we make another
1296
internal_innobase_data_file_path = strdup(innobase_data_file_path);
1298
ret = (bool) srv_parse_data_file_paths_and_sizes(
1299
internal_innobase_data_file_path);
1302
"xtrabackup: syntax error in innodb_data_file_path\n");
1304
free(internal_innobase_data_file_path);
1308
if (xtrabackup_prepare) {
1309
/* "--prepare" needs filenames only */
1312
for (i=0; i < srv_n_data_files; i++) {
1315
p = srv_data_file_names[i];
1316
while ((p = strstr(p, SRV_PATH_SEPARATOR_STR)) != NULL)
1319
srv_data_file_names[i] = p;
1325
srv_doublewrite_file = innobase_doublewrite_file;
1327
srv_extra_undoslots = (ibool) innobase_extra_undoslots;
1331
/* -------------- Log files ---------------------------*/
1333
/* The default dir for log files is the datadir of MySQL */
1335
if (!((xtrabackup_backup || xtrabackup_stats) && innobase_log_group_home_dir)) {
1336
innobase_log_group_home_dir = default_path;
1338
if (xtrabackup_prepare && xtrabackup_incremental_dir) {
1339
innobase_log_group_home_dir = xtrabackup_incremental_dir;
1341
fprintf(stderr, "xtrabackup: innodb_log_group_home_dir = %s\n",
1342
innobase_log_group_home_dir);
1344
#ifdef UNIV_LOG_ARCHIVE
1345
/* Since innodb_log_arch_dir has no relevance under MySQL,
1346
starting from 4.0.6 we always set it the same as
1347
innodb_log_group_home_dir: */
1349
innobase_log_arch_dir = innobase_log_group_home_dir;
1351
srv_arch_dir = innobase_log_arch_dir;
1352
#endif /* UNIG_LOG_ARCHIVE */
1355
srv_parse_log_group_home_dirs(innobase_log_group_home_dir);
1357
if (ret == FALSE || innobase_mirrored_log_groups != 1) {
1358
fprintf(stderr, "xtrabackup: syntax error in innodb_log_group_home_dir, or a "
1359
"wrong number of mirrored log groups\n");
1361
goto mem_free_and_error;
1364
srv_adaptive_flushing = FALSE;
1365
srv_use_sys_malloc = TRUE;
1366
srv_file_format = 1; /* Barracuda */
1367
srv_max_file_format_at_startup = DICT_TF_FORMAT_51; /* on */
1369
/* --------------------------------------------------*/
1371
srv_file_flush_method_str = innobase_unix_file_flush_method;
1373
srv_n_log_groups = (ulint) innobase_mirrored_log_groups;
1374
srv_n_log_files = (ulint) innobase_log_files_in_group;
1375
srv_log_file_size = (ulint) innobase_log_file_size;
1376
fprintf(stderr, "xtrabackup: innodb_log_files_in_group = %ld\n",
1378
fprintf(stderr, "xtrabackup: innodb_log_file_size = %ld\n",
1381
#ifdef UNIV_LOG_ARCHIVE
1382
srv_log_archive_on = (ulint) innobase_log_archive;
1383
#endif /* UNIV_LOG_ARCHIVE */
1384
srv_log_buffer_size = (ulint) innobase_log_buffer_size;
1386
/* We set srv_pool_size here in units of 1 kB. InnoDB internally
1387
changes the value so that it becomes the number of database pages. */
1389
//srv_buf_pool_size = (ulint) innobase_buffer_pool_size;
1390
srv_buf_pool_size = (ulint) xtrabackup_use_memory;
1392
srv_mem_pool_size = (ulint) innobase_additional_mem_pool_size;
1394
srv_n_file_io_threads = (ulint) innobase_file_io_threads;
1396
srv_n_read_io_threads = (ulint) innobase_read_io_threads;
1397
srv_n_write_io_threads = (ulint) innobase_write_io_threads;
1399
srv_force_recovery = (ulint) innobase_force_recovery;
1401
srv_use_doublewrite_buf = (ibool) innobase_use_doublewrite;
1402
srv_use_checksums = (ibool) innobase_use_checksums;
1404
btr_search_enabled = innobase_adaptive_hash_index ? true : false;
1406
os_use_large_pages = (ibool) innobase_use_large_pages;
1407
os_large_page_size = (ulint) innobase_large_page_size;
1409
row_rollback_on_timeout = (ibool) innobase_rollback_on_timeout;
1411
srv_file_per_table = innobase_file_per_table ? true : false;
1413
srv_locks_unsafe_for_binlog = (ibool) innobase_locks_unsafe_for_binlog;
1415
srv_max_n_open_files = (ulint) innobase_open_files;
1416
srv_innodb_status = (ibool) innobase_create_status_file;
1418
srv_print_verbose_log = 1;
1420
/* Store the default charset-collation number of this MySQL
1423
/* We cannot treat characterset here for now!! */
1424
data_mysql_default_charset_coll = (ulint)default_charset_info->number;
1426
ut_a(DATA_MYSQL_BINARY_CHARSET_COLL == my_charset_bin.number);
1428
//innobase_commit_concurrency_init_default();
1430
/* Since we in this module access directly the fields of a trx
1431
struct, and due to different headers and flags it might happen that
1432
mutex_t has a different size in this module and in InnoDB
1433
modules, we check at run time that the size is the same in
1434
these compilation modules. */
1437
/* On 5.5 srv_use_native_aio is TRUE by default. It is later reset
1438
if it is not supported by the platform in
1439
innobase_start_or_create_for_mysql(). As we don't call it in xtrabackup,
1440
we have to duplicate checks from that function here. */
1443
switch (os_get_os_version()) {
1447
/* On Win 95, 98, ME, Win32 subsystem for Windows 3.1,
1448
and NT use simulated aio. In NT Windows provides async i/o,
1449
but when run in conjunction with InnoDB Hot Backup, it seemed
1450
to corrupt the data files. */
1452
srv_use_native_aio = FALSE;
1457
/* On 2000 and XP, async IO is available. */
1458
srv_use_native_aio = TRUE;
1462
/* Vista and later have both async IO and condition variables */
1463
srv_use_native_aio = TRUE;
1464
srv_use_native_conditions = TRUE;
1468
#elif defined(LINUX_NATIVE_AIO)
1470
if (srv_use_native_aio) {
1471
ut_print_timestamp(stderr);
1473
" InnoDB: Using Linux native AIO\n");
1476
/* Currently native AIO is supported only on windows and linux
1477
and that also when the support is compiled in. In all other
1478
cases, we ignore the setting of innodb_use_native_aio. */
1479
srv_use_native_aio = FALSE;
1486
fprintf(stderr, "xtrabackup: innodb_init_param(): Error occured.\n");
1495
err = innobase_start_or_create_for_mysql();
1497
if (err != DB_SUCCESS) {
1498
free(internal_innobase_data_file_path);
1502
/* They may not be needed for now */
1503
// (void) hash_init(&innobase_open_tables,system_charset_info, 32, 0, 0,
1504
// (hash_get_key) innobase_get_key, 0, 0);
1505
// pthread_mutex_init(&innobase_share_mutex, MY_MUTEX_INIT_FAST);
1506
// pthread_mutex_init(&prepare_commit_mutex, MY_MUTEX_INIT_FAST);
1507
// pthread_mutex_init(&commit_threads_m, MY_MUTEX_INIT_FAST);
1508
// pthread_mutex_init(&commit_cond_m, MY_MUTEX_INIT_FAST);
1509
// pthread_cond_init(&commit_cond, NULL);
1516
fprintf(stderr, "xtrabackup: innodb_init(): Error occured.\n");
1523
srv_fast_shutdown = (ulint) innobase_fast_shutdown;
1526
fprintf(stderr, "xtrabackup: starting shutdown with innodb_fast_shutdown = %lu\n",
1529
if (innobase_shutdown_for_mysql() != DB_SUCCESS) {
1532
free(internal_innobase_data_file_path);
1534
/* They may not be needed for now */
1535
// hash_free(&innobase_open_tables);
1536
// pthread_mutex_destroy(&innobase_share_mutex);
1537
// pthread_mutex_destroy(&prepare_commit_mutex);
1538
// pthread_mutex_destroy(&commit_threads_m);
1539
// pthread_mutex_destroy(&commit_cond_m);
1540
// pthread_cond_destroy(&commit_cond);
1545
fprintf(stderr, "xtrabackup: innodb_end(): Error occured.\n");
1549
/* ================= common ================= */
1551
xtrabackup_read_metadata(char *filename)
1555
fp = fopen(filename,"r");
1557
fprintf(stderr, "xtrabackup: Error: cannot open %s\n", filename);
1561
if (fscanf(fp, "backup_type = %29s\n", metadata_type)
1564
if (fscanf(fp, "from_lsn = %"PRIu64"\n", &metadata_from_lsn)
1567
if (fscanf(fp, "to_lsn = %"PRIu64"\n", &metadata_to_lsn)
1570
if (fscanf(fp, "last_lsn = %"PRIu64"\n", &metadata_last_lsn)
1572
metadata_last_lsn = 0;
1581
xtrabackup_write_metadata(char *filename)
1585
fp = fopen(filename,"w");
1587
fprintf(stderr, "xtrabackup: Error: cannot open %s\n", filename);
1591
if (fprintf(fp, "backup_type = %s\n", metadata_type)
1594
if (fprintf(fp, "from_lsn = %"PRIu64"\n", metadata_from_lsn)
1597
if (fprintf(fp, "to_lsn = %"PRIu64"\n", metadata_to_lsn)
1600
if (fprintf(fp, "last_lsn = %"PRIu64"\n", metadata_last_lsn)
1609
/***********************************************************************
1610
Read meta info for an incremental delta.
1611
@return TRUE on success, FALSE on failure. */
1613
xb_read_delta_metadata(const char *filepath, xb_delta_info_t *info)
1617
memset(info, 0, sizeof(xb_delta_info_t));
1619
fp = fopen(filepath, "r");
1621
/* Meta files for incremental deltas are optional */
1625
if (fscanf(fp, "page_size = %lu\n", &info->page_size) != 1)
1633
/***********************************************************************
1634
Write meta info for an incremental delta.
1635
@return TRUE on success, FALSE on failure. */
1637
xb_write_delta_metadata(const char *filepath, const xb_delta_info_t *info)
1641
fp = fopen(filepath, "w");
1643
fprintf(stderr, "xtrabackup: Error: cannot open %s\n", filepath);
1647
if (fprintf(fp, "page_size = %lu\n", info->page_size) < 0)
1655
/* ================= backup ================= */
1657
xtrabackup_io_throttling(void)
1659
if (xtrabackup_throttle && (io_ticket--) < 0) {
1660
os_event_reset(wait_throttle);
1661
os_event_wait(wait_throttle);
1666
/* TODO: We may tune the behavior (e.g. by fil_aio)*/
1667
#define COPY_CHUNK 64
1670
xtrabackup_copy_datafile(fil_node_t* node, uint thread_n)
1672
os_file_t src_file = -1;
1673
os_file_t dst_file = -1;
1674
char dst_path[FN_REFLEN];
1675
char meta_path[FN_REFLEN];
1681
ulint page_in_buffer= 0;
1682
ulint incremental_buffers = 0;
1684
ulint page_size_shift;
1686
xb_delta_info_t info;
1691
if (xtrabackup_tables && (!trx_sys_sys_space(node->space->id)))
1693
if (xtrabackup_tables && (node->space->id != 0))
1695
{ /* must backup id==0 */
1697
int p_len, regres= 0;
1704
while ((next = strstr(p, SRV_PATH_SEPARATOR_STR)) != NULL)
1709
p_len = strlen(p) - strlen(".ibd");
1712
/* unknown situation: skip filtering */
1716
/* TODO: Fix this lazy implementation... */
1721
for (i = 0; i < tables_regex_num; i++) {
1722
regres = regexec(&tables_regex[i], prev, 1, tables_regmatch, 0);
1723
if (regres != REG_NOMATCH)
1728
*(p - 1) = SRV_PATH_SEPARATOR;
1730
if ( regres == REG_NOMATCH ) {
1731
printf("[%02u] Copying %s is skipped.\n",
1732
thread_n, node->name);
1738
if (xtrabackup_tables_file && (!trx_sys_sys_space(node->space->id)))
1740
if (xtrabackup_tables_file && (node->space->id != 0))
1742
{ /* must backup id==0 */
1743
xtrabackup_tables_t* table;
1751
while ((next = strstr(p, SRV_PATH_SEPARATOR_STR)) != NULL)
1756
p_len = strlen(p) - strlen(".ibd");
1759
/* unknown situation: skip filtering */
1763
/* TODO: Fix this lazy implementation... */
1767
HASH_SEARCH(name_hash, tables_hash, ut_fold_string(prev),
1768
xtrabackup_tables_t*,
1771
!strcmp(table->name, prev));
1776
printf("[%02u] Copying %s is skipped.\n",
1777
thread_n, node->name);
1783
zip_size = fil_space_get_zip_size(node->space->id);
1784
if (zip_size == ULINT_UNDEFINED) {
1785
fprintf(stderr, "[%02u] xtrabackup: Warning: "
1786
"Failed to determine page size for %s.\n"
1787
"[%02u] xtrabackup: Warning: We assume the table was "
1788
"dropped during xtrabackup execution and ignore the "
1789
"file.\n", thread_n, node->name, thread_n);
1791
} else if (zip_size) {
1792
page_size = zip_size;
1793
page_size_shift = get_bit_shift(page_size);
1794
fprintf(stderr, "[%02u] %s is compressed with page size = "
1795
"%lu bytes\n", thread_n, node->name, page_size);
1796
if (page_size_shift < 10 || page_size_shift > 14) {
1797
fprintf(stderr, "[%02u] xtrabackup: Error: Invalid "
1798
"page size.\n", thread_n);
1802
page_size = UNIV_PAGE_SIZE;
1803
page_size_shift = UNIV_PAGE_SIZE_SHIFT;
1807
if (trx_sys_sys_space(node->space->id))
1809
if (node->space->id == 0)
1813
/* system datafile "/fullpath/datafilename.ibd" or "./datafilename.ibd" */
1815
while ((next = strstr(p, SRV_PATH_SEPARATOR_STR)) != NULL)
1819
sprintf(dst_path, "%s/%s", xtrabackup_target_dir, p);
1821
/* file per table style "./database/table.ibd" */
1822
sprintf(dst_path, "%s%s", xtrabackup_target_dir, strstr(node->name, SRV_PATH_SEPARATOR_STR));
1825
if (xtrabackup_incremental) {
1826
snprintf(meta_path, sizeof(meta_path),
1827
"%s%s", dst_path, XB_DELTA_INFO_SUFFIX);
1828
strcat(dst_path, ".delta");
1831
bzero(incremental_buffer, (page_size/4) * page_size);
1833
mach_write_to_4(incremental_buffer, 0x78747261UL);/*"xtra"*/
1836
info.page_size = page_size;
1841
src_file = os_file_create_simple_no_error_handling(
1842
0 /* dummy of innodb_file_data_key */,
1843
node->name, OS_FILE_OPEN,
1844
OS_FILE_READ_ONLY, &success);
1846
/* The following call prints an error message */
1847
os_file_get_last_error(TRUE);
1850
"[%02u] xtrabackup: Warning: cannot open %s\n"
1851
"[%02u] xtrabackup: Warning: We assume the "
1852
"table was dropped during xtrabackup execution "
1853
"and ignore the file.\n",
1854
thread_n, node->name, thread_n);
1858
if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
1859
os_file_set_nocache(src_file, node->name, "OPEN");
1862
src_file = node->handle;
1865
#ifdef USE_POSIX_FADVISE
1866
posix_fadvise(src_file, 0, 0, POSIX_FADV_SEQUENTIAL);
1867
posix_fadvise(src_file, 0, 0, POSIX_FADV_DONTNEED);
1871
/* os_file_create reads srv_unix_file_flush_method */
1872
dst_file = os_file_create(
1873
0 /* dummy of innodb_file_data_key */,
1874
dst_path, OS_FILE_CREATE,
1875
OS_FILE_NORMAL, OS_DATA_FILE, &success);
1877
/* The following call prints an error message */
1878
os_file_get_last_error(TRUE);
1880
fprintf(stderr,"[%02u] xtrabackup: error: "
1881
"cannot open %s\n", thread_n, dst_path);
1885
#ifdef USE_POSIX_FADVISE
1886
posix_fadvise(dst_file, 0, 0, POSIX_FADV_DONTNEED);
1889
/* copy : TODO: tune later */
1890
printf("[%02u] Copying %s \n to %s\n", thread_n,
1891
node->name, dst_path);
1893
buf2 = (unsigned char*) ut_malloc(COPY_CHUNK * page_size + UNIV_PAGE_SIZE);
1894
page = (unsigned char*) ut_align(buf2, UNIV_PAGE_SIZE);
1896
success = os_file_read(src_file, page, 0, 0, UNIV_PAGE_SIZE);
1901
file_size = os_file_get_size_as_iblonglong(src_file);
1903
for (offset = 0; offset < file_size; offset += COPY_CHUNK * page_size) {
1906
ulint retry_count = 10;
1908
if ((ulint)(file_size - offset) > COPY_CHUNK * page_size) {
1909
chunk = COPY_CHUNK * page_size;
1911
chunk = (ulint)(file_size - offset);
1915
xtrabackup_io_throttling();
1917
success = os_file_read(src_file, page,
1918
(ulint)(offset & 0xFFFFFFFFUL),
1919
(ulint)(offset >> 32), chunk);
1924
/* check corruption and retry */
1925
for (chunk_offset = 0; chunk_offset < chunk; chunk_offset += page_size) {
1926
if (buf_page_is_corrupted(page + chunk_offset, zip_size))
1930
trx_sys_sys_space(node->space->id)
1932
node->space->id == 0
1934
&& ((offset + (IB_INT64)chunk_offset) >> page_size_shift)
1936
&& ((offset + (IB_INT64)chunk_offset) >> page_size_shift)
1937
< FSP_EXTENT_SIZE * 3) {
1938
/* double write buffer may have old data in the end
1939
or it may contain the other format page like COMPRESSED.
1940
So, we can pass the check of double write buffer.*/
1941
ut_a(page_size == UNIV_PAGE_SIZE);
1942
fprintf(stderr, "[%02u] xtrabackup: "
1943
"Page %lu seems double write "
1944
"buffer. passing the check.\n",
1947
(IB_INT64)chunk_offset) >>
1951
if (retry_count == 0) {
1953
"[%02u] xtrabackup: "
1954
"Error: 10 retries "
1955
"resulted in fail. This"
1961
fprintf(stderr, "[%02u] xtrabackup: "
1962
"Database page corruption "
1963
"detected at page %lu. "
1967
(IB_INT64)chunk_offset)
1968
>> page_size_shift));
1974
if (xtrabackup_incremental) {
1975
for (chunk_offset = 0; chunk_offset < chunk; chunk_offset += page_size) {
1977
/* This condition may be OK for header, ibuf and fsp */
1978
if (ut_dulint_cmp(incremental_lsn,
1979
MACH_READ_64(page + chunk_offset + FIL_PAGE_LSN)) < 0) {
1980
/* ========================================= */
1981
IB_INT64 offset_on_page;
1983
if (page_in_buffer == page_size/4) {
1985
success = os_file_write(dst_path, dst_file, incremental_buffer,
1986
((incremental_buffers * (page_size/4))
1987
<< page_size_shift) & 0xFFFFFFFFUL,
1988
(incremental_buffers * (page_size/4))
1989
>> (32 - page_size_shift),
1990
page_in_buffer * page_size);
1995
incremental_buffers++;
1998
bzero(incremental_buffer, (page_size/4) * page_size);
2000
mach_write_to_4(incremental_buffer, 0x78747261UL);/*"xtra"*/
2004
offset_on_page = ((offset + (IB_INT64)chunk_offset) >> page_size_shift);
2005
ut_a(offset_on_page >> 32 == 0);
2007
mach_write_to_4(incremental_buffer + page_in_buffer * 4, (ulint)offset_on_page);
2008
memcpy(incremental_buffer + page_in_buffer * page_size,
2009
page + chunk_offset, page_size);
2012
/* ========================================= */
2016
success = os_file_write(dst_path, dst_file, page,
2017
(ulint)(offset & 0xFFFFFFFFUL),
2018
(ulint)(offset >> 32), chunk);
2026
if (xtrabackup_incremental) {
2028
if (page_in_buffer != page_size/4) {
2029
mach_write_to_4(incremental_buffer + page_in_buffer * 4, 0xFFFFFFFFUL);
2032
mach_write_to_4(incremental_buffer, 0x58545241UL);/*"XTRA"*/
2035
success = os_file_write(dst_path, dst_file, incremental_buffer,
2036
((incremental_buffers * (page_size/4))
2037
<< page_size_shift) & 0xFFFFFFFFUL,
2038
(incremental_buffers * (page_size/4))
2039
>> (32 - page_size_shift),
2040
page_in_buffer * page_size);
2044
if (!xb_write_delta_metadata(meta_path, &info)) {
2045
fprintf(stderr, "[%02u] xtrabackup: Error: "
2046
"failed to write meta info for %s\n",
2047
thread_n, dst_path);
2052
success = os_file_flush(dst_file);
2058
/* check size again */
2059
/* TODO: but is it needed ?? */
2060
// if (file_size < os_file_get_size_as_iblonglong(src_file)) {
2061
// offset -= COPY_CHUNK * page_size;
2062
// file_size = os_file_get_size_as_iblonglong(src_file);
2066
/* TODO: How should we treat double_write_buffer here? */
2067
/* (currently, don't care about. Because,
2068
the blocks is newer than the last checkpoint anyway.) */
2071
printf("[%02u] ...done\n", thread_n);
2073
os_file_close(src_file);
2075
os_file_close(dst_file);
2079
if (src_file != -1 && !node->open)
2080
os_file_close(src_file);
2082
os_file_close(dst_file);
2085
fprintf(stderr, "[%02u] xtrabackup: Error: "
2086
"xtrabackup_copy_datafile() failed.\n", thread_n);
2087
return(TRUE); /*ERROR*/
2090
if (src_file != -1 && !node->open)
2091
os_file_close(src_file);
2093
os_file_close(dst_file);
2096
fprintf(stderr, "[%02u] xtrabackup: Warning: skipping file %s.\n",
2097
thread_n, node->name);
2102
xtrabackup_copy_logfile(LSN64 from_lsn, bool is_last)
2104
/* definition from recv_recovery_from_checkpoint_start() */
2106
LSN64 group_scanned_lsn;
2107
LSN64 contiguous_lsn;
2111
if (!xtrabackup_stream)
2112
ut_a(dst_log != -1);
2114
/* read from checkpoint_lsn_start to current */
2115
contiguous_lsn = ut_dulint_align_down(from_lsn,
2116
OS_FILE_LOG_BLOCK_SIZE);
2118
/* TODO: We must check the contiguous_lsn still exists in log file.. */
2120
group = UT_LIST_GET_FIRST(log_sys->log_groups);
2128
/* reference recv_group_scan_log_recs() */
2131
start_lsn = contiguous_lsn;
2134
end_lsn = ut_dulint_add(start_lsn, RECV_SCAN_SIZE);
2136
xtrabackup_io_throttling();
2138
log_group_read_log_seg(LOG_RECOVER, log_sys->buf,
2139
group, start_lsn, end_lsn);
2141
//printf("log read from (%lu %lu) to (%lu %lu)\n",
2142
// start_lsn.high, start_lsn.low, end_lsn.high, end_lsn.low);
2144
/* reference recv_scan_log_recs() */
2151
ulint scanned_checkpoint_no = 0;
2155
log_block = log_sys->buf;
2156
scanned_lsn = start_lsn;
2158
while (log_block < log_sys->buf + RECV_SCAN_SIZE && !finished) {
2160
no = log_block_get_hdr_no(log_block);
2162
if (no != log_block_convert_lsn_to_no(scanned_lsn)
2163
|| !log_block_checksum_is_ok_or_old_format(log_block)) {
2165
if (no > log_block_convert_lsn_to_no(scanned_lsn)
2166
&& log_block_checksum_is_ok_or_old_format(log_block)) {
2168
">> ###Warning###: The copying transaction log migh be overtaken already by the target.\n"
2169
">> : Waiting log block no %lu, but the bumber is already %lu.\n"
2170
">> : If the number equals %lu + n * %lu, it should be overtaken already.\n",
2171
(ulong) log_block_convert_lsn_to_no(scanned_lsn),
2173
(ulong) log_block_convert_lsn_to_no(scanned_lsn),
2174
(ulong) (log_block_convert_lsn_to_no(
2175
log_group_get_capacity(group)
2178
} else if (no == log_block_convert_lsn_to_no(scanned_lsn)
2179
&& !log_block_checksum_is_ok_or_old_format(
2182
"xtrabackup: Log block no %lu at lsn %"PRIu64" has\n"
2183
"xtrabackup: ok header, but checksum field contains %lu, should be %lu\n",
2186
(ulong) log_block_get_checksum(log_block),
2187
(ulong) log_block_calc_checksum(log_block));
2190
/* Garbage or an incompletely written log block */
2197
if (log_block_get_flush_bit(log_block)) {
2198
/* This block was a start of a log flush operation:
2199
we know that the previous flush operation must have
2200
been completed for all log groups before this block
2201
can have been flushed to any of the groups. Therefore,
2202
we know that log data is contiguous up to scanned_lsn
2203
in all non-corrupt log groups. */
2205
if (ut_dulint_cmp(scanned_lsn, contiguous_lsn) > 0) {
2206
contiguous_lsn = scanned_lsn;
2210
data_len = log_block_get_data_len(log_block);
2213
(scanned_checkpoint_no > 0)
2214
&& (log_block_get_checkpoint_no(log_block)
2215
< scanned_checkpoint_no)
2216
&& (scanned_checkpoint_no
2217
- log_block_get_checkpoint_no(log_block)
2220
/* Garbage from a log buffer flush which was made
2221
before the most recent database recovery */
2227
scanned_lsn = ut_dulint_add(scanned_lsn, data_len);
2228
scanned_checkpoint_no = log_block_get_checkpoint_no(log_block);
2230
if (data_len < OS_FILE_LOG_BLOCK_SIZE) {
2231
/* Log data for this group ends here */
2235
log_block += OS_FILE_LOG_BLOCK_SIZE;
2237
} /* while (log_block < log_sys->buf + RECV_SCAN_SIZE && !finished) */
2239
group_scanned_lsn = scanned_lsn;
2245
/* ===== write log to 'xtrabackup_logfile' ====== */
2250
write_size = RECV_SCAN_SIZE;
2252
write_size = ut_dulint_minus(
2253
ut_dulint_align_up(group_scanned_lsn, OS_FILE_LOG_BLOCK_SIZE),
2257
//printf("Wrinting offset= %lld, size= %lu\n", log_copy_offset, write_size);
2259
if (!xtrabackup_stream) {
2260
success = os_file_write(dst_log_path, dst_log, log_sys->buf,
2261
(ulint)(log_copy_offset & 0xFFFFFFFFUL),
2262
(ulint)(log_copy_offset >> 32), write_size);
2265
ulint stdout_write_size = write_size;
2266
if (finished && !is_last
2267
&& group_scanned_lsn % OS_FILE_LOG_BLOCK_SIZE
2269
stdout_write_size -= OS_FILE_LOG_BLOCK_SIZE;
2270
if (stdout_write_size) {
2271
ret = write(fileno(stdout), log_sys->buf, stdout_write_size);
2272
if (ret == stdout_write_size) {
2275
fprintf(stderr, "write: %lu > %lu\n", stdout_write_size, ret);
2279
success = TRUE; /* do nothing */
2283
log_copy_offset += write_size;
2285
if (finished && group_scanned_lsn % OS_FILE_LOG_BLOCK_SIZE)
2287
/* if continue, it will start from align_down(group_scanned_lsn) */
2288
log_copy_offset -= OS_FILE_LOG_BLOCK_SIZE;
2292
if (!xtrabackup_stream) {
2293
fprintf(stderr, "xtrabackup: Error: os_file_write to %s\n", dst_log_path);
2295
fprintf(stderr, "xtrabackup: Error: write to stdout\n");
2307
start_lsn = end_lsn;
2312
group->scanned_lsn = group_scanned_lsn;
2315
fprintf(stderr, ">> log scanned up to (%"PRIu64")\n",group->scanned_lsn);
2317
group = UT_LIST_GET_NEXT(log_groups, group);
2319
/* update global variable*/
2320
log_copy_scanned_lsn = group_scanned_lsn;
2322
/* innodb_mirrored_log_groups must be 1, no other groups */
2323
ut_a(group == NULL);
2327
if (!xtrabackup_stream) {
2328
success = os_file_flush(dst_log);
2341
if (!xtrabackup_stream)
2342
os_file_close(dst_log);
2343
fprintf(stderr, "xtrabackup: Error: xtrabackup_copy_logfile() failed.\n");
2347
/* copying logfile in background */
2348
#define SLEEPING_PERIOD 5
2361
if (!xtrabackup_stream)
2362
ut_a(dst_log != -1);
2364
log_copying_running = TRUE;
2366
while(log_copying) {
2367
os_thread_sleep(200000); /*0.2 sec*/
2370
if(counter >= SLEEPING_PERIOD * 5) {
2371
if(xtrabackup_copy_logfile(log_copy_scanned_lsn, FALSE))
2378
if(xtrabackup_copy_logfile(log_copy_scanned_lsn, TRUE))
2381
log_copying_succeed = TRUE;
2383
log_copying_running = FALSE;
2384
os_thread_exit(NULL);
2389
/* io throttle watching (rough) */
2399
/* currently, for --backup only */
2400
ut_a(xtrabackup_backup);
2402
while (log_copying) {
2403
os_thread_sleep(1000000); /*1 sec*/
2406
//if (io_ticket == xtrabackup_throttle) {
2407
// fprintf(stderr, "There seem to be no IO...?\n");
2410
io_ticket = xtrabackup_throttle;
2411
os_event_set(wait_throttle);
2414
/* stop io throttle */
2415
xtrabackup_throttle = 0;
2416
os_event_set(wait_throttle);
2418
os_thread_exit(NULL);
2423
/************************************************************************
2424
I/o-handler thread function. */
2439
segment = *((ulint*)arg);
2442
fil_aio_wait(segment);
2445
/* We count the number of threads in os_thread_exit(). A created
2446
thread should always use that to exit and not use return() to exit.
2447
The thread actually never comes here because it is exited in an
2450
os_thread_exit(NULL);
2453
return(NULL); /* Not reached */
2459
/***************************************************************************
2460
Creates an output directory for a given tablespace, if it does not exist */
2463
xtrabackup_create_output_dir(
2464
/*==========================*/
2465
/* out: 0 if succes, -1 if failure */
2466
fil_space_t *space) /* in: tablespace */
2468
char path[FN_REFLEN];
2471
/* mkdir if not exist */
2472
ptr1 = strstr(space->name, SRV_PATH_SEPARATOR_STR);
2474
ptr2 = strstr(ptr1 + 1, SRV_PATH_SEPARATOR_STR);
2479
if(!trx_sys_sys_space(space->id) && ptr2)
2481
if(space->id && ptr2)
2484
/* single table space */
2485
*ptr2 = 0; /* temporary (it's my lazy..)*/
2486
snprintf(path, sizeof(path), "%s%s", xtrabackup_target_dir,
2488
*ptr2 = SRV_PATH_SEPARATOR;
2490
if (mkdir(path, 0777) != 0 && errno != EEXIST) {
2492
"xtrabackup: Error: cannot mkdir %d: %s\n",
2500
/**************************************************************************
2501
Datafiles copying thread.*/
2504
data_copy_thread_func(
2505
/*==================*/
2506
void *arg) /* thread context */
2508
data_thread_ctxt_t *ctxt = (data_thread_ctxt_t *) arg;
2509
uint num = ctxt->num;
2511
ibool space_changed;
2514
while ((node = datafiles_iter_next(ctxt->it, &space_changed)) != NULL) {
2515
space = node->space;
2517
if (space_changed && xtrabackup_create_output_dir(space))
2520
/* copy the datafile */
2521
if(xtrabackup_copy_datafile(node, num)) {
2522
fprintf(stderr, "[%02u] xtrabackup: Error: "
2523
"failed to copy datafile.\n",
2529
os_mutex_enter(ctxt->count_mutex);
2531
os_mutex_exit(ctxt->count_mutex);
2533
os_thread_exit(NULL);
2534
OS_THREAD_DUMMY_RETURN;
2537
/* CAUTION(?): Don't rename file_per_table during backup */
2539
xtrabackup_backup_func(void)
2541
struct stat stat_info;
2544
#ifdef USE_POSIX_FADVISE
2545
fprintf(stderr, "xtrabackup: uses posix_fadvise().\n");
2550
if (chdir(mysql_real_data_home) != 0)
2552
fprintf(stderr, "xtrabackup: cannot my_setwd %s\n", mysql_real_data_home);
2555
fprintf(stderr, "xtrabackup: cd to %s\n", mysql_real_data_home);
2557
mysql_data_home= mysql_data_home_buff;
2558
mysql_data_home[0]=FN_CURLIB; // all paths are relative from here
2559
mysql_data_home[1]=0;
2562
srv_read_only = TRUE;
2564
/* initialize components */
2565
if(innodb_init_param())
2568
if (srv_file_flush_method_str == NULL) {
2569
/* These are the default options */
2570
srv_unix_file_flush_method = SRV_UNIX_FSYNC;
2572
srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
2574
} else if (0 == ut_strcmp(srv_file_flush_method_str, "fsync")) {
2575
srv_unix_file_flush_method = SRV_UNIX_FSYNC;
2577
} else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DSYNC")) {
2578
srv_unix_file_flush_method = SRV_UNIX_O_DSYNC;
2580
} else if (0 == ut_strcmp(srv_file_flush_method_str, "O_DIRECT")) {
2581
srv_unix_file_flush_method = SRV_UNIX_O_DIRECT;
2582
fprintf(stderr,"xtrabackup: use O_DIRECT\n");
2583
} else if (0 == ut_strcmp(srv_file_flush_method_str, "littlesync")) {
2584
srv_unix_file_flush_method = SRV_UNIX_LITTLESYNC;
2586
} else if (0 == ut_strcmp(srv_file_flush_method_str, "nosync")) {
2587
srv_unix_file_flush_method = SRV_UNIX_NOSYNC;
2589
} else if (0 == ut_strcmp(srv_file_flush_method_str, "normal")) {
2590
srv_win_file_flush_method = SRV_WIN_IO_NORMAL;
2591
os_aio_use_native_aio = FALSE;
2593
} else if (0 == ut_strcmp(srv_file_flush_method_str, "unbuffered")) {
2594
srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
2595
os_aio_use_native_aio = FALSE;
2597
} else if (0 == ut_strcmp(srv_file_flush_method_str,
2598
"async_unbuffered")) {
2599
srv_win_file_flush_method = SRV_WIN_IO_UNBUFFERED;
2603
"xtrabackup: Unrecognized value %s for innodb_flush_method\n",
2604
srv_file_flush_method_str);
2608
if (srv_buf_pool_size >= 1000 * 1024 * 1024) {
2609
/* Here we still have srv_pool_size counted
2610
in kilobytes (in 4.0 this was in bytes)
2611
srv_boot() converts the value to
2612
pages; if buffer pool is less than 1000 MB,
2613
assume fewer threads. */
2614
srv_max_n_threads = 50000;
2617
} else if (srv_buf_pool_size >= 8 * 1024 * 1024) {
2619
srv_max_n_threads = 10000;
2621
srv_max_n_threads = 1000; /* saves several MB of memory,
2622
especially in 64-bit
2630
nr = srv_n_data_files;
2632
for (i = 0; i < nr; i++) {
2633
srv_data_file_sizes[i] = srv_data_file_sizes[i]
2634
* ((1024 * 1024) / UNIV_PAGE_SIZE);
2637
srv_last_file_size_max = srv_last_file_size_max
2638
* ((1024 * 1024) / UNIV_PAGE_SIZE);
2640
srv_log_file_size = srv_log_file_size / UNIV_PAGE_SIZE;
2642
srv_log_buffer_size = srv_log_buffer_size / UNIV_PAGE_SIZE;
2644
srv_lock_table_size = 5 * (srv_buf_pool_size / UNIV_PAGE_SIZE);
2647
os_sync_mutex = NULL;
2651
ibool create_new_db;
2653
ibool create_new_doublewrite_file;
2655
ibool log_file_created;
2656
ibool log_created = FALSE;
2657
ibool log_opened = FALSE;
2658
LSN64 min_flushed_lsn;
2659
LSN64 max_flushed_lsn;
2660
ulint sum_of_new_sizes;
2667
#define SRV_N_PENDING_IOS_PER_THREAD OS_AIO_N_PENDING_IOS_PER_THREAD
2668
#define SRV_MAX_N_PENDING_SYNC_IOS 100
2670
srv_n_file_io_threads = 2 + srv_n_read_io_threads + srv_n_write_io_threads;
2672
os_aio_init(8 * SRV_N_PENDING_IOS_PER_THREAD,
2673
srv_n_read_io_threads,
2674
srv_n_write_io_threads,
2675
SRV_MAX_N_PENDING_SYNC_IOS);
2677
fil_init(srv_file_per_table ? 50000 : 5000,
2678
srv_max_n_open_files);
2683
lock_sys_create(srv_lock_table_size);
2685
for (i = 0; i < srv_n_file_io_threads; i++) {
2688
os_thread_create(io_handler_thread, thread_nr + i, thread_ids + i);
2691
os_thread_sleep(200000); /*0.2 sec*/
2693
err = open_or_create_data_files(&create_new_db,
2695
&create_new_doublewrite_file,
2697
&min_flushed_lsn, &max_flushed_lsn,
2699
if (err != DB_SUCCESS) {
2701
"xtrabackup: Could not open or create data files.\n"
2702
"xtrabackup: If you tried to add new data files, and it failed here,\n"
2703
"xtrabackup: you should now edit innodb_data_file_path in my.cnf back\n"
2704
"xtrabackup: to what it was, and remove the new ibdata files InnoDB created\n"
2705
"xtrabackup: in this failed attempt. InnoDB only wrote those files full of\n"
2706
"xtrabackup: zeros, but did not yet use them in any way. But be careful: do not\n"
2707
"xtrabackup: remove old data files which contain your precious data!\n");
2709
//return((int) err);
2713
/* create_new_db must not be TRUE.. */
2714
if (create_new_db) {
2715
fprintf(stderr, "xtrabackup: Something wrong with source files...\n");
2719
for (i = 0; i < srv_n_log_files; i++) {
2720
err = open_or_create_log_file(create_new_db, &log_file_created,
2722
if (err != DB_SUCCESS) {
2724
//return((int) err);
2728
if (log_file_created) {
2733
if ((log_opened && create_new_db)
2734
|| (log_opened && log_created)) {
2736
"xtrabackup: Error: all log files must be created at the same time.\n"
2737
"xtrabackup: All log files must be created also in database creation.\n"
2738
"xtrabackup: If you want bigger or smaller log files, shut down the\n"
2739
"xtrabackup: database and make sure there were no errors in shutdown.\n"
2740
"xtrabackup: Then delete the existing log files. Edit the .cnf file\n"
2741
"xtrabackup: and start the database again.\n");
2748
/* log_file_created must not be TRUE, if online */
2749
if (log_file_created) {
2750
fprintf(stderr, "xtrabackup: Something wrong with source files...\n");
2754
fil_load_single_table_tablespaces();
2758
/* create extra LSN dir if it does not exist. */
2759
if (xtrabackup_extra_lsndir
2760
&& (stat(xtrabackup_extra_lsndir,&stat_info) != 0)
2761
&& (mkdir(xtrabackup_extra_lsndir,0777) != 0)){
2762
fprintf(stderr,"xtrabackup: Error: cannot mkdir %d: %s\n",errno,xtrabackup_extra_lsndir);
2767
if (!xtrabackup_stream) {
2769
/* create target dir if not exist */
2770
if (stat(xtrabackup_target_dir,&stat_info) != 0
2771
&& (mkdir(xtrabackup_target_dir,0777) != 0)){
2772
fprintf(stderr,"xtrabackup: Error: cannot mkdir %d: %s\n",errno,xtrabackup_target_dir);
2777
fprintf(stderr,"xtrabackup: Stream mode.\n");
2778
/* stdout can treat binary at Linux */
2779
//setmode(fileno(stdout), O_BINARY);
2783
fil_system_t* f_system = fil_system;
2785
/* definition from recv_recovery_from_checkpoint_start() */
2786
log_group_t* max_cp_group;
2789
byte log_hdr_buf_[LOG_FILE_HDR_SIZE + OS_FILE_LOG_BLOCK_SIZE];
2795
/* start back ground thread to copy newer log */
2796
os_thread_id_t log_copying_thread_id;
2797
datafiles_iter_t *it;
2799
log_hdr_buf = (unsigned char*)ut_align(log_hdr_buf_, OS_FILE_LOG_BLOCK_SIZE);
2802
//space = UT_LIST_GET_NEXT(space_list, UT_LIST_GET_FIRST(f_system->space_list));
2803
//printf("space: name=%s, id=%d, purpose=%d, size=%d\n",
2804
// space->name, space->id, space->purpose, space->size);
2806
/* get current checkpoint_lsn */
2807
/* Look for the latest checkpoint from any of the log groups */
2809
err = recv_find_max_checkpoint(&max_cp_group, &max_cp_field);
2811
if (err != DB_SUCCESS) {
2816
log_group_read_checkpoint_info(max_cp_group, max_cp_field);
2817
buf = log_sys->checkpoint_buf;
2819
checkpoint_lsn_start = MACH_READ_64(buf + LOG_CHECKPOINT_LSN);
2820
checkpoint_no_start = MACH_READ_64(buf + LOG_CHECKPOINT_NO);
2823
fil_io(OS_FILE_READ | OS_FILE_LOG, TRUE, max_cp_group->space_id,
2825
0, 0, LOG_FILE_HDR_SIZE,
2826
log_hdr_buf, max_cp_group);
2828
/* check consistency of log file header to copy */
2829
err = recv_find_max_checkpoint(&max_cp_group, &max_cp_field);
2831
if (err != DB_SUCCESS) {
2836
log_group_read_checkpoint_info(max_cp_group, max_cp_field);
2837
buf = log_sys->checkpoint_buf;
2839
if(ut_dulint_cmp(checkpoint_no_start,
2840
MACH_READ_64(buf + LOG_CHECKPOINT_NO)) != 0) {
2841
checkpoint_lsn_start = MACH_READ_64(buf + LOG_CHECKPOINT_LSN);
2842
checkpoint_no_start = MACH_READ_64(buf + LOG_CHECKPOINT_NO);
2843
goto reread_log_header;
2846
if (!xtrabackup_stream) {
2848
/* open 'xtrabackup_logfile' */
2849
sprintf(dst_log_path, "%s%s", xtrabackup_target_dir, "/xtrabackup_logfile");
2850
srv_normalize_path_for_win(dst_log_path);
2851
/* os_file_create reads srv_unix_file_flush_method for OS_DATA_FILE*/
2852
dst_log = os_file_create(
2853
0 /* dummy of innodb_file_data_key */,
2854
dst_log_path, OS_FILE_CREATE,
2855
OS_FILE_NORMAL, OS_DATA_FILE, &success);
2858
/* The following call prints an error message */
2859
os_file_get_last_error(TRUE);
2862
"xtrabackup: error: cannot open %s\n",
2867
#ifdef USE_POSIX_FADVISE
2868
posix_fadvise(dst_log, 0, 0, POSIX_FADV_DONTNEED);
2874
strcpy((char*) log_hdr_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
2876
ut_sprintf_timestamp(
2877
(char*) log_hdr_buf + (LOG_FILE_WAS_CREATED_BY_HOT_BACKUP
2878
+ (sizeof "xtrabkup ") - 1));
2880
if (!xtrabackup_stream) {
2881
success = os_file_write(dst_log_path, dst_log, log_hdr_buf,
2882
0, 0, LOG_FILE_HDR_SIZE);
2885
if (write(fileno(stdout), log_hdr_buf, LOG_FILE_HDR_SIZE)
2886
== LOG_FILE_HDR_SIZE) {
2893
log_copy_offset += LOG_FILE_HDR_SIZE;
2896
os_file_close(dst_log);
2903
/* start io throttle */
2904
if(xtrabackup_throttle) {
2905
os_thread_id_t io_watching_thread_id;
2907
io_ticket = xtrabackup_throttle;
2908
wait_throttle = os_event_create(NULL);
2910
os_thread_create(io_watching_thread, NULL, &io_watching_thread_id);
2914
/* copy log file by current position */
2915
if(xtrabackup_copy_logfile(checkpoint_lsn_start, FALSE))
2919
os_thread_create(log_copying_thread, NULL, &log_copying_thread_id);
2923
if (!xtrabackup_stream) { /* stream mode is transaction log only */
2926
os_mutex_t count_mutex;
2927
data_thread_ctxt_t *data_threads;
2932
printf("xtrabackup: Starting %u threads for parallel "
2933
"data files transfer\n", parallel);
2935
it = datafiles_iter_new(f_system);
2938
"xtrabackup: Error: "
2939
"datafiles_iter_new() failed.\n");
2943
/* Create data copying threads */
2946
data_threads = (data_thread_ctxt_t *)
2947
ut_malloc(sizeof(data_thread_ctxt_t) * parallel);
2949
count_mutex = OS_MUTEX_CREATE();
2951
for (i = 0; i < parallel; i++) {
2952
data_threads[i].it = it;
2953
data_threads[i].num = i+1;
2954
data_threads[i].count = &count;
2955
data_threads[i].count_mutex = count_mutex;
2956
os_thread_create(data_copy_thread_func,
2958
&data_threads[i].id);
2961
/* Wait for threads to exit */
2963
os_thread_sleep(1000000);
2964
os_mutex_enter(count_mutex);
2966
os_mutex_exit(count_mutex);
2969
os_mutex_exit(count_mutex);
2971
/* NOTE: It may not needed at "--backup" for now */
2972
/* mutex_enter(&(f_system->mutex)); */
2974
os_mutex_free(count_mutex);
2975
datafiles_iter_free(it);
2977
} //if (!xtrabackup_stream)
2979
//mutex_exit(&(f_system->mutex));
2983
/* suspend-at-end */
2984
if (xtrabackup_suspend_at_end) {
2985
os_file_t suspend_file = -1;
2986
char suspend_path[FN_REFLEN];
2987
ibool success, exists;
2988
os_file_type_t type;
2990
sprintf(suspend_path, "%s%s", xtrabackup_target_dir,
2991
"/xtrabackup_suspended");
2993
srv_normalize_path_for_win(suspend_path);
2994
/* os_file_create reads srv_unix_file_flush_method */
2995
suspend_file = os_file_create(
2996
0 /* dummy of innodb_file_data_key */,
2997
suspend_path, OS_FILE_OVERWRITE,
2998
OS_FILE_NORMAL, OS_DATA_FILE, &success);
3001
fprintf(stderr, "xtrabackup: Error: failed to create file 'xtrabackup_suspended'\n");
3004
if (suspend_file != -1)
3005
os_file_close(suspend_file);
3009
os_thread_sleep(200000); /*0.2 sec*/
3010
success = os_file_status(suspend_path, &exists, &type);
3014
xtrabackup_suspend_at_end = FALSE; /* suspend is 1 time */
3017
/* read the latest checkpoint lsn */
3018
latest_cp = ut_dulint_zero;
3020
log_group_t* max_cp_group;
3024
err = recv_find_max_checkpoint(&max_cp_group, &max_cp_field);
3026
if (err != DB_SUCCESS) {
3027
fprintf(stderr, "xtrabackup: Error: recv_find_max_checkpoint() failed.\n");
3031
log_group_read_checkpoint_info(max_cp_group, max_cp_field);
3033
latest_cp = MACH_READ_64(log_sys->checkpoint_buf + LOG_CHECKPOINT_LSN);
3035
if (!xtrabackup_stream) {
3036
printf("xtrabackup: The latest check point (for incremental): '%"PRIu64"'\n",
3039
fprintf(stderr, "xtrabackup: The latest check point (for incremental): '%"PRIu64"'\n",
3044
/* stop log_copying_thread */
3045
log_copying = FALSE;
3046
if (!xtrabackup_stream) {
3047
printf("xtrabackup: Stopping log copying thread");
3048
while (log_copying_running) {
3050
os_thread_sleep(200000); /*0.2 sec*/
3054
while (log_copying_running)
3055
os_thread_sleep(200000); /*0.2 sec*/
3058
/* output to metadata file */
3060
char filename[FN_REFLEN];
3062
if(!xtrabackup_incremental) {
3063
strcpy(metadata_type, "full-backuped");
3064
metadata_from_lsn = ut_dulint_zero;
3066
strcpy(metadata_type, "incremental");
3067
metadata_from_lsn = incremental_lsn;
3069
metadata_to_lsn = latest_cp;
3070
metadata_last_lsn = log_copy_scanned_lsn;
3072
sprintf(filename, "%s/%s", xtrabackup_target_dir, XTRABACKUP_METADATA_FILENAME);
3073
if (xtrabackup_write_metadata(filename))
3074
fprintf(stderr, "xtrabackup: error: xtrabackup_write_metadata(xtrabackup_target_dir)\n");
3076
if(xtrabackup_extra_lsndir) {
3077
sprintf(filename, "%s/%s", xtrabackup_extra_lsndir, XTRABACKUP_METADATA_FILENAME);
3078
if (xtrabackup_write_metadata(filename))
3079
fprintf(stderr, "xtrabackup: error: xtrabackup_write_metadata(xtrabackup_extra_lsndir)\n");
3083
if (!log_copying_succeed) {
3084
fprintf(stderr, "xtrabackup: Error: log_copying_thread failed.\n");
3088
if (!xtrabackup_stream)
3089
os_file_close(dst_log);
3092
os_event_free(wait_throttle);
3094
if (!xtrabackup_stream) {
3095
printf("xtrabackup: Transaction log of lsn (%"PRIu64") to (%"PRIu64") was copied.\n",
3096
checkpoint_lsn_start, log_copy_scanned_lsn);
3098
fprintf(stderr, "xtrabackup: Transaction log of lsn (%"PRIu64") to (%"PRIu64") was copied.\n",
3099
checkpoint_lsn_start, log_copy_scanned_lsn);
3100
if(xtrabackup_extra_lsndir) {
3101
char filename[FN_REFLEN];
3102
sprintf(filename, "%s/%s", xtrabackup_extra_lsndir, XTRABACKUP_METADATA_FILENAME);
3103
if (xtrabackup_write_metadata(filename))
3104
fprintf(stderr, "xtrabackup: error: xtrabackup_write_metadata(xtrabackup_extra_lsndir)\n");
3109
/* ================= stats ================= */
3111
xtrabackup_stats_level(
3112
dict_index_t* index,
3120
ulint right_page_no;
3125
mem_heap_t* heap = mem_heap_create(256);
3127
ulint* offsets = NULL;
3129
uint64_t n_pages, n_pages_extern;
3130
uint64_t sum_data, sum_data_extern;
3134
n_pages = sum_data = n_recs = 0;
3135
n_pages_extern = sum_data_extern = 0;
3141
fprintf(stdout, " leaf pages: ");
3143
fprintf(stdout, " level %lu pages: ", level);
3147
mtr_x_lock(&(index->lock), &mtr);
3148
block = btr_root_block_get(index, &mtr);
3149
page = buf_block_get_frame(block);
3151
space = page_get_space_id(page);
3152
zip_size = fil_space_get_zip_size(space);
3154
while (level != btr_page_get_level(page, &mtr)) {
3156
ut_a(space == buf_block_get_space(block));
3157
ut_a(space == page_get_space_id(page));
3158
ut_a(!page_is_leaf(page));
3160
page_cur_set_before_first(block, &cursor);
3161
page_cur_move_to_next(&cursor);
3163
node_ptr = page_cur_get_rec(&cursor);
3164
offsets = rec_get_offsets(node_ptr, index, offsets,
3165
ULINT_UNDEFINED, &heap);
3167
block = btr_node_ptr_get_child(node_ptr, index, offsets, &mtr);
3168
page = buf_block_get_frame(block);
3172
mem_heap_empty(heap);
3174
mtr_x_lock(&(index->lock), &mtr);
3176
right_page_no = btr_page_get_next(page, &mtr);
3179
/*=================================*/
3180
//fprintf(stdout, "%lu ", (ulint) buf_frame_get_page_no(page));
3183
sum_data += page_get_data_size(page);
3184
n_recs += page_get_n_recs(page);
3191
mem_heap_t* local_heap = NULL;
3192
ulint offsets_[REC_OFFS_NORMAL_SIZE];
3193
ulint* local_offsets = offsets_;
3195
*offsets_ = (sizeof offsets_) / sizeof *offsets_;
3197
page_cur_set_before_first(block, &cur);
3199
page_cur_move_to_next(&cur);
3202
if (page_cur_is_after_last(&cur)) {
3206
local_offsets = rec_get_offsets(cur.rec, index, local_offsets,
3207
ULINT_UNDEFINED, &local_heap);
3208
n_fields = rec_offs_n_fields(local_offsets);
3210
for (i = 0; i < n_fields; i++) {
3211
if (rec_offs_nth_extern(local_offsets, i)) {
3221
buf_block_t* local_block;
3223
data = rec_get_nth_field(cur.rec, local_offsets, i, &local_len);
3225
ut_a(local_len >= BTR_EXTERN_FIELD_REF_SIZE);
3226
local_len -= BTR_EXTERN_FIELD_REF_SIZE;
3228
space_id = mach_read_from_4(data + local_len + BTR_EXTERN_SPACE_ID);
3229
page_no = mach_read_from_4(data + local_len + BTR_EXTERN_PAGE_NO);
3230
offset = mach_read_from_4(data + local_len + BTR_EXTERN_OFFSET);
3232
if (offset != FIL_PAGE_DATA)
3233
fprintf(stderr, "\nWarning: several record may share same external page.\n");
3236
mtr_start(&local_mtr);
3238
local_block = btr_block_get(space_id, zip_size, page_no, RW_S_LATCH, &local_mtr);
3239
local_page = buf_block_get_frame(local_block);
3241
blob_header = local_page + offset;
3242
#define BTR_BLOB_HDR_PART_LEN 0
3243
#define BTR_BLOB_HDR_NEXT_PAGE_NO 4
3244
//part_len = btr_blob_get_part_len(blob_header);
3245
part_len = mach_read_from_4(blob_header + BTR_BLOB_HDR_PART_LEN);
3247
//page_no = btr_blob_get_next_page_no(blob_header);
3248
page_no = mach_read_from_4(blob_header + BTR_BLOB_HDR_NEXT_PAGE_NO);
3250
offset = FIL_PAGE_DATA;
3255
/*=================================*/
3256
//fprintf(stdout, "[%lu] ", (ulint) buf_frame_get_page_no(page));
3259
sum_data_extern += part_len;
3262
mtr_commit(&local_mtr);
3264
if (page_no == FIL_NULL)
3270
page_cur_move_to_next(&cur);
3278
if (right_page_no != FIL_NULL) {
3280
block = btr_block_get(space, zip_size, right_page_no, RW_X_LATCH, &mtr);
3281
page = buf_block_get_frame(block);
3284
mem_heap_free(heap);
3287
page_size = zip_size;
3289
page_size = UNIV_PAGE_SIZE;
3293
fprintf(stdout, "recs=%"PRIu64", ", n_recs);
3295
fprintf(stdout, "pages=%"PRIu64", data=%"PRIu64" bytes, data/pages=%"PRIu64"%%",
3297
((sum_data * 100)/ page_size)/n_pages);
3300
if (level == 0 && n_pages_extern) {
3302
/* also scan blob pages*/
3303
fprintf(stdout, " external pages: ");
3305
fprintf(stdout, "pages=%"PRIu64", data=%"PRIu64" bytes, data/pages=%"PRIu64"%%",
3306
n_pages_extern, sum_data_extern,
3307
((sum_data_extern * 100)/ page_size)/n_pages_extern);
3313
xtrabackup_stats_level(index, level - 1);
3320
xtrabackup_stats_func(void)
3326
if (chdir(mysql_real_data_home) != 0)
3328
fprintf(stderr, "xtrabackup: cannot my_setwd %s\n", mysql_real_data_home);
3331
fprintf(stderr, "xtrabackup: cd to %s\n", mysql_real_data_home);
3333
mysql_data_home= mysql_data_home_buff;
3334
mysql_data_home[0]=FN_CURLIB; // all paths are relative from here
3335
mysql_data_home[1]=0;
3338
srv_read_only = TRUE;
3339
srv_fake_write = TRUE;
3341
/* initialize components */
3342
if(innodb_init_param())
3345
/* Check if the log files have been created, otherwise innodb_init()
3346
will crash when called with srv_read_only == TRUE */
3347
for (n = 0; n < srv_n_log_files; n++) {
3348
char logname[FN_REFLEN];
3350
os_file_type_t type;
3352
sprintf(logname, "ib_logfile%lu", (ulong) n);
3353
if (!os_file_status(logname, &exists, &type) || !exists ||
3354
type != OS_FILE_TYPE_FILE) {
3355
fprintf(stderr, "xtrabackup: Error: "
3356
"Cannot find log file %s.\n", logname);
3357
fprintf(stderr, "xtrabackup: Error: "
3358
"to use the statistics feature, you need a "
3359
"clean copy of the database including "
3360
"correctly sized log files, so you need to "
3361
"execute with --prepare twice to use this "
3362
"functionality on a backup.\n");
3367
fprintf(stderr, "xtrabackup: Starting 'read-only' InnoDB instance to gather index statistics.\n"
3368
"xtrabackup: Using %"PRIu64" bytes for buffer pool (set by --use-memory parameter)\n",
3369
xtrabackup_use_memory);
3374
fprintf(stdout, "\n\n<INDEX STATISTICS>\n");
3379
dict_table_t* sys_tables;
3380
dict_index_t* sys_index;
3381
dict_table_t* table;
3388
/* Enlarge the fatal semaphore wait timeout during the InnoDB table
3391
mutex_enter(&kernel_mutex);
3392
srv_fatal_semaphore_wait_threshold += 72000; /* 20 hours */
3393
mutex_exit(&kernel_mutex);
3395
mutex_enter(&(dict_sys->mutex));
3399
sys_tables = dict_table_get_low("SYS_TABLES");
3400
sys_index = UT_LIST_GET_FIRST(sys_tables->indexes);
3402
btr_pcur_open_at_index_side(TRUE, sys_index, BTR_SEARCH_LEAF, &pcur,
3405
btr_pcur_move_to_next_user_rec(&pcur, &mtr);
3407
rec = btr_pcur_get_rec(&pcur);
3409
if (!btr_pcur_is_on_user_rec(&pcur))
3413
btr_pcur_close(&pcur);
3416
mutex_exit(&(dict_sys->mutex));
3418
/* Restore the fatal semaphore wait timeout */
3420
mutex_enter(&kernel_mutex);
3421
srv_fatal_semaphore_wait_threshold -= 72000; /* 20 hours */
3422
mutex_exit(&kernel_mutex);
3427
field = rec_get_nth_field_old(rec, 0, &len);
3429
if (!rec_get_deleted_flag(rec, 0))
3434
char* table_name = mem_strdupl((char*) field, len);
3436
btr_pcur_store_position(&pcur, &mtr);
3440
table = dict_table_get_low(table_name);
3441
mem_free(table_name);
3444
if (xtrabackup_tables) {
3449
p = strstr(table->name, SRV_PATH_SEPARATOR_STR);
3454
for (i = 0; i < tables_regex_num; i++) {
3455
regres = regexec(&tables_regex[i], table->name, 1, tables_regmatch, 0);
3456
if (regres != REG_NOMATCH)
3461
*p = SRV_PATH_SEPARATOR;
3463
if ( regres == REG_NOMATCH )
3467
if (xtrabackup_tables_file) {
3468
xtrabackup_tables_t* xtable;
3470
HASH_SEARCH(name_hash, tables_hash, ut_fold_string(table->name),
3471
xtrabackup_tables_t*,
3473
ut_ad(xtable->name),
3474
!strcmp(xtable->name, table->name));
3481
if (table == NULL) {
3482
fputs("InnoDB: Failed to load table ", stderr);
3483
ut_print_namel(stderr, NULL, TRUE, (char*) field, len);
3486
dict_index_t* index;
3488
/* The table definition was corrupt if there
3491
if (dict_table_get_first_index(table)) {
3493
dict_update_statistics(table, TRUE, FALSE);
3494
#elif defined(INNODB_VERSION_SHORT)
3495
dict_update_statistics(table, TRUE);
3497
dict_update_statistics_low(table, TRUE);
3501
//dict_table_print_low(table);
3503
index = UT_LIST_GET_FIRST(table->indexes);
3504
while (index != NULL) {
3508
if (index->n_user_defined_cols > 0) {
3509
n_vals = index->stat_n_diff_key_vals[
3510
index->n_user_defined_cols];
3512
n_vals = index->stat_n_diff_key_vals[1];
3516
" table: %s, index: %s, space id: %lu, root page: %lu"
3518
"\n estimated statistics in dictionary:\n"
3519
" key vals: %lu, leaf pages: %lu, size pages: %lu\n"
3520
" real statistics:\n",
3521
table->name, index->name,
3522
(ulong) index->space,
3523
(ulong) index->page,
3524
(ulong) fil_space_get_zip_size(index->space),
3526
(ulong) index->stat_n_leaf_pages,
3527
(ulong) index->stat_index_size);
3534
mtr_start(&local_mtr);
3536
mtr_x_lock(&(index->lock), &local_mtr);
3537
root = btr_root_get(index, &local_mtr);
3539
page_level = btr_page_get_level(root, &local_mtr);
3541
xtrabackup_stats_level(index, page_level);
3543
mtr_commit(&local_mtr);
3548
index = UT_LIST_GET_NEXT(indexes, index);
3555
btr_pcur_restore_position(BTR_SEARCH_LEAF, &pcur, &mtr);
3564
/* shutdown InnoDB */
3569
/* ================= prepare ================= */
3572
xtrabackup_init_temp_log(void)
3574
os_file_t src_file = -1;
3575
char src_path[FN_REFLEN];
3576
char dst_path[FN_REFLEN];
3581
byte* log_buf_ = NULL;
3587
LSN64 checkpoint_no;
3591
max_no = ut_dulint_zero;
3593
if(!xtrabackup_incremental_dir) {
3594
sprintf(dst_path, "%s%s", xtrabackup_target_dir, "/ib_logfile0");
3595
sprintf(src_path, "%s%s", xtrabackup_target_dir, "/xtrabackup_logfile");
3597
sprintf(dst_path, "%s%s", xtrabackup_incremental_dir, "/ib_logfile0");
3598
sprintf(src_path, "%s%s", xtrabackup_incremental_dir, "/xtrabackup_logfile");
3601
srv_normalize_path_for_win(dst_path);
3602
srv_normalize_path_for_win(src_path);
3604
src_file = os_file_create_simple_no_error_handling(
3605
0 /* dummy of innodb_file_data_key */,
3606
src_path, OS_FILE_OPEN,
3607
OS_FILE_READ_WRITE /* OS_FILE_READ_ONLY */, &success);
3609
/* The following call prints an error message */
3610
os_file_get_last_error(TRUE);
3613
"xtrabackup: Warning: cannot open %s. will try to find.\n",
3616
/* check if ib_logfile0 may be xtrabackup_logfile */
3617
src_file = os_file_create_simple_no_error_handling(
3618
0 /* dummy of innodb_file_data_key */,
3619
dst_path, OS_FILE_OPEN,
3620
OS_FILE_READ_WRITE /* OS_FILE_READ_ONLY */, &success);
3622
os_file_get_last_error(TRUE);
3624
" xtrabackup: Fatal error: cannot find %s.\n",
3630
log_buf_ = (unsigned char*) ut_malloc(LOG_FILE_HDR_SIZE * 2);
3631
log_buf = (unsigned char*) ut_align(log_buf_, LOG_FILE_HDR_SIZE);
3633
success = os_file_read(src_file, log_buf, 0, 0, LOG_FILE_HDR_SIZE);
3638
if ( ut_memcmp(log_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
3639
(byte*)"xtrabkup", (sizeof "xtrabkup") - 1) == 0) {
3641
" xtrabackup: 'ib_logfile0' seems to be 'xtrabackup_logfile'. will retry.\n");
3646
os_file_close(src_file);
3649
/* rename and try again */
3650
success = os_file_rename(
3651
0 /* dummy of innodb_file_data_key */,
3652
dst_path, src_path);
3661
" xtrabackup: Fatal error: cannot find %s.\n",
3667
os_file_close(src_file);
3673
#ifdef USE_POSIX_FADVISE
3674
posix_fadvise(src_file, 0, 0, POSIX_FADV_SEQUENTIAL);
3675
posix_fadvise(src_file, 0, 0, POSIX_FADV_DONTNEED);
3678
if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
3679
os_file_set_nocache(src_file, src_path, "OPEN");
3682
file_size = os_file_get_size_as_iblonglong(src_file);
3685
/* TODO: We should skip the following modifies, if it is not the first time. */
3686
log_buf_ = (unsigned char*) ut_malloc(UNIV_PAGE_SIZE * 129);
3687
log_buf = (unsigned char*) ut_align(log_buf_, UNIV_PAGE_SIZE);
3689
/* read log file header */
3690
success = os_file_read(src_file, log_buf, 0, 0, LOG_FILE_HDR_SIZE);
3695
if ( ut_memcmp(log_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
3696
(byte*)"xtrabkup", (sizeof "xtrabkup") - 1) != 0 ) {
3697
printf("xtrabackup: notice: xtrabackup_logfile was already used to '--prepare'.\n");
3700
/* clear it later */
3701
//memset(log_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP,
3705
/* read last checkpoint lsn */
3706
for (field = LOG_CHECKPOINT_1; field <= LOG_CHECKPOINT_2;
3707
field += LOG_CHECKPOINT_2 - LOG_CHECKPOINT_1) {
3708
if (!recv_check_cp_is_consistent(log_buf + field))
3709
goto not_consistent;
3711
checkpoint_no = MACH_READ_64(log_buf + field + LOG_CHECKPOINT_NO);
3713
if (ut_dulint_cmp(checkpoint_no, max_no) >= 0) {
3714
max_no = checkpoint_no;
3715
max_lsn = MACH_READ_64(log_buf + field + LOG_CHECKPOINT_LSN);
3717
mach_write_to_4(log_buf + field + LOG_CHECKPOINT_OFFSET,
3718
LOG_FILE_HDR_SIZE + ut_dulint_minus(max_lsn,
3719
ut_dulint_align_down(max_lsn,OS_FILE_LOG_BLOCK_SIZE)));
3722
fold = ut_fold_binary(log_buf + field, LOG_CHECKPOINT_CHECKSUM_1);
3723
mach_write_to_4(log_buf + field + LOG_CHECKPOINT_CHECKSUM_1, fold);
3725
fold = ut_fold_binary(log_buf + field + LOG_CHECKPOINT_LSN,
3726
LOG_CHECKPOINT_CHECKSUM_2 - LOG_CHECKPOINT_LSN);
3727
mach_write_to_4(log_buf + field + LOG_CHECKPOINT_CHECKSUM_2, fold);
3734
if (ut_dulint_cmp(max_no, ut_dulint_zero) == 0) {
3735
fprintf(stderr, "xtrabackup: No valid checkpoint found.\n");
3740
/* It seems to be needed to overwrite the both checkpoint area. */
3741
MACH_WRITE_64(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_LSN, max_lsn);
3742
mach_write_to_4(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_OFFSET,
3743
LOG_FILE_HDR_SIZE + ut_dulint_minus(max_lsn,
3744
ut_dulint_align_down(max_lsn,OS_FILE_LOG_BLOCK_SIZE)));
3746
MACH_WRITE_64(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_ARCHIVED_LSN,
3747
(ib_uint64_t)(LOG_FILE_HDR_SIZE + ut_dulint_minus(max_lsn,
3748
ut_dulint_align_down(max_lsn,OS_FILE_LOG_BLOCK_SIZE))));
3750
fold = ut_fold_binary(log_buf + LOG_CHECKPOINT_1, LOG_CHECKPOINT_CHECKSUM_1);
3751
mach_write_to_4(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_CHECKSUM_1, fold);
3753
fold = ut_fold_binary(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_LSN,
3754
LOG_CHECKPOINT_CHECKSUM_2 - LOG_CHECKPOINT_LSN);
3755
mach_write_to_4(log_buf + LOG_CHECKPOINT_1 + LOG_CHECKPOINT_CHECKSUM_2, fold);
3757
MACH_WRITE_64(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_LSN, max_lsn);
3758
mach_write_to_4(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_OFFSET,
3759
LOG_FILE_HDR_SIZE + ut_dulint_minus(max_lsn,
3760
ut_dulint_align_down(max_lsn,OS_FILE_LOG_BLOCK_SIZE)));
3762
MACH_WRITE_64(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_ARCHIVED_LSN,
3763
(ib_uint64_t)(LOG_FILE_HDR_SIZE + ut_dulint_minus(max_lsn,
3764
ut_dulint_align_down(max_lsn,OS_FILE_LOG_BLOCK_SIZE))));
3766
fold = ut_fold_binary(log_buf + LOG_CHECKPOINT_2, LOG_CHECKPOINT_CHECKSUM_1);
3767
mach_write_to_4(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_CHECKSUM_1, fold);
3769
fold = ut_fold_binary(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_LSN,
3770
LOG_CHECKPOINT_CHECKSUM_2 - LOG_CHECKPOINT_LSN);
3771
mach_write_to_4(log_buf + LOG_CHECKPOINT_2 + LOG_CHECKPOINT_CHECKSUM_2, fold);
3774
success = os_file_write(src_path, src_file, log_buf, 0, 0, LOG_FILE_HDR_SIZE);
3779
/* expand file size (9/8) and align to UNIV_PAGE_SIZE */
3781
if (file_size % UNIV_PAGE_SIZE) {
3782
memset(log_buf, 0, UNIV_PAGE_SIZE);
3783
success = os_file_write(src_path, src_file, log_buf,
3784
(ulint)(file_size & 0xFFFFFFFFUL),
3785
(ulint)(file_size >> 32),
3786
UNIV_PAGE_SIZE - (file_size % UNIV_PAGE_SIZE));
3791
file_size = os_file_get_size_as_iblonglong(src_file);
3794
/* TODO: We should judge whether the file is already expanded or not... */
3798
memset(log_buf, 0, UNIV_PAGE_SIZE * 128);
3799
expand = file_size / UNIV_PAGE_SIZE / 8;
3801
for (; expand > 128; expand -= 128) {
3802
success = os_file_write(src_path, src_file, log_buf,
3803
(ulint)(file_size & 0xFFFFFFFFUL),
3804
(ulint)(file_size >> 32),
3805
UNIV_PAGE_SIZE * 128);
3809
file_size += UNIV_PAGE_SIZE * 128;
3813
success = os_file_write(src_path, src_file, log_buf,
3814
(ulint)(file_size & 0xFFFFFFFFUL),
3815
(ulint)(file_size >> 32),
3816
expand * UNIV_PAGE_SIZE);
3820
file_size += UNIV_PAGE_SIZE * expand;
3824
/* make larger than 2MB */
3825
if (file_size < 2*1024*1024L) {
3826
memset(log_buf, 0, UNIV_PAGE_SIZE);
3827
while (file_size < 2*1024*1024L) {
3828
success = os_file_write(src_path, src_file, log_buf,
3829
(ulint)(file_size & 0xFFFFFFFFUL),
3830
(ulint)(file_size >> 32),
3835
file_size += UNIV_PAGE_SIZE;
3837
file_size = os_file_get_size_as_iblonglong(src_file);
3840
printf("xtrabackup: xtrabackup_logfile detected: size=%"PRIu64", start_lsn=(%"PRIu64")\n",
3841
file_size, max_lsn);
3843
os_file_close(src_file);
3846
/* Backup log parameters */
3847
innobase_log_group_home_dir_backup = innobase_log_group_home_dir;
3848
innobase_log_file_size_backup = innobase_log_file_size;
3849
innobase_log_files_in_group_backup = innobase_log_files_in_group;
3852
innobase_log_group_home_dir = NULL;
3853
innobase_log_file_size = file_size;
3854
innobase_log_files_in_group = 1;
3856
srv_thread_concurrency = 0;
3858
/* rename 'xtrabackup_logfile' to 'ib_logfile0' */
3859
success = os_file_rename(
3860
0 /* dummy of innodb_file_data_key */,
3861
src_path, dst_path);
3865
xtrabackup_logfile_is_renamed = TRUE;
3872
os_file_close(src_file);
3879
os_file_close(src_file);
3882
fprintf(stderr, "xtrabackup: Error: xtrabackup_init_temp_log() failed.\n");
3883
return(TRUE); /*ERROR*/
3886
/***********************************************************************
3887
Generates path to the meta file path from a given path to an incremental .delta
3888
by replacing trailing ".delta" with ".meta", or returns error if 'delta_path'
3889
does not end with the ".delta" character sequence.
3890
@return TRUE on success, FALSE on error. */
3894
const char *delta_path, /* in: path to a .delta file */
3895
char *meta_path) /* out: path to the corresponding .meta
3898
size_t len = strlen(delta_path);
3900
if (len <= 6 || strcmp(delta_path + len - 6, ".delta")) {
3903
memcpy(meta_path, delta_path, len - 6);
3904
strcpy(meta_path + len - 6, XB_DELTA_INFO_SUFFIX);
3910
xtrabackup_apply_delta(
3911
const char* dirname, /* in: dir name of incremental */
3912
const char* dbname, /* in: database name (ibdata: NULL) */
3913
const char* filename, /* in: file name (not a path),
3914
including the .delta extension */
3917
os_file_t src_file = -1;
3918
os_file_t dst_file = -1;
3919
char src_path[FN_REFLEN];
3920
char dst_path[FN_REFLEN];
3921
char meta_path[FN_REFLEN];
3924
ibool last_buffer = FALSE;
3925
ulint page_in_buffer;
3926
ulint incremental_buffers = 0;
3928
xb_delta_info_t info;
3930
ulint page_size_shift;
3932
ut_a(xtrabackup_incremental);
3935
snprintf(src_path, sizeof(src_path), "%s/%s/%s",
3936
dirname, dbname, filename);
3937
snprintf(dst_path, sizeof(dst_path), "%s/%s/%s",
3938
xtrabackup_real_target_dir, dbname, filename);
3940
snprintf(src_path, sizeof(src_path), "%s/%s",
3942
snprintf(dst_path, sizeof(dst_path), "%s/%s",
3943
xtrabackup_real_target_dir, filename);
3945
dst_path[strlen(dst_path) - 6] = '\0';
3947
if (!get_meta_path(src_path, meta_path)) {
3951
srv_normalize_path_for_win(dst_path);
3952
srv_normalize_path_for_win(src_path);
3953
srv_normalize_path_for_win(meta_path);
3955
if (!xb_read_delta_metadata(meta_path, &info)) {
3959
page_size = info.page_size;
3960
page_size_shift = get_bit_shift(page_size);
3961
fprintf(stderr, "xtrabackup: page size for %s is %lu bytes\n",
3962
src_path, page_size);
3963
if (page_size_shift < 10 ||
3964
page_size_shift > UNIV_PAGE_SIZE_SHIFT_MAX) {
3966
"xtrabackup: error: invalid value of page_size "
3967
"(%lu bytes) read from %s\n", page_size, meta_path);
3971
src_file = os_file_create_simple_no_error_handling(
3972
0 /* dummy of innodb_file_data_key */,
3973
src_path, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success);
3975
os_file_get_last_error(TRUE);
3977
"xtrabackup: error: cannot open %s\n",
3982
#ifdef USE_POSIX_FADVISE
3983
posix_fadvise(src_file, 0, 0, POSIX_FADV_SEQUENTIAL);
3984
posix_fadvise(src_file, 0, 0, POSIX_FADV_DONTNEED);
3987
if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
3988
os_file_set_nocache(src_file, src_path, "OPEN");
3991
dst_file = os_file_create_simple_no_error_handling(
3992
0 /* dummy of innodb_file_data_key */,
3993
dst_path, OS_FILE_OPEN, OS_FILE_READ_WRITE, &success);
3995
os_file_get_last_error(TRUE);
3997
"xtrabackup: error: cannot open %s\n",
4002
#ifdef USE_POSIX_FADVISE
4003
posix_fadvise(dst_file, 0, 0, POSIX_FADV_DONTNEED);
4006
if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
4007
os_file_set_nocache(dst_file, dst_path, "OPEN");
4010
printf("Applying %s ...\n", src_path);
4012
while (!last_buffer) {
4013
ulint cluster_header;
4015
/* read to buffer */
4016
/* first block of block cluster */
4017
success = os_file_read(src_file, incremental_buffer,
4018
((incremental_buffers * (page_size / 4))
4019
<< page_size_shift) & 0xFFFFFFFFUL,
4020
(incremental_buffers * (page_size / 4))
4021
>> (32 - page_size_shift),
4027
cluster_header = mach_read_from_4(incremental_buffer);
4028
switch(cluster_header) {
4029
case 0x78747261UL: /*"xtra"*/
4031
case 0x58545241UL: /*"XTRA"*/
4036
"xtrabackup: error: %s seems not .delta file.\n",
4041
for (page_in_buffer = 1; page_in_buffer < page_size / 4;
4043
if (mach_read_from_4(incremental_buffer + page_in_buffer * 4)
4048
ut_a(last_buffer || page_in_buffer == page_size / 4);
4050
/* read whole of the cluster */
4051
success = os_file_read(src_file, incremental_buffer,
4052
((incremental_buffers * (page_size / 4))
4053
<< page_size_shift) & 0xFFFFFFFFUL,
4054
(incremental_buffers * (page_size / 4))
4055
>> (32 - page_size_shift),
4056
page_in_buffer * page_size);
4061
for (page_in_buffer = 1; page_in_buffer < page_size / 4;
4063
ulint offset_on_page;
4065
offset_on_page = mach_read_from_4(incremental_buffer + page_in_buffer * 4);
4067
if (offset_on_page == 0xFFFFFFFFUL)
4070
/* apply blocks in the cluster */
4071
// if (ut_dulint_cmp(incremental_lsn,
4072
// MACH_READ_64(incremental_buffer
4073
// + page_in_buffer * page_size
4074
// + FIL_PAGE_LSN)) >= 0)
4077
success = os_file_write(dst_path, dst_file,
4078
incremental_buffer +
4079
page_in_buffer * page_size,
4080
(offset_on_page << page_size_shift) &
4082
offset_on_page >> (32 - page_size_shift),
4089
incremental_buffers++;
4093
os_file_close(src_file);
4095
os_file_close(dst_file);
4100
os_file_close(src_file);
4102
os_file_close(dst_file);
4103
fprintf(stderr, "xtrabackup: Error: xtrabackup_apply_delta() failed.\n");
4108
xtrabackup_apply_deltas(bool check_newer)
4111
char dbpath[FN_REFLEN];
4113
os_file_dir_t dbdir;
4114
os_file_stat_t dbinfo;
4115
os_file_stat_t fileinfo;
4116
ulint err = DB_SUCCESS;
4117
static char current_dir[2];
4119
current_dir[0] = FN_CURLIB;
4121
srv_data_home = current_dir;
4124
dbdir = os_file_opendir(xtrabackup_incremental_dir, FALSE);
4126
if (dbdir != NULL) {
4127
ret = fil_file_readdir_next_file(&err, xtrabackup_incremental_dir, dbdir,
4130
if (fileinfo.type == OS_FILE_TYPE_DIR) {
4131
goto next_file_item_1;
4134
if (strlen(fileinfo.name) > 6
4135
&& 0 == strcmp(fileinfo.name +
4136
strlen(fileinfo.name) - 6,
4138
xtrabackup_apply_delta(
4139
xtrabackup_incremental_dir, NULL,
4140
fileinfo.name, check_newer);
4143
ret = fil_file_readdir_next_file(&err,
4144
xtrabackup_incremental_dir, dbdir,
4148
os_file_closedir(dbdir);
4150
fprintf(stderr, "xtrabackup: Cannot open dir %s\n", xtrabackup_incremental_dir);
4153
/* single table tablespaces */
4154
dir = os_file_opendir(xtrabackup_incremental_dir, FALSE);
4157
fprintf(stderr, "xtrabackup: Cannot open dir %s\n", xtrabackup_incremental_dir);
4160
ret = fil_file_readdir_next_file(&err, xtrabackup_incremental_dir, dir,
4163
if (dbinfo.type == OS_FILE_TYPE_FILE
4164
|| dbinfo.type == OS_FILE_TYPE_UNKNOWN) {
4166
goto next_datadir_item;
4169
sprintf(dbpath, "%s/%s", xtrabackup_incremental_dir,
4171
srv_normalize_path_for_win(dbpath);
4173
dbdir = os_file_opendir(dbpath, FALSE);
4175
if (dbdir != NULL) {
4177
ret = fil_file_readdir_next_file(&err, dbpath, dbdir,
4181
if (fileinfo.type == OS_FILE_TYPE_DIR) {
4183
goto next_file_item_2;
4186
if (strlen(fileinfo.name) > 6
4187
&& 0 == strcmp(fileinfo.name +
4188
strlen(fileinfo.name) - 6,
4190
/* The name ends in .delta; try opening
4192
xtrabackup_apply_delta(
4193
xtrabackup_incremental_dir, dbinfo.name,
4194
fileinfo.name, check_newer);
4197
ret = fil_file_readdir_next_file(&err,
4202
os_file_closedir(dbdir);
4205
ret = fil_file_readdir_next_file(&err,
4206
xtrabackup_incremental_dir,
4210
os_file_closedir(dir);
4215
xtrabackup_close_temp_log(bool clear_flag)
4217
os_file_t src_file = -1;
4218
char src_path[FN_REFLEN];
4219
char dst_path[FN_REFLEN];
4223
byte* log_buf_ = NULL;
4226
if (!xtrabackup_logfile_is_renamed)
4229
/* Restore log parameters */
4230
innobase_log_group_home_dir = innobase_log_group_home_dir_backup;
4231
innobase_log_file_size = innobase_log_file_size_backup;
4232
innobase_log_files_in_group = innobase_log_files_in_group_backup;
4234
/* rename 'ib_logfile0' to 'xtrabackup_logfile' */
4235
if(!xtrabackup_incremental_dir) {
4236
sprintf(dst_path, "%s%s", xtrabackup_target_dir, "/ib_logfile0");
4237
sprintf(src_path, "%s%s", xtrabackup_target_dir, "/xtrabackup_logfile");
4239
sprintf(dst_path, "%s%s", xtrabackup_incremental_dir, "/ib_logfile0");
4240
sprintf(src_path, "%s%s", xtrabackup_incremental_dir, "/xtrabackup_logfile");
4243
srv_normalize_path_for_win(dst_path);
4244
srv_normalize_path_for_win(src_path);
4246
success = os_file_rename(
4247
0 /* dummy of innodb_file_data_key */,
4248
dst_path, src_path);
4252
xtrabackup_logfile_is_renamed = FALSE;
4257
/* clear LOG_FILE_WAS_CREATED_BY_HOT_BACKUP field */
4258
src_file = os_file_create_simple_no_error_handling(
4259
0 /* dummy of innodb_file_data_key */,
4260
src_path, OS_FILE_OPEN,
4261
OS_FILE_READ_WRITE, &success);
4266
#ifdef USE_POSIX_FADVISE
4267
posix_fadvise(src_file, 0, 0, POSIX_FADV_DONTNEED);
4270
if (srv_unix_file_flush_method == SRV_UNIX_O_DIRECT) {
4271
os_file_set_nocache(src_file, src_path, "OPEN");
4274
log_buf_ = (unsigned char*) ut_malloc(LOG_FILE_HDR_SIZE * 2);
4275
log_buf = (unsigned char*) ut_align(log_buf_, LOG_FILE_HDR_SIZE);
4277
success = os_file_read(src_file, log_buf, 0, 0, LOG_FILE_HDR_SIZE);
4282
memset(log_buf + LOG_FILE_WAS_CREATED_BY_HOT_BACKUP, ' ', 4);
4284
success = os_file_write(src_path, src_file, log_buf, 0, 0, LOG_FILE_HDR_SIZE);
4289
os_file_close(src_file);
4295
os_file_close(src_file);
4298
fprintf(stderr, "xtrabackup: Error: xtrabackup_close_temp_log() failed.\n");
4299
return(TRUE); /*ERROR*/
4303
xtrabackup_prepare_func(void)
4305
/* cd to target-dir */
4307
if (chdir(xtrabackup_real_target_dir) != 0)
4309
fprintf(stderr, "xtrabackup: cannot my_setwd %s\n", xtrabackup_real_target_dir);
4312
fprintf(stderr, "xtrabackup: cd to %s\n", xtrabackup_real_target_dir);
4314
xtrabackup_target_dir= mysql_data_home_buff;
4315
mysql_data_home_buff[0]=FN_CURLIB; // all paths are relative from here
4316
mysql_data_home_buff[1]=0;
4318
/* read metadata of target */
4320
char filename[FN_REFLEN];
4322
sprintf(filename, "%s/%s", xtrabackup_target_dir, XTRABACKUP_METADATA_FILENAME);
4324
if (xtrabackup_read_metadata(filename))
4325
fprintf(stderr, "xtrabackup: error: xtrabackup_read_metadata()\n");
4327
if (!strcmp(metadata_type, "full-backuped")) {
4328
fprintf(stderr, "xtrabackup: This target seems to be not prepared yet.\n");
4329
} else if (!strcmp(metadata_type, "full-prepared")) {
4330
fprintf(stderr, "xtrabackup: This target seems to be already prepared.\n");
4333
fprintf(stderr, "xtrabackup: This target seems not to have correct metadata...\n");
4336
if (xtrabackup_incremental) {
4338
"xtrabackup: error: applying incremental backup needs target prepared.\n");
4342
if (xtrabackup_incremental
4343
&& ut_dulint_cmp(metadata_to_lsn, incremental_lsn) != 0) {
4345
"xtrabackup: error: This incremental backup seems not to be proper for the target.\n"
4346
"xtrabackup: Check 'to_lsn' of the target and 'from_lsn' of the incremental.\n");
4351
/* Create logfiles for recovery from 'xtrabackup_logfile', before start InnoDB */
4352
srv_max_n_threads = 1000;
4353
os_sync_mutex = NULL;
4356
/* temporally dummy value to avoid crash */
4357
srv_page_size_shift = 14;
4358
srv_page_size = (1 << srv_page_size_shift);
4362
os_io_init_simple();
4363
if(xtrabackup_init_temp_log())
4366
if(xtrabackup_incremental)
4367
xtrabackup_apply_deltas(TRUE);
4370
sync_initialized = FALSE;
4372
os_sync_mutex = NULL;
4375
/* check the accessibility of target-dir */
4376
/* ############# TODO ##################### */
4378
if(innodb_init_param())
4381
srv_apply_log_only = (ibool) xtrabackup_apply_log_only;
4383
/* increase IO threads */
4384
if(srv_n_file_io_threads < 10) {
4385
srv_n_file_io_threads = 10;
4388
fprintf(stderr, "xtrabackup: Starting InnoDB instance for recovery.\n"
4389
"xtrabackup: Using %"PRIu64" bytes for buffer pool (set by --use-memory parameter)\n",
4390
xtrabackup_use_memory);
4395
//printf("Hello InnoDB world!\n");
4397
/* TEST: innodb status*/
4399
ulint trx_list_start = ULINT_UNDEFINED;
4400
ulint trx_list_end = ULINT_UNDEFINED;
4401
srv_printf_innodb_monitor(stdout, &trx_list_start, &trx_list_end);
4403
/* TEST: list of datafiles and transaction log files and LSN*/
4406
fil_system_t* f_system = fil_system;
4410
mutex_enter(&(f_system->mutex));
4412
space = UT_LIST_GET_FIRST(f_system->space_list);
4414
while (space != NULL) {
4415
printf("space: name=%s, id=%d, purpose=%d, size=%d\n",
4416
space->name, space->id, space->purpose, space->size);
4418
node = UT_LIST_GET_FIRST(space->chain);
4420
while (node != NULL) {
4421
printf("node: name=%s, open=%d, size=%d\n",
4422
node->name, node->open, node->size);
4424
node = UT_LIST_GET_NEXT(chain, node);
4426
space = UT_LIST_GET_NEXT(space_list, space);
4429
mutex_exit(&(f_system->mutex));
4432
/* align space sizes along with fsp header */
4434
fil_system_t* f_system = fil_system;
4437
mutex_enter(&(f_system->mutex));
4438
space = UT_LIST_GET_FIRST(f_system->space_list);
4440
while (space != NULL) {
4448
if (space->purpose == FIL_TABLESPACE) {
4449
mutex_exit(&(f_system->mutex));
4453
mtr_s_lock(fil_space_get_latch(space->id, &flags), &mtr);
4455
block = buf_page_get(space->id,
4456
dict_table_flags_to_zip_size(flags),
4457
0, RW_S_LATCH, &mtr);
4458
header = FIL_PAGE_DATA /*FSP_HEADER_OFFSET*/
4459
+ buf_block_get_frame(block);
4461
size = mtr_read_ulint(header + 8 /* FSP_SIZE */, MLOG_4BYTES, &mtr);
4465
//printf("%d, %d\n", space->id, size);
4467
fil_extend_space_to_desired_size(&actual_size, space->id, size);
4469
mutex_enter(&(f_system->mutex));
4472
space = UT_LIST_GET_NEXT(space_list, space);
4475
mutex_exit(&(f_system->mutex));
4480
if (xtrabackup_export) {
4481
printf("xtrabackup: export option is specified.\n");
4482
if (innobase_file_per_table) {
4483
fil_system_t* f_system = fil_system;
4486
os_file_t info_file = -1;
4487
char info_file_path[FN_REFLEN];
4489
char table_name[FN_REFLEN];
4494
buf = (byte*) ut_malloc(UNIV_PAGE_SIZE * 2);
4495
page = (byte*) ut_align(buf, UNIV_PAGE_SIZE);
4497
/* flush insert buffer at shutdwon */
4498
innobase_fast_shutdown = 0;
4500
mutex_enter(&(f_system->mutex));
4502
space = UT_LIST_GET_FIRST(f_system->space_list);
4503
while (space != NULL) {
4504
/* treat file_per_table only */
4505
if (space->purpose != FIL_TABLESPACE
4507
|| trx_sys_sys_space(space->id)
4513
space = UT_LIST_GET_NEXT(space_list, space);
4517
node = UT_LIST_GET_FIRST(space->chain);
4518
while (node != NULL) {
4520
char *next, *prev, *p;
4521
dict_table_t* table;
4522
dict_index_t* index;
4525
/* node exist == file exist, here */
4526
strncpy(info_file_path, node->name, FN_REFLEN);
4527
len = strlen(info_file_path);
4528
info_file_path[len - 3] = 'e';
4529
info_file_path[len - 2] = 'x';
4530
info_file_path[len - 1] = 'p';
4534
while ((next = strstr(p, SRV_PATH_SEPARATOR_STR)) != NULL)
4539
info_file_path[len - 4] = 0;
4540
strncpy(table_name, prev, FN_REFLEN);
4542
info_file_path[len - 4] = '.';
4544
mutex_exit(&(f_system->mutex));
4545
mutex_enter(&(dict_sys->mutex));
4547
table = dict_table_get_low(table_name);
4550
"xtrabackup: error: cannot find dictionary record of table %s\n", table_name);
4553
index = dict_table_get_first_index(table);
4554
n_index = UT_LIST_GET_LEN(table->indexes);
4557
"xtrabackup: error: sorry, cannot export over 31 indexes for now.\n");
4562
bzero(page, UNIV_PAGE_SIZE);
4563
mach_write_to_4(page , 0x78706f72UL);
4564
mach_write_to_4(page + 4, 0x74696e66UL);/*"xportinf"*/
4565
mach_write_to_4(page + 8, n_index);
4566
strncpy((char*)page + 12, table_name, 500);
4569
"xtrabackup: export metadata of table '%s' to file `%s` (%lu indexes)\n",
4570
table_name, info_file_path, n_index);
4574
mach_write_to_8(page + n_index * 512, index->id);
4575
mach_write_to_4(page + n_index * 512 + 8,
4578
strncpy((char*)page + n_index * 512 + 12, index->name, 500);
4581
"xtrabackup: name=%s, id.low=%lu, page=%lu\n",
4583
(ulint)(index->id & 0xFFFFFFFFUL),
4585
(ulint) index->page);
4587
index = dict_table_get_next_index(index);
4591
srv_normalize_path_for_win(info_file_path);
4592
info_file = os_file_create(
4593
0 /* dummy of innodb_file_data_key */,
4594
info_file_path, OS_FILE_OVERWRITE,
4595
OS_FILE_NORMAL, OS_DATA_FILE, &success);
4597
os_file_get_last_error(TRUE);
4600
success = os_file_write(info_file_path, info_file, page,
4601
0, 0, UNIV_PAGE_SIZE);
4603
os_file_get_last_error(TRUE);
4606
success = os_file_flush(info_file);
4608
os_file_get_last_error(TRUE);
4612
if (info_file != -1) {
4613
os_file_close(info_file);
4616
mutex_exit(&(dict_sys->mutex));
4617
mutex_enter(&(f_system->mutex));
4619
node = UT_LIST_GET_NEXT(chain, node);
4622
space = UT_LIST_GET_NEXT(space_list, space);
4624
mutex_exit(&(f_system->mutex));
4628
printf("xtrabackup: export option is for file_per_table only, disabled.\n");
4632
/* print binlog position (again?) */
4633
printf("\n[notice (again)]\n"
4634
" If you use binary log and don't use any hack of group commit,\n"
4635
" the binary log position seems to be:\n");
4636
// FIXME: trx_sys_print_mysql_binlog_offset();
4639
/* output to xtrabackup_binlog_pos_innodb */
4641
//FIXME if (*trx_sys_mysql_bin_log_name != '\0') {
4644
fp = fopen("xtrabackup_binlog_pos_innodb", "w");
4646
fprintf(fp, "%s\t%llu\n",
4649
trx_sys_mysql_bin_log_name,
4650
trx_sys_mysql_bin_log_pos);*/
4653
printf("xtrabackup: failed to open 'xtrabackup_binlog_pos_innodb'\n");
4657
/* Check whether the log is applied enough or not. */
4658
if ((xtrabackup_incremental
4659
&& ut_dulint_cmp(srv_start_lsn, incremental_last_lsn) < 0)
4660
||(!xtrabackup_incremental
4661
&& ut_dulint_cmp(srv_start_lsn, metadata_last_lsn) < 0)) {
4662
printf( "xtrabackup: ########################################################\n"
4663
"xtrabackup: # !!WARNING!! #\n"
4664
"xtrabackup: # The transaction log file should be wrong or corrupt. #\n"
4665
"xtrabackup: # The log was not applied to the intended LSN! #\n"
4666
"xtrabackup: ########################################################\n");
4667
if (xtrabackup_incremental) {
4668
printf("xtrabackup: The intended lsn is %"PRIu64"\n",
4669
incremental_last_lsn);
4671
printf("xtrabackup: The intended lsn is %"PRIu64"\n",
4679
sync_initialized = FALSE;
4680
os_sync_mutex = NULL;
4682
/* re-init necessary components */
4687
os_io_init_simple();
4689
if(xtrabackup_close_temp_log(TRUE))
4692
/* output to metadata file */
4694
char filename[FN_REFLEN];
4696
strcpy(metadata_type, "full-prepared");
4698
if(xtrabackup_incremental
4699
&& ut_dulint_cmp(metadata_to_lsn, incremental_to_lsn) < 0)
4701
metadata_to_lsn = incremental_to_lsn;
4702
metadata_last_lsn = incremental_last_lsn;
4705
sprintf(filename, "%s/%s", xtrabackup_target_dir, XTRABACKUP_METADATA_FILENAME);
4706
if (xtrabackup_write_metadata(filename))
4707
fprintf(stderr, "xtrabackup: error: xtrabackup_write_metadata(xtrabackup_target_dir)\n");
4709
if(xtrabackup_extra_lsndir) {
4710
sprintf(filename, "%s/%s", xtrabackup_extra_lsndir, XTRABACKUP_METADATA_FILENAME);
4711
if (xtrabackup_write_metadata(filename))
4712
fprintf(stderr, "xtrabackup: error: xtrabackup_write_metadata(xtrabackup_extra_lsndir)\n");
4716
if(!xtrabackup_create_ib_logfile)
4719
/* TODO: make more smart */
4721
printf("\n[notice]\nWe cannot call InnoDB second time during the process lifetime.\n");
4722
printf("Please re-execte to create ib_logfile*. Sorry.\n");
4724
printf("Restart InnoDB to create ib_logfile*.\n");
4726
if(innodb_init_param())
4739
xtrabackup_close_temp_log(FALSE);
4744
/* ================= main =================== */
4746
int main(int argc, char **argv)
4748
po::options_description commandline_options(_("Options used only in command line"));
4749
commandline_options.add_options()
4750
("target-dir", po::value<std::string>(), _("destination directory"))
4751
("backup", po::value<bool>(&xtrabackup_backup)->default_value(false)->zero_tokens(), _("take backup to target-dir"))
4752
("stats", po::value<bool>(&xtrabackup_stats)->default_value(false)->zero_tokens(), _("calc statistic of datadir (offline mysqld is recommended)"))
4753
("prepare", po::value<bool>(&xtrabackup_prepare)->default_value(false)->zero_tokens(), _("prepare a backup for starting mysql server on the backup."))
4754
("export", po::value<bool>(&xtrabackup_export)->default_value(false)->zero_tokens(), _("create files to import to another database when prepare."))
4755
("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."))
4756
("print-param", po::value<bool>(&xtrabackup_print_param)->default_value(false)->zero_tokens(), _("print parameter of mysqld needed for copyback."))
4757
("use-memory", po::value<uint64_t>(&xtrabackup_use_memory)->default_value(100*1024*1024), _("The value is used instead of buffer_pool_size"))
4758
("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'"))
4759
("throttle", po::value<long>(&xtrabackup_throttle), _("limit count of IO operations (pairs of read&write) per second to IOS values (for '--backup')"))
4760
("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')."))
4761
("extra-lsndir", po::value<std::string>(), _("(for --backup): save an extra copy of the xtrabackup_checkpoints file in this directory."))
4762
("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!"))
4763
("incremental-basedir", po::value<std::string>(), _("(for --backup): copy only .ibd pages newer than backup at specified directory."))
4764
("incremental-dir", po::value<std::string>(), _("(for --prepare): apply .delta files and logfile in the specified directory."))
4765
("tables", po::value<std::string>(), _("filtering by regexp for table names."))
4766
("tables-file", po::value<std::string>(), _("filtering by list of the exact database.table name in the file."))
4767
("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. ###"))
4768
("datadir,h", po::value<std::string>(), _("Path to the database root."))
4769
("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."))
4770
("parallel", po::value<uint32_t>(¶llel)->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."))
4771
("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."))
4772
("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."))
4773
("innodb-autoextend-increment", po::value<uint32_t>(&srv_auto_extend_increment)->default_value(8), _("Data file autoextend increment in megabytes"))
4774
("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."))
4775
("innodb-checksums", po::value<bool>(&innobase_use_checksums)->default_value(true), _("Enable InnoDB checksums validation (enabled by default). Disable with --skip-innodb-checksums."))
4776
("innodb-data-file-path", po::value<std::string>(), _("Path to individual files and their sizes."))
4777
("innodb-data-home-dir", po::value<std::string>(), _("The common part for InnoDB table spaces."))
4778
("innodb-doublewrite", po::value<bool>(&innobase_use_doublewrite)->default_value(true), _("Enable InnoDB doublewrite buffer (enabled by default). Disable with --skip-innodb-doublewrite."))
4779
("innodb-file-io-threads", po::value<long>(&innobase_file_io_threads)->default_value(4), _("Number of file I/O threads in InnoDB."))
4780
("innodb-file-per-table", po::value<bool>(&innobase_file_per_table), _("Stores each InnoDB table to an .ibd file in the database dir."))
4781
("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)."))
4782
("innodb-flush-method", po::value<std::string>(), _("With which method to flush data."))
4783
/* ####### Should we use this option? ####### */
4784
("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."))
4785
("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."))
4786
("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."))
4787
("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."))
4788
("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."))
4789
("innodb-log-group-home-dir", po::value<std::string>(), _("Path to InnoDB log files."))
4790
("innodb-max_dirty-pages-pct", po::value<ulong>(&srv_max_buf_pool_modified_pct)->default_value(90), _("Percentage of dirty pages allowed in bufferpool."))
4791
("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."))
4793
("innodb-page-size", po::value<uint32_t>(&innobase_page_size)->default_value(1 << 14), _("The universal page size of the database."))
4794
("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!"))
4795
("innodb-fast-checksum", po::value<bool>(&innobase_fast_checksum), _("Change the algorithm of checksum for the whole of datapage to 4-bytes word based."))
4796
("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."))
4797
("innodb-doublewrite-file", po::value<char *>(&innobase_doublewrite_file), _("Path to special datafile for doublewrite buffer. (default is "": not used)"))
4801
po::variables_map vm;
4802
// Disable allow_guessing, it is evil and broken
4803
int style = po::command_line_style::default_style & ~po::command_line_style::allow_guessing;
4804
po::store(po::command_line_parser(argc, argv).options(commandline_options).style(style).run(), vm);
4807
if (vm.count("target-dir"))
4808
xtrabackup_target_dir= vm["target-dir"].as<std::string>().c_str();
4810
if (vm.count("extra-lsndir"))
4811
xtrabackup_extra_lsndir= vm["extra-lsndir"].as<std::string>().c_str();
4813
if (vm.count("incremental-lsn"))
4814
xtrabackup_incremental= vm["incremental-lsn"].as<std::string>().c_str();
4816
if (vm.count("incremental-basedir"))
4817
xtrabackup_incremental_basedir= vm["incremental-basedir"].as<std::string>().c_str();
4819
boost::scoped_ptr<char> xtrabackup_tables_autoptr(new char[(vm.count("tables")) ? vm["tables"].as<std::string>().length() + 1: 0]);
4820
if (vm.count("tables"))
4822
xtrabackup_tables= xtrabackup_tables_autoptr.get();
4823
strcpy(xtrabackup_tables, vm["tables"].as<std::string>().c_str());
4826
if (vm.count("tables-file"))
4827
xtrabackup_tables_file= vm["tables-file"].as<std::string>().c_str();
4829
if (vm.count("tmpdir"))
4830
opt_mysql_tmpdir= vm["tmpdir"].as<std::string>().c_str();
4832
if (vm.count("innodb-data-file-path"))
4833
innobase_data_file_path= vm["innodb-data-file-path"].as<std::string>().c_str();
4835
boost::scoped_ptr<char> xtrabackup_incremental_dir_autoptr(new char[(vm.count("incremental-dir")) ? vm["incremental-dir"].as<std::string>().length() + 1: 0]);
4836
if (vm.count("incremental-dir"))
4838
xtrabackup_incremental_dir= xtrabackup_incremental_dir_autoptr.get();
4839
strcpy(xtrabackup_incremental_dir, vm["incremental-dir"].as<std::string>().c_str());
4842
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]);
4843
if (vm.count("innodb-data-home-dir"))
4845
innobase_data_home_dir= innobase_data_home_dir_autoptr.get();
4846
strcpy(innobase_data_home_dir, vm["innodb-data-home-dir"].as<std::string>().c_str());
4849
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]);
4850
if (vm.count("innodb-flush-method"))
4852
innobase_unix_file_flush_method= innobase_flush_method_autoptr.get();
4853
strcpy(innobase_unix_file_flush_method, vm["innodb-flush-method"].as<std::string>().c_str());
4856
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]);
4858
if (vm.count("innodb-log-group-home-dir"))
4860
innobase_log_group_home_dir= innobase_log_group_home_dir_autoptr.get();
4861
strcpy(innobase_log_group_home_dir, vm["innodb-log-group-home-dir"].as<std::string>().c_str());
4864
xtrabackup_use_memory-= xtrabackup_use_memory % (1024*1024);
4865
if (xtrabackup_use_memory < (1024*1024)) {
4866
fprintf(stderr, "xtrabackup: use-memory out of range\n");
4871
fprintf(stderr, "xtrabackup: parallel needs to be greater than 0\n");
4875
innobase_additional_mem_pool_size-= innobase_additional_mem_pool_size % 1024;
4876
if (innobase_additional_mem_pool_size < (512*1024)) {
4877
fprintf(stderr, "xtrabackup: innodb-additional-mem-pool-size out of range\n");
4881
if ((srv_auto_extend_increment < 1) || (srv_auto_extend_increment > 8)) {
4882
fprintf(stderr, "xtrabackup: innodb-auto-extend-increment out of range\n");
4886
innobase_buffer_pool_size-= innobase_buffer_pool_size % (1024*1024);
4887
if (innobase_buffer_pool_size < (1024*1024)) {
4888
fprintf(stderr, "xtrabackup: innodb-buffer-pool-size out of range\n");
4892
if ((innobase_file_io_threads < 4) || (innobase_file_io_threads > 64)) {
4893
fprintf(stderr, "xtrabackup: innodb-file-io-threads out of range\n");
4897
if (srv_flush_log_at_trx_commit > 2) {
4898
fprintf(stderr, "xtrabackup: innodb-flush-log-at-trx-commit out of range\n");
4902
if (innobase_force_recovery > 6) {
4903
fprintf(stderr, "xtrabackup: innodb-force-recovery out of range\n");
4907
if ((innobase_lock_wait_timeout < 1) || (innobase_lock_wait_timeout > (1024*1024*1024))) {
4908
fprintf(stderr, "xtrabackup: innodb-lock-wait-timeout out of range\n");
4912
innobase_log_buffer_size-= innobase_log_buffer_size % 1024;
4913
if (innobase_additional_mem_pool_size < (256*1024)) {
4914
fprintf(stderr, "xtrabackup: innodb-log-buffer-size out of range\n");
4918
if (innobase_additional_mem_pool_size < (1024*1024)) {
4919
fprintf(stderr, "xtrabackup: innodb-log-file-size out of range\n");
4923
if ((innobase_log_files_in_group < 2) || (innobase_log_files_in_group > (100))) {
4924
fprintf(stderr, "xtrabackup: innodb-log-files-in-group out of range\n");
4928
if (srv_max_buf_pool_modified_pct > 100) {
4929
fprintf(stderr, "xtrabackup: innodb-max-buf-pool-modified-pct out of range\n");
4933
if (innobase_open_files < 10) {
4934
fprintf(stderr, "xtrabackup: innodb-open-files out of range\n");
4938
if ((innobase_page_size < (1 << 12)) || (innobase_page_size > (1 << UNIV_PAGE_SIZE_SHIFT_MAX))) {
4939
fprintf(stderr, "xtrabackup: innodb-page-size out of range\n");
4943
if ((innobase_log_block_size < (512)) || (innobase_log_block_size > (1 << UNIV_PAGE_SIZE_SHIFT_MAX))) {
4944
fprintf(stderr, "xtrabackup: innodb-log-block-size out of range\n");
4948
if (vm.count("datadir"))
4950
mysql_data_home_arg.assign(vm["datadir"].as<std::string>());
4954
mysql_data_home_arg.assign(LOCALSTATEDIR);
4957
mysql_data_home= (char*)malloc(mysql_data_home_arg.length());
4958
strcpy(mysql_data_home, mysql_data_home_arg.c_str());
4960
if ((!xtrabackup_prepare) && (strcmp(mysql_data_home, "./") == 0)) {
4961
if (!xtrabackup_print_param)
4963
printf("\nxtrabackup: Error: Please set parameter 'datadir'\n");
4967
if (xtrabackup_tables) {
4973
tables_regex_num = 1;
4975
p = xtrabackup_tables;
4976
while ((p = strchr(p, ',')) != NULL) {
4981
tables_regex = (regex_t*) ut_malloc(sizeof(regex_t) * tables_regex_num);
4983
p = xtrabackup_tables;
4984
for (i=0; i < tables_regex_num; i++) {
4985
next = strchr(p, ',');
4986
ut_a(next || i == tables_regex_num - 1);
4989
if (i != tables_regex_num - 1)
4992
regerror(regcomp(&tables_regex[i],p,REG_EXTENDED),
4993
&tables_regex[i],errbuf,sizeof(errbuf));
4994
fprintf(stderr, "xtrabackup: tables regcomp(%s): %s\n",p,errbuf);
4996
if (i != tables_regex_num - 1)
5002
if (xtrabackup_tables_file) {
5003
char name_buf[NAME_LEN*2+2];
5006
if (xtrabackup_stream) {
5007
fprintf(stderr, "xtrabackup: Warning: --tables_file option doesn't affect with --stream.\n");
5008
xtrabackup_tables_file = NULL;
5009
goto skip_tables_file_register;
5012
name_buf[NAME_LEN*2+1] = '\0';
5014
/* init tables_hash */
5015
tables_hash = hash_create(1000);
5017
/* read and store the filenames */
5018
fp = fopen(xtrabackup_tables_file,"r");
5020
fprintf(stderr, "xtrabackup: cannot open %s\n", xtrabackup_tables_file);
5024
xtrabackup_tables_t* table;
5027
if ( fgets(name_buf, NAME_LEN*2+1, fp) == 0 ) {
5031
while (*p != '\0') {
5037
p = strchr(name_buf, '\n');
5043
table = (xtrabackup_tables_t*) malloc(sizeof(xtrabackup_tables_t) + strlen(name_buf) + 1);
5044
memset(table, '\0', sizeof(xtrabackup_tables_t) + strlen(name_buf) + 1);
5045
table->name = ((char*)table) + sizeof(xtrabackup_tables_t);
5046
strcpy(table->name, name_buf);
5048
HASH_INSERT(xtrabackup_tables_t, name_hash, tables_hash,
5049
ut_fold_string(table->name), table);
5051
printf("xtrabackup: table '%s' is registerd to the list.\n", table->name);
5054
skip_tables_file_register:
5057
/* temporary setting of enough size */
5058
srv_page_size_shift = UNIV_PAGE_SIZE_SHIFT_MAX;
5059
srv_page_size = UNIV_PAGE_SIZE_MAX;
5060
srv_log_block_size = 512;
5062
if (xtrabackup_backup && xtrabackup_incremental) {
5063
/* direct specification is only for --backup */
5064
/* and the lsn is prior to the other option */
5069
incremental_lsn = strtoll(xtrabackup_incremental, &endchar, 10);
5070
if (*endchar != '\0')
5074
fprintf(stderr, "xtrabackup: value '%s' may be wrong format for incremental option.\n",
5075
xtrabackup_incremental);
5079
/* allocate buffer for incremental backup (4096 pages) */
5080
incremental_buffer_base = (byte*) malloc((UNIV_PAGE_SIZE_MAX / 4 + 1) *
5081
UNIV_PAGE_SIZE_MAX);
5082
incremental_buffer = (byte*) ut_align(incremental_buffer_base,
5083
UNIV_PAGE_SIZE_MAX);
5084
} else if (xtrabackup_backup && xtrabackup_incremental_basedir) {
5085
char filename[FN_REFLEN];
5087
sprintf(filename, "%s/%s", xtrabackup_incremental_basedir, XTRABACKUP_METADATA_FILENAME);
5089
if (xtrabackup_read_metadata(filename)) {
5091
"xtrabackup: error: failed to read metadata from %s\n",
5096
incremental_lsn = metadata_to_lsn;
5097
xtrabackup_incremental = xtrabackup_incremental_basedir; //dummy
5099
/* allocate buffer for incremental backup (4096 pages) */
5100
incremental_buffer_base = (byte*) malloc((UNIV_PAGE_SIZE_MAX / 4 + 1) *
5101
UNIV_PAGE_SIZE_MAX);
5102
incremental_buffer = (byte*) ut_align(incremental_buffer_base,
5103
UNIV_PAGE_SIZE_MAX);
5104
} else if (xtrabackup_prepare && xtrabackup_incremental_dir) {
5105
char filename[FN_REFLEN];
5107
sprintf(filename, "%s/%s", xtrabackup_incremental_dir, XTRABACKUP_METADATA_FILENAME);
5109
if (xtrabackup_read_metadata(filename)) {
5111
"xtrabackup: error: failed to read metadata from %s\n",
5116
incremental_lsn = metadata_from_lsn;
5117
incremental_to_lsn = metadata_to_lsn;
5118
incremental_last_lsn = metadata_last_lsn;
5119
xtrabackup_incremental = xtrabackup_incremental_dir; //dummy
5121
/* allocate buffer for incremental backup (4096 pages) */
5122
incremental_buffer_base = (byte*) malloc((UNIV_PAGE_SIZE / 4 + 1) *
5124
incremental_buffer = (byte*) ut_align(incremental_buffer_base,
5127
/* allocate buffer for applying incremental (for header page only) */
5128
incremental_buffer_base = (byte*) malloc((1 + 1) * UNIV_PAGE_SIZE_MAX);
5129
incremental_buffer = (byte*) ut_align(incremental_buffer_base,
5130
UNIV_PAGE_SIZE_MAX);
5132
xtrabackup_incremental = NULL;
5136
if (xtrabackup_print_param) {
5137
printf("# This MySQL options file was generated by XtraBackup.\n");
5138
printf("[mysqld]\n");
5139
printf("datadir = \"%s\"\n", mysql_data_home);
5140
printf("tmpdir = \"%s\"\n", opt_mysql_tmpdir);
5141
printf("innodb_data_home_dir = \"%s\"\n",
5142
innobase_data_home_dir ? innobase_data_home_dir : mysql_data_home);
5143
printf("innodb_data_file_path = \"%s\"\n",
5144
innobase_data_file_path ? innobase_data_file_path : "ibdata1:10M:autoextend");
5145
printf("innodb_log_group_home_dir = \"%s\"\n",
5146
innobase_log_group_home_dir ? innobase_log_group_home_dir : mysql_data_home);
5147
printf("innodb_log_files_in_group = %ld\n", innobase_log_files_in_group);
5148
printf("innodb_log_file_size = %"PRIu64"\n", (uint64_t)innobase_log_file_size);
5149
printf("innodb_flush_method = \"%s\"\n",
5150
(innobase_unix_file_flush_method != NULL) ?
5151
innobase_unix_file_flush_method : "");
5155
if (!xtrabackup_stream) {
5157
if (xtrabackup_incremental) {
5158
printf("incremental backup from %"PRIu64" is enabled.\n",
5162
if (xtrabackup_backup) {
5163
xtrabackup_suspend_at_end = TRUE;
5164
fprintf(stderr, "xtrabackup: suspend-at-end is enabled.\n");
5168
/* cannot execute both for now */
5172
if (xtrabackup_backup) num++;
5173
if (xtrabackup_stats) num++;
5174
if (xtrabackup_prepare) num++;
5175
if (num != 1) { /* !XOR (for now) */
5182
if (xtrabackup_backup)
5183
xtrabackup_backup_func();
5186
if (xtrabackup_stats)
5187
xtrabackup_stats_func();
5190
if (xtrabackup_prepare)
5191
xtrabackup_prepare_func();
5193
free(incremental_buffer_base);
5195
if (xtrabackup_tables) {
5199
for (i = 0; i < tables_regex_num; i++) {
5200
regfree(&tables_regex[i]);
5202
ut_free(tables_regex);
5205
if (xtrabackup_tables_file) {
5208
/* free the hash elements */
5209
for (i = 0; i < hash_get_n_cells(tables_hash); i++) {
5210
xtrabackup_tables_t* table;
5212
table = (xtrabackup_tables_t*)
5213
HASH_GET_FIRST(tables_hash, i);
5216
xtrabackup_tables_t* prev_table = table;
5218
table = (xtrabackup_tables_t*)
5219
HASH_GET_NEXT(name_hash, prev_table);
5221
HASH_DELETE(xtrabackup_tables_t, name_hash, tables_hash,
5222
ut_fold_string(prev_table->name), prev_table);
5227
/* free tables_hash */
5228
hash_table_free(tables_hash);