3
# A script for making backups of InnoDB and MyISAM tables, indexes and .frm
6
# Copyright 2003, 2009 Innobase Oy and Percona Inc 2009-2011. All Rights Reserved.
12
use Pod::Usage qw(pod2usage);
14
use POSIX ":sys_wait_h";
18
use English qw(-no_match_vars);
20
# version of this script
21
my $innobackup_version = '1.5.1-xtrabackup';
22
my $innobackup_script = basename($0);
25
my $copyright_notice =
26
"InnoDB Backup Utility v${innobackup_version}; Copyright 2003, 2009 Innobase Oy
27
and Percona Inc 2009-2011. All Rights Reserved.
29
This software is published under
30
the GNU GENERAL PUBLIC LICENSE Version 2, June 1991.
34
# required Perl version (5.005)
35
my @required_perl_version = (5, 0, 5);
36
my $required_perl_version_old_style = 5.005;
38
# force flush after every write and print
41
######################################################################
42
# modifiable parameters
43
######################################################################
45
# maximum number of files in a database directory which are
46
# separately printed when a backup is made
47
my $backup_file_print_limit = 9;
49
# timeout in seconds for a reply from mysql
50
my $mysql_response_timeout = 900;
52
# default compression level (this is an argument to ibbackup)
53
my $default_compression_level = 1;
55
# time in seconds after which a dummy query is sent to mysql server
56
# in order to keep the database connection alive
57
my $mysql_keep_alive_timeout = 1800;
59
######################################################################
60
# end of modifiable parameters
61
######################################################################
64
# command line options
66
my $option_version = '';
67
my $option_apply_log = '';
68
my $option_redo_only = '';
69
my $option_copy_back = '';
70
my $option_include = '';
71
my $option_databases = '';
72
my $option_tables_file = '';
73
my $option_throttle = '';
74
my $option_sleep = '';
75
my $option_compress = 999;
76
my $option_uncompress = '';
77
my $option_export = '';
78
my $option_use_memory = '';
79
my $option_mysql_password = '';
80
my $option_mysql_user = '';
81
my $option_mysql_port = '';
82
my $option_mysql_socket = '';
83
my $option_mysql_host = '';
84
my $option_no_timestamp = '';
85
my $option_slave_info = '';
86
my $option_no_lock = '';
87
my $option_ibbackup_binary = 'autodetect';
89
my $option_defaults_file = '';
90
my $option_incremental = '';
91
my $option_incremental_basedir = '';
92
my $option_incremental_dir = '';
93
my $option_incremental_lsn = '';
94
my $option_extra_lsndir = '';
95
my $option_remote_host = '';
96
my $option_stream = '';
97
my $option_tmpdir = '';
99
my $option_tar4ibd = '';
100
my $option_force_tar = '';
101
my $option_scp_opt = '-Cp -c arcfour';
103
my $option_parallel = '';
105
my $option_safe_slave_backup = '';
106
my $option_safe_slave_backup_timeout = 300;
108
# name of the my.cnf configuration file
109
#my $config_file = '';
111
# root of the backup directory
112
my $backup_root = '';
114
# backup directory pathname
117
# name of the ibbackup suspend-at-end file
118
my $suspend_file = '';
120
# name of the temporary transaction log file during the backup
121
my $tmp_logfile = '';
123
# home directory of innoDB log files
124
my $innodb_log_group_home_dir = '';
127
my $backup_config_file = '';
129
# options from the options file
132
# options from the backup options file
135
# list of databases to be included in a backup
138
# list of tables to be included in a backup
141
# prefix for output lines
142
my $prefix = "$innobackup_script:";
144
# process id of mysql client program (runs as a child process of this script)
147
# mysql server version string
148
my $mysql_server_version = '';
150
# name of the file where stderr of mysql process is directed
151
my $mysql_stderr = 'stderr';
153
# name of the file where stdout of mysql process is directed
154
my $mysql_stdout = 'stdout';
156
# name of the file where binlog position info is written
159
# name of the file where slave info is written
162
# mysql binlog position as given by "SHOW MASTER STATUS" command
163
my $mysql_binlog_position = '';
165
# mysql master's binlog position as given by "SHOW SLAVE STATUS" command
166
# run on a slave server
167
my $mysql_slave_position = '';
169
# time of the most recent mysql_check call. (value returned by time() function)
170
my $mysql_last_access_time = 0;
172
# process id of ibbackup program (runs as a child process of this script)
173
my $ibbackup_pid = '';
175
# a counter for numbering mysql connection checks
178
# the request which has been sent to mysqld, but to which
179
# mysqld has not yet replied. Empty string denotes that no
180
# request has been sent to mysqld or that mysqld has replied
182
my $current_mysql_request = '';
184
# escape sequences for options files
185
my %option_value_escapes = ('b' => "\b",
192
# signal that is sent to child processes when they are killed
193
my $kill_signal = 15;
198
# incremental backup base directory
199
my $incremental_basedir = '';
203
my $win = ($^O eq 'MSWin32' ? 1 : 0);
204
my $CP_CMD = ($win eq 1 ? "copy /Y" : "cp -p");
205
my $xtrabackup_binary_file = 'xtrabackup_binary';
206
######################################################################
207
# program execution begins here
208
######################################################################
210
# check command-line args
213
# print program version and copyright
216
# initialize global variables and perform some checks
217
if ($option_copy_back) {
218
$option_ibbackup_binary = 'xtrabackup_51';
219
} elsif ($option_apply_log) {
220
# Read XtraBackup version from backup dir
221
if (-e "$backup_dir/$xtrabackup_binary_file") {
222
# Read XtraBackup version from file
223
open XTRABACKUP_BINARY, "$backup_dir/$xtrabackup_binary_file"
224
or die "Cannot open file $backup_dir/$xtrabackup_binary_file: $!\n";
225
$option_ibbackup_binary = <XTRABACKUP_BINARY>;
226
close XTRABACKUP_BINARY;
230
if( $option_ibbackup_binary eq "autodetect" ){
231
# Try to connect MySQL and get the version
232
print "option_ibbackup_binary is autodetect, trying to connect to MySQL\n";
233
my $options = get_mysql_options();
234
$mysql_pid = open(*MYSQL_WRITER, "| mysql $options >$mysql_stdout 2>$mysql_stderr ");
235
print "Connected to MySQL with pid $mysql_pid\n";
237
if ($mysql_pid && $mysql_pid == waitpid($mysql_pid, &WNOHANG)) {
238
my $reason = `cat $mysql_stderr`;
240
# Failed to connect to MySQL
241
die "Failed to connect to MySQL server to detect version.\nYou must set xtrabackup version to use with --ibbackup option.\nPossible values are xtrabackup_51 (for MySQL 5.0 and 5.1) or xtrabackup (for MySQL 5.1 with InnoDB plugin or Percona Server)\n";
245
print "Connected successfully\n";
246
$option_ibbackup_binary = set_xtrabackup_version();
251
$option_ibbackup_binary = set_xtrabackup_version();
255
my $ibbackup_exit_code = 0;
257
if ($option_copy_back) {
258
# copy files from backup directory back to their original locations
260
} elsif ($option_apply_log) {
261
# expand data files in backup directory by applying log files to them
264
# make a backup of InnoDB and MyISAM tables, indexes and .frm files.
265
$ibbackup_exit_code = backup();
266
open XTRABACKUP_BINARY, "> $backup_dir/$xtrabackup_binary_file"
267
or die "Cannot open file $backup_dir/$xtrabackup_binary_file: $!\n";
268
print XTRABACKUP_BINARY $option_ibbackup_binary;
269
close XTRABACKUP_BINARY;
272
$now = current_time();
274
if ($option_stream eq 'tar') {
275
print STDERR "$prefix You must use -i (--ignore-zeros) option for extraction of the tar stream.\n";
278
if ( $ibbackup_exit_code == 0 ) {
279
# program has completed successfully
280
print STDERR "$now $prefix completed OK!\n";
283
print STDERR "$now $prefix $option_ibbackup_binary failed! (exit code $ibbackup_exit_code) The backup may not be complete.\n";
286
exit $ibbackup_exit_code;
288
######################################################################
289
# end of program execution
290
######################################################################
294
# print_version subroutine prints program version and copyright.
297
printf(STDERR $copyright_notice);
302
# usage subroutine prints instructions of how to use this program to stdout.
305
my $msg = shift || '';
306
pod2usage({ -msg => $msg, -verbose => 1});
312
# return current local time as string in form "070816 12:23:15"
315
return strftime("%y%m%d %H:%M:%S", localtime());
320
# Die subroutine kills all child processes and exits this process.
321
# This subroutine takes the same argument as the built-in die function.
323
# message string which is printed to stdout
329
# kill all child processes of this process
330
kill_child_processes();
332
if ($current_mysql_request) {
333
$extra_info = " while waiting for reply to MySQL request:" .
334
" '$current_mysql_request'";
336
die "$prefix Error: $message$extra_info";
341
# backup subroutine makes a backup of InnoDB and MyISAM tables, indexes and
342
# .frm files. It connects to the database server and runs ibbackup as a child
346
my $orig_datadir = get_option(\%config, 'mysqld', 'datadir');
348
# check that we can connect to the database. This done by
349
# connecting, issuing a query, and closing the connection.
354
# start ibbackup as a child process
357
# wait for ibbackup to suspend itself
358
if (!$option_remote_host && !$option_stream) {
359
wait_for_ibbackup_suspend();
362
if (!$option_incremental) {
363
# connect to database
366
if ( $option_safe_slave_backup ) {
367
wait_for_safe_slave();
370
# flush tables with read lock
372
mysql_lockall() if !$option_no_lock;
376
# backup .frm, .MRG, .MYD, .MYI, .TRG, .TRN, .ARM, .ARZ, .CSM, .CSV and .opt files
379
# resume ibbackup and wait till it has finished
380
my $ibbackup_exit_code = resume_ibbackup();
382
if (!$option_incremental) {
383
# release read locks on all tables
384
mysql_unlockall() if !$option_no_lock;
386
if ( $option_safe_slave_backup ) {
387
print STDERR "$prefix: Starting slave SQL thread\n";
388
mysql_send('START SLAVE SQL_THREAD;');
391
# disconnect from database
395
if ($option_remote_host) {
396
system("scp $option_scp_opt '$tmp_logfile' '$option_remote_host:$backup_dir/xtrabackup_logfile'")
397
and Die "Failed to scp file '$option_remote_host:$backup_dir/xtrabackup_logfile': $!";
398
unlink $tmp_logfile || Die "Failed to delete '$tmp_logfile': $!";
400
system("scp $option_scp_opt '$orig_datadir/xtrabackup_checkpoints' '$option_remote_host:$backup_dir/xtrabackup_checkpoints'")
401
and Die "Failed to scp file '$option_remote_host:$backup_dir/xtrabackup_checkpoints': $!";
402
unlink "$orig_datadir/xtrabackup_checkpoints" || Die "Failed to delete '$orig_datadir/xtrabackup_checkpoints': $!";
403
} elsif ($option_stream eq 'tar') {
404
system("cd $option_tmpdir; tar chf - xtrabackup_logfile")
405
and Die "Failed to stream 'xtrabackup_logfile': $!";
406
unlink $tmp_logfile || Die "Failed to delete '$tmp_logfile': $!";
408
system("cd $orig_datadir; tar chf - xtrabackup_checkpoints")
409
and Die "Failed to stream 'xtrabackup_checkpoints': $!";
410
unlink "$orig_datadir/xtrabackup_checkpoints" || Die "Failed to delete '$orig_datadir/xtrabackup_checkpoints': $!";
413
print STDERR "\n$prefix Backup created in directory '$backup_dir'\n";
414
if ($mysql_binlog_position) {
415
print STDERR "$prefix MySQL binlog position: $mysql_binlog_position\n";
417
if ($mysql_slave_position && $option_slave_info) {
418
print STDERR "$prefix MySQL slave binlog position: $mysql_slave_position\n";
421
return $ibbackup_exit_code;
426
# are_equal_innodb_data_file_paths subroutine checks if the given
427
# InnoDB data file option values are equal.
429
# str1 InnoDB data file path option value
430
# str2 InnoDB data file path option value
432
# 1 if values are equal
435
sub are_equal_innodb_data_file_paths {
438
my @array1 = split(/;/, $str1);
439
my @array2 = split(/;/, $str2);
441
if ($#array1 != $#array2) { return 0; }
443
for (my $i = 0; $i <= $#array1; $i++) {
444
my @def1 = split(/:/, $array1[$i]);
445
my @def2 = split(/:/, $array2[$i]);
447
if ($#def1 != $#def2) { return 0; }
449
for (my $j = 0; $j <= $#def1; $j++) {
450
if ($def1[$j] ne $def2[$j]) { return 0; }
458
# is_in_array subroutine checks if the given string is in the array.
461
# array_ref a reference to an array of strings
463
# 1 if string is in the array
468
my $array_ref = shift;
470
if (grep { $str eq $_ } @{$array_ref}) {
478
# copy_back subroutine copies data and index files from backup directory
479
# back to their original locations.
482
my $orig_datadir = get_option(\%config, 'mysqld', 'datadir');
483
my $orig_ibdata_dir =
484
get_option(\%config, 'mysqld', 'innodb_data_home_dir');
485
my $orig_innodb_data_file_path =
486
get_option(\%config, 'mysqld', 'innodb_data_file_path');
488
get_option(\%config, 'mysqld', 'innodb_log_group_home_dir');
490
'^(\.\.?|backup-my\.cnf|xtrabackup_logfile|mysql-std(err|out)|.*\.ibz)$';
492
my $iblog_files = '^ib_logfile.*$';
493
my $compressed_data_file = '.*\.ibz$';
495
my $backup_innodb_data_file_path;
496
# check that original data directory exists
497
if (! -d $orig_datadir) {
498
Die "Original data directory '$orig_datadir' does not exist!";
500
# check that original InnoDB data directory exists
501
if (! -d $orig_ibdata_dir) {
502
Die "Original InnoDB data directory '$orig_ibdata_dir' does not exist!";
504
# check that original InnoDB log directory exists
505
if (! -d $orig_iblog_dir) {
506
Die "Original InnoDB log directory '$orig_iblog_dir' does not exist!";
509
# check that the original options file and the backup options file have
510
# the same value for "innodb_data_file_path" option
511
#$backup_innodb_data_file_path =
512
# get_option(\%backup_config, 'mysqld', 'innodb_data_file_path');
513
#if (!are_equal_innodb_data_file_paths($orig_innodb_data_file_path,
514
# $backup_innodb_data_file_path)
516
# Die "The value of 'innodb_data_file_path' option in the original "
517
# . "my.cnf file '$config_file' is different from the value "
518
# . "in the backup my.cnf file '$backup_config_file'.\n(original: "
519
# . "'$orig_innodb_data_file_path')\n"
520
# . "(backup: '$backup_innodb_data_file_path')";
523
# make a list of all ibdata files in the backup directory and all
524
# directories in the backup directory under which there are ibdata files
525
foreach my $a (split(/;/, $orig_innodb_data_file_path)) {
526
my $path = (split(/:/,$a))[0];
527
my $filename = (split(/\/+/, $path))[-1];
529
# check that the backup data file exists
530
if (! -e "$backup_dir/$filename") {
531
if (-e "$backup_dir/${filename}.ibz") {
532
Die "Backup data file '$backup_dir/$filename' does not exist, but "
533
. "its compressed copy '${path}.ibz' exists. Check "
534
. "that you have run '$innobackup_script --apply-log --uncompress "
535
. "...' before attempting '$innobackup_script --copy-back ...' !";
537
Die "Backup data file '$backup_dir/$filename' does not exist.";
541
if (!is_in_array($filename, \@ibdata_files)) {
542
push(@ibdata_files, $filename);
546
# copy files from backup dir to their original locations
548
# copy files to original data directory
549
opendir(DIR, $backup_dir)
550
|| Die "Can't open directory '$backup_dir': $!\n";
551
print STDERR "$prefix Starting to copy MyISAM tables, indexes,\n";
552
print STDERR "$prefix .MRG, .TRG, .TRN, .ARM, .ARZ, .CSM, .CSV, .opt, and .frm files\n";
553
print STDERR "$prefix in '$backup_dir'\n";
554
print STDERR "$prefix back to original data directory '$orig_datadir'\n";
555
while (defined($file = readdir(DIR))) {
556
if ($file =~ /$excluded_files/) { next; }
557
if (is_in_array($file, \@ibdata_files)) { next; }
558
if ($file =~ /$iblog_files/) { next; }
559
if (-d "$backup_dir/$file") {
560
my $subdir = "$backup_dir/$file";
563
print STDERR "$prefix Copying directory '$subdir'\n";
564
if (! -x "\"".escape_path("$orig_datadir/$file")."\"") {
565
system("mkdir \"".escape_path("$orig_datadir/$file")."\"")
566
and Die "Failed to create directory "
567
. "'$orig_datadir/$file' : $!";
569
opendir(SUBDIR, "$subdir")
570
|| Die "Can't open directory '$subdir': $!\n";
571
while (defined($file2 = readdir(SUBDIR))) {
572
if (-d "$subdir/$file2") { next; }
573
if ($file2 =~ /$compressed_data_file/) { next; }
574
$src_name = escape_path("$subdir/$file2");
575
$dst_name = escape_path("$orig_datadir/$file");
576
system("$CP_CMD \"$src_name\" \"$dst_name\"")
577
and Die "Failed to copy file '$file': $!";
581
print STDERR "$prefix Copying file " .
582
"'$backup_dir/$file'\n";
583
$src_name = escape_path("$backup_dir/$file");
584
$dst_name = escape_path("$orig_datadir");
585
system("$CP_CMD \"$src_name\" \"$dst_name\"")
586
and Die "Failed to copy file '$file': $!";
591
# copy InnoDB data files to original InnoDB data directory
592
print STDERR "\n$prefix Starting to copy InnoDB tables and indexes\n";
593
print STDERR "$prefix in '$backup_dir'\n";
594
print STDERR "$prefix back to original InnoDB data directory '$orig_ibdata_dir'\n";
595
foreach my $a (split(/;/, $orig_innodb_data_file_path)) {
596
# get the relative pathname of a data file
597
my $path = (split(/:/,$a))[0];
598
my $filename = (split(/\/+/, $path))[-1];
599
print STDERR "$prefix Copying file '$backup_dir/$filename'\n";
600
$src_name = escape_path("$backup_dir/$filename");
601
$dst_name = escape_path("$orig_ibdata_dir/$path");
602
system("$CP_CMD \"$src_name\" \"$dst_name\"")
603
and Die "Failed to copy file '$filename': $!";
606
# copy InnoDB log files to original InnoDB log directory
607
opendir(DIR, $backup_dir)
608
|| Die "Can't open directory '$backup_dir': $!\n";
609
print STDERR "\n$prefix Starting to copy InnoDB log files\n";
610
print STDERR "$prefix in '$backup_dir'\n";
611
print STDERR "$prefix back to original InnoDB log directory '$orig_iblog_dir'\n";
612
while (defined($file = readdir(DIR))) {
613
if ($file =~ /$iblog_files/ && -f "$backup_dir/$file") {
614
print STDERR "$prefix Copying file '$backup_dir/$file'\n";
615
$src_name = escape_path("$backup_dir/$file");
616
$dst_name = escape_path("$orig_iblog_dir");
617
system("$CP_CMD \"$src_name\" \"$dst_name\"")
618
and Die "Failed to copy file '$file': $!";
623
print STDERR "$prefix Finished copying back files.\n\n";
628
# apply_log subroutine prepares a backup for starting database server
629
# on the backup. It applies InnoDB log files to the InnoDB data files.
636
if ($option_defaults_file) {
637
$options = $options . " --defaults-file=\"$option_defaults_file\" ";
640
$options = $options . "--prepare --target-dir=$backup_dir";
642
if ($option_uncompress) {
643
$options = $options . ' --uncompress';
645
if ($option_export) {
646
$options = $options . ' --export';
648
if ($option_redo_only) {
649
$options = $options . ' --apply-log-only';
651
if ($option_use_memory) {
652
$options = $options . " --use-memory=$option_use_memory";
655
if ($option_incremental_dir) {
656
$options = $options . " --incremental-dir=$option_incremental_dir";
659
# run ibbackup as a child process
660
$cmdline = "$option_ibbackup_binary $options";
661
$now = current_time();
662
print STDERR "\n$now $prefix Starting ibbackup with command: $cmdline\n\n";
663
$rcode = system("$cmdline");
666
Die "\n$prefix ibbackup failed";
669
# We should not create ib_logfile files if we prepare for following incremental applies
670
# Also we do not prepare ib_logfile if we applied incremental changes
671
if (!( ($option_redo_only) or ($option_incremental_dir))) {
672
$now = current_time();
673
print STDERR "\n$now $prefix Restarting xtrabackup with command: $cmdline\nfor creating ib_logfile*\n\n";
674
$rcode = system("$cmdline");
677
Die "\n$prefix xtrabackup (2nd execution) failed";
684
# wait_for_ibbackup_suspend subroutine waits until ibbackup has suspended
687
sub wait_for_ibbackup_suspend {
688
print STDERR "$prefix Waiting for ibbackup (pid=$ibbackup_pid) to suspend\n";
689
print STDERR "$prefix Suspend file '$suspend_file'\n\n";
692
last if -e $suspend_file;
694
# check that ibbackup child process is still alive
695
if ($ibbackup_pid == waitpid($ibbackup_pid, &WNOHANG)) {
697
Die "ibbackup child process has died";
700
$now = current_time();
701
print STDERR "\n$now $prefix Continuing after ibbackup has suspended\n";
706
# resume_ibbackup subroutine signals ibbackup to complete its execution
707
# by deleting the 'ibbackup_suspended' file.
709
sub resume_ibbackup {
710
print STDERR "$prefix Resuming ibbackup\n\n";
711
unlink $suspend_file || Die "Failed to delete '$suspend_file': $!";
713
# wait for ibbackup to finish
714
waitpid($ibbackup_pid, 0);
716
return $CHILD_ERROR >> 8;
721
# start_ibbackup subroutine spawns a child process running ibbackup
722
# program for backing up InnoDB tables and indexes.
729
if ($option_defaults_file) {
730
$options = $options . " --defaults-file=\"$option_defaults_file\" ";
733
$options = $options . "--backup --suspend-at-end";
735
if (!$option_remote_host && !$option_stream) {
736
$options = $options . " --target-dir=$backup_dir";
738
#(datadir) for 'xtrabackup_suspended' and 'xtrabackup_checkpoints'
739
$options = $options . " --log-stream --target-dir=./";
742
# prepare command line for running ibbackup
743
if ($option_throttle) {
744
$options = $options . " --throttle=$option_throttle";
747
$options = $options . " --sleep=$option_sleep";
749
if ($option_compress) {
750
$options = $options . " --compress=$option_compress";
752
if ($option_use_memory) {
753
$options = $options . " --use-memory=$option_use_memory";
755
if ($option_include) {
756
$options = $options . " --tables='$option_include'";
758
if ($option_extra_lsndir) {
759
$options = $options . " --extra-lsndir='$option_extra_lsndir'";
762
if ($option_incremental) {
763
if($option_incremental_lsn) {
764
$options = $options . " --incremental-lsn='$option_incremental_lsn'";
766
$options = $options . " --incremental-basedir='$incremental_basedir'";
770
if ($option_tables_file) {
771
$options = $options . " --tables_file='$option_tables_file'";
773
if ($option_parallel) {
774
$options = $options. " --parallel=$option_parallel";
776
$cmdline = "$option_ibbackup_binary $options";
778
# run ibbackup as a child process
779
$now = current_time();
780
print STDERR "\n$now $prefix Starting ibbackup with command: $cmdline\n";
781
if (defined($pid = fork)) {
784
$ibbackup_pid = $pid;
786
if($option_remote_host || $option_stream) {
787
#direct copy to remote
788
my $orig_datadir = get_option(\%config, 'mysqld', 'datadir');
789
my $orig_ibdata_dir =
790
get_option(\%config, 'mysqld', 'innodb_data_home_dir');
791
my $orig_innodb_data_file_path =
792
get_option(\%config, 'mysqld', 'innodb_data_file_path');
793
my $innodb_flush_method =
794
get_option(\%config, 'mysqld', 'innodb_flush_method');
795
my $innodb_use_odirect;
796
$innodb_use_odirect = 1 if $innodb_flush_method =~ m/O_DIRECT/i;
801
if($option_remote_host) {
802
if (system("ssh $option_remote_host test -e $backup_dir/ib_logfile0")
804
print STDERR "$prefix Remove $option_remote_host:$backup_dir/ib_logfile*\n";
805
system("ssh $option_remote_host rm $backup_dir/ib_logfile\*")
806
and Die "Failed to rm file '$backup_dir/ib_logfile*': $!";
810
wait_for_ibbackup_suspend();
812
#InnoDB data files from original InnoDB data directory
813
print STDERR "\n$prefix Starting to backup InnoDB tables and indexes\n";
814
if($option_remote_host) {
815
print STDERR "$prefix to '$backup_dir'\n";
817
print STDERR "$prefix from original InnoDB data directory '$orig_ibdata_dir'\n";
818
foreach my $a (split(/;/, $orig_innodb_data_file_path)) {
819
my $path = (split(/:/,$a))[0];
820
$path=~s/([\$\\\" ])/\\$1/g;
821
if($option_remote_host) {
822
print STDERR "$prefix Backing up file '$orig_ibdata_dir/$path'\n";
823
system("scp $option_scp_opt '$orig_ibdata_dir/$path' '$option_remote_host:$backup_dir/$path'")
824
and Die "Failed to scp file '$path': $!";
825
} elsif($option_stream eq 'tar') {
828
print STDERR "$prefix Backing up as tar stream '$path'\n";
829
if (!$option_tar4ibd) {
830
$tarcmd = "tar chf - -b 32";
833
if ($innodb_use_odirect) {
834
$tarcmd = "$tarcmd -d";
836
$tarcmd = "$tarcmd -c";
838
$ret = system("cd $orig_ibdata_dir; $tarcmd $path") >> 8;
840
print STDERR "$prefix If you use GNU tar, this warning can be ignored.\n";
841
} elsif ($ret != 0) {
842
print STDERR "$prefix tar returned with exit code $ret.\n";
843
if ( -e "$orig_ibdata_dir/$path" ) {
844
Die "Failed to stream '$orig_ibdata_dir/$path': $!";
847
print STDERR "$prefix Ignoring nonexistent file '$orig_ibdata_dir/$path'.\n";
854
opendir(DIR, $orig_datadir)
855
|| Die "Can't open directory '$orig_datadir': $!\n";
856
while (defined($subdir = readdir(DIR))) {
857
my $print_each_file = 0;
860
if ($subdir eq '.' || $subdir eq '..') { next; }
861
next unless -d "$orig_datadir/$subdir";
862
next unless check_if_required($subdir);
864
@list = glob("$orig_datadir/$subdir/" . '*.ibd');
867
if ($file_c <= $backup_file_print_limit) {
868
$print_each_file = 1;
870
print STDERR "$prefix Backing up files " .
871
"'$orig_datadir/$subdir/*.ibd' ($file_c files)\n";
873
foreach $file (@list) {
874
next unless check_if_required($subdir, $file);
875
if($option_include) {
878
$table_name = substr($file, rindex($file, '/'));
879
$table_name = substr($table_name, 1, rindex($table_name, '.') - 1);
880
$table_name = $subdir . "." . $table_name;
882
if (!($table_name =~ /$option_include/)) {
883
print STDERR "'$file' is skipped.\n";
888
if ($print_each_file) {
889
print STDERR "$prefix Backing up file '$file'\n";
891
if($option_remote_host) {
892
if (system("ssh $option_remote_host test -e $backup_dir/$subdir")
894
system("ssh $option_remote_host mkdir $backup_dir/$subdir");
896
system("scp $option_scp_opt '$file' '$option_remote_host:$backup_dir/$subdir/'")
897
and Die "Failed to scp file '$file': $!";
898
} elsif($option_stream eq 'tar') {
900
my $file_name = substr($file, rindex($file, '/') + 1);
901
$file_name=~s/([\$\\\" ])/\\$1/g;
902
if (!$option_tar4ibd) {
903
$ret = system("cd $orig_datadir; tar chf - -b 32 $subdir/$file_name") >> 8;
905
$ret = system("cd $orig_datadir; tar4ibd -c $subdir/$file_name") >> 8;
908
print STDERR "$prefix If you use GNU tar, this warning can be ignored.\n";
909
} elsif ($ret != 0) {
910
print STDERR "$prefix tar returned with exit code $ret.\n";
911
if ( -e "$orig_datadir/$subdir/$file_name" ) {
912
Die "Failed to stream '$orig_datadir/$subdir/$file_name': $!";
915
print STDERR "$prefix Ignoring nonexistent file '$orig_datadir/$subdir/$file_name'.\n";
924
if($option_remote_host || $option_stream) {
925
open(STDOUT, "> $tmp_logfile")
926
|| Die "Failed to open file '$tmp_logfile': $!"
930
exec($cmdline) || Die "Failed to exec ibbackup: $!";
933
Die "failed to fork ibbackup child process: $!";
939
# get_mysql_options subroutine returns the options to mysql client program
940
# as a string. The options are determined from the options given by the
941
# user to innobackup.
943
sub get_mysql_options {
946
# this option has to be first
947
if ($option_defaults_file) {
948
$options = "$options --defaults-file='$option_defaults_file'";
951
if ($option_mysql_password) {
952
$options = "$options --password='$option_mysql_password'";
954
if ($option_mysql_user) {
955
$options = "$options --user='$option_mysql_user'";
957
if ($option_mysql_host) {
958
$options = "$options --host='$option_mysql_host'";
960
if ($option_mysql_port) {
961
$options = "$options --port='$option_mysql_port'";
963
if ($option_mysql_socket) {
964
$options = "$options --socket='$option_mysql_socket'";
966
$options = "$options --unbuffered --";
972
# mysql_open subroutine starts mysql as a child process with
976
my $options = get_mysql_options();
977
# run mysql as a child process with a pipe connection
978
$now = current_time();
979
print STDERR "$now $prefix Starting mysql with options: $options\n";
980
$mysql_pid = open(*MYSQL_WRITER, "| mysql $options >$mysql_stdout 2>$mysql_stderr ") or Die "Failed to spawn mysql child process: $!";
981
MYSQL_WRITER->autoflush(1);
982
$now = current_time();
983
print STDERR "$now $prefix Connected to database with mysql child process (pid=$mysql_pid)\n";
990
# mysql_check subroutine checks that the connection to mysql child process
994
my $mysql_pid_copy = $mysql_pid;
996
# send a dummy query to mysql child process
998
my $hello_message = "innobackup hello $hello_id";
999
print MYSQL_WRITER "select '$hello_message';\n"
1000
or Die "Connection to mysql child process failed: $!";
1004
local $SIG{ALRM} = sub { die "alarm clock restart" };
1007
alarm $mysql_response_timeout;
1008
while (index($stdout, $hello_message) < 0) {
1010
if ($mysql_pid && $mysql_pid == waitpid($mysql_pid, &WNOHANG)) {
1011
my $reason = `cat $mysql_stderr`;
1013
die "mysql child process has died: $reason";
1015
$stdout = `cat $mysql_stdout`;
1016
$stderr = `cat $mysql_stderr | grep -v ^Warning`;
1018
# mysql has reported an error, do exit
1019
die "mysql error: $stderr";
1024
if ($@ =~ /alarm clock restart/) {
1025
Die "Connection to mysql child process (pid=$mysql_pid_copy) timedout."
1026
. " (Time limit of $mysql_response_timeout seconds exceeded."
1027
. " You may adjust time limit by editing the value of parameter"
1028
. " \"\$mysql_response_timeout\" in this script.)";
1029
} elsif ($@) { Die $@; }
1031
$mysql_last_access_time = time();
1036
# mysql_keep_alive subroutine tries to keep connection to the mysqld database
1037
# server alive by sending a dummy query when the connection has been idle
1038
# for the specified time.
1040
sub mysql_keep_alive {
1041
if ((time() - $mysql_last_access_time) > $mysql_keep_alive_timeout) {
1042
# too long idle, send a dummy query
1049
# mysql_send subroutine send a request string to mysql child process.
1050
# This subroutine appends a newline character to the request and checks
1051
# that mysqld receives the query.
1053
# request request string
1056
my $request = shift;
1058
$current_mysql_request = $request;
1059
print MYSQL_WRITER "$request\n";
1061
$current_mysql_request = '';
1066
# mysql_close subroutine terminates mysql child process gracefully.
1069
print MYSQL_WRITER "quit\n";
1070
$now = current_time();
1071
print STDERR "$now $prefix Connection to database server closed\n";
1077
# write_binlog_info subroutine retrieves MySQL binlog position and
1078
# saves it in a file. It also prints it to stdout.
1080
sub write_binlog_info {
1082
my @info_lines = ();
1086
# get binlog position
1087
mysql_send "SHOW MASTER STATUS;";
1089
# get "show master status" output lines (2) from mysql output
1090
file_to_array($mysql_stdout, \@lines);
1091
foreach my $line (@lines) {
1092
if ($line =~ m/innobackup hello/) {
1093
# this is a hello message, ignore it
1095
# this is output line from "show master status"
1096
push(@info_lines, $line);
1100
# write binlog info file
1101
if (!defined $info_lines[1]) {
1102
$info_lines[1] = "";
1104
if (!$option_remote_host) {
1105
open(FILE, ">$binlog_info") ||
1106
Die "Failed to open file '$binlog_info': $!";
1108
open(FILE, "| ssh $option_remote_host 'cat > $binlog_info'") ||
1109
Die "Failed to open file '$option_remote_host:$binlog_info': $!";
1111
print FILE "$info_lines[1]\n";
1114
if ($option_stream eq 'tar') {
1115
system("cd $option_tmpdir; tar chf - xtrabackup_binlog_info")
1116
and Die "Failed to stream 'xtrabackup_binlog_info': $!";
1117
unlink $binlog_info || Die "Failed to delete '$binlog_info': $!";
1120
# get the name of the last binlog file and position in it
1121
($filename, $position) = $info_lines[1] =~ /^\s*([^\s]+)\s+(.*)$/;
1123
if (defined $filename && defined $position) {
1124
$mysql_binlog_position = "filename '$filename', position $position";
1126
$mysql_binlog_position = "filename '', position ";
1132
# write_slave_info subroutine retrieves MySQL binlog position of the
1133
# master server in a replication setup and saves it in a file. It
1134
# also saves it in $msql_slave_position variable.
1136
sub write_slave_info {
1143
# get slave status. Use single quotes here, otherwise
1144
# \G is evaluated as a control character.
1145
mysql_send 'SHOW SLAVE STATUS\G;';
1147
# get output of the "show slave status" command from mysql output
1148
# and extract binlog position of the master server
1149
file_to_array($mysql_stdout, \@lines);
1151
$master = $1 if /Master_Host:\s*(\S*)\s*$/;
1152
$filename = $1 if /Master_Log_File:\s*(\S*)\s*$/;
1153
$position = $1 if /Master_Log_Pos:\s*(\S*)\s*$/;
1156
# print slave status to a file
1157
if (!$option_remote_host) {
1158
open(FILE, ">$slave_info") ||
1159
Die "Failed to open file '$slave_info': $!";
1161
open(FILE, "| ssh $option_remote_host 'cat > $slave_info'") ||
1162
Die "Failed to open file '$option_remote_host:$slave_info': $!";
1164
print FILE "CHANGE MASTER TO MASTER_LOG_FILE='$filename', MASTER_LOG_POS=$position\n";
1167
if ($option_stream eq 'tar') {
1168
system("cd $option_tmpdir; tar chf - xtrabackup_slave_info")
1169
and Die "Failed to stream 'xtrabackup_slave_info': $!";
1170
unlink $slave_info || Die "Failed to delete '$slave_info': $!";
1173
$mysql_slave_position = "master host '$master', filename '$filename', position $position";
1178
# mysql_lockall subroutine puts a read lock on all tables in all databases.
1181
$now = current_time();
1182
print STDERR "$now $prefix Starting to lock all tables...\n";
1184
mysql_send "USE mysql;";
1185
# mysql_send "DROP TABLE IF EXISTS ibbackup_binlog_marker;";
1186
# if (compare_versions($mysql_server_version, '4.1.0') == -1) {
1187
# # MySQL server version is 4.0 or older, ENGINE keyword not supported
1188
# mysql_send "CREATE TABLE ibbackup_binlog_marker(a INT) TYPE=INNODB;";
1190
# # MySQL server version is 4.1 or newer, use ENGINE keyword
1191
# mysql_send "CREATE TABLE ibbackup_binlog_marker(a INT) ENGINE=INNODB;";
1193
mysql_send "SET AUTOCOMMIT=0;";
1194
# mysql_send "INSERT INTO ibbackup_binlog_marker VALUES (1);";
1195
if (compare_versions($mysql_server_version, '4.0.22') == 0
1196
|| compare_versions($mysql_server_version, '4.1.7') == 0) {
1197
# MySQL server version is 4.0.22 or 4.1.7
1198
mysql_send "COMMIT;";
1199
mysql_send "FLUSH TABLES WITH READ LOCK;";
1201
# MySQL server version is other than 4.0.22 or 4.1.7
1202
mysql_send "FLUSH TABLES WITH READ LOCK;";
1203
mysql_send "COMMIT;";
1206
write_slave_info if $option_slave_info;
1208
$now = current_time();
1209
print STDERR "$now $prefix All tables locked and flushed to disk\n";
1214
# mysql_unlockall subroutine releases read locks on all tables in all
1217
sub mysql_unlockall {
1218
mysql_send "UNLOCK TABLES;";
1219
# mysql_send "DROP TABLE IF EXISTS ibbackup_binlog_marker;";
1221
$now = current_time();
1222
print STDERR "$now $prefix All tables unlocked\n";
1227
# catch_sigpipe subroutine is a signal handler for SIGPIPE.
1232
if ($mysql_pid && (-1 == ($rcode = waitpid($mysql_pid, &WNOHANG))
1233
|| $rcode == $mysql_pid)) {
1234
my $reason = `cat $mysql_stderr`;
1235
print STDERR "Pipe to mysql child process broken: $reason at";
1236
system("date +'%H:%M:%S'");
1245
# kill_child_processes subroutine kills all child processes of this process.
1247
sub kill_child_processes {
1248
if ($ibbackup_pid) {
1249
kill($kill_signal, $ibbackup_pid);
1254
kill($kill_signal, $mysql_pid);
1261
# require_external subroutine checks that an external program is runnable
1262
# via the shell. This is tested by calling the program with the
1263
# given arguments. It is checked that the program returns 0 and does
1264
# not print anything to stderr. If this check fails, this subroutine exits.
1266
# program pathname of the program file
1267
# args arguments to the program
1268
# pattern a string containing a regular expression for finding
1269
# the program version.
1270
# this pattern should contain a subpattern enclosed
1271
# in parentheses which is matched with the version.
1272
# version_ref a reference to a variable where the program version
1273
# string is returned. Example "2.0-beta2".
1275
sub require_external {
1276
my $program = shift;
1278
my $pattern = shift;
1279
my $version_ref = shift;
1281
my $tmp_stdout = tmpnam();
1282
my $tmp_stderr = tmpnam();
1286
$rcode = system("$program $args >$tmp_stdout 2>$tmp_stderr");
1290
my $stderr = `cat $tmp_stderr | grep -v ^Warning`;
1292
if ($stderr ne '') {
1295
Die "Couldn't run $program: $stderr";
1299
Die "Couldn't run $program: $error";
1303
my $stdout = `cat $tmp_stdout`;
1305
@lines = split(/\n|;/,$stdout);
1306
print STDERR "$prefix Using $lines[0]\n";
1308
# get version string from the first output line of the program
1309
${$version_ref} = '';
1310
if ($lines[0] =~ /$pattern/) {
1311
${$version_ref} = $1;
1316
# compare_versions subroutine compares two GNU-style version strings.
1317
# A GNU-style version string consists of three decimal numbers delimitted
1318
# by dots, and optionally followed by extra attributes.
1319
# Examples: "4.0.1", "4.1.1-alpha-debug".
1321
# str1 a GNU-style version string
1322
# str2 a GNU-style version string
1327
sub compare_versions {
1336
# remove possible extra attributes
1337
($str1, $extra1) = $str1 =~ /^([0-9.]*)(.*)/;
1338
($str2, $extra2) = $str2 =~ /^([0-9.]*)(.*)/;
1340
# split "dotted" decimal number string into an array
1341
@array1 = split('\.', $str1);
1342
@array2 = split('\.', $str2);
1344
# compare in lexicographic order
1345
for ($i = 0; $i <= $#array1 && $i <= $#array2; $i++) {
1346
if ($array1[$i] < $array2[$i]) {
1348
} elsif ($array1[$i] > $array2[$i]) {
1352
if ($#array1 < $#array2) {
1354
} elsif ($#array1 > $#array2) {
1363
# init subroutine initializes global variables and performs some checks on the
1364
# system we are running on.
1367
my $mysql_version = '';
1368
my $ibbackup_version = '';
1371
# print some instructions to the user
1372
if (!$option_apply_log && !$option_copy_back) {
1374
} elsif ($option_copy_back) {
1379
print STDERR "IMPORTANT: Please check that the $run run completes successfully.\n";
1380
print STDERR " At the end of a successful $run run $innobackup_script\n";
1381
print STDERR " prints \"completed OK!\".\n\n";
1383
# check that MySQL client program and InnoDB Hot Backup program
1384
# are runnable via shell
1385
if (!$option_copy_back) {
1386
# we are making a backup or applying log to backup
1387
if (!$option_apply_log) {
1388
# we are making a backup, we need mysql server
1392
# check that we have mysql client program
1393
require_external('mysql', '--version', 'Ver ([^,]+)',
1396
# get mysql server version
1397
my $options = get_mysql_options();
1398
@lines = split('\n',
1399
`mysql $options -e "select \@\@version"`);
1400
$mysql_server_version = $lines[1];
1401
print STDERR "$prefix Using mysql server version $mysql_server_version\n";
1403
#require_external($option_ibbackup_binary, '--license',
1404
# 'version (\S+)', \$ibbackup_version);
1408
&& $ibbackup_version
1409
&& $ibbackup_version le "2.0") {
1410
# --include option was given, but ibbackup is too
1412
Die "--include option was given, but ibbackup is too old"
1413
. " to support it. You must upgrade to InnoDB Hot Backup"
1414
. " v2.0 in order to use --include option.\n";
1418
# set signal handlers
1419
$SIG{PIPE} = \&catch_sigpipe;
1421
# read MySQL options file
1422
#read_config_file($config_file, \%config);
1423
read_config_file(\%config);
1425
if(!$option_tmpdir) {
1426
$option_tmpdir = get_option(\%config, 'mysqld', 'tmpdir');
1429
# get innodb log home directory from options file
1430
#$innodb_log_group_home_dir =
1431
# get_option(\%config, 'mysqld', 'innodb_log_group_home_dir');
1433
if (!$option_apply_log && !$option_copy_back) {
1434
# we are making a backup, create a new backup directory
1435
if (!$option_remote_host) {
1436
$backup_dir = File::Spec->rel2abs(make_backup_dir());
1438
$backup_dir = make_backup_dir();
1440
print STDERR "$prefix Created backup directory $backup_dir\n";
1441
if (!$option_remote_host && !$option_stream) {
1442
$backup_config_file = $backup_dir . '/backup-my.cnf';
1443
$suspend_file = $backup_dir . '/xtrabackup_suspended';
1444
$mysql_stdout = $backup_dir . '/mysql-stdout';
1445
$mysql_stderr = $backup_dir . '/mysql-stderr';
1446
$binlog_info = $backup_dir . '/xtrabackup_binlog_info';
1447
$slave_info = $backup_dir . '/xtrabackup_slave_info';
1449
$suspend_file = get_option(\%config, 'mysqld', 'datadir') . '/xtrabackup_suspended';
1450
$tmp_logfile = $option_tmpdir . '/xtrabackup_logfile';
1451
$mysql_stdout = $option_tmpdir . '/mysql-stdout';
1452
$mysql_stderr = $option_tmpdir . '/mysql-stderr';
1453
if ($option_stream) {
1454
$backup_config_file = $option_tmpdir . '/backup-my.cnf';
1455
$binlog_info = $option_tmpdir . '/xtrabackup_binlog_info';
1456
$slave_info = $option_tmpdir . '/xtrabackup_slave_info';
1458
$backup_config_file = $backup_dir . '/backup-my.cnf';
1459
$binlog_info = $backup_dir . '/xtrabackup_binlog_info';
1460
$slave_info = $backup_dir . '/xtrabackup_slave_info';
1463
write_backup_config_file($backup_config_file);
1464
} elsif ($option_copy_back) {
1465
#$backup_config_file = $backup_dir . '/backup-my.cnf';
1466
#read_config_file($backup_config_file, \%backup_config);
1472
# write_backup_config_file subroutine creates a backup options file for
1473
# ibbackup program. It writes to the file only those options that
1474
# are required by ibbackup.
1476
# filename name for the created options file
1478
sub write_backup_config_file {
1479
my $filename = shift;
1480
my $innodb_data_file_path =
1481
get_option(\%config, 'mysqld', 'innodb_data_file_path');
1482
my $innodb_log_files_in_group =
1483
get_option(\%config, 'mysqld', 'innodb_log_files_in_group');
1484
my $innodb_log_file_size =
1485
get_option(\%config, 'mysqld', 'innodb_log_file_size');
1488
my @array = split(/;/, $innodb_data_file_path);
1489
for (my $i = 0; $i <= $#array; $i++) {
1490
my @tmp = split(/\/+/, $array[$i]);
1491
$array[$i] = $tmp[-1];
1493
$innodb_data_file_path = join(";", @array);
1495
if (!$option_remote_host) {
1496
$root = $backup_dir;
1497
open(FILE, "> $filename") || Die "Failed to open file '$filename': $!";
1499
$root = `ssh $option_remote_host 'cd $backup_dir; pwd'`;
1500
open(FILE, "| ssh $option_remote_host 'cat > $filename'")
1501
|| Die "Failed to open file '$option_remote_host:$filename': $!";
1504
print FILE "# This MySQL options file was generated by $innobackup_script.\n\n" .
1505
"# The MySQL server\n" .
1508
"innodb_data_home_dir=$root\n" .
1509
"innodb_data_file_path=$innodb_data_file_path\n" .
1510
"innodb_log_group_home_dir=$root\n" .
1511
"innodb_log_files_in_group=$innodb_log_files_in_group\n" .
1512
"innodb_log_file_size=$innodb_log_file_size\n";
1515
if ($option_stream) {
1516
my $filename_dir = dirname($filename);
1517
my $filename_name = basename($filename);
1518
if ($option_stream eq 'tar') {
1519
system("cd $filename_dir; tar chf - $filename_name")
1520
and Die "Failed to stream '$filename_name': $!";
1522
unlink $filename || Die "Failed to delete '$filename': $!";
1528
# check_args subroutine checks command line arguments. If there is a problem,
1529
# this subroutine prints error message and exits.
1537
# check the version of the perl we are running
1539
# this perl is prior to 5.6.0 and uses old style version string
1540
my $required_version = $required_perl_version_old_style;
1541
if ($] lt $required_version) {
1542
print STDERR "$prefix Warning: " .
1543
"Your perl is too old! Innobackup requires\n";
1544
print STDERR "$prefix Warning: perl $required_version or newer!\n";
1549
# no command line arguments
1550
print STDERR "$prefix You must specify the backup directory.\n";
1554
# read command line options
1555
$rcode = GetOptions('compress:i' => \$option_compress,
1556
'help' => \$option_help,
1557
'version' => \$option_version,
1558
'throttle=i' => \$option_throttle,
1559
'sleep=i' => \$option_sleep,
1560
'apply-log' => \$option_apply_log,
1561
'redo-only' => \$option_redo_only,
1562
'copy-back' => \$option_copy_back,
1563
'include=s' => \$option_include,
1564
'databases=s' => \$option_databases,
1565
'tables-file=s', => \$option_tables_file,
1566
'use-memory=s' => \$option_use_memory,
1567
'uncompress' => \$option_uncompress,
1568
'export' => \$option_export,
1569
'password=s' => \$option_mysql_password,
1570
'user=s' => \$option_mysql_user,
1571
'host=s' => \$option_mysql_host,
1572
'port=s' => \$option_mysql_port,
1573
'slave-info' => \$option_slave_info,
1574
'socket=s' => \$option_mysql_socket,
1575
'no-timestamp' => \$option_no_timestamp,
1576
'defaults-file=s' => \$option_defaults_file,
1577
'incremental' => \$option_incremental,
1578
'incremental-basedir=s' => \$option_incremental_basedir,
1579
'incremental-lsn=s' => \$option_incremental_lsn,
1580
'incremental-dir=s' => \$option_incremental_dir,
1581
'extra-lsndir=s' => \$option_extra_lsndir,
1582
'remote-host=s' => \$option_remote_host,
1583
'stream=s' => \$option_stream,
1584
'tmpdir=s' => \$option_tmpdir,
1585
'no-lock' => \$option_no_lock,
1586
'ibbackup=s' => \$option_ibbackup_binary,
1587
'scpopt=s' => \$option_scp_opt,
1588
'force-tar', => \$option_force_tar,
1589
'parallel=i' => \$option_parallel,
1590
'safe-slave-backup' => \$option_safe_slave_backup,
1591
'safe-slave-backup-timeout' => $option_safe_slave_backup_timeout,
1595
# failed to read options
1596
print STDERR "$prefix Bad command line arguments\n";
1600
# print help text and exit
1604
if ($option_version) {
1605
# print program version and copyright
1610
if ($option_compress == 0) {
1611
# compression level no specified, use default level
1612
$option_compress = $default_compression_level;
1615
if ($option_compress == 999) {
1616
# compress option not given in the command line
1617
$option_compress = 0;
1621
print STDERR "$prefix Missing command line argument\n";
1623
} elsif (@ARGV > 1) {
1624
print STDERR "$prefix Too many command line arguments\n";
1628
if ($option_stream) {
1629
if ($option_stream eq 'tar') {
1630
if ( !$option_force_tar ) {
1631
$option_tar4ibd = 'tar4ibd';
1634
print STDERR "Forcing tar instead of tar4ibd\n";
1636
} elsif ($option_stream eq 'tar4ibd') {
1637
$option_stream = 'tar';
1638
$option_tar4ibd = 'tar4ibd';
1639
} elsif ($option_stream eq 'cpio') {
1640
print STDERR "$prefix --stream=cpio is not supported yet\n";
1643
print STDERR "$prefix Unknown option --stream=$option_stream\n";
1648
# get options file name
1649
#$config_file = $ARGV[0];
1651
if (!$option_apply_log && !$option_copy_back) {
1652
# we are making a backup, get backup root directory
1653
$backup_root = $ARGV[0];
1654
if ($option_incremental) {
1655
my @dirs = `ls -1 -t $backup_root`;
1656
my $inc_dir = $dirs[0];
1658
if ($option_incremental_basedir) {
1659
$incremental_basedir = $option_incremental_basedir;
1661
$incremental_basedir = File::Spec->catfile($backup_root, $inc_dir);
1664
#print STDERR "--incremental_basedir=$incremental_basedir\n";
1665
#print STDERR "incremental backup is not supported for now.\n";
1669
# get backup directory
1670
$backup_dir = File::Spec->rel2abs($ARGV[0]);
1675
parse_databases_option_value();
1676
parse_tables_file_option_value($option_tables_file);
1681
# make_backup_dir subroutine creates a new backup directory and returns
1684
sub make_backup_dir {
1686
my $innodb_data_file_path =
1687
get_option(\%config, 'mysqld', 'innodb_data_file_path');
1689
# create backup directory
1690
$dir = $backup_root;
1691
if ($option_stream) {
1695
$dir .= '/' . strftime("%Y-%m-%d_%H-%M-%S", localtime())
1696
unless $option_no_timestamp;
1697
if (!$option_remote_host) {
1698
mkdir($dir, 0777) || Die "Failed to create backup directory $dir: $!";
1700
system("ssh $option_remote_host mkdir $dir");
1703
# create subdirectories for ibdata files if needed
1704
# foreach my $a (split(/;/, $innodb_data_file_path)) {
1705
# my $path = (split(/:/,$a))[0];
1706
# my @relative_path = split(/\/+/, $path);
1707
# pop @relative_path;
1708
# if (@relative_path) {
1709
# # there is a non-trivial path from the backup directory
1710
# # to the directory of this backup ibdata file, check
1711
# # that all the directories in the path exist.
1712
# create_path_if_needed($dir, \@relative_path);
1721
# create_path_if_needed subroutine checks that all components
1722
# in the given relative path are directories. If the
1723
# directories do not exist, they are created.
1725
# root a path to the root directory of the relative pathname
1726
# relative_path a relative pathname (a reference to an array of
1727
# pathname components)
1729
sub create_path_if_needed {
1731
my $relative_path = shift;
1735
foreach $a (@{$relative_path}) {
1736
$path = $path . "/" . $a;
1737
if (!$option_remote_host) {
1739
# this directory does not exist, create it !
1740
mkdir($path, 0777) || Die "Failed to create backup directory: $!";
1743
if (system("ssh $option_remote_host test -d $path") != 0) {
1744
system("ssh $option_remote_host mkdir $path");
1752
# remove_from_array subroutine removes excluded element from the array.
1754
# array_ref a reference to an array of strings
1755
# excluded a string to be excluded from the copy
1757
sub remove_from_array {
1758
my $array_ref = shift;
1759
my $excluded = shift;
1763
foreach my $str (@{$array_ref}) {
1764
if ($str ne $excluded) {
1765
$copy[$size] = $str;
1769
@{$array_ref} = @copy;
1774
# backup_files subroutine copies .frm, .MRG, .MYD and .MYI files to
1778
my $source_dir = get_option(\%config, 'mysqld', 'datadir');
1782
my $wildcard = '*.{frm,MYD,MYI,MRG,TRG,TRN,ARM,ARZ,CSM,CSV,opt,par}';
1784
opendir(DIR, $source_dir)
1785
|| Die "Can't open directory '$source_dir': $!\n";
1786
$now = current_time();
1787
print STDERR "\n$now $prefix Starting to backup .frm, .MRG, .MYD, .MYI,\n";
1788
print STDERR "$prefix .TRG, .TRN, .ARM, .ARZ, .CSM, .CSV and .opt files in\n";
1789
print STDERR "$prefix subdirectories of '$source_dir'\n";
1790
# loop through all database directories
1791
while (defined($database = readdir(DIR))) {
1792
my $print_each_file = 0;
1795
# skip files that are not database directories
1796
if ($database eq '.' || $database eq '..') { next; }
1797
next unless -d "$source_dir/$database";
1798
next unless check_if_required($database);
1800
if (!$option_remote_host && !$option_stream) {
1801
if (! -e "$backup_dir/$database") {
1802
# create database directory for the backup
1803
mkdir("$backup_dir/$database", 0777)
1804
|| Die "Couldn't create directory '$backup_dir/$database': $!";
1806
} elsif ($option_remote_host) {
1807
if (system("ssh $option_remote_host test -e $backup_dir/$database")
1809
system("ssh $option_remote_host mkdir $backup_dir/$database");
1813
# copy files of this database
1814
opendir(DBDIR, "$source_dir/$database");
1815
@list = grep(/\.(frm)|(MYD)|(MYI)|(MRG)|(TRG)|(TRN)|(ARM)|(ARZ)|(CSM)|(CSV)|(opt)|(par)$/, readdir(DBDIR));
1818
if ($file_c <= $backup_file_print_limit) {
1819
$print_each_file = 1;
1821
print STDERR "$prefix Backing up files " .
1822
"'$source_dir/$database/$wildcard' ($file_c files)\n";
1824
foreach $file (@list) {
1825
# copying may take a long time, so we have to prevent
1826
# mysql connection from timing out
1828
next unless check_if_required($database, $file);
1830
if($option_include) {
1831
if (!("$database.$file" =~ /$option_include/)) {
1832
print STDERR "$database.$file is skipped because it does not match $option_include.\n";
1838
if ($print_each_file) {
1839
print STDERR "$prefix Backing up file '$source_dir/$database/$file'\n";
1841
if (!$option_remote_host && !$option_stream) {
1842
$src_name = escape_path("$source_dir/$database/$file");
1843
$dst_name = escape_path("$backup_dir/$database");
1844
system("$CP_CMD \"$src_name\" \"$dst_name\"")
1845
and Die "Failed to copy file '$file': $!";
1846
} elsif ($option_remote_host) {
1847
# Queue up files for one single scp per database.
1848
push(@scp_files, "'$file'");
1849
} elsif($option_stream eq 'tar') {
1851
my $file_name = substr($file, rindex($file, '/') + 1);
1852
$file_name=~s/([\$\\\" ])/\\$1/g;
1853
$ret = system("cd $source_dir; tar cf - $database/$file_name") >> 8;
1855
print STDERR "$prefix If you use GNU tar, this warning can be ignored.\n";
1856
} elsif ($ret != 0) {
1857
print STDERR "$prefix tar returned with exit code $ret.\n";
1858
Die "Failed to stream '$database/$file_name': $!";
1862
if ($option_remote_host and @scp_files) {
1863
my $scp_file_list = join(" ", map { "$source_dir/$database/$_" } @scp_files);
1864
system("scp $option_scp_opt $scp_file_list '$option_remote_host:$backup_dir/$database/'")
1865
and Die "Failed to execute \"scp $option_scp_opt $scp_file_list '$option_remote_host:$backup_dir/$database/'\": $!";
1870
$now = current_time();
1871
print STDERR "$now $prefix Finished backing up .frm, .MRG, .MYD, .MYI, .TRG, .TRN, .ARM, .ARZ, .CSV, .CSM and .opt files\n\n";
1876
# file_to_array subroutine reads the given text file into an array and
1877
# stores each line as an element of the array. The end-of-line
1878
# character(s) are removed from the lines stored in the array.
1880
# filename name of a text file
1881
# lines_ref a reference to an array
1884
my $filename = shift;
1885
my $lines_ref = shift;
1887
open(FILE, $filename) || Die "can't open file '$filename': $!";
1888
@{$lines_ref} = <FILE>;
1889
close(FILE) || Die "can't close file '$filename': $!";
1891
foreach my $a (@{$lines_ref}) {
1898
# unescape_string subroutine expands escape sequences found in the string and
1899
# returns the expanded string. It also removes possible single or double quotes
1904
# a string with expanded escape sequences
1906
sub unescape_string {
1911
# remove quotes around the value if they exist
1912
if (length($value) >= 2) {
1913
if ((substr($value, 0, 1) eq "'" && substr($value, -1, 1) eq "'")
1914
|| (substr($value, 0, 1) eq '"' && substr($value, -1, 1) eq '"')) {
1915
$value = substr($value, 1, -1);
1919
# expand escape sequences
1920
while ($offset < length($value)) {
1921
my $pos = index($value, "\\", $offset);
1923
$pos = length($value);
1924
$result = $result . substr($value, $offset, $pos - $offset);
1927
my $replacement = substr($value, $pos, 2);
1928
my $escape_code = substr($value, $pos + 1, 1);
1929
if (exists $option_value_escapes{$escape_code}) {
1930
$replacement = $option_value_escapes{$escape_code};
1933
. substr($value, $offset, $pos - $offset)
1944
# read_config_file subroutine reads MySQL options file and
1945
# returns the options in a hash containing one hash per group.
1947
# filename name of a MySQL options file
1948
# groups_ref a reference to hash variable where the read
1949
# options are returned
1951
sub read_config_file {
1952
#my $filename = shift;
1953
my $groups_ref = shift;
1962
if ($option_defaults_file) {
1963
$options = $options . " --defaults-file=\"$option_defaults_file\" ";
1966
$options = $options . "--print-param";
1969
# read file to an array, one line per element
1970
#file_to_array($filename, \@lines);
1971
$cmdline = "$option_ibbackup_binary $options";
1972
@lines = `$cmdline`;
1974
# classify lines and save option values
1976
$group_hash_ref = {};
1977
${$groups_ref}{$group} = $group_hash_ref;
1978
# this pattern described an option value which may be
1979
# quoted with single or double quotes. This pattern
1980
# does not work by its own. It assumes that the first
1981
# opening parenthesis in this string is the second opening
1982
# parenthesis in the full pattern.
1983
my $value_pattern = q/((["'])([^\\\4]|(\\[^\4]))*\4)|([^\s]+)/;
1984
for ($i = 0; $i < @lines; $i++) {
1985
SWITCH: for ($lines[$i]) {
1994
if (!exists ${$groups_ref}{$group}) {
1995
$group_hash_ref = {};
1996
${$groups_ref}{$group} = $group_hash_ref;
1998
$group_hash_ref = ${$groups_ref}{$group};
2004
/^\s*([^\s=]+)\s*(#.*)?$/
2006
${$group_hash_ref}{$1} = '';
2010
# set-variable = option = value
2011
/^\s*set-variable\s*=\s*([^\s=]+)\s*=\s*($value_pattern)\s*(#.*)?$/
2012
&& do { ${$group_hash_ref}{$1} = unescape_string($2); last; };
2015
/^\s*([^\s=]+)\s*=\s*($value_pattern)\s*(#.*)?$/
2016
&& do { ${$group_hash_ref}{$1} = unescape_string($2); last; };
2023
print("$prefix: Warning: Ignored unrecognized line ",
2025
" in options : '${lines[$i]}'\n"
2033
# get_option subroutine returns the value of given option in the config
2034
# structure. If option is missing, this subroutine calls exit.
2036
# config_ref a reference to a config data
2037
# group option group name
2038
# option_name name of the option
2040
# option value as a string
2043
my $config_ref = shift;
2045
my $option_name = shift;
2048
if (!exists $config{$group}) {
2050
print STDERR "$prefix fatal error: no '$group' group in MySQL options\n";
2051
print STDERR "$prefix fatal error: OR no 'datadir' option in group '$group' in MySQL options\n";
2055
$group_hash_ref = ${$config_ref}{$group};
2056
if (!exists ${$group_hash_ref}{$option_name}) {
2058
print STDERR "$prefix fatal error: no '$option_name' option in group '$group' in MySQL options\n";
2062
return ${$group_hash_ref}{$option_name};
2065
# check_if_required subroutine returns 1 if the specified database and
2066
# table needs to be backed up.
2068
# $_[0] name of database to be checked
2069
# $_[1] full path of table file (This argument is optional)
2071
# 1 if backup should be done and 0 if not
2073
sub check_if_required {
2074
my ( $db, $table_path ) = @_;
2075
my $db_count = scalar keys %databases_list;
2076
my $tbl_count = scalar keys %table_list;
2080
if ( $db_count == 0 && $tbl_count == 0 ) {
2081
# No databases defined with --databases option, include all databases,
2082
# and no tables defined with --tables-file option, include all tables.
2086
if ( $table_path ) {
2087
# get the last component in the table pathname
2088
$filename = (reverse(split(/\//, $table_path)))[0];
2089
# get name of the table by removing file suffix
2090
$table = (split(/\./, $filename))[0];
2094
# Filter for --databases.
2096
if (defined $databases_list{$db}) {
2097
if (defined $table_path) {
2098
my $db_hash = $databases_list{$db};
2099
$db_count = keys %$db_hash;
2100
if ($db_count > 0 && ! defined $databases_list{$db}->{$table}) {
2101
# --databases option specified, but table is not included
2105
# include this database and table
2109
# --databases option given, but database is not included
2114
# Filter for --tables-file.
2116
return 0 unless exists $table_list{$db};
2117
return 0 if $table && !$table_list{$db}->{$table};
2120
return 1; # backup the table
2124
# parse_databases_option_value subroutine parses the value of
2125
# --databases option. If the option value begins with a slash
2126
# it is considered a pathname and the option value is read
2129
# This subroutine sets the global "databases_list" variable.
2131
sub parse_databases_option_value {
2134
if ($option_databases =~ /^\//) {
2135
# the value of the --databases option begins with a slash,
2136
# the option value is pathname of the file containing
2138
if (! -f $option_databases) {
2139
Die "can't find file '$option_databases'";
2142
# read from file the value of --databases option
2144
file_to_array($option_databases, \@lines);
2145
$option_databases = join(" ", @lines);
2148
# mark each database or database.table definition in the
2149
# global databases_list.
2150
foreach $item (split(/\s/, $option_databases)) {
2156
# ignore empty strings
2160
# get database and table names
2161
if ($item =~ /(\S*)\.(\S*)/) {
2162
# item is of the form DATABASE.TABLE
2166
# item is database name, table is undefined
2170
if (! defined $databases_list{$db}) {
2171
# create empty hash for the database
2172
$databases_list{$db} = \%hash;
2175
# add mapping table --> 1 to the database hash
2176
my $h = $databases_list{$db};
2182
# Parse the --tables-file file to determine which InnoDB tables
2183
# are backedup up. Only backedup tables have their .frm, etc.
2185
sub parse_tables_file_option_value {
2186
my ( $filename ) = @_;
2188
return unless $filename;
2190
open my $fh, '<', $filename;
2192
while ( my $line = <$fh> ) {
2194
my ( $db, $tbl ) = $line =~ m/\s*([^\.]+)\.([^\.]+)\s*/;
2195
if ( $db && $tbl ) {
2196
$table_list{$db}->{$tbl} = 1;
2197
print STDERR "$prefix $db.$tbl will be registerd to the list\n";
2200
warn "$prefix Invalid line in $filename: $line";
2205
warn "$prefix Cannot read --tables-file $filename: $OS_ERROR";
2215
$str =~ s/\\\\/\\/g;
2218
$str =~ s/\/\//\//g;
2224
sub set_xtrabackup_version {
2225
# Based on MySQL version choose correct binary
2226
# MySQL 5.0.* - xtrabackup_51
2227
# MySQL 5.1.* - xtrabackup_51
2228
# MySQL 5.1.* with InnoDB plugin - xtrabackup
2229
# Percona Server >= 11.0 - xtrabackup
2230
# MySQL 5.5.* - xtrabackup_55
2233
my $var_version = '';
2234
my $var_innodb_version = '';
2235
my $ibbackup_binary;
2237
mysql_send "SHOW VARIABLES LIKE 'version'\\G";
2238
file_to_array($mysql_stdout, \@lines);
2240
$var_version = $1 if /Value:\s+(\S+)/;
2242
mysql_send "SHOW VARIABLES LIKE 'innodb_version'\\G";
2243
file_to_array($mysql_stdout, \@lines);
2245
$var_innodb_version = $1 if /Value:\s+(\S+)/;
2247
if($var_version =~ m/5\.0\.\d/){
2248
$ibbackup_binary = ($win eq 1 ? 'xtrabackup.exe' : 'xtrabackup_51');
2250
if($var_version =~ m/5\.1\.\d/ and $var_innodb_version =~ m//){
2251
$ibbackup_binary = ($win eq 1 ? 'xtrabackup.exe' : 'xtrabackup_51');
2253
if($var_version =~ m/5\.1\.\d/ and $var_innodb_version =~ m/1\.0\.\d+$/){
2254
$ibbackup_binary = ($win eq 1 ? 'xtrabackup.exe' : 'xtrabackup');
2256
if($var_version =~ m/5\.1\.\d/ and $var_innodb_version =~ m/1\.0\.\d+-\d/){
2257
$ibbackup_binary = ($win eq 1 ? 'xtrabackup.exe' : 'xtrabackup');
2259
if($var_version =~ m/5\.5\.\d/){
2260
$ibbackup_binary = ($win eq 1 ? 'xtrabackup.exe' : 'xtrabackup_55');
2263
return $ibbackup_binary;
2266
# Wait until it's safe to backup a slave. Returns immediately if
2267
# the host isn't a slave. Currently there's only one check:
2268
# Slave_open_temp_tables has to be zero. Dies on timeout.
2269
sub wait_for_safe_slave {
2272
my $host_is_slave = 0;
2273
mysql_send 'SHOW SLAVE STATUS\G;';
2274
file_to_array($mysql_stdout, \@lines);
2275
foreach my $line ( @lines ) {
2276
if ( $line =~ m/Read_Master_Log_Pos/ ) {
2281
if ( !$host_is_slave ) {
2282
print STDERR "$prefix: Not checking slave open temp tables for --safe-slave-backup because host is not a slave\n";
2286
mysql_send 'STOP SLAVE SQL_THREAD;';
2288
my $open_temp_tables = get_slave_open_temp_tables();
2289
print STDERR "$prefix: Slave open temp tables: $open_temp_tables\n";
2291
return if $open_temp_tables == 0;
2294
my $n_attempts = int($option_safe_slave_backup_timeout / $sleep_time) || 1;
2295
while ( $n_attempts-- ) {
2296
print STDERR "$prefix: Starting slave SQL thread, waiting $sleep_time seconds, then checking Slave_open_temp_tables again ($n_attempts attempts remaining)...\n";
2298
mysql_send 'START SLAVE SQL_THREAD;';
2300
mysql_send 'STOP SLAVE SQL_THREAD;';
2302
$open_temp_tables = get_slave_open_temp_tables();
2303
print STDERR "$prefix: Slave open temp tables: $open_temp_tables\n";
2304
if ( !$open_temp_tables ) {
2305
print STDERR "$prefix: Slave is safe to backup\n";
2310
Die "Slave_open_temp_tables did not become zero after waiting $option_safe_slave_backup_timeout seconds";
2313
sub get_slave_open_temp_tables {
2315
mysql_send 'SHOW STATUS LIKE "slave_open_temp_tables"\G;';
2316
file_to_array($mysql_stdout, \@lines);
2318
for my $i ( 0..$#lines ) {
2319
$last_value = $i + 1
2320
if $lines[$i] =~ m/Variable_name: Slave_open_temp_tables/i;
2322
Die "SHOW STATUS LIKE 'slave_open_temp_tables' did not return anything"
2325
Die "Failed to get Slave_open_temp_tables from SHOW STATUS"
2326
unless defined $lines[$last_value];
2328
my ($n) = $lines[$last_value] =~ m/(\d+)/;
2336
innobackupex - Non-blocking backup tool for InnoDB, XtraDB and HailDB databases
2340
innobackupex [--compress[=LEVEL]] [--include=REGEXP] [--user=NAME]
2341
[--password=WORD] [--port=PORT] [--socket=SOCKET]
2342
[--no-timestamp] [--ibbackup-binary=IBBACKUP-BINARY]
2343
[--slave-info] [--stream=tar] [--force-tar]
2344
[--scpopt=OPTIONS-FOR-SCP] [--defaults-file=MY.CNF]
2345
[--databases=LIST] [--remote-host=HOSTNAME] [--no-lock]
2346
[--tmpdir=DIRECTORY] [--tables-file=FILE]
2347
[--incremental] [--incremental-basedir]
2348
[--incremental-dir] [--incremental-lsn]
2351
innobackupex --apply-log [--use-memory=MB] [--uncompress]
2352
[--defaults-file=MY.CNF]
2353
[--export] [--redo-only] [--ibbackup=IBBACKUP-BINARY]
2356
innobackupex --copy-back [--defaults-file=MY.CNF] BACKUP-DIR
2360
The first command line above makes a hot backup of a MySQL database.
2361
By default it creates a backup directory (named by the current date
2362
and time) in the given backup root directory. With the --no-timestamp
2363
option it does not create a time-stamped backup directory, but it puts
2364
the backup in the given directory (which must not exist). This
2365
command makes a complete backup of all MyISAM and InnoDB tables and
2366
indexes in all databases or in all of the databases specified with the
2367
--databases option. The created backup contains .frm, .MRG, .MYD,
2368
.MYI, .TRG, .TRN, .ARM, .ARZ, .CSM, CSV, .opt, .par, and InnoDB data and log files.
2369
The MY.CNF options file defines the location of the database. This command
2370
connects to the MySQL server using the mysql client program, and runs
2371
xtrabackup as a child process.
2373
The --apply-log command prepares a backup for starting a MySQL
2374
server on the backup. This command recovers InnoDB data files as specified
2375
in BACKUP-DIR/backup-my.cnf using BACKUP-DIR/xtrabackup_logfile,
2376
and creates new InnoDB log files as specified in BACKUP-DIR/backup-my.cnf.
2377
The BACKUP-DIR should be the path to a backup directory created by
2378
xtrabackup. This command runs xtrabackup as a child process, but it does not
2379
connect to the database server.
2381
The --copy-back command copies data, index, and log files
2382
from the backup directory back to their original locations.
2383
The MY.CNF options file defines the original location of the database.
2384
The BACKUP-DIR is the path to a backup directory created by xtrabackup.
2386
On success the exit code innobackupex is 0. A non-zero exit code
2396
Prepare a backup in BACKUP-DIR by applying the transaction log file named "xtrabackup_logfile" located in the same directory. Also, create new transaction logs. The InnoDB configuration is read from the file "backup-my.cnf".
2400
Copy all the files in a previously made backup from the backup directory to their original locations.
2402
=item --databases=LIST
2404
This option specifies the list of databases that innobackupex should back up. The option accepts a string argument. The list is of the form "databasename1[.table_name1] databasename2[.table_name2] . . .". If this option is not specified, all databases containing MyISAM and InnoDB tables will be backed up. Please make sure that --databases contains all of the InnoDB databases and tables, so that all of the innodb.frm files are also backed up. In case the list is very long, this can be specified in a file, and the full path of the file can be specified instead of the list. (See option --tables-file.)
2406
=item --defaults-file=[MY.CNF]
2408
This option specifies what file to read the default MySQL options from. The option accepts a string argument. It is also passed directly to xtrabackup's --defaults-file option. See the xtrabackup documentation for details.
2412
This option is passed directly to xtrabackup's --export option. It enables exporting individual tables for import into another server. See the xtrabackup documentation for details.
2414
=item --extra-lsndir=DIRECTORY
2416
This option specifies the directory in which to save an extra copy of the "xtrabackup_checkpoints" file. The option accepts a string argument. It is passed directly to xtrabackup's --extra-lsndir option. See the xtrabackup documentation for details.
2420
This option forces the use of tar when creating a streamed backup, rather than tar4ibd, which is the default.
2424
This option displays a help screen and exits.
2428
This option specifies the host to use when connecting to the database server with TCP/IP. The option accepts a string argument. It is passed to the mysql child process without alteration. See mysql --help for details.
2430
=item --ibbackup-binary=IBBACKUP-BINARY
2432
This option specifies which xtrabackup binary should be used. The option accepts a string argument. IBBACKUP-BINARY should be the command used to run XtraBackup. The option can be useful if the xtrabackup binary is not in your search path or working directory. If this option is not specified, innobackupex attempts to determine the binary to use automatically. By default, "xtrabackup" is the command used. However, when option --copy-back is specified, "xtrabackup_51" is the command used. And when option --apply-log is specified, the binary is used whose name is in the file "xtrabackup_binary" in the backup directory, if that file exists.
2434
=item --include=REGEXP
2436
This option is a regular expression to be matched against table names in databasename.tablename format. It is passed directly to xtrabackup's --tables option. See the xtrabackup documentation for details.
2440
This option tells xtrabackup to create an incremental backup, rather than a full one. It is passed to the xtrabackup child process. When this option is specified, either --incremental-lsn or --incremental-basedir can also be given. If neither option is given, option --incremental-basedir is passed to xtrabackup by default, set to the first timestamped backup directory in the backup base directory.
2442
=item --incremental-basedir=DIRECTORY
2444
This option specifies the directory containing the full backup that is the base dataset for the incremental backup. The option accepts a string argument. It is used with the --incremental option.
2446
=item --incremental-dir=DIRECTORY
2448
This option specifies the directory where the incremental backup will be combined with the full backup to make a new full backup. The option accepts a string argument. It is used with the --incremental option.
2450
=item --incremental-lsn
2452
This option specifies the log sequence number (LSN) to use for the incremental backup. The option accepts a string argument. It is used with the --incremental option. It is used instead of specifying --incremental-basedir. For databases created by MySQL and Percona Server 5.0-series versions, specify the LSN as two 32-bit integers in high:low format. For databases created in 5.1 and later, specify the LSN as a single 64-bit integer.
2456
Use this option to disable table lock with "FLUSH TABLES WITH READ LOCK". Use it only if ALL your tables are InnoDB and you DO NOT CARE about the binary log position of the backup.
2458
=item --no-timestamp
2460
This option prevents creation of a time-stamped subdirectory of the BACKUP-ROOT-DIR given on the command line. When it is specified, the backup is done in BACKUP-ROOT-DIR instead.
2462
=item --parallel=NUMBER-OF-THREADS
2464
This option specifies the number of threads the xtrabackup child process should use to back up files concurrently. The option accepts an integer argument. It is passed directly to xtrabackup's --parallel option. See the xtrabackup documentation for details.
2467
=item --password=WORD
2469
This option specifies the password to use when connecting to the database. It accepts a string argument. It is passed to the mysql child process without alteration. See mysql --help for details.
2473
This option specifies the port to use when connecting to the database server with TCP/IP. The option accepts a string argument. It is passed to the mysql child process. It is passed to the mysql child process without alteration. See mysql --help for details.
2477
This option is passed directly to xtrabackup's --apply-log-only option. This forces xtrabackup to skip the "rollback" phase and do a "redo" only. This is necessary if the backup will have incremental changes applied to it later. See the xtrabackup documentation for details.
2479
=item --remote-host=HOSTNAME
2481
This option specifies the remote host on which the backup files will be created, by using an ssh connection. The option accepts a string argument.
2483
=item --safe-slave-backup
2485
Stop slave SQL thread and wait to start backup until Slave_open_temp_tables in "SHOW STATUS" is zero. If there are no open temporary tables, the backup will take place, otherwise the SQL thread will be started and stopped until there are no open temporary tables. The backup will fail if Slave_open_temp_tables does not become zero after --safe-slave-backup-timeout seconds. The slave SQL thread will be restarted when the backup finishes.
2487
=item --safe-slave-backup-timeout
2489
How many seconds --safe-slave-backup should wait for Slave_open_temp_tables to become zero. (default 300)
2491
=item --scpopt=SCP-OPTIONS
2493
This option specifies the command line options to pass to scp when the option --remost-host is specified. The option accepts a string argument. If the option is not specified, the default options are "-Cp -c arcfour".
2497
This option is useful when backing up a replication slave server. It prints the binary log position and name of the master server. It also writes this information to the "xtrabackup_slave_info" file as a "CHANGE MASTER" command. A new slave for this master can be set up by starting a slave server on this backup and issuing a "CHANGE MASTER" command with the binary log position saved in the "xtrabackup_slave_info" file.
2499
=item --socket=SOCKET
2501
This option specifies the socket to use when connecting to the local database server with a UNIX domain socket. The option accepts a string argument. It is passed to the mysql child process without alteration. See mysql --help for details.
2503
=item --stream=[tar|. . .]
2505
This option specifies the format in which to do the streamed backup. The option accepts a string argument. The backup will be done to STDOUT in the specified format. Currently, the only supported format is tar. Uses tar4ibd, which is available in XtraBackup distributions.
2507
=item --tables-file=FILE
2509
This option specifies the file in which there are a list of names of the form database. The option accepts a string argument.table, one per line. The option is passed directly to xtrabackup's --tables-file option.
2511
=item --throttle=IOS
2513
This option specifies a number of I/O operations (pairs of read+write) per second. It accepts an integer argument. It is passed directly to xtrabackup's --throttle option.
2515
=item --tmpdir=DIRECTORY
2517
This option specifies the location where a temporary file will be stored. The option accepts a string argument. It should be used when --remote-host or --stream is specified. For these options, the transaction log will first be stored to a temporary file, before streaming or copying to a remote host. This option specifies the location where that temporary file will be stored. If the option is not specifed, the default is to use the value of tmpdir read from the server configuration.
2519
=item --use-memory=MB
2521
This option specifies the amount of memory in megabytes for xtrabackup to use for crash recovery while preparing a backup. The option accepts a string argument. It is used only with the option --apply-log. It is passed directly to xtrabackup's --use-memory option. See the xtrabackup documentation for details.
2525
This option specifies the MySQL username used when connecting to the server, if that's not the current user. The option accepts a string argument. It is passed to the mysql child process without alteration. See mysql --help for details.
2529
This option displays the xtrabackup version and copyright notice and then exits.
2535
Bugs can be reported on Launchpad: https://bugs.launchpad.net/percona-xtrabackup/+filebug
2539
InnoDB Backup Utility Copyright 2003, 2009 Innobase Oy and Percona, Inc 2009-2011. All Rights Reserved.
2541
This software is published under the GNU GENERAL PUBLIC LICENSE Version 2, June 1991.