Merge lp:~akopytov/percona-xtrabackup/bug1135441-2.1 into lp:percona-xtrabackup/2.1

Proposed by Alexey Kopytov
Status: Merged
Approved by: Stewart Smith
Approved revision: no longer in the source branch.
Merged at revision: 661
Proposed branch: lp:~akopytov/percona-xtrabackup/bug1135441-2.1
Merge into: lp:percona-xtrabackup/2.1
Diff against target: 782 lines (+153/-137)
2 files modified
innobackupex (+140/-137)
src/xtrabackup.cc (+13/-0)
To merge this branch: bzr merge lp:~akopytov/percona-xtrabackup/bug1135441-2.1
Reviewer Review Type Date Requested Status
Stewart Smith (community) Approve
Registry Administrators Pending
Review via email: mp+180050@code.launchpad.net

Description of the change

    Bug #1135441: Make sure all child processes are killed on error

    Modified innobackupex to handle the following cases:

    1. the xtrabackup and the query killer processes are killed on errors
    raised by the script itself (regardless of the way it is done)

    2. the xtrabackup and the query killer processes are killed on
    interceptable signals (such as SIGINT, SIGTERM, etc.) received by
    innobackupex.

    3. (on Linux only) the xtrabackup process is killed even if innobackupex
    is terminated with a non-interceptable signal (such as SIGKILL).

To post a comment you must log in.
Revision history for this message
Alexey Kopytov (akopytov) wrote :
Revision history for this message
Alexey Kopytov (akopytov) wrote :

Heh, bug664986.sh still cowardly fails with the fix. Will investigate and recommit.

Revision history for this message
Alexey Kopytov (akopytov) wrote :
Revision history for this message
Stewart Smith (stewart) wrote :

Looks good. We could start using Autodie and other fancy things in the perl code which will help catch places where we may not die gracefully, but that should be a different patch.

This looks good though.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'innobackupex'
--- innobackupex 2013-07-31 11:28:11 +0000
+++ innobackupex 2013-08-15 09:38:11 +0000
@@ -200,6 +200,9 @@
200# run on a slave server200# run on a slave server
201my $mysql_slave_position = '';201my $mysql_slave_position = '';
202202
203# process id if the script itself
204my $innobackupex_pid = $$;
205
203# process id of ibbackup program (runs as a child process of this script)206# process id of ibbackup program (runs as a child process of this script)
204my $ibbackup_pid = '';207my $ibbackup_pid = '';
205208
@@ -400,22 +403,63 @@
400 return strftime("%y%m%d %H:%M:%S", localtime());403 return strftime("%y%m%d %H:%M:%S", localtime());
401}404}
402405
403406#
404#407# Global initialization:
405# Die subroutine kills all child processes and exits this process.408# 1. Override the 'die' builtin to customize the format of error messages
406# This subroutine takes the same argument as the built-in die function.409#
407# Parameters:410# 2. Setup signal handlers to terminate gracefully on fatal signals
408# message string which is printed to stdout411#
409#412BEGIN {
410sub Die {413 *CORE::GLOBAL::die = sub {
411 my $message = shift;414
412415 print STDERR "$prefix Error: @_";
413 # kill all child processes of this process416
414 kill_child_processes();417 # Mimic the default 'die' behavior: append information about the caller
415418 # and the new line, if the argument does not already end with a newline
416 die "$prefix Error: $message";419 if ($_[-1] !~ m(\n$)) {
417}420 my ($pkg, $file, $line) = caller 0;
418 421
422 print STDERR " at $file line $line.\n";
423 }
424
425 exit(1);
426 };
427
428 foreach ('HUP', 'INT', 'QUIT', 'ABRT', 'PIPE', 'TERM', 'XFSZ') {
429 $SIG{$_} = \&catch_fatal_signal;
430 }
431}
432
433#
434# Make sure all child processes are killed on exit. This doesn't cover cases
435# when innobackupex is terminated with a signal.
436#
437END {
438 # We only want to execute this in the parent script process, and ignore
439 # for all child processes it may spawn
440 if ($$ == $innobackupex_pid) {
441 kill_child_processes();
442 }
443}
444
445#
446# kill child processes spawned by the script
447#
448sub kill_child_processes {
449 if ($ibbackup_pid) {
450 kill($kill_signal, $ibbackup_pid);
451 wait_for_ibbackup_finish();
452 }
453 stop_query_killer();
454}
455
456sub catch_fatal_signal {
457 # Don't print anything if a child process is terminated with a signal
458 if ($$ == $innobackupex_pid) {
459 die "Terminated with SIG$_[0]"
460 }
461}
462
419#463#
420# Finds all files that match the given pattern recursively beneath464# Finds all files that match the given pattern recursively beneath
421# the given directory. Returns a list of files with their paths relative 465# the given directory. Returns a list of files with their paths relative
@@ -429,7 +473,7 @@
429 my @retlist;473 my @retlist;
430 474
431 opendir(FINDDIR, $dir)475 opendir(FINDDIR, $dir)
432 || Die "Can't open directory '$dir': $!\n";476 || die "Can't open directory '$dir': $!";
433477
434 while (defined($child = readdir(FINDDIR))) {478 while (defined($child = readdir(FINDDIR))) {
435 next if $child eq "." || $child eq "..";479 next if $child eq "." || $child eq "..";
@@ -464,10 +508,10 @@
464 } elsif ($mode == 2) {508 } elsif ($mode == 2) {
465 $file_cmd = "qpress -do " . $file . " > " . $dest_file;509 $file_cmd = "qpress -do " . $file . " > " . $dest_file;
466 } else {510 } else {
467 Die("Unknown decrypt_decompress mode : $mode\n"); 511 die "Unknown decrypt_decompress mode : $mode";
468 }512 }
469 print STDERR "$prefix $file_cmd\n";513 print STDERR "$prefix $file_cmd\n";
470 system("$file_cmd") && Die "$file_cmd failed with $!\n";514 system("$file_cmd") && die "$file_cmd failed with $!";
471 system("rm -f $file");515 system("rm -f $file");
472}516}
473517
@@ -505,7 +549,7 @@
505 } elsif ($mode == 2) {549 } elsif ($mode == 2) {
506 $file_ext = ".qp";550 $file_ext = ".qp";
507 } else {551 } else {
508 Die("Unknown decrypt_decompress mode : $mode\n"); 552 die "Unknown decrypt_decompress mode : $mode";
509 }553 }
510554
511 # recursively find all files of interest in the backup set555 # recursively find all files of interest in the backup set
@@ -547,11 +591,11 @@
547 if ($status == $pids[$freepidindex]) {591 if ($status == $pids[$freepidindex]) {
548 my $childretcode = $? >> 8;592 my $childretcode = $? >> 8;
549 if ($childretcode != 0) {593 if ($childretcode != 0) {
550 Die("Child failed on $workingfiles[$freepidindex] : $childretcode");594 die "Child failed on $workingfiles[$freepidindex] : $childretcode";
551 }595 }
552 last;596 last;
553 } elsif ($status == -1) {597 } elsif ($status == -1) {
554 Die("waitpid failed on $workingfiles[$freepidindex] : $status");598 die "waitpid failed on $workingfiles[$freepidindex] : $status";
555 }599 }
556 }600 }
557 # couldn't find a free slot yet so sleep for 1/10 th of a second or so.601 # couldn't find a free slot yet so sleep for 1/10 th of a second or so.
@@ -581,10 +625,10 @@
581 my $childretcode = $? >> 8;625 my $childretcode = $? >> 8;
582 if ($status == $pids[$freepidindex]) {626 if ($status == $pids[$freepidindex]) {
583 if ($childretcode != 0) {627 if ($childretcode != 0) {
584 Die("Child failed on $workingfiles[$freepidindex] : $childretcode");628 die "Child failed on $workingfiles[$freepidindex] : $childretcode";
585 }629 }
586 } else {630 } else {
587 Die("waitpid failed on $workingfiles[$freepidindex] : $status");631 die "waitpid failed on $workingfiles[$freepidindex] : $status";
588 }632 }
589 }633 }
590 }634 }
@@ -795,7 +839,7 @@
795 my $dst_path = shift;839 my $dst_path = shift;
796840
797 print STDERR "$prefix Copying '$src_path' to '$dst_path'\n";841 print STDERR "$prefix Copying '$src_path' to '$dst_path'\n";
798 copy($src_path, $dst_path) or Die "copy failed: $!";842 copy($src_path, $dst_path) or die "copy failed: $!";
799}843}
800844
801#845#
@@ -806,7 +850,7 @@
806 my $dst_path = shift;850 my $dst_path = shift;
807851
808 print STDERR "$prefix Moving '$src_path' to '$dst_path'\n";852 print STDERR "$prefix Moving '$src_path' to '$dst_path'\n";
809 move($src_path, $dst_path) or Die "move failed: $!";853 move($src_path, $dst_path) or die "move failed: $!";
810}854}
811855
812856
@@ -851,14 +895,14 @@
851 # Create the directory in the destination if necessary895 # Create the directory in the destination if necessary
852 if (! -e "$dst_path") {896 if (! -e "$dst_path") {
853 print STDERR "$prefix Creating directory '$dst_path'\n";897 print STDERR "$prefix Creating directory '$dst_path'\n";
854 mkdir "$dst_path" or Die "mkdir failed: $!";898 mkdir "$dst_path" or die "mkdir failed: $!";
855 } elsif (! -d "$dst_path") {899 } elsif (! -d "$dst_path") {
856 Die "$dst_path exists, but is not a directory";900 die "$dst_path exists, but is not a directory";
857 }901 }
858 } else {902 } else {
859 # Don't overwrite files unless $copy_dir_overwrite is 1903 # Don't overwrite files unless $copy_dir_overwrite is 1
860 if (!$copy_dir_overwrite && -e "$copy_dir_dst/$_") {904 if (!$copy_dir_overwrite && -e "$copy_dir_dst/$_") {
861 Die "Failed to process file $File::Find::name: " .905 die "Failed to process file $File::Find::name: " .
862 "not overwriting file $copy_dir_dst/$_";906 "not overwriting file $copy_dir_dst/$_";
863 }907 }
864908
@@ -898,7 +942,7 @@
898 }942 }
899 if (! exists $processed_files{$rel_path}) {943 if (! exists $processed_files{$rel_path}) {
900 unlink($File::Find::name) or944 unlink($File::Find::name) or
901 Die("Cannot remove file $File::Find::name");945 die "Cannot remove file $File::Find::name";
902 }946 }
903}947}
904948
@@ -1043,20 +1087,6 @@
1043 "Original undo directory");1087 "Original undo directory");
1044 }1088 }
10451089
1046 # check that the original options file and the backup options file have
1047 # the same value for "innodb_data_file_path" option
1048 #$backup_innodb_data_file_path =
1049 # get_option(\%backup_config, 'mysqld', 'innodb_data_file_path');
1050 #if (!are_equal_innodb_data_file_paths($orig_innodb_data_file_path,
1051 # $backup_innodb_data_file_path)
1052 #) {
1053 # Die "The value of 'innodb_data_file_path' option in the original "
1054 # . "my.cnf file '$config_file' is different from the value "
1055 # . "in the backup my.cnf file '$backup_config_file'.\n(original: "
1056 # . "'$orig_innodb_data_file_path')\n"
1057 # . "(backup: '$backup_innodb_data_file_path')";
1058 #}
1059
1060 # make a list of all ibdata files in the backup directory and all1090 # make a list of all ibdata files in the backup directory and all
1061 # directories in the backup directory under which there are ibdata files1091 # directories in the backup directory under which there are ibdata files
1062 foreach my $c (parse_innodb_data_file_path($orig_innodb_data_file_path)) {1092 foreach my $c (parse_innodb_data_file_path($orig_innodb_data_file_path)) {
@@ -1064,7 +1094,7 @@
1064 # check that the backup data file exists1094 # check that the backup data file exists
1065 if (! -e "$backup_dir/$c->{filename}") {1095 if (! -e "$backup_dir/$c->{filename}") {
1066 if (-e "$backup_dir/$c->{filename}.ibz") {1096 if (-e "$backup_dir/$c->{filename}.ibz") {
1067 Die "Backup data file '$backup_dir/$c->{filename}' "1097 die "Backup data file '$backup_dir/$c->{filename}' "
1068 . "does not exist, but "1098 . "does not exist, but "
1069 . "its compressed copy '$c->{path}.ibz' exists. Check "1099 . "its compressed copy '$c->{path}.ibz' exists. Check "
1070 . "that you have decompressed "1100 . "that you have decompressed "
@@ -1072,7 +1102,7 @@
1072 . "'$innobackup_script --copy-back ...' "1102 . "'$innobackup_script --copy-back ...' "
1073 . "or '$innobackup_script --move-back ...' !";1103 . "or '$innobackup_script --move-back ...' !";
1074 } elsif (-e "$backup_dir/$c->{filename}.qp") {1104 } elsif (-e "$backup_dir/$c->{filename}.qp") {
1075 Die "Backup data file '$backup_dir/$c->{filename}' "1105 die "Backup data file '$backup_dir/$c->{filename}' "
1076 . "does not exist, but "1106 . "does not exist, but "
1077 . "its compressed copy '$c->{path}.qp' exists. Check "1107 . "its compressed copy '$c->{path}.qp' exists. Check "
1078 . "that you have run "1108 . "that you have run "
@@ -1081,7 +1111,7 @@
1081 . "'$innobackup_script --copy-back ...' "1111 . "'$innobackup_script --copy-back ...' "
1082 . "or '$innobackup_script --move-back ...' !";1112 . "or '$innobackup_script --move-back ...' !";
1083 } elsif (-e "$backup_dir/$c->{filename}.xbcrypt") {1113 } elsif (-e "$backup_dir/$c->{filename}.xbcrypt") {
1084 Die "Backup data file '$backup_dir/$c->{filename}' "1114 die "Backup data file '$backup_dir/$c->{filename}' "
1085 . "does not exist, but "1115 . "does not exist, but "
1086 . "its compressed copy '$c->{path}.xbcrypt' exists. Check "1116 . "its compressed copy '$c->{path}.xbcrypt' exists. Check "
1087 . "that you have run "1117 . "that you have run "
@@ -1090,7 +1120,7 @@
1090 . "'$innobackup_script --copy-back ...' "1120 . "'$innobackup_script --copy-back ...' "
1091 . "or '$innobackup_script --move-back ...' !";1121 . "or '$innobackup_script --move-back ...' !";
1092 } else {1122 } else {
1093 Die "Backup data file '$backup_dir/$c->{filename}' "1123 die "Backup data file '$backup_dir/$c->{filename}' "
1094 . "does not exist.";1124 . "does not exist.";
1095 }1125 }
1096 }1126 }
@@ -1123,7 +1153,7 @@
1123 print STDERR "$prefix in '$backup_dir'\n";1153 print STDERR "$prefix in '$backup_dir'\n";
1124 print STDERR "$prefix back to '$orig_undo_dir'\n";1154 print STDERR "$prefix back to '$orig_undo_dir'\n";
1125 opendir(DIR, $backup_dir)1155 opendir(DIR, $backup_dir)
1126 || Die "Can't open directory '$backup_dir': $!\n";1156 || die "Can't open directory '$backup_dir': $!";
1127 while (defined($file = readdir(DIR))) {1157 while (defined($file = readdir(DIR))) {
1128 if ($file =~ /^$ibundo_files$/ && -f "$backup_dir/$file") {1158 if ($file =~ /^$ibundo_files$/ && -f "$backup_dir/$file") {
1129 $src_name = escape_path("$backup_dir/$file");1159 $src_name = escape_path("$backup_dir/$file");
@@ -1135,7 +1165,7 @@
11351165
1136 # copy InnoDB log files to original InnoDB log directory1166 # copy InnoDB log files to original InnoDB log directory
1137 opendir(DIR, $backup_dir) 1167 opendir(DIR, $backup_dir)
1138 || Die "Can't open directory '$backup_dir': $!\n";1168 || die "Can't open directory '$backup_dir': $!";
1139 print STDERR "\n$prefix Starting to $operation InnoDB log files\n";1169 print STDERR "\n$prefix Starting to $operation InnoDB log files\n";
1140 print STDERR "$prefix in '$backup_dir'\n";1170 print STDERR "$prefix in '$backup_dir'\n";
1141 print STDERR "$prefix back to original InnoDB log directory '$orig_iblog_dir'\n";1171 print STDERR "$prefix back to original InnoDB log directory '$orig_iblog_dir'\n";
@@ -1216,7 +1246,7 @@
1216 $rcode = system("$cmdline");1246 $rcode = system("$cmdline");
1217 if ($rcode) {1247 if ($rcode) {
1218 # failure1248 # failure
1219 Die "\n$prefix ibbackup failed";1249 die "\n$prefix ibbackup failed";
1220 }1250 }
12211251
1222 # We should not create ib_logfile files if we prepare for following incremental applies1252 # We should not create ib_logfile files if we prepare for following incremental applies
@@ -1228,7 +1258,7 @@
1228 $rcode = system("$cmdline");1258 $rcode = system("$cmdline");
1229 if ($rcode) {1259 if ($rcode) {
1230 # failure1260 # failure
1231 Die "\n$prefix xtrabackup (2nd execution) failed";1261 die "\n$prefix xtrabackup (2nd execution) failed";
1232 }1262 }
1233 }1263 }
12341264
@@ -1275,7 +1305,8 @@
12751305
1276 if ($ibbackup_pid == $pid) {1306 if ($ibbackup_pid == $pid) {
1277 # The file doesn't exist, but the process has terminated1307 # The file doesn't exist, but the process has terminated
1278 Die "ibbackup child process has died";1308 $ibbackup_pid = '';
1309 die "The xtrabackup child process has died";
1279 }1310 }
12801311
1281 sleep 1;1312 sleep 1;
@@ -1309,7 +1340,7 @@
1309#1340#
1310sub resume_ibbackup {1341sub resume_ibbackup {
1311 my $suspend_file = shift;1342 my $suspend_file = shift;
1312 unlink $suspend_file || Die "Failed to delete '$suspend_file': $!";1343 unlink $suspend_file || die "Failed to delete '$suspend_file': $!";
1313}1344}
13141345
1315#1346#
@@ -1325,7 +1356,7 @@
13251356
1326 wait_for_ibbackup_file_create($suspend_file);1357 wait_for_ibbackup_file_create($suspend_file);
13271358
1328 unlink $suspend_file || Die "Failed to delete '$suspend_file': $!";1359 unlink $suspend_file || die "Failed to delete '$suspend_file': $!";
1329}1360}
13301361
1331#1362#
@@ -1460,10 +1491,10 @@
1460 $ibbackup_pid = $pid;1491 $ibbackup_pid = $pid;
1461 } else {1492 } else {
1462 # child process1493 # child process
1463 exec($cmdline) || Die "Failed to exec ibbackup: $!";1494 exec($cmdline) || die "Failed to exec ibbackup: $!";
1464 }1495 }
1465 } else {1496 } else {
1466 Die "failed to fork ibbackup child process: $!";1497 die "failed to fork ibbackup child process: $!";
1467 }1498 }
1468}1499}
1469 1500
@@ -1513,7 +1544,7 @@
1513 my $con = shift;1544 my $con = shift;
15141545
1515 if (defined($con->{keep_alive_pid})) {1546 if (defined($con->{keep_alive_pid})) {
1516 Die "Keep-alive process has already been started for this connection."1547 die "Keep-alive process has already been started for this connection."
1517 }1548 }
15181549
1519 my $keep_alive_pid = fork();1550 my $keep_alive_pid = fork();
@@ -1557,7 +1588,7 @@
1557 my $con = shift;1588 my $con = shift;
15581589
1559 if (!defined($con->{keep_alive_pid})) {1590 if (!defined($con->{keep_alive_pid})) {
1560 Die "Keep-alive process has never been started for this connection."1591 die "Keep-alive process has never been started for this connection."
1561 }1592 }
15621593
1563 kill 'INT', $con->{keep_alive_pid};1594 kill 'INT', $con->{keep_alive_pid};
@@ -1565,7 +1596,7 @@
1565 my $rc = $? >> 8;1596 my $rc = $? >> 8;
15661597
1567 if ($rc != 0) {1598 if ($rc != 0) {
1568 Die "Keep-alive process died with exit code " . $rc;1599 die "Keep-alive process died with exit code " . $rc;
1569 }1600 }
1570 undef $con->{keep_alive_pid};1601 undef $con->{keep_alive_pid};
1571}1602}
@@ -1611,11 +1642,11 @@
16111642
1612 if ($args{abort_on_error}) {1643 if ($args{abort_on_error}) {
1613 if (!$dbd_mysql_installed) {1644 if (!$dbd_mysql_installed) {
1614 die "ERROR: Failed to connect to MySQL server as " .1645 die "Failed to connect to MySQL server as " .
1615 "DBD::mysql module is not installed";1646 "DBD::mysql module is not installed";
1616 } else {1647 } else {
1617 if (!$con{dbh}) {1648 if (!$con{dbh}) {
1618 die "ERROR: Failed to connect to MySQL server: " .1649 die "Failed to connect to MySQL server: " .
1619 $con{connect_error};1650 $con{connect_error};
1620 }1651 }
1621 }1652 }
@@ -1670,7 +1701,7 @@
1670 }1701 }
1671 };1702 };
1672 if ($EVAL_ERROR) {1703 if ($EVAL_ERROR) {
1673 Die "\nError executing '$query': $EVAL_ERROR\n";1704 die "\nError executing '$query': $EVAL_ERROR";
1674 }1705 }
1675}1706}
16761707
@@ -1925,7 +1956,7 @@
1925 sleep(1);1956 sleep(1);
1926 }1957 }
19271958
1928 Die "Unable to obtain lock. Please try again.";1959 die "Unable to obtain lock. Please try again.";
1929}1960}
19301961
19311962
@@ -1964,6 +1995,7 @@
1964 if (defined($query_killer_pid)) {1995 if (defined($query_killer_pid)) {
1965 kill 'HUP' => $query_killer_pid;1996 kill 'HUP' => $query_killer_pid;
1966 waitpid($query_killer_pid, 0);1997 waitpid($query_killer_pid, 0);
1998 undef $query_killer_pid;
1967 print STDERR "Query killing process is finished\n";1999 print STDERR "Query killing process is finished\n";
1968 }2000 }
1969}2001}
@@ -2029,18 +2061,6 @@
2029}2061}
20302062
2031#2063#
2032# kill_child_processes subroutine kills all child processes of this process.
2033#
2034sub kill_child_processes {
2035 if ($ibbackup_pid) {
2036 kill($kill_signal, $ibbackup_pid);
2037 $ibbackup_pid = '';
2038 }
2039 stop_query_killer();
2040}
2041
2042
2043#
2044# require_external subroutine checks that an external program is runnable2064# require_external subroutine checks that an external program is runnable
2045# via the shell. This is tested by calling the program with the2065# via the shell. This is tested by calling the program with the
2046# given arguments. It is checked that the program returns 0 and does 2066# given arguments. It is checked that the program returns 0 and does
@@ -2075,11 +2095,11 @@
2075 if ($stderr ne '') {2095 if ($stderr ne '') {
2076 # failure2096 # failure
2077 unlink $tmp_stdout;2097 unlink $tmp_stdout;
2078 Die "Couldn't run $program: $stderr";2098 die "Couldn't run $program: $stderr";
2079 } elsif ($rcode) {2099 } elsif ($rcode) {
2080 # failure2100 # failure
2081 unlink $tmp_stdout;2101 unlink $tmp_stdout;
2082 Die "Couldn't run $program: $error";2102 die "Couldn't run $program: $error";
2083 }2103 }
20842104
2085 # success2105 # success
@@ -2186,7 +2206,7 @@
2186 && $ibbackup_version le "2.0") {2206 && $ibbackup_version le "2.0") {
2187 # --include option was given, but ibbackup is too2207 # --include option was given, but ibbackup is too
2188 # old to support it2208 # old to support it
2189 Die "--include option was given, but ibbackup is too old"2209 die "--include option was given, but ibbackup is too old"
2190 . " to support it. You must upgrade to InnoDB Hot Backup"2210 . " to support it. You must upgrade to InnoDB Hot Backup"
2191 . " v2.0 in order to use --include option.\n";2211 . " v2.0 in order to use --include option.\n";
2192 }2212 }
@@ -2229,7 +2249,7 @@
2229 "WARNING : A left over instance of " .2249 "WARNING : A left over instance of " .
2230 "suspend file '$suspend_file' was found.\n";2250 "suspend file '$suspend_file' was found.\n";
2231 unlink "$suspend_file"2251 unlink "$suspend_file"
2232 || Die "Failed to delete '$suspend_file': $!";2252 || die "Failed to delete '$suspend_file': $!";
2233 }2253 }
2234 }2254 }
22352255
@@ -2238,7 +2258,7 @@
2238 "file '$option_tmpdir/$xtrabackup_pid_file' " .2258 "file '$option_tmpdir/$xtrabackup_pid_file' " .
2239 "was found.\n";2259 "was found.\n";
2240 unlink $option_tmpdir . "/" . $xtrabackup_pid_file || 2260 unlink $option_tmpdir . "/" . $xtrabackup_pid_file ||
2241 Die "Failed to delete " .2261 die "Failed to delete " .
2242 "'$option_tmpdir/$xtrabackup_pid_file': $!";2262 "'$option_tmpdir/$xtrabackup_pid_file': $!";
2243 }2263 }
22442264
@@ -2313,12 +2333,6 @@
2313 }2333 }
2314 }2334 }
23152335
2316 if (@ARGV == 0) {
2317 # no command line arguments
2318 print STDERR "$prefix You must specify the backup directory.\n";
2319 exit(1);
2320 }
2321
2322 # read command line options2336 # read command line options
2323 $rcode = GetOptions('compress' => \$option_compress,2337 $rcode = GetOptions('compress' => \$option_compress,
2324 'decompress' => \$option_decompress,2338 'decompress' => \$option_decompress,
@@ -2383,11 +2397,16 @@
2383 'lock-wait-query-type=s' =>2397 'lock-wait-query-type=s' =>
2384 \$option_lock_wait_query_type2398 \$option_lock_wait_query_type
2385 );2399 );
2386 2400
2401 if (@ARGV == 0) {
2402 die "You must specify the backup directory.\n";
2403 } elsif (@ARGV > 1) {
2404 die "Too many command line arguments\n";
2405 }
2406
2387 if (!$rcode) {2407 if (!$rcode) {
2388 # failed to read options2408 # failed to read options
2389 print STDERR "$prefix Bad command line arguments\n";2409 die "Bad command line arguments\n";
2390 exit(1);
2391 }2410 }
2392 if ($option_help) {2411 if ($option_help) {
2393 # print help text and exit2412 # print help text and exit
@@ -2401,9 +2420,8 @@
2401 }2420 }
24022421
2403 if ($option_defaults_file && $option_defaults_extra_file) {2422 if ($option_defaults_file && $option_defaults_extra_file) {
2404 print STDERR "$prefix --defaults-file and --defaults-extra-file " .2423 die "--defaults-file and --defaults-extra-file " .
2405 "options are mutually exclusive";2424 "options are mutually exclusive";
2406 exit(1);
2407 }2425 }
24082426
2409 if ($option_copy_back && $option_move_back) {2427 if ($option_copy_back && $option_move_back) {
@@ -2423,19 +2441,18 @@
24232441
2424 # validate lock-wait-query-type and kill-long-query-type values2442 # validate lock-wait-query-type and kill-long-query-type values
2425 if (!(grep {$_ eq $option_lock_wait_query_type} qw/all update/)) {2443 if (!(grep {$_ eq $option_lock_wait_query_type} qw/all update/)) {
2426 Die "Wrong value of lock-wait-query-type. ".2444 die "Wrong value of lock-wait-query-type. ".
2427 "Possible values are all|update, but $option_lock_wait_query_type ".2445 "Possible values are all|update, but $option_lock_wait_query_type ".
2428 "is specified.";2446 "is specified.";
2429 }2447 }
2430 if (!(grep {$_ eq $option_kill_long_query_type} qw/all select/)) {2448 if (!(grep {$_ eq $option_kill_long_query_type} qw/all select/)) {
2431 Die "Wrong value of kill-long-query-type. ".2449 die "Wrong value of kill-long-query-type. ".
2432 "Possible values are all|select, but $option_kill_long_query_type ".2450 "Possible values are all|select, but $option_kill_long_query_type ".
2433 "is specified.";2451 "is specified.";
2434 }2452 }
24352453
2436 if ($option_parallel && $option_parallel < 1) {2454 if ($option_parallel && $option_parallel < 1) {
2437 Die "$prefix --parallel must be a positive numerical value" .2455 die "--parallel must be a positive value.\n";
2438 "greater than 0";
2439 }2456 }
24402457
2441 if ($option_stream eq 'tar') {2458 if ($option_stream eq 'tar') {
@@ -2457,14 +2474,6 @@
2457 }2474 }
2458 }2475 }
24592476
2460 if (@ARGV < 1) {
2461 print STDERR "$prefix Missing command line argument\n";
2462 exit(1);
2463 } elsif (@ARGV > 1) {
2464 print STDERR "$prefix Too many command line arguments\n";
2465 exit(1);
2466 }
2467
2468 if (!$option_apply_log && !$option_copy_back && !$option_move_back2477 if (!$option_apply_log && !$option_copy_back && !$option_move_back
2469 && !$option_decrypt && !$option_decompress) {2478 && !$option_decrypt && !$option_decompress) {
2470 # we are making a backup, get backup root directory2479 # we are making a backup, get backup root directory
@@ -2487,20 +2496,17 @@
24872496
2488 if ($option_slave_info) {2497 if ($option_slave_info) {
2489 if ($option_no_lock and !$option_safe_slave_backup) {2498 if ($option_no_lock and !$option_safe_slave_backup) {
2490 print STDERR "--slave-info is used with --no-lock but without --safe-slave-backup. The binlog position cannot be consistent with the backup data.\n";2499 die "--slave-info is used with --no-lock but without --safe-slave-backup. The binlog position cannot be consistent with the backup data.\n";
2491 exit(1);
2492 }2500 }
2493 }2501 }
24942502
2495 if ($option_rsync && $option_stream) {2503 if ($option_rsync && $option_stream) {
2496 print STDERR "--rsync doesn't work with --stream\n";2504 die "--rsync doesn't work with --stream\n";
2497 exit(1);
2498 }2505 }
24992506
2500 if ($option_decompress) {2507 if ($option_decompress) {
2501 if (system("which qpress &>/dev/null") >> 8 != 0) {2508 if (system("which qpress &>/dev/null") >> 8 != 0) {
2502 print STDERR "--decompress requires qpress\n";2509 die "--decompress requires qpress\n";
2503 exit(1);
2504 }2510 }
2505 }2511 }
25062512
@@ -2528,7 +2534,7 @@
25282534
2529 $dir .= '/' . strftime("%Y-%m-%d_%H-%M-%S", localtime())2535 $dir .= '/' . strftime("%Y-%m-%d_%H-%M-%S", localtime())
2530 unless $option_no_timestamp;2536 unless $option_no_timestamp;
2531 mkdir($dir, 0777) || Die "Failed to create backup directory $dir: $!";2537 mkdir($dir, 0777) || die "Failed to create backup directory $dir: $!";
25322538
2533 # create subdirectories for ibdata files if needed2539 # create subdirectories for ibdata files if needed
2534# foreach my $a (split(/;/, $innodb_data_file_path)) {2540# foreach my $a (split(/;/, $innodb_data_file_path)) {
@@ -2566,7 +2572,7 @@
2566 $path = $path . "/" . $a;2572 $path = $path . "/" . $a;
2567 if (! -d $path) {2573 if (! -d $path) {
2568 # this directory does not exist, create it !2574 # this directory does not exist, create it !
2569 mkdir($path, 0777) || Die "Failed to create backup directory: $!";2575 mkdir($path, 0777) || die "Failed to create backup directory: $!";
2570 }2576 }
2571 }2577 }
2572}2578}
@@ -2626,11 +2632,11 @@
2626 $rsync_file_list = $rsync_tmpfile_pass2;2632 $rsync_file_list = $rsync_tmpfile_pass2;
2627 }2633 }
2628 open(RSYNC, ">$rsync_file_list")2634 open(RSYNC, ">$rsync_file_list")
2629 || Die "Can't open $rsync_file_list for writing: $!\n";2635 || die "Can't open $rsync_file_list for writing: $!";
2630 }2636 }
26312637
2632 opendir(DIR, $source_dir) 2638 opendir(DIR, $source_dir)
2633 || Die "Can't open directory '$source_dir': $!\n";2639 || die "Can't open directory '$source_dir': $!";
2634 $now = current_time();2640 $now = current_time();
2635 if ($prep_mode) {2641 if ($prep_mode) {
2636 $operation = "a prep copy of";2642 $operation = "a prep copy of";
@@ -2653,7 +2659,7 @@
2653 if (! -e "$backup_dir/$database") {2659 if (! -e "$backup_dir/$database") {
2654 # create database directory for the backup2660 # create database directory for the backup
2655 mkdir("$backup_dir/$database", 0777)2661 mkdir("$backup_dir/$database", 0777)
2656 || Die "Couldn't create directory '$backup_dir/$database': $!";2662 || die "Couldn't create directory '$backup_dir/$database': $!";
2657 }2663 }
2658 }2664 }
26592665
@@ -2720,7 +2726,7 @@
2720 # ignore errors in the prep mode, since we are running without lock,2726 # ignore errors in the prep mode, since we are running without lock,
2721 # so some files may have disappeared.2727 # so some files may have disappeared.
2722 if (system("$rsync_cmd") && !$prep_mode) {2728 if (system("$rsync_cmd") && !$prep_mode) {
2723 Die "rsync failed: $!\n";2729 die "rsync failed: $!";
2724 }2730 }
27252731
2726 $now = current_time();2732 $now = current_time();
@@ -2731,7 +2737,7 @@
2731 # with --files-from.2737 # with --files-from.
2732 if (!$prep_mode && !$option_no_lock) {2738 if (!$prep_mode && !$option_no_lock) {
2733 open(RSYNC, "<$rsync_tmpfile_pass1")2739 open(RSYNC, "<$rsync_tmpfile_pass1")
2734 || Die "Can't open $rsync_tmpfile_pass1 for reading: $!\n";2740 || die "Can't open $rsync_tmpfile_pass1 for reading: $!";
27352741
2736 while (<RSYNC>) {2742 while (<RSYNC>) {
2737 chomp;2743 chomp;
@@ -2743,9 +2749,9 @@
27432749
2744 close(RSYNC);2750 close(RSYNC);
2745 unlink "$rsync_tmpfile_pass1" || \2751 unlink "$rsync_tmpfile_pass1" || \
2746 Die "Failed to delete $rsync_tmpfile_pass1: $!";2752 die "Failed to delete $rsync_tmpfile_pass1: $!";
2747 unlink "$rsync_tmpfile_pass2" || \2753 unlink "$rsync_tmpfile_pass2" || \
2748 Die "Failed to delete $rsync_tmpfile_pass2: $!";2754 die "Failed to delete $rsync_tmpfile_pass2: $!";
2749 }2755 }
2750 }2756 }
27512757
@@ -2771,9 +2777,9 @@
2771 my $filename = shift;2777 my $filename = shift;
2772 my $lines_ref = shift;2778 my $lines_ref = shift;
2773 2779
2774 open(FILE, $filename) || Die "can't open file '$filename': $!";2780 open(FILE, $filename) || die "can't open file '$filename': $!";
2775 @{$lines_ref} = <FILE>;2781 @{$lines_ref} = <FILE>;
2776 close(FILE) || Die "can't close file '$filename': $!";2782 close(FILE) || die "can't close file '$filename': $!";
27772783
2778 foreach my $a (@{$lines_ref}) {2784 foreach my $a (@{$lines_ref}) {
2779 chomp($a);2785 chomp($a);
@@ -2943,8 +2949,7 @@
29432949
2944 if (!exists ${$config_ref}{$group}) {2950 if (!exists ${$config_ref}{$group}) {
2945 # no group2951 # no group
2946 print STDERR "$prefix fatal error: no '$group' group in MySQL options\n";2952 die "no '$group' group in MySQL options";
2947 exit(1);
2948 }2953 }
29492954
2950 $group_hash_ref = ${$config_ref}{$group};2955 $group_hash_ref = ${$config_ref}{$group};
@@ -2970,15 +2975,13 @@
29702975
2971 if (!exists $config{$group}) {2976 if (!exists $config{$group}) {
2972 # no group2977 # no group
2973 print STDERR "$prefix fatal error: no '$group' group in MySQL options\n";2978 die "no '$group' group in MySQL options";
2974 exit(1);
2975 }2979 }
2976 2980
2977 $group_hash_ref = ${$config_ref}{$group};2981 $group_hash_ref = ${$config_ref}{$group};
2978 if (!exists ${$group_hash_ref}{$option_name}) {2982 if (!exists ${$group_hash_ref}{$option_name}) {
2979 # no option2983 # no option
2980 print STDERR "$prefix fatal error: no '$option_name' option in group '$group' in MySQL options\n";2984 die "no '$option_name' option in group '$group' in MySQL options";
2981 exit(1);
2982 }2985 }
29832986
2984 return ${$group_hash_ref}{$option_name};2987 return ${$group_hash_ref}{$option_name};
@@ -3089,7 +3092,7 @@
3089 # the option value is pathname of the file containing3092 # the option value is pathname of the file containing
3090 # list of databases3093 # list of databases
3091 if (! -f $option_databases) {3094 if (! -f $option_databases) {
3092 Die "can't find file '$option_databases'";3095 die "can't find file '$option_databases'";
3093 }3096 }
30943097
3095 # read from file the value of --databases option3098 # read from file the value of --databases option
@@ -3199,11 +3202,11 @@
31993202
32003203
3201 if($var_version =~ m/5\.0\.\d/) {3204 if($var_version =~ m/5\.0\.\d/) {
3202 Die "MySQL 5.0 support was removed in Percona XtraBackup 2.1. The last version to support MySQL 5.0 was Percona XtraBackup 2.0.";3205 die "MySQL 5.0 support was removed in Percona XtraBackup 2.1. The last version to support MySQL 5.0 was Percona XtraBackup 2.0.\n";
3203 }3206 }
32043207
3205 if($var_version =~ m/5\.1\.\d/ && !defined($var_innodb_version)) {3208 if($var_version =~ m/5\.1\.\d/ && !defined($var_innodb_version)) {
3206 Die "Support for MySQL 5.1 with builtin InnoDB (not the plugin) was removed in Percona XtraBackup 2.1. The last version to support MySQL 5.1 with builtin InnoDB was Percona XtraBackup 2.0.";3209 die "Support for MySQL 5.1 with builtin InnoDB (not the plugin) was removed in Percona XtraBackup 2.1. The last version to support MySQL 5.1 with builtin InnoDB was Percona XtraBackup 2.0.\n";
3207 }3210 }
32083211
3209 if($var_version =~ m/5\.1\.\d/) {3212 if($var_version =~ m/5\.1\.\d/) {
@@ -3227,7 +3230,7 @@
3227 }3230 }
32283231
3229 if (!$ibbackup_binary) {3232 if (!$ibbackup_binary) {
3230 Die "Unsupported server version: '$var_version' " .3233 die "Unsupported server version: '$var_version' " .
3231 "(InnoDB version: '$var_innodb_version'). " .3234 "(InnoDB version: '$var_innodb_version'). " .
3232 "Please report a bug at ".3235 "Please report a bug at ".
3233 "https://bugs.launchpad.net/percona-xtrabackup\n";3236 "https://bugs.launchpad.net/percona-xtrabackup\n";
@@ -3295,7 +3298,7 @@
3295 mysql_query($con, 'START SLAVE SQL_THREAD');3298 mysql_query($con, 'START SLAVE SQL_THREAD');
3296 }3299 }
32973300
3298 Die "Slave_open_temp_tables did not become zero after waiting $option_safe_slave_backup_timeout seconds";3301 die "Slave_open_temp_tables did not become zero after $option_safe_slave_backup_timeout seconds";
3299}3302}
33003303
3301sub get_slave_open_temp_tables {3304sub get_slave_open_temp_tables {
@@ -3304,10 +3307,10 @@
3304 get_mysql_status($con);3307 get_mysql_status($con);
33053308
3306 if (!defined($con->{status}->{Slave_open_temp_tables})) {3309 if (!defined($con->{status}->{Slave_open_temp_tables})) {
3307 Die "Failed to get Slave_open_temp_tables from SHOW STATUS"3310 die "Failed to get Slave_open_temp_tables from SHOW STATUS"
3308 }3311 }
3309 if (!defined($con->{status}->{Slave_open_temp_tables}->{Value})) {3312 if (!defined($con->{status}->{Slave_open_temp_tables}->{Value})) {
3310 Die "SHOW STATUS LIKE 'slave_open_temp_tables' did not return anything"3313 die "SHOW STATUS LIKE 'slave_open_temp_tables' did not return anything"
3311 }3314 }
33123315
3313 return $con->{status}->{Slave_open_temp_tables}->{Value};3316 return $con->{status}->{Slave_open_temp_tables}->{Value};
@@ -3352,7 +3355,7 @@
3352 }3355 }
3353 # Only treat as fatal cases where the file exists3356 # Only treat as fatal cases where the file exists
3354 if ( -e "$src_path/$src_file" ) {3357 if ( -e "$src_path/$src_file" ) {
3355 Die "Failed to stream '$src_path/$src_file': $ret";3358 die "Failed to stream '$src_path/$src_file': $ret";
3356 } else {3359 } else {
3357 print STDERR "$prefix Ignoring nonexistent file '$src_path/$src_file'.\n";3360 print STDERR "$prefix Ignoring nonexistent file '$src_path/$src_file'.\n";
3358 }3361 }
@@ -3377,12 +3380,12 @@
3377 $dst_file_esc = $dst_file_esc . ".xbcrypt";3380 $dst_file_esc = $dst_file_esc . ".xbcrypt";
3378 $ret = system("$encrypt_cmd -i \"$src_file_esc\" -o \"$dst_file_esc\"");3381 $ret = system("$encrypt_cmd -i \"$src_file_esc\" -o \"$dst_file_esc\"");
3379 if ($ret != 0) {3382 if ($ret != 0) {
3380 Die "Failed to copy and encrypt file '$src_file': $ret";3383 die "Failed to copy and encrypt file '$src_file': $ret";
3381 }3384 }
3382 } elsif ( -e "$src_file_esc" ) {3385 } elsif ( -e "$src_file_esc" ) {
3383 $ret = system("$CP_CMD \"$src_file_esc\" \"$dst_file_esc\"");3386 $ret = system("$CP_CMD \"$src_file_esc\" \"$dst_file_esc\"");
3384 if ($ret != 0) {3387 if ($ret != 0) {
3385 Die "Failed to copy file '$src_file': $ret";3388 die "Failed to copy file '$src_file': $ret";
3386 }3389 }
3387 }3390 }
3388}3391}
33893392
=== modified file 'src/xtrabackup.cc'
--- src/xtrabackup.cc 2013-08-12 11:42:38 +0000
+++ src/xtrabackup.cc 2013-08-15 09:38:11 +0000
@@ -59,6 +59,10 @@
5959
60#include <fcntl.h>60#include <fcntl.h>
6161
62#ifdef __linux__
63# include <sys/prctl.h>
64#endif
65
62#define G_PTR uchar*66#define G_PTR uchar*
6367
64#include "common.h"68#include "common.h"
@@ -5595,6 +5599,15 @@
5595{5599{
5596 int ho_error;5600 int ho_error;
55975601
5602#ifdef __linux__
5603 /* Ensure xtrabackup process is killed when the parent one
5604 (innobackupex) is terminated with an unhandled signal */
5605
5606 if (prctl(PR_SET_PDEATHSIG, SIGINT)) {
5607 msg("prctl() failed with errno = %d\n", errno);
5608 exit(EXIT_FAILURE);
5609 }
5610#endif
5598 MY_INIT(argv[0]);5611 MY_INIT(argv[0]);
5599 xb_regex_init();5612 xb_regex_init();
56005613

Subscribers

People subscribed via source and target branches

to all changes: