Merge lp:~sergei.glushchenko/percona-xtrabackup/bug711166_part-1.6 into lp:percona-xtrabackup/1.6

Proposed by Sergei Glushchenko
Status: Rejected
Rejected by: Alexey Kopytov
Proposed branch: lp:~sergei.glushchenko/percona-xtrabackup/bug711166_part-1.6
Merge into: lp:percona-xtrabackup/1.6
Diff against target: 756 lines (+482/-154)
9 files modified
innobackupex (+27/-11)
test/inc/ib_part.sh (+76/-0)
test/t/ib_part_databases.sh (+42/-0)
test/t/ib_part_include.sh (+51/-0)
test/t/ib_part_include_stream.sh (+42/-0)
test/t/ib_part_tf_innodb.sh (+49/-0)
test/t/ib_part_tf_innodb_stream.sh (+43/-0)
test/t/ib_part_tf_myisam.sh (+42/-0)
xtrabackup.c (+110/-143)
To merge this branch: bzr merge lp:~sergei.glushchenko/percona-xtrabackup/bug711166_part-1.6
Reviewer Review Type Date Requested Status
Alexey Kopytov (community) Needs Fixing
Review via email: mp+91013@code.launchpad.net

Description of the change

Bug 711166
Implement full support for backups of partitioned tables.

Fixed support for partitioned tables (both innobackupex and xtrabackup.c)
when --tables-file option specified. This also fixes support for
partitioned tables when --databases option specified. Two testcases
added. First one for MyISAM partitioned table with --tables-file option
and DATA DIRECTORY/INDEX DIRECTORY specified, second one for InnoDB
partitioned table with --tables-file option.

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

Sergei,

Partial backups can also be created with the --include option of innobackupex (or its xtrabackup equivalent, --tables). That does not seem to be covered by the fix.

I've amended the bug report so we take that into account in the fix.

Some minor comments:

- innobackupex should be used in tests rather than IB_BIN directly

- please use --copy-back to restored when innobackupex is used to create a backup, so we also test that functionality

- you can use the checksum_table() function from common.sh

- xtrabackup.c (mostly) follows the InnoDB coding style. so the closin */ in comments should be on the last comment line, rather than on a separate one.

- typo ("Cheking")

- typo ("parttition")

review: Needs Fixing
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :

Alexei,

> Sergei,
>
> Partial backups can also be created with the --include option of innobackupex
> (or its xtrabackup equivalent, --tables). That does not seem to be covered by
> the fix.
>

--include option passed directly to --tables option of xtrabackup.
Each database.table value passed to --tables option considered as regular
expression. So if we pass --tables=test.test, all partitions of database test
would be backed up because of test.test matches all files test/test#P#*
I think it's a good behavior.

Thanks for your comments! I'll do my best to fix tescases.

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

Sergei,

On 01.02.12 21:20, Sergei Glushchenko wrote:
> Alexei,
>
>> Sergei,
>>
>> Partial backups can also be created with the --include option of innobackupex
>> (or its xtrabackup equivalent, --tables). That does not seem to be covered by
>> the fix.
>>
>
> --include option passed directly to --tables option of xtrabackup.

Not always. It is handled in innobackupex for streaming backups.

> Each database.table value passed to --tables option considered as regular
> expression. So if we pass --tables=test.test, all partitions of database test
> would be backed up because of test.test matches all files test/test#P#*
> I think it's a good behavior.
>

Consider a case when I have tables 'test' and 'test_table'. So to be
able to backup only 'test', but not 'test_table', I have to use
--tables='test$'. But that won't work if 'test' is partitioned, right?

Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :

Bug 711166
Partitioned tables are not correctly handled by the --databases, --include,
--tables-file options of innobackupex, and by the --tables and
--tables-file options of xtrabackup.
Solution is to remove partition suffix (#P#...) before doing filtering.
Testcases cover variants of using filtering options with MyISAM and
InnoDB tables (to test both innobackupex and xtrabackup) with either stream
mode turned on and turned off.

Since last MP request:
 added --include option handling
 added more testcases

Jenkins build:
lp:~sergei.glushchenko/percona-xtrabackup/bug711166_part-1.6

Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :
Revision history for this message
Alexey Kopytov (akopytov) wrote :

Sergei,

   - I think you can avoid some code duplication in test cases by
     putting the table definition to a common file in the inc/ directory
     and using the default_storage_engine server variable.
   - you can also reduce the test sizes considerably by not messing with
     information_schema and performance_schema. I_S is actually not a
     storage engine, so it doesn't have any files in the data dir. And
     you could just drop the test database before shutting down the
     server and restoring, rather than just remove the entire data dir,
     so you don't have to care about performance_schema and mysql DBs. I
     think that would make test cases much smaller and easier to read,
     but without any impact on test coverage.
   - you can also make tests faster by not inserting 500 rows into the
     table. Inserting that many rows one-by-one by invoking the client
     each time actually take significant time. I think the following
     would be sufficient for your purposes:
       INSERT INTO test VALUES (1), (101), (201), (301), (401);
   - Unlike the core server, InnoDB code encloses "if" blocks in braces
     even if the block consists of only 1 statement.
   - I think changes in xtrabackup.c have to much duplication and
     unnecessary work. The whole point of those transformations is to
     check whether a specific table should be skipped. Please take a
     look at my changes to that code here
     http://bazaar.launchpad.net/~akopytov/percona-xtrabackup/compact-backups/view/head:/src/xtrabackup.c#L1550
     Perhaps it even makes sense to backport check_if_skip_table() from
     compact backups branch to 1.6/trunk and base your fix on that
     function?

review: Needs Fixing
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :

Alexey,

> - I think you can avoid some code duplication in test cases by
> putting the table definition to a common file in the inc/ directory
> and using the default_storage_engine server variable.

yes. You're right about that.

> - you can also reduce the test sizes considerably by not messing with
> information_schema and performance_schema. I_S is actually not a
> storage engine, so it doesn't have any files in the data dir. And
> you could just drop the test database before shutting down the
> server and restoring, rather than just remove the entire data dir,
> so you don't have to care about performance_schema and mysql DBs. I
> think that would make test cases much smaller and easier to read,
> but without any impact on test coverage.

We can't just drop database `test` and keep other databases in their places.
copy-back function expects that data directory is empty when we are
restoring backup.

> - you can also make tests faster by not inserting 500 rows into the
> table. Inserting that many rows one-by-one by invoking the client
> each time actually take significant time. I think the following
> would be sufficient for your purposes:
> INSERT INTO test VALUES (1), (101), (201), (301), (401);

OK. I'll follow your advice.

> - Unlike the core server, InnoDB code encloses "if" blocks in braces
> even if the block consists of only 1 statement.

Thanks. I should print InnoDB code guidelines somewhere and put it somewhere over my eyes.

> - I think changes in xtrabackup.c have to much duplication and
> unnecessary work. The whole point of those transformations is to
> check whether a specific table should be skipped. Please take a
> look at my changes to that code here
> http://bazaar.launchpad.net/~akopytov/percona-xtrabackup/compact-
> backups/view/head:/src/xtrabackup.c#L1550
> Perhaps it even makes sense to backport check_if_skip_table() from
> compact backups branch to 1.6/trunk and base your fix on that
> function?

As I can see check_if_skip_table does pretty much the same thing, but does
in-place patching instead of copying. I tried to avoid in-place patching,
because of it is not good from my point of view to modify data which is
not belongs to us. You should look at xtrabackup_stats_func in your
branch. It contains pretty much the same code as check_if_skip_table.

I'm surely can write something similar to check_if_skip_table, but avoiding
in-place patching. What do you think about that?

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

Sergei,

On 17.02.12 14:05, Sergei Glushchenko wrote:
>> - you can also reduce the test sizes considerably by not messing with
>> information_schema and performance_schema. I_S is actually not a
>> storage engine, so it doesn't have any files in the data dir. And
>> you could just drop the test database before shutting down the
>> server and restoring, rather than just remove the entire data dir,
>> so you don't have to care about performance_schema and mysql DBs. I
>> think that would make test cases much smaller and easier to read,
>> but without any impact on test coverage.
>
> We can't just drop database `test` and keep other databases in their places.
> copy-back function expects that data directory is empty when we are
> restoring backup.
>

Right, which means --copy-back is useless for partial backups. It either
creates an unusable datadir, if it was empty originally, or just fails,
if it wasn't empty.

Which in turn means users are expected to restore manually from a
partial backups. And so we should do the same in the test suite?

>
>> - Unlike the core server, InnoDB code encloses "if" blocks in braces
>> even if the block consists of only 1 statement.
>
> Thanks. I should print InnoDB code guidelines somewhere and put it somewhere over my eyes.
>

The problem is that there's no such thing as InnoDB code guidelines. If
you find them, let me know! :)

>> - I think changes in xtrabackup.c have to much duplication and
>> unnecessary work. The whole point of those transformations is to
>> check whether a specific table should be skipped. Please take a
>> look at my changes to that code here
>> http://bazaar.launchpad.net/~akopytov/percona-xtrabackup/compact-
>> backups/view/head:/src/xtrabackup.c#L1550
>> Perhaps it even makes sense to backport check_if_skip_table() from
>> compact backups branch to 1.6/trunk and base your fix on that
>> function?
>
> As I can see check_if_skip_table does pretty much the same thing, but does
> in-place patching instead of copying. I tried to avoid in-place patching,
> because of it is not good from my point of view to modify data which is
> not belongs to us. You should look at xtrabackup_stats_func in your
> branch. It contains pretty much the same code as check_if_skip_table.
>
> I'm surely can write something similar to check_if_skip_table, but avoiding
> in-place patching. What do you think about that?
>

Sure, my point was that encapsulating the entire logic to decide whether
a table should be skipped or not is better than implementing some
auxiliary functions and passing the buffers around.

In-place modifications are certainly not nice, I just didn't have time
to fix that too, as I was after something completely different, so I
left that work for better times. Such as now :)

But thanks for pointing out the same code is in xtrabackup_stats_func().
I didn't notice it, because the main object of refactoring was
xtrabackup_copy_datafile().

OTOH I think malloc()s can be avoided and replaced with a
stack-allocated bufer.

Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :

Tescases were reduced and improved a little. It allowed to find mistake in testcase and implementation. (tar command in stream mode didn't relsolve symbolic likns). check_if_skip_table was implemented instead of auxiliary functions.

Jenkins:
http://jenkins.percona.com/view/Percona%20Xtrabackup/job/percona-xtrabackup-1.6-param/119/

Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote :
Revision history for this message
Alexey Kopytov (akopytov) wrote :

Sergei,

As discussed previously, we will not be fixing this bug in 1.6. Please create a 2.0 MP.

Unmerged revisions

348. By Sergei Glushchenko

Partitioned tables are not correctly handled by the --databases, --include,
--tables-file options of innobackupex, and by the --tables and
--tables-file options of xtrabackup.
Solution is to remove partition suffix (#P#...) before doing filtering.
Testcases cover variants of using filtering options with MyISAM and
InnoDB tables (to test both innobackupex and xtrabackup) with either stream
mode turned on and turned off.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'innobackupex'
--- innobackupex 2012-06-08 18:46:19 +0000
+++ innobackupex 2012-09-18 13:09:33 +0000
@@ -975,11 +975,9 @@
975 if($option_include) {975 if($option_include) {
976 my $table_name;976 my $table_name;
977977
978 $table_name = substr($file, rindex($file, '/'));978 $table_name = get_table_name($file);
979 $table_name = substr($table_name, 1, rindex($table_name, '.') - 1);
980 $table_name = $subdir . "." . $table_name;
981979
982 if (!($table_name =~ /$option_include/)) {980 if (!("$subdir.$table_name" =~ /$option_include/)) {
983 print STDERR "'$file' is skipped.\n";981 print STDERR "'$file' is skipped.\n";
984 next;982 next;
985 }983 }
@@ -1984,7 +1982,8 @@
1984 next unless check_if_required($database, $file);1982 next unless check_if_required($database, $file);
19851983
1986 if($option_include) {1984 if($option_include) {
1987 if (!("$database.$file" =~ /$option_include/)) {1985 my $table_name = get_table_name($file);
1986 if (!("$database.$table_name" =~ /$option_include/)) {
1988 print STDERR "$database.$file is skipped because it does not match $option_include.\n";1987 print STDERR "$database.$file is skipped because it does not match $option_include.\n";
1989 next;1988 next;
1990 }1989 }
@@ -2013,7 +2012,7 @@
2013 my $ret = 0;2012 my $ret = 0;
2014 my $file_name = substr($file, rindex($file, '/') + 1);2013 my $file_name = substr($file, rindex($file, '/') + 1);
2015 $file_name=~s/([\$\\\" ])/\\$1/g;2014 $file_name=~s/([\$\\\" ])/\\$1/g;
2016 $ret = system("cd $source_dir; tar cf - $database/$file_name") >> 8;2015 $ret = system("cd $source_dir; tar chf - $database/$file_name") >> 8;
2017 if ($ret == 1) {2016 if ($ret == 1) {
2018 print STDERR "$prefix If you use GNU tar, this warning can be ignored.\n";2017 print STDERR "$prefix If you use GNU tar, this warning can be ignored.\n";
2019 # Check for non-zero exit code2018 # Check for non-zero exit code
@@ -2303,6 +2302,27 @@
2303 return ${$group_hash_ref}{$option_name};2302 return ${$group_hash_ref}{$option_name};
2304}2303}
23052304
2305# get_table_name subroutine returns table name of specified file.
2306# Parameters:
2307# $_[0] table path
2308# Return value:
2309# 1 table name
2310#
2311sub get_table_name {
2312 my $table_path = shift;
2313 my $filename;
2314 my $table;
2315
2316 # get the last component in the table pathname
2317 $filename = (reverse(split(/\//, $table_path)))[0];
2318 # get name of the table by removing file suffix
2319 $table = (split(/\./, $filename))[0];
2320 # and partition suffix
2321 $table = (split('#P#', $table))[0];
2322
2323 return $table;
2324}
2325
2306# check_if_required subroutine returns 1 if the specified database and2326# check_if_required subroutine returns 1 if the specified database and
2307# table needs to be backed up.2327# table needs to be backed up.
2308# Parameters:2328# Parameters:
@@ -2315,7 +2335,6 @@
2315 my ( $db, $table_path ) = @_;2335 my ( $db, $table_path ) = @_;
2316 my $db_count = scalar keys %databases_list;2336 my $db_count = scalar keys %databases_list;
2317 my $tbl_count = scalar keys %table_list;2337 my $tbl_count = scalar keys %table_list;
2318 my $filename;
2319 my $table;2338 my $table;
23202339
2321 if ( $db_count == 0 && $tbl_count == 0 ) {2340 if ( $db_count == 0 && $tbl_count == 0 ) {
@@ -2325,10 +2344,7 @@
2325 }2344 }
2326 else {2345 else {
2327 if ( $table_path ) {2346 if ( $table_path ) {
2328 # get the last component in the table pathname 2347 $table = get_table_name($table_path);
2329 $filename = (reverse(split(/\//, $table_path)))[0];
2330 # get name of the table by removing file suffix
2331 $table = (split(/\./, $filename))[0];
2332 }2348 }
2333 }2349 }
23342350
23352351
=== added file 'test/inc/ib_part.sh'
--- test/inc/ib_part.sh 1970-01-01 00:00:00 +0000
+++ test/inc/ib_part.sh 2012-09-18 13:09:33 +0000
@@ -0,0 +1,76 @@
1
2function ib_part_schema()
3{
4 topdir=$1
5 engine=$2
6
7 cat <<EOF
8CREATE TABLE test (
9 a int(11) DEFAULT NULL
10) ENGINE=$engine DEFAULT CHARSET=latin1
11PARTITION BY RANGE (a)
12(PARTITION p0 VALUES LESS THAN (100) ENGINE = $engine,
13 PARTITION P1 VALUES LESS THAN (200) ENGINE = $engine,
14 PARTITION p2 VALUES LESS THAN (300)
15 DATA DIRECTORY = '$topdir/ext' INDEX DIRECTORY = '$topdir/ext'
16 ENGINE = $engine,
17 PARTITION p3 VALUES LESS THAN (400)
18 DATA DIRECTORY = '$topdir/ext' INDEX DIRECTORY = '$topdir/ext'
19 ENGINE = $engine,
20 PARTITION p4 VALUES LESS THAN MAXVALUE ENGINE = $engine);
21EOF
22}
23
24function ib_part_data()
25{
26 echo 'INSERT INTO test VALUES (1), (101), (201), (301), (401);';
27}
28
29function ib_part_init()
30{
31 topdir=$1
32 engine=$2
33
34 if [ -d $topdir/ext ] ; then
35 rm -rf $topdir/ext
36 fi
37 mkdir -p $topdir/ext
38
39 ib_part_schema $topdir $engine | run_cmd $MYSQL $MYSQL_ARGS test
40 ib_part_data $topdir $engine | run_cmd $MYSQL $MYSQL_ARGS test
41}
42
43function ib_part_restore()
44{
45 topdir=$1
46 mysql_datadir=$2
47
48 # Remove database
49 rm -rf $mysql_datadir/test/*
50 rm -rf $topdir/ext/*
51 vlog "Original database removed"
52
53 # Restore database from backup
54 cp -rv $topdir/backup/test/* $mysql_datadir/test
55 vlog "database restored from backup"
56
57}
58
59function ib_part_assert_checksum()
60{
61 checksum_a=$1
62
63 vlog "Checking checksums"
64 checksum_b=`checksum_table test test`
65
66 vlog "Checksums are $checksum_a and $checksum_b"
67
68 if [ "$checksum_a" != "$checksum_b" ]
69 then
70 vlog "Checksums are not equal"
71 exit -1
72 fi
73
74 vlog "Checksums are OK"
75
76}
077
=== added file 'test/t/ib_part_databases.sh'
--- test/t/ib_part_databases.sh 1970-01-01 00:00:00 +0000
+++ test/t/ib_part_databases.sh 2012-09-18 13:09:33 +0000
@@ -0,0 +1,42 @@
1########################################################################
2# Bug #711166: Partitioned tables are not correctly handled by the
3# --databases and --tables-file options of innobackupex,
4# and by the --tables option of xtrabackup.
5# Testcase covers using --databases option with MyISAM
6# database
7########################################################################
8
9. inc/common.sh
10. inc/ib_part.sh
11
12start_server
13
14if ! ${MYSQL} ${MYSQL_ARGS} -e "SHOW VARIABLES LIKE '%partition%';" | grep YES ; then
15 echo "Requires partition support" > $SKIPPED_REASON
16 exit $SKIPPED_EXIT_CODE
17fi
18
19# Create MyISAM partitioned table with some partitions in
20# different location
21ib_part_init $topdir MyISAM
22
23# Saving the checksum of original table
24checksum_a=`checksum_table test test`
25
26# Take a backup
27cat >$topdir/databases_file <<EOF
28test.test
29EOF
30innobackupex --no-timestamp --databases=$topdir/databases_file $topdir/backup
31innobackupex --apply-log $topdir/backup
32vlog "Backup taken"
33
34stop_server
35
36# Restore partial backup
37ib_part_restore $topdir $mysql_datadir
38
39start_server
40
41# compare checksum
42ib_part_assert_checksum $checksum_a
043
=== added file 'test/t/ib_part_include.sh'
--- test/t/ib_part_include.sh 1970-01-01 00:00:00 +0000
+++ test/t/ib_part_include.sh 2012-09-18 13:09:33 +0000
@@ -0,0 +1,51 @@
1########################################################################
2# Bug #711166: Partitioned tables are not correctly handled by the
3# --databases and --tables-file options of innobackupex,
4# and by the --tables option of xtrabackup.
5# Testcase covers using --include option with InnoDB
6# database
7########################################################################
8
9. inc/common.sh
10. inc/ib_part.sh
11
12start_server --innodb_file_per_table
13
14if ! ${MYSQL} ${MYSQL_ARGS} -e "SHOW VARIABLES LIKE '%partition%';" | grep YES ; then
15 echo "Requires partition support" > $SKIPPED_REASON
16 exit $SKIPPED_EXIT_CODE
17fi
18
19# Create InnoDB partitioned table
20ib_part_init $topdir InnoDB
21
22# Saving the checksum of original table
23checksum_a=`checksum_table test test`
24
25# Take a backup
26# Only backup of test.test table will be taken
27cat >$topdir/tables <<EOF
28test.test
29EOF
30innobackupex --no-timestamp --include='test.test$' $topdir/backup
31innobackupex --apply-log $topdir/backup
32vlog "Backup taken"
33
34# also test xtrabackup --stats work with --tables-file
35COUNT=`xtrabackup --stats --tables='test.test$' --datadir=$topdir/backup 2>&1 \
36 | grep table: | awk '{print $2}' | sort -u | wc -l`
37
38if [ $COUNT != 5 ] ; then
39 xtrabackup --stats --tables='test.test$' --datadir=$topdir/backup
40 vlog "xtrabackup --stats does not work. count = $COUNT"
41 exit -1
42fi
43
44stop_server
45
46# Restore partial backup
47ib_part_restore $topdir $mysql_datadir
48
49start_server
50
51ib_part_assert_checksum $checksum_a
052
=== added file 'test/t/ib_part_include_stream.sh'
--- test/t/ib_part_include_stream.sh 1970-01-01 00:00:00 +0000
+++ test/t/ib_part_include_stream.sh 2012-09-18 13:09:33 +0000
@@ -0,0 +1,42 @@
1########################################################################
2# Bug #711166: Partitioned tables are not correctly handled by the
3# --databases and --tables-file options of innobackupex,
4# and by the --tables option of xtrabackup.
5# Testcase covers using --include option with InnoDB
6# database and --stream mode
7########################################################################
8
9. inc/common.sh
10. inc/ib_part.sh
11
12start_server --innodb_file_per_table
13
14if ! ${MYSQL} ${MYSQL_ARGS} -e "SHOW VARIABLES LIKE '%partition%';" | grep YES ; then
15 echo "Requires partition support" > $SKIPPED_REASON
16 exit $SKIPPED_EXIT_CODE
17fi
18
19# Create MyISAM partitioned table
20ib_part_init $topdir MyISAM
21
22# Saving the checksum of original table
23checksum_a=`checksum_table test test`
24
25# Take a backup
26mkdir -p $topdir/backup
27innobackupex --stream=tar --include='test.test$' $topdir/backup > $topdir/backup/backup.tar
28$TAR ixvf $topdir/backup/backup.tar -C $topdir/backup
29$TAR cvhf $topdir/backup/backup11.tar $mysql_datadir/test/*
30
31innobackupex --apply-log $topdir/backup
32
33vlog "Backup taken"
34
35stop_server
36
37# Restore partial backup
38ib_part_restore $topdir $mysql_datadir
39
40start_server
41
42ib_part_assert_checksum $checksum_a
043
=== added file 'test/t/ib_part_tf_innodb.sh'
--- test/t/ib_part_tf_innodb.sh 1970-01-01 00:00:00 +0000
+++ test/t/ib_part_tf_innodb.sh 2012-09-18 13:09:33 +0000
@@ -0,0 +1,49 @@
1########################################################################
2# Bug #711166: Partitioned tables are not correctly handled by the
3# --databases and --tables-file options of innobackupex,
4# and by the --tables option of xtrabackup.
5# Testcase covers using --tables-file option with InnoDB
6# database
7########################################################################
8
9. inc/common.sh
10. inc/ib_part.sh
11
12start_server --innodb_file_per_table
13
14if ! ${MYSQL} ${MYSQL_ARGS} -e "SHOW VARIABLES LIKE '%partition%';" | grep YES ; then
15 echo "Requires partition support" > $SKIPPED_REASON
16 exit $SKIPPED_EXIT_CODE
17fi
18
19# Create InnoDB partitioned table
20ib_part_init $topdir InnoDB
21
22# Saving the checksum of original table
23checksum_a=`checksum_table test test`
24
25# Take a backup
26# Only backup of test.test table will be taken
27cat >$topdir/tables <<EOF
28test.test
29EOF
30innobackupex --no-timestamp --tables-file=$topdir/tables $topdir/backup
31innobackupex --apply-log $topdir/backup
32vlog "Backup taken"
33
34COUNT=`xtrabackup --stats --tables-file=$topdir/tables --datadir=$topdir/backup 2>&1 \
35 | grep table: | awk '{print $2}' | sort -u | wc -l`
36
37if [ $COUNT != 5 ] ; then
38 vlog "xtrabackup --stats does not work"
39 exit -1
40fi
41
42stop_server
43
44# Restore partial backup
45ib_part_restore $topdir $mysql_datadir
46
47start_server
48
49ib_part_assert_checksum $checksum_a
050
=== added file 'test/t/ib_part_tf_innodb_stream.sh'
--- test/t/ib_part_tf_innodb_stream.sh 1970-01-01 00:00:00 +0000
+++ test/t/ib_part_tf_innodb_stream.sh 2012-09-18 13:09:33 +0000
@@ -0,0 +1,43 @@
1########################################################################
2# Bug #711166: Partitioned tables are not correctly handled by the
3# --databases and --tables-file options of innobackupex,
4# and by the --tables option of xtrabackup.
5# Testcase covers using --tables-file option with InnoDB
6# database and --stream mode
7########################################################################
8
9. inc/common.sh
10. inc/ib_part.sh
11
12start_server --innodb_file_per_table
13
14if ! ${MYSQL} ${MYSQL_ARGS} -e "SHOW VARIABLES LIKE '%partition%';" | grep YES ; then
15 echo "Requires partition support" > $SKIPPED_REASON
16 exit $SKIPPED_EXIT_CODE
17fi
18
19# Create InnoDB partitioned table
20ib_part_init $topdir InnoDB
21
22# Saving the checksum of original table
23checksum_a=`checksum_table test test`
24
25# Take a backup
26# Only backup of test.test table will be taken
27cat >$topdir/tables <<EOF
28test.test
29EOF
30mkdir -p $topdir/backup
31innobackupex --stream=tar --no-timestamp --tables-file=$topdir/tables $topdir/backup > $topdir/backup/backup.tar
32$TAR ixvf $topdir/backup/backup.tar -C $topdir/backup
33innobackupex --apply-log $topdir/backup
34vlog "Backup taken"
35
36stop_server
37
38# Restore partial backup
39ib_part_restore $topdir $mysql_datadir
40
41start_server
42
43ib_part_assert_checksum $checksum_a
044
=== added file 'test/t/ib_part_tf_myisam.sh'
--- test/t/ib_part_tf_myisam.sh 1970-01-01 00:00:00 +0000
+++ test/t/ib_part_tf_myisam.sh 2012-09-18 13:09:33 +0000
@@ -0,0 +1,42 @@
1########################################################################
2# Bug #711166: Partitioned tables are not correctly handled by the
3# --databases and --tables-file options of innobackupex,
4# and by the --tables option of xtrabackup.
5# Testcase covers using --tables-file option with MyISAM
6# database
7########################################################################
8
9. inc/common.sh
10. inc/ib_part.sh
11
12start_server
13
14if ! ${MYSQL} ${MYSQL_ARGS} -e "SHOW VARIABLES LIKE '%partition%';" | grep YES ; then
15 echo "Requires partition support" > $SKIPPED_REASON
16 exit $SKIPPED_EXIT_CODE
17fi
18
19# Create MyISAM partitioned table with some partitions in
20# different location
21ib_part_init $topdir MyISAM
22
23# Saving the checksum of original table
24checksum_a=`checksum_table test test`
25
26# Take a backup
27# Only backup of test.test table will be taken
28cat >$topdir/tables <<EOF
29test.test
30EOF
31innobackupex --no-timestamp --tables-file=$topdir/tables $topdir/backup
32innobackupex --apply-log $topdir/backup
33vlog "Backup taken"
34
35stop_server
36
37# Restore partial backup
38ib_part_restore $topdir $mysql_datadir
39
40start_server
41
42ib_part_assert_checksum $checksum_a
043
=== modified file 'xtrabackup.c'
--- xtrabackup.c 2012-05-28 16:37:00 +0000
+++ xtrabackup.c 2012-09-18 13:09:33 +0000
@@ -576,6 +576,15 @@
576576
577#endif /* INNODB_VERSION_SHORT */577#endif /* INNODB_VERSION_SHORT */
578578
579#ifdef INNODB_VERSION_SHORT
580#define XB_HASH_SEARCH(NAME, TABLE, FOLD, DATA, ASSERTION, TEST) \
581 HASH_SEARCH(NAME, TABLE, FOLD, xtrabackup_tables_t*, DATA, ASSERTION, \
582 TEST)
583#else
584#define XB_HASH_SEARCH(NAME, TABLE, FOLD, DATA, ASSERTION, TEST) \
585 HASH_SEARCH(NAME, TABLE, FOLD, DATA, TEST)
586#endif
587
579typedef struct {588typedef struct {
580 ulint page_size;589 ulint page_size;
581} xb_delta_info_t;590} xb_delta_info_t;
@@ -2518,6 +2527,73 @@
2518 return(r);2527 return(r);
2519}2528}
25202529
2530static my_bool
2531check_if_skip_table(const char *path, const char *suffix)
2532{
2533 char buf[FN_REFLEN];
2534 const char *dbname, *tbname;
2535 const char *ptr;
2536 char *eptr;
2537 int dbname_len;
2538
2539 if (xtrabackup_tables == NULL && xtrabackup_tables_file == NULL) {
2540 return(FALSE);
2541 }
2542
2543 dbname= NULL;
2544 tbname= path;
2545 while ((ptr= strstr(tbname, SRV_PATH_SEPARATOR_STR)) != NULL) {
2546 dbname= tbname;
2547 tbname= ptr + 1;
2548 }
2549
2550 if (dbname == NULL) {
2551 return(TRUE);
2552 }
2553
2554 strncpy(buf, dbname, FN_REFLEN);
2555 buf[FN_REFLEN - 1]= 0;
2556 buf[tbname - 1 - dbname]= '.';
2557
2558 dbname_len= strlen(dbname) - strlen(suffix);
2559 if (dbname_len < 1) {
2560 return(TRUE);
2561 }
2562 buf[dbname_len - 1]= 0;
2563
2564 if ((eptr= strstr(buf, "#P")) != NULL) {
2565 *eptr= 0;
2566 }
2567
2568 if (xtrabackup_tables) {
2569 int regres = REG_NOMATCH;
2570 int i;
2571 for (i = 0; i < tables_regex_num; i++) {
2572 regres = regexec(&tables_regex[i], buf, 1,
2573 tables_regmatch, 0);
2574 if (regres != REG_NOMATCH) {
2575 break;
2576 }
2577 }
2578 if (regres == REG_NOMATCH) {
2579 return(TRUE);
2580 }
2581 }
2582
2583 if (xtrabackup_tables_file) {
2584 xtrabackup_tables_t* table;
2585
2586 XB_HASH_SEARCH(name_hash, tables_hash, ut_fold_string(buf),
2587 table, ut_ad(table->name),
2588 !strcmp(table->name, buf));
2589 if (!table) {
2590 return(TRUE);
2591 }
2592 }
2593
2594 return(FALSE);
2595}
2596
2521/***********************************************************************2597/***********************************************************************
2522Read meta info for an incremental delta.2598Read meta info for an incremental delta.
2523@return TRUE on success, FALSE on failure. */2599@return TRUE on success, FALSE on failure. */
@@ -2639,102 +2715,38 @@
2639 info.page_size = 0;2715 info.page_size = 0;
26402716
2641#ifdef XTRADB_BASED2717#ifdef XTRADB_BASED
2642 if (xtrabackup_tables && (!trx_sys_sys_space(node->space->id)))2718 if (xtrabackup_tables && (!trx_sys_sys_space(node->space->id))
2643#else2719#else
2644 if (xtrabackup_tables && (node->space->id != 0))2720 if (xtrabackup_tables && (node->space->id != 0)
2645#endif2721#endif
2646 { /* must backup id==0 */2722 && check_if_skip_table(node->name, "ibd")) {
2647 char *p;2723 printf("[%02u] Copying %s is skipped.\n",
2648 int p_len, regres= 0;2724 thread_n, node->name);
2649 char *next, *prev;2725 return(FALSE);
2650 char tmp;2726 }
2651 int i;2727
26522728#ifndef INNODB_VERSION_SHORT
2653 p = node->name;2729 page_size = UNIV_PAGE_SIZE;
2654 prev = NULL;2730 page_size_shift = UNIV_PAGE_SIZE_SHIFT;
2655 while ((next = strstr(p, SRV_PATH_SEPARATOR_STR)) != NULL)2731#else
2656 {2732 zip_size = fil_space_get_zip_size(node->space->id);
2657 prev = p;2733 if (zip_size == ULINT_UNDEFINED) {
2658 p = next + 1;2734 goto skip;
2659 }2735 } else if (zip_size) {
2660 p_len = strlen(p) - strlen(".ibd");2736 page_size = zip_size;
26612737 page_size_shift = get_bit_shift(page_size);
2662 if (p_len < 1) {2738 fprintf(stderr, "[%02u] %s is compressed with page size = "
2663 /* unknown situation: skip filtering */2739 "%lu bytes\n", thread_n, node->name, page_size);
2664 goto skip_filter;2740 if (page_size_shift < 10 || page_size_shift > 14) {
2665 }2741 fprintf(stderr, "[%02u] xtrabackup: Error: Invalid "
26662742 "page size.\n", thread_n);
2667 /* TODO: Fix this lazy implementation... */2743 ut_error;
2668 tmp = p[p_len];2744 }
2669 p[p_len] = 0;2745 } else {
2670 *(p - 1) = '.';2746 page_size = UNIV_PAGE_SIZE;
26712747 page_size_shift = UNIV_PAGE_SIZE_SHIFT;
2672 for (i = 0; i < tables_regex_num; i++) {2748 }
2673 regres = regexec(&tables_regex[i], prev, 1, tables_regmatch, 0);2749#endif
2674 if (regres != REG_NOMATCH)
2675 break;
2676 }
2677
2678 p[p_len] = tmp;
2679 *(p - 1) = SRV_PATH_SEPARATOR;
2680
2681 if ( regres == REG_NOMATCH ) {
2682 printf("[%02u] Copying %s is skipped.\n",
2683 thread_n, node->name);
2684 return(FALSE);
2685 }
2686 }
2687
2688#ifdef XTRADB_BASED
2689 if (xtrabackup_tables_file && (!trx_sys_sys_space(node->space->id)))
2690#else
2691 if (xtrabackup_tables_file && (node->space->id != 0))
2692#endif
2693 { /* must backup id==0 */
2694 xtrabackup_tables_t* table;
2695 char *p;
2696 int p_len;
2697 char *next, *prev;
2698 char tmp;
2699
2700 p = node->name;
2701 prev = NULL;
2702 while ((next = strstr(p, SRV_PATH_SEPARATOR_STR)) != NULL)
2703 {
2704 prev = p;
2705 p = next + 1;
2706 }
2707 p_len = strlen(p) - strlen(".ibd");
2708
2709 if (p_len < 1) {
2710 /* unknown situation: skip filtering */
2711 goto skip_filter;
2712 }
2713
2714 /* TODO: Fix this lazy implementation... */
2715 tmp = p[p_len];
2716 p[p_len] = 0;
2717
2718 HASH_SEARCH(name_hash, tables_hash, ut_fold_string(prev),
2719#ifdef INNODB_VERSION_SHORT
2720 xtrabackup_tables_t*,
2721#endif
2722 table,
2723#ifdef INNODB_VERSION_SHORT
2724 ut_ad(table->name),
2725#endif
2726 !strcmp(table->name, prev));
2727
2728 p[p_len] = tmp;
2729
2730 if (!table) {
2731 printf("[%02u] Copying %s is skipped.\n",
2732 thread_n, node->name);
2733 return(FALSE);
2734 }
2735 }
2736
2737skip_filter:
27382750
2739#ifdef XTRADB_BASED2751#ifdef XTRADB_BASED
2740 if (trx_sys_sys_space(node->space->id))2752 if (trx_sys_sys_space(node->space->id))
@@ -4610,47 +4622,8 @@
4610 table = dict_table_get_low(table_name);4622 table = dict_table_get_low(table_name);
4611 mem_free(table_name);4623 mem_free(table_name);
46124624
46134625 if (table && check_if_skip_table(table->name, ""))
4614 if (xtrabackup_tables) {4626 goto skip;
4615 char *p;
4616 int regres= 0;
4617 int i;
4618
4619 p = strstr(table->name, SRV_PATH_SEPARATOR_STR);
4620
4621 if (p)
4622 *p = '.';
4623
4624 for (i = 0; i < tables_regex_num; i++) {
4625 regres = regexec(&tables_regex[i], table->name, 1, tables_regmatch, 0);
4626 if (regres != REG_NOMATCH)
4627 break;
4628 }
4629
4630 if (p)
4631 *p = SRV_PATH_SEPARATOR;
4632
4633 if ( regres == REG_NOMATCH )
4634 goto skip;
4635 }
4636
4637 if (xtrabackup_tables_file) {
4638 xtrabackup_tables_t* xtable;
4639
4640 HASH_SEARCH(name_hash, tables_hash, ut_fold_string(table->name),
4641#ifdef INNODB_VERSION_SHORT
4642 xtrabackup_tables_t*,
4643#endif
4644 xtable,
4645#ifdef INNODB_VERSION_SHORT
4646 ut_ad(xtable->name),
4647#endif
4648 !strcmp(xtable->name, table->name));
4649
4650 if (!xtable)
4651 goto skip;
4652 }
4653
46544627
4655 if (table == NULL) {4628 if (table == NULL) {
4656 fputs("InnoDB: Failed to load table ", stderr);4629 fputs("InnoDB: Failed to load table ", stderr);
@@ -6174,12 +6147,6 @@
6174 break;6147 break;
6175 }6148 }
61766149
6177 while (*p != '\0') {
6178 if (*p == '.') {
6179 *p = '/';
6180 }
6181 p++;
6182 }
6183 p = strchr(name_buf, '\n');6150 p = strchr(name_buf, '\n');
6184 if (p)6151 if (p)
6185 {6152 {

Subscribers

People subscribed via source and target branches