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

Proposed by Alexey Kopytov
Status: Merged
Approved by: Alexey Kopytov
Approved revision: no longer in the source branch.
Merged at revision: 701
Proposed branch: lp:~akopytov/percona-xtrabackup/bug1164945-2.1
Merge into: lp:percona-xtrabackup/2.1
Diff against target: 273 lines (+176/-15)
4 files modified
innobackupex.pl (+65/-15)
test/t/bug1049291.sh (+23/-0)
test/t/bug1164945.sh (+47/-0)
test/t/bug382742.sh (+41/-0)
To merge this branch: bzr merge lp:~akopytov/percona-xtrabackup/bug1164945-2.1
Reviewer Review Type Date Requested Status
Alexey Kopytov (community) Approve
Review via email: mp+195922@code.launchpad.net

Description of the change

    Bug #1164945: move-back/copy-back should allow non-empty directories in
                  some cases

    The patches introduces a new innobackupex option,
    --force-non-empty-directories. When specified, it makes --copy-back or
    --move-back transfer files to non-empty directories. Note that no
    existing files will be overwritten. If --copy-back or --nove-back has to
    copy a file from the backup directory which already exists in the
    destination directory, it will still fail with an error.

http://jenkins.percona.com/view/XtraBackup/job/percona-xtrabackup-2.1-param/500/

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'innobackupex.pl'
--- innobackupex.pl 2013-11-15 11:01:25 +0000
+++ innobackupex.pl 2013-11-20 09:11:18 +0000
@@ -144,6 +144,8 @@
144144
145my $option_version_check = '1';145my $option_version_check = '1';
146146
147my $option_force_non_empty_dirs = '';
148
147my %mysql;149my %mysql;
148my $option_backup = '';150my $option_backup = '';
149151
@@ -2090,6 +2092,18 @@
2090}2092}
20912093
2092#2094#
2095# Check if a given directory exists, or fail with an error otherwise
2096#
2097
2098sub if_directory_exists {
2099 my $empty_dir = shift;
2100 my $is_directory_empty_comment = shift;
2101 if (! -d $empty_dir) {
2102 die "$is_directory_empty_comment directory '$empty_dir' does not exist!";
2103 }
2104}
2105
2106#
2093# if_directory_exists_and_empty accepts two arguments:2107# if_directory_exists_and_empty accepts two arguments:
2094# variable with directory name and comment.2108# variable with directory name and comment.
2095# Sub checks that directory exists and is empty2109# Sub checks that directory exists and is empty
@@ -2099,14 +2113,30 @@
2099sub if_directory_exists_and_empty {2113sub if_directory_exists_and_empty {
2100 my $empty_dir = shift;2114 my $empty_dir = shift;
2101 my $is_directory_empty_comment = shift;2115 my $is_directory_empty_comment = shift;
2102 if (! -d $empty_dir) {2116
2103 die "$is_directory_empty_comment directory '$empty_dir' does not exist!";2117 if_directory_exists($empty_dir, $is_directory_empty_comment);
2104 }2118
2105 opendir (my $dh, $empty_dir) or die "$is_directory_empty_comment directory '$empty_dir': Not a directory";2119 if (!$option_force_non_empty_dirs) {
2106 if ( ! scalar( grep { $_ ne "." && $_ ne ".." && $_ ne "my.cnf" && $_ ne "master.info"} readdir($dh)) == 0) {2120 opendir (my $dh, $empty_dir) or
2107 die "$is_directory_empty_comment directory '$empty_dir' is not empty!";2121 die "$is_directory_empty_comment directory '$empty_dir': Not a directory";
2108 }2122 if ( ! scalar( grep { $_ ne "." && $_ ne ".." && $_ ne "my.cnf" &&
2109 closedir($dh);2123 $_ ne "master.info"} readdir($dh)) == 0) {
2124 die "$is_directory_empty_comment directory '$empty_dir' is not empty!";
2125 }
2126 closedir($dh);
2127 }
2128}
2129
2130#
2131# Fail with an error if file exists
2132#
2133
2134sub die_if_exists {
2135 my $path = shift;
2136
2137 if (-e $path) {
2138 die "Cannot overwrite file: $path";
2139 }
2110}2140}
21112141
2112#2142#
@@ -2358,10 +2388,12 @@
23582388
2359 # check that original data directories exist and they are empty2389 # check that original data directories exist and they are empty
2360 if_directory_exists_and_empty($orig_datadir, "Original data");2390 if_directory_exists_and_empty($orig_datadir, "Original data");
2361 if_directory_exists_and_empty($orig_ibdata_dir, "Original InnoDB data");2391 if ($orig_ibdata_dir) {
2362 if_directory_exists_and_empty($orig_iblog_dir, "Original InnoDB log");2392 if_directory_exists($orig_ibdata_dir, "Original InnoDB data");
2393 }
2394 if_directory_exists($orig_iblog_dir, "Original InnoDB log");
2363 if ($orig_undo_dir) {2395 if ($orig_undo_dir) {
2364 if_directory_exists_and_empty($orig_undo_dir,2396 if_directory_exists($orig_undo_dir,
2365 "Original undo directory");2397 "Original undo directory");
2366 }2398 }
23672399
@@ -2421,7 +2453,17 @@
2421 foreach my $c (parse_innodb_data_file_path($orig_innodb_data_file_path)) {2453 foreach my $c (parse_innodb_data_file_path($orig_innodb_data_file_path)) {
2422 # get the relative pathname of a data file2454 # get the relative pathname of a data file
2423 $src_name = escape_path("$backup_dir/$c->{filename}");2455 $src_name = escape_path("$backup_dir/$c->{filename}");
2424 $dst_name = escape_path("$orig_ibdata_dir/$c->{path}");2456 if ($orig_ibdata_dir) {
2457 $dst_name = escape_path("$orig_ibdata_dir/$c->{path}");
2458 } else {
2459 # If innodb_data_home_dir is empty, but file path(s) in
2460 # innodb_data_file_path are relative, InnoDB treats them as if
2461 # innodb_data_home_dir was the same as datadir.
2462
2463 my $dst_root = ($c->{path} =~ /^\//) ? "" : $orig_datadir;
2464 $dst_name = escape_path("$dst_root/$c->{path}");
2465 }
2466 die_if_exists($dst_name);
2425 &$move_or_copy_file($src_name, $dst_name);2467 &$move_or_copy_file($src_name, $dst_name);
2426 }2468 }
24272469
@@ -2435,7 +2477,8 @@
2435 while (defined($file = readdir(DIR))) {2477 while (defined($file = readdir(DIR))) {
2436 if ($file =~ /^$ibundo_files$/ && -f "$backup_dir/$file") {2478 if ($file =~ /^$ibundo_files$/ && -f "$backup_dir/$file") {
2437 $src_name = escape_path("$backup_dir/$file");2479 $src_name = escape_path("$backup_dir/$file");
2438 $dst_name = escape_path("$orig_undo_dir");2480 $dst_name = escape_path("$orig_undo_dir/$file");
2481 die_if_exists($dst_name);
2439 &$move_or_copy_file($src_name, $dst_name);2482 &$move_or_copy_file($src_name, $dst_name);
2440 }2483 }
2441 }2484 }
@@ -2450,7 +2493,8 @@
2450 while (defined($file = readdir(DIR))) {2493 while (defined($file = readdir(DIR))) {
2451 if ($file =~ /^$iblog_files$/ && -f "$backup_dir/$file") {2494 if ($file =~ /^$iblog_files$/ && -f "$backup_dir/$file") {
2452 $src_name = escape_path("$backup_dir/$file");2495 $src_name = escape_path("$backup_dir/$file");
2453 $dst_name = escape_path("$orig_iblog_dir");2496 $dst_name = escape_path("$orig_iblog_dir/$file");
2497 die_if_exists($dst_name);
2454 &$move_or_copy_file($src_name, $dst_name);2498 &$move_or_copy_file($src_name, $dst_name);
2455 }2499 }
2456 }2500 }
@@ -3695,7 +3739,9 @@
3695 'lock-wait-threshold=i' => \$option_lock_wait_threshold,3739 'lock-wait-threshold=i' => \$option_lock_wait_threshold,
3696 'lock-wait-query-type=s' =>3740 'lock-wait-query-type=s' =>
3697 \$option_lock_wait_query_type,3741 \$option_lock_wait_query_type,
3698 'version-check!' => \$option_version_check3742 'version-check!' => \$option_version_check,
3743 'force-non-empty-directories' =>
3744 \$option_force_non_empty_dirs
3699 );3745 );
37003746
3701 if (@ARGV == 0) {3747 if (@ARGV == 0) {
@@ -4950,6 +4996,10 @@
49504996
4951This 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.4997This 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.
49524998
4999==item --force-non-empty-directories
5000
5001This option, when specified, makes --copy-back or --move-back transfer files to non-empty directories. Note that no existing files will be overwritten. If --copy-back or --nove-back has to copy a file from the backup directory which already exists in the destination directory, it will still fail with an error.
5002
4953=item --galera-info5003=item --galera-info
49545004
4955This options creates the xtrabackup_galera_info file which contains the local node state at the time of the backup. Option should be used when performing the backup of Percona-XtraDB-Cluster.5005This options creates the xtrabackup_galera_info file which contains the local node state at the time of the backup. Option should be used when performing the backup of Percona-XtraDB-Cluster.
49565006
=== added file 'test/t/bug1049291.sh'
--- test/t/bug1049291.sh 1970-01-01 00:00:00 +0000
+++ test/t/bug1049291.sh 2013-11-20 09:11:18 +0000
@@ -0,0 +1,23 @@
1########################################################################
2# Bug #1049291: innobackupex --copy-back fails with an empty
3# innodb-data-home-dir
4########################################################################
5
6MYSQLD_EXTRA_MY_CNF_OPTS="
7innodb_data_home_dir=
8"
9start_server
10
11innobackupex --no-timestamp $topdir/backup
12
13stop_server
14
15rm -rf $MYSQLD_DATADIR/*
16
17innobackupex --apply-log $topdir/backup
18
19innobackupex --copy-back $topdir/backup
20
21test -f $MYSQLD_DATADIR/ibdata1
22
23rm -rf $MYSQLD_DATADIR
024
=== added file 'test/t/bug1164945.sh'
--- test/t/bug1164945.sh 1970-01-01 00:00:00 +0000
+++ test/t/bug1164945.sh 2013-11-20 09:11:18 +0000
@@ -0,0 +1,47 @@
1##############################################################################
2# Bug #1164945: move-back/copy-back should allow non-empty directories in some
3# cases
4##############################################################################
5
6start_server
7
8innobackupex --no-timestamp $topdir/backup
9
10stop_server
11
12innobackupex --apply-log $topdir/backup
13
14cp -a $topdir/backup $topdir/backup_copy
15
16function test_force_non_empty_dirs()
17{
18 rm -rf $MYSQLD_DATADIR/*
19
20 mkdir $MYSQLD_DATADIR/empty_subdir
21
22 touch $MYSQLD_DATADIR/non_existing_file
23
24 # check that --*-back fails without --force-non-empty-directories
25 run_cmd_expect_failure $IB_BIN $IB_ARGS $1 $topdir/backup
26
27 rm -rf $topdir/backup
28 cp -a $topdir/backup_copy $topdir/backup
29
30 # check that --*-back works with --force-non-empty-directories
31 innobackupex $1 --force-non-empty-directories $topdir/backup
32
33 rm -rf $topdir/backup
34 cp -a $topdir/backup_copy $topdir/backup
35
36 # check that --*-back --force-non-empty-directories does not overwrite files
37 touch $MYSQLD_DATADIR/ibdata1
38 run_cmd_expect_failure $IB_BIN $IB_ARGS $1 --force-non-empty-directories \
39 $topdir/backup
40
41 rm -rf $topdir/backup
42 cp -a $topdir/backup_copy $topdir/backup
43}
44
45test_force_non_empty_dirs --copy-back
46
47test_force_non_empty_dirs --move-back
048
=== added file 'test/t/bug382742.sh'
--- test/t/bug382742.sh 1970-01-01 00:00:00 +0000
+++ test/t/bug382742.sh 2013-11-20 09:11:18 +0000
@@ -0,0 +1,41 @@
1########################################################################
2# Bug #382742: Absolute paths in innodb_data_file_path are not supported
3########################################################################
4
5# Use this as an absolute path prefix in innodb_data_file_path
6innodb_data_home_dir=$TEST_VAR_ROOT/innodb_data_home_dir
7
8mkdir $innodb_data_home_dir
9
10MYSQLD_EXTRA_MY_CNF_OPTS="
11innodb_file_per_table=0
12innodb_data_home_dir=/
13innodb_data_file_path=$innodb_data_home_dir/ibdata1:3M;$innodb_data_home_dir/ibdata2:10M:autoextend
14"
15
16start_server
17
18test -f $innodb_data_home_dir/ibdata1
19test -f $innodb_data_home_dir/ibdata2
20
21$MYSQL $MYSQL_ARGS -e "CREATE TABLE test.t(a INT)"
22
23record_db_state test
24
25innobackupex --no-timestamp $topdir/backup
26
27stop_server
28
29rm -rf $MYSQLD_DATADIR/*
30rm -rf $innodb_data_home_dir/*
31
32innobackupex --apply-log $topdir/backup
33
34innobackupex --copy-back $topdir/backup
35
36test -f $innodb_data_home_dir/ibdata1
37test -f $innodb_data_home_dir/ibdata2
38
39start_server
40
41verify_db_state test

Subscribers

People subscribed via source and target branches

to all changes: