Merge lp:~akopytov/percona-xtrabackup/bug1049291-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: 700
Proposed branch: lp:~akopytov/percona-xtrabackup/bug1049291-2.1
Merge into: lp:percona-xtrabackup/2.1
Diff against target: 183 lines (+111/-9)
3 files modified
innobackupex.pl (+47/-9)
test/t/bug1049291.sh (+23/-0)
test/t/bug382742.sh (+41/-0)
To merge this branch: bzr merge lp:~akopytov/percona-xtrabackup/bug1049291-2.1
Reviewer Review Type Date Requested Status
Alexey Kopytov (community) Approve
Review via email: mp+195754@code.launchpad.net

Description of the change

  Bug #1049291: innobackupex --copy-back fails with an empty
                innodb-data-home-dir

  The problem was that innobackupex unconditionally required
  innodb-data-home-dir to exist and be empty. There are, however, cases
  when the value of that variable does not represent a valid path (it may
  be empty), or point to root directory ("/") which naturally cannot be
  empty.

  Solutions:

  - do not perform any checks for an empty innodb-data-home-dir

  - assume an empty innodb-data-home-dir to be identical to MySQL’s
  datadir to replicate InnoDB behavior

  - do not require innodb-data-home-dir to be empty, but instead refuse to
  existing files in that directory. The non-empty requirement for the
  data directory makes sense, it was implemented to fix bug
  #737569. Requiring other directories to be empty is redundant, it is
  sufficient to just refuse to overwrite any files.

  The above changes, together with some previous bugfixes, automatically
  fix bug #382742. So this patch adds a test case for that bug.

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

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
1=== modified file 'innobackupex.pl'
2--- innobackupex.pl 2013-11-15 11:01:25 +0000
3+++ innobackupex.pl 2013-11-19 11:58:36 +0000
4@@ -2090,6 +2090,18 @@
5 }
6
7 #
8+# Check if a given directory exists, or fail with an error otherwise
9+#
10+
11+sub if_directory_exists {
12+ my $empty_dir = shift;
13+ my $is_directory_empty_comment = shift;
14+ if (! -d $empty_dir) {
15+ die "$is_directory_empty_comment directory '$empty_dir' does not exist!";
16+ }
17+}
18+
19+#
20 # if_directory_exists_and_empty accepts two arguments:
21 # variable with directory name and comment.
22 # Sub checks that directory exists and is empty
23@@ -2099,9 +2111,9 @@
24 sub if_directory_exists_and_empty {
25 my $empty_dir = shift;
26 my $is_directory_empty_comment = shift;
27- if (! -d $empty_dir) {
28- die "$is_directory_empty_comment directory '$empty_dir' does not exist!";
29- }
30+
31+ if_directory_exists($empty_dir, $is_directory_empty_comment);
32+
33 opendir (my $dh, $empty_dir) or die "$is_directory_empty_comment directory '$empty_dir': Not a directory";
34 if ( ! scalar( grep { $_ ne "." && $_ ne ".." && $_ ne "my.cnf" && $_ ne "master.info"} readdir($dh)) == 0) {
35 die "$is_directory_empty_comment directory '$empty_dir' is not empty!";
36@@ -2110,6 +2122,18 @@
37 }
38
39 #
40+# Fail with an error if file exists
41+#
42+
43+sub die_if_exists {
44+ my $path = shift;
45+
46+ if (-e $path) {
47+ die "Cannot overwrite file: $path";
48+ }
49+}
50+
51+#
52 # copy() wrapper with error handling
53 #
54 sub copy_file {
55@@ -2358,10 +2382,12 @@
56
57 # check that original data directories exist and they are empty
58 if_directory_exists_and_empty($orig_datadir, "Original data");
59- if_directory_exists_and_empty($orig_ibdata_dir, "Original InnoDB data");
60- if_directory_exists_and_empty($orig_iblog_dir, "Original InnoDB log");
61+ if ($orig_ibdata_dir) {
62+ if_directory_exists($orig_ibdata_dir, "Original InnoDB data");
63+ }
64+ if_directory_exists($orig_iblog_dir, "Original InnoDB log");
65 if ($orig_undo_dir) {
66- if_directory_exists_and_empty($orig_undo_dir,
67+ if_directory_exists($orig_undo_dir,
68 "Original undo directory");
69 }
70
71@@ -2421,7 +2447,17 @@
72 foreach my $c (parse_innodb_data_file_path($orig_innodb_data_file_path)) {
73 # get the relative pathname of a data file
74 $src_name = escape_path("$backup_dir/$c->{filename}");
75- $dst_name = escape_path("$orig_ibdata_dir/$c->{path}");
76+ if ($orig_ibdata_dir) {
77+ $dst_name = escape_path("$orig_ibdata_dir/$c->{path}");
78+ } else {
79+ # If innodb_data_home_dir is empty, but file path(s) in
80+ # innodb_data_file_path are relative, InnoDB treats them as if
81+ # innodb_data_home_dir was the same as datadir.
82+
83+ my $dst_root = ($c->{path} =~ /^\//) ? "" : $orig_datadir;
84+ $dst_name = escape_path("$dst_root/$c->{path}");
85+ }
86+ die_if_exists($dst_name);
87 &$move_or_copy_file($src_name, $dst_name);
88 }
89
90@@ -2435,7 +2471,8 @@
91 while (defined($file = readdir(DIR))) {
92 if ($file =~ /^$ibundo_files$/ && -f "$backup_dir/$file") {
93 $src_name = escape_path("$backup_dir/$file");
94- $dst_name = escape_path("$orig_undo_dir");
95+ $dst_name = escape_path("$orig_undo_dir/$file");
96+ die_if_exists($dst_name);
97 &$move_or_copy_file($src_name, $dst_name);
98 }
99 }
100@@ -2450,7 +2487,8 @@
101 while (defined($file = readdir(DIR))) {
102 if ($file =~ /^$iblog_files$/ && -f "$backup_dir/$file") {
103 $src_name = escape_path("$backup_dir/$file");
104- $dst_name = escape_path("$orig_iblog_dir");
105+ $dst_name = escape_path("$orig_iblog_dir/$file");
106+ die_if_exists($dst_name);
107 &$move_or_copy_file($src_name, $dst_name);
108 }
109 }
110
111=== added file 'test/t/bug1049291.sh'
112--- test/t/bug1049291.sh 1970-01-01 00:00:00 +0000
113+++ test/t/bug1049291.sh 2013-11-19 11:58:36 +0000
114@@ -0,0 +1,23 @@
115+########################################################################
116+# Bug #1049291: innobackupex --copy-back fails with an empty
117+# innodb-data-home-dir
118+########################################################################
119+
120+MYSQLD_EXTRA_MY_CNF_OPTS="
121+innodb_data_home_dir=
122+"
123+start_server
124+
125+innobackupex --no-timestamp $topdir/backup
126+
127+stop_server
128+
129+rm -rf $MYSQLD_DATADIR/*
130+
131+innobackupex --apply-log $topdir/backup
132+
133+innobackupex --copy-back $topdir/backup
134+
135+test -f $MYSQLD_DATADIR/ibdata1
136+
137+rm -rf $MYSQLD_DATADIR
138
139=== added file 'test/t/bug382742.sh'
140--- test/t/bug382742.sh 1970-01-01 00:00:00 +0000
141+++ test/t/bug382742.sh 2013-11-19 11:58:36 +0000
142@@ -0,0 +1,41 @@
143+########################################################################
144+# Bug #382742: Absolute paths in innodb_data_file_path are not supported
145+########################################################################
146+
147+# Use this as an absolute path prefix in innodb_data_file_path
148+innodb_data_home_dir=$TEST_VAR_ROOT/innodb_data_home_dir
149+
150+mkdir $innodb_data_home_dir
151+
152+MYSQLD_EXTRA_MY_CNF_OPTS="
153+innodb_file_per_table=0
154+innodb_data_home_dir=/
155+innodb_data_file_path=$innodb_data_home_dir/ibdata1:3M;$innodb_data_home_dir/ibdata2:10M:autoextend
156+"
157+
158+start_server
159+
160+test -f $innodb_data_home_dir/ibdata1
161+test -f $innodb_data_home_dir/ibdata2
162+
163+$MYSQL $MYSQL_ARGS -e "CREATE TABLE test.t(a INT)"
164+
165+record_db_state test
166+
167+innobackupex --no-timestamp $topdir/backup
168+
169+stop_server
170+
171+rm -rf $MYSQLD_DATADIR/*
172+rm -rf $innodb_data_home_dir/*
173+
174+innobackupex --apply-log $topdir/backup
175+
176+innobackupex --copy-back $topdir/backup
177+
178+test -f $innodb_data_home_dir/ibdata1
179+test -f $innodb_data_home_dir/ibdata2
180+
181+start_server
182+
183+verify_db_state test

Subscribers

People subscribed via source and target branches

to all changes: