Merge lp:~sergei.glushchenko/percona-xtrabackup/BT-26901-2.0 into lp:percona-xtrabackup/2.0

Proposed by Sergei Glushchenko
Status: Merged
Approved by: Alexey Kopytov
Approved revision: no longer in the source branch.
Merged at revision: 480
Proposed branch: lp:~sergei.glushchenko/percona-xtrabackup/BT-26901-2.0
Merge into: lp:percona-xtrabackup/2.0
Diff against target: 283 lines (+148/-26)
3 files modified
innobackupex (+14/-1)
src/xtrabackup.c (+14/-25)
test/t/ib_doublewrite.sh (+120/-0)
To merge this branch: bzr merge lp:~sergei.glushchenko/percona-xtrabackup/BT-26901-2.0
Reviewer Review Type Date Requested Status
Alexey Kopytov (community) Approve
Laurynas Biveinis Pending
Review via email: mp+134512@code.launchpad.net

This proposal supersedes a proposal from 2012-11-12.

Description of the change

Bug #1066843: Fix for bug #932623 does not take separate doublewrite
tablespace into account

Fixed by checking trx_sys_sys_space instead of space_id == 0.
innodb_doublewrite_file been added to backup-my.cnf.
Copy back now skip doublewrite tablespace.

lp:~sergei.glushchenko/percona-xtrabackup/BT-26901-2.0

To post a comment you must log in.
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote : Posted in a previous version of this proposal

#26901

Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote : Posted in a previous version of this proposal

What is the purpose of chunk at 23-40?

That chunk and the innobackupex change seem to fix some other bug, not a regression from 932623. Can you link that bug, or if there is none, report it?

Please introduce a wrapper around #ifdef ... == 0 #else ... trx_sys_sys_space ... #endif.

Why does the testcase skip in case of !XtraDB? I think this test applies to all InnoDB flavors.

Is it necessary to grep innobackupex output for full_backup_dir? IIRC other testcases dont't do this. Likewise for inc_backup_dir.

I am not sure if the testcase should be all the way to table checksum checking with restored data, or the steps up to the crashing point are necessary. In this particular instance I'd err on the side of more testing.

review: Needs Fixing
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote : Posted in a previous version of this proposal

> What is the purpose of chunk at 23-40?
>
> That chunk and the innobackupex change seem to fix some other bug, not a
> regression from 932623. Can you link that bug, or if there is none, report it?
>

OK. I'll report separate bug for that. Or maybe it's possible to change description of existing one?

> Please introduce a wrapper around #ifdef ... == 0 #else ... trx_sys_sys_space
> ... #endif.
>

This can be done.

> Why does the testcase skip in case of !XtraDB? I think this test applies to
> all InnoDB flavors.
>

It's because of usage of innodb_doublewrite_file.

> Is it necessary to grep innobackupex output for full_backup_dir? IIRC other
> testcases dont't do this. Likewise for inc_backup_dir.
>

Yep. Could be changed to use --no-timestamps

> I am not sure if the testcase should be all the way to table checksum checking
> with restored data, or the steps up to the crashing point are necessary. In
> this particular instance I'd err on the side of more testing.

Basically I had failures at last server startup. This is what 23-40 and innobackupex changes are needed.

Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote : Posted in a previous version of this proposal

Explanation of changes in innobackupex is following.

During backup xtrabackup copies doublewrite buffer file from the path specified in my.cnf to the root backup directory. Then during prepare double file is not specified in backup-my.cnf, and not used. When copy back is done old doublewrite buffer file copied to root data directory, which could cause failures on server startup.

Following are incorrect and being fixed:
1. Path to doublewrite buffer file is not specified in backup-my.cnf
2. Prepare should use doublewrite buffer file from root of backup dir
3. Copy back should not copy doublewrite buffer file as it is not needed after prepare is done.

Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote : Posted in a previous version of this proposal

In the case of run with our test framework we have even worst behavior. Instead of looking at backup-my.cnf prepare look at original my.cnf (--defaults-file is specified) and modify original doublewrite buffer file.

Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote : Posted in a previous version of this proposal

Bug failed and linked, testcase changed to use --no-timestamp, wrapper for trx_sys_sys_space introduced.

http://jenkins.percona.com/view/XtraBackup/job/percona-xtrabackup-2.0-param/283/

Revision history for this message
Laurynas Biveinis (laurynas-biveinis) : Posted in a previous version of this proposal
review: Approve
Revision history for this message
Alexey Kopytov (akopytov) wrote : Posted in a previous version of this proposal

Sergei,

A few of comments:

- what if innodb_doublewrite_file is not specified in my.cnf? As I understand, --print-param will either crash or print "innodb_doublewrite_file = (null)" (on Linux), and then innobackupex will assume we have a doublewrite full with "(null)" as its name.

- why don't we write stripped innodb_doublewrite_file (i.e. with path removed) to backup-my.cnf? Less code in innobackupex to strip it on --copy-back

- why don't we make 2.0 and 2.1 consistent and just modify trx_sys_sys_space(id) to include the #ifdef and avoid having a separate macro? Less code changes in 2.0, less conflicts when merging 2.0->2.1 in the future.

- please use one of MYSQLD_VARDIR/MYSQLD_DATADIR/MYSQLD_TMPDIR instead of hardcoded paths as in "${TEST_BASEDIR}/var1..."

- s/.idb/.ibd/

review: Needs Fixing
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote : Posted in a previous version of this proposal

> Sergei,
>
> A few of comments:
>
> - what if innodb_doublewrite_file is not specified in my.cnf? As I understand,
> --print-param will either crash or print "innodb_doublewrite_file = (null)"
> (on Linux), and then innobackupex will assume we have a doublewrite full with
> "(null)" as its name.
>

Yes, i fixed it.

> - why don't we write stripped innodb_doublewrite_file (i.e. with path removed)
> to backup-my.cnf? Less code in innobackupex to strip it on --copy-back
>

The reason was to avoid hacking in testcase. Also we modified some values from my.cnf when put them to backup-my.cnf before. Currently we don't. But I agree that full original path is not needed in backup-my.cnf for xtrabackup to operate. So I rewrite to do path strip before writing to backup-my.cnf.

> - why don't we make 2.0 and 2.1 consistent and just modify
> trx_sys_sys_space(id) to include the #ifdef and avoid having a separate macro?
> Less code changes in 2.0, less conflicts when merging 2.0->2.1 in the future.
>

Yep. The reason was I did not see it before. Then see in 2.1 and fix and not yet synced 2.0 with it.

> - please use one of MYSQLD_VARDIR/MYSQLD_DATADIR/MYSQLD_TMPDIR instead of
> hardcoded paths as in "${TEST_BASEDIR}/var1..."
>

It isn't possible due to unavailability of MYSQLD_* before server startup.

> - s/.idb/.ibd/

OK.

Revision history for this message
Alexey Kopytov (akopytov) wrote : Posted in a previous version of this proposal

Sergei,

Thanks, everything looks good now, except that I think we can still avoid hard-coded path for the doublewrite file.

On server startup, the path can be relative to the data, i.e. --innodb-doublewrite-path=foo.ibd. If you need a full path to it later (I don't think you actually need, but still), you can refer to it as $MYSQL_DATADIR/foo.ibd.

review: Needs Fixing
Revision history for this message
Sergei Glushchenko (sergei.glushchenko) wrote : Posted in a previous version of this proposal

Testcase been modified. Path to dblwr.ibd is not specified now.

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'
--- innobackupex 2012-11-07 06:44:45 +0000
+++ innobackupex 2012-11-15 16:48:23 +0000
@@ -719,6 +719,13 @@
719 my $file;719 my $file;
720 my $backup_innodb_data_file_path;720 my $backup_innodb_data_file_path;
721721
722 if (has_option(\%config, $option_defaults_group, 'innodb_doublewrite_file')) {
723 my $doublewrite_file =
724 get_option(\%config, $option_defaults_group,
725 'innodb_doublewrite_file');
726 $excluded_files = $excluded_files . '|' . $doublewrite_file;
727 }
728
722 # check whether files should be copied or moved to dest directory729 # check whether files should be copied or moved to dest directory
723 my $move_or_copy_file = $move_flag ? \&move_file : \&copy_file;730 my $move_or_copy_file = $move_flag ? \&move_file : \&copy_file;
724 my $move_or_copy_dir = $move_flag ?731 my $move_or_copy_dir = $move_flag ?
@@ -1727,7 +1734,7 @@
1727 "innodb_log_file_size",1734 "innodb_log_file_size",
1728 "innodb_fast_checksum",1735 "innodb_fast_checksum",
1729 "innodb_page_size",1736 "innodb_page_size",
1730 "innodb_log_block_size",1737 "innodb_log_block_size"
1731 );1738 );
17321739
1733 my $options_dump = "# This MySQL options file was generated by $innobackup_script.\n\n" .1740 my $options_dump = "# This MySQL options file was generated by $innobackup_script.\n\n" .
@@ -1741,6 +1748,12 @@
1741 $options_dump .= "$option_name=$option_value\n";1748 $options_dump .= "$option_name=$option_value\n";
1742 }1749 }
1743 }1750 }
1751 if (has_option(\%config,
1752 $option_defaults_group, "innodb_doublewrite_file")) {
1753 $options_dump .= "innodb_doublewrite_file=" . (split(/\/+/,
1754 get_option(\%config, $option_defaults_group,
1755 'innodb_doublewrite_file')))[-1] . "\n";
1756 }
17441757
1745 print FILE $options_dump;1758 print FILE $options_dump;
1746 close(FILE);1759 close(FILE);
17471760
=== modified file 'src/xtrabackup.c'
--- src/xtrabackup.c 2012-11-08 23:42:03 +0000
+++ src/xtrabackup.c 2012-11-15 16:48:23 +0000
@@ -2970,6 +2970,10 @@
2970 HASH_SEARCH(NAME, TABLE, FOLD, DATA, TEST)2970 HASH_SEARCH(NAME, TABLE, FOLD, DATA, TEST)
2971#endif2971#endif
29722972
2973#ifndef XTRADB_BASED
2974#define trx_sys_sys_space(id) (id == 0)
2975#endif
2976
2973/****************************************************************//**2977/****************************************************************//**
2974A simple function to open or create a file.2978A simple function to open or create a file.
2975@return own: handle to the file, not defined if error, error number2979@return own: handle to the file, not defined if error, error number
@@ -3137,11 +3141,7 @@
3137 info.zip_size = 0;3141 info.zip_size = 0;
3138 info.space_id = 0;3142 info.space_id = 0;
31393143
3140#ifdef XTRADB_BASED
3141 if (xtrabackup_tables && (!trx_sys_sys_space(node->space->id)))3144 if (xtrabackup_tables && (!trx_sys_sys_space(node->space->id)))
3142#else
3143 if (xtrabackup_tables && (node->space->id != 0))
3144#endif
3145 { /* must backup id==0 */3145 { /* must backup id==0 */
3146 char *p;3146 char *p;
3147 int p_len, regres = REG_NOMATCH;3147 int p_len, regres = REG_NOMATCH;
@@ -3185,11 +3185,7 @@
3185 }3185 }
3186 }3186 }
31873187
3188#ifdef XTRADB_BASED
3189 if (xtrabackup_tables_file && (!trx_sys_sys_space(node->space->id)))3188 if (xtrabackup_tables_file && (!trx_sys_sys_space(node->space->id)))
3190#else
3191 if (xtrabackup_tables_file && (node->space->id != 0))
3192#endif
3193 { /* must backup id==0 */3189 { /* must backup id==0 */
3194 xtrabackup_tables_t* table;3190 xtrabackup_tables_t* table;
3195 char *p;3191 char *p;
@@ -3231,11 +3227,7 @@
32313227
3232skip_filter:3228skip_filter:
32333229
3234#ifdef XTRADB_BASED
3235 if (trx_sys_sys_space(node->space->id))3230 if (trx_sys_sys_space(node->space->id))
3236#else
3237 if (node->space->id == 0)
3238#endif
3239 {3231 {
3240 char *next, *p;3232 char *next, *p;
3241 /* system datafile "/fullpath/datafilename.ibd" or "./datafilename.ibd" */3233 /* system datafile "/fullpath/datafilename.ibd" or "./datafilename.ibd" */
@@ -3396,11 +3388,7 @@
3396#endif3388#endif
3397 {3389 {
3398 if (3390 if (
3399#ifdef XTRADB_BASED
3400 trx_sys_sys_space(node->space->id)3391 trx_sys_sys_space(node->space->id)
3401#else
3402 node->space->id == 0
3403#endif
3404 && ((offset + (IB_INT64)chunk_offset) >> page_size_shift)3392 && ((offset + (IB_INT64)chunk_offset) >> page_size_shift)
3405 >= FSP_EXTENT_SIZE3393 >= FSP_EXTENT_SIZE
3406 && ((offset + (IB_INT64)chunk_offset) >> page_size_shift)3394 && ((offset + (IB_INT64)chunk_offset) >> page_size_shift)
@@ -4060,11 +4048,7 @@
4060 } else {4048 } else {
4061 ptr2 = NULL;4049 ptr2 = NULL;
4062 }4050 }
4063#ifdef XTRADB_BASED
4064 if(!trx_sys_sys_space(space->id) && ptr2)4051 if(!trx_sys_sys_space(space->id) && ptr2)
4065#else
4066 if(space->id && ptr2)
4067#endif
4068 {4052 {
4069 /* single table space */4053 /* single table space */
4070 *ptr2 = 0; /* temporary (it's my lazy..)*/4054 *ptr2 = 0; /* temporary (it's my lazy..)*/
@@ -5794,7 +5778,9 @@
5794 os_file_t file = 0;5778 os_file_t file = 0;
5795 ulint tablespace_flags;5779 ulint tablespace_flags;
57965780
5797 ut_a(dbname != NULL || space_id == 0 || space_id == ULINT_UNDEFINED);5781 ut_a(dbname != NULL ||
5782 trx_sys_sys_space(space_id) ||
5783 space_id == ULINT_UNDEFINED);
57985784
5799 *success = FALSE;5785 *success = FALSE;
58005786
@@ -5823,6 +5809,10 @@
5823 return file;5809 return file;
5824 }5810 }
58255811
5812 if (trx_sys_sys_space(space_id)) {
5813 goto found;
5814 }
5815
5826 mutex_enter(&fil_system->mutex);5816 mutex_enter(&fil_system->mutex);
5827 fil_space = xb_space_get_by_name(dest_space_name);5817 fil_space = xb_space_get_by_name(dest_space_name);
5828 mutex_exit(&fil_system->mutex);5818 mutex_exit(&fil_system->mutex);
@@ -6552,11 +6542,7 @@
6552 while (space != NULL) {6542 while (space != NULL) {
6553 /* treat file_per_table only */6543 /* treat file_per_table only */
6554 if (space->purpose != FIL_TABLESPACE6544 if (space->purpose != FIL_TABLESPACE
6555#ifdef XTRADB_BASED
6556 || trx_sys_sys_space(space->id)6545 || trx_sys_sys_space(space->id)
6557#else
6558 || space->id == 0
6559#endif
6560 )6546 )
6561 {6547 {
6562 space = UT_LIST_GET_NEXT(space_list, space);6548 space = UT_LIST_GET_NEXT(space_list, space);
@@ -7089,6 +7075,9 @@
7089 printf("innodb_fast_checksum = %d\n", innobase_fast_checksum);7075 printf("innodb_fast_checksum = %d\n", innobase_fast_checksum);
7090 printf("innodb_page_size = %ld\n", innobase_page_size);7076 printf("innodb_page_size = %ld\n", innobase_page_size);
7091 printf("innodb_log_block_size = %lu\n", innobase_log_block_size);7077 printf("innodb_log_block_size = %lu\n", innobase_log_block_size);
7078 if (innobase_doublewrite_file != NULL) {
7079 printf("innodb_doublewrite_file = %s\n", innobase_doublewrite_file);
7080 }
7092#endif7081#endif
7093 exit(EXIT_SUCCESS);7082 exit(EXIT_SUCCESS);
7094 }7083 }
70957084
=== added file 'test/t/ib_doublewrite.sh'
--- test/t/ib_doublewrite.sh 1970-01-01 00:00:00 +0000
+++ test/t/ib_doublewrite.sh 2012-11-15 16:48:23 +0000
@@ -0,0 +1,120 @@
1########################################################################
2# Bug #1066843: Fix for bug #932623 does not take separate doublewrite
3# tablespace into account
4# Bug #1068470: XtraBackup handles separate doublewrite buffer file
5# incorrectly
6# We testing full and incremental backup and restore to check that
7# separate doublewrite buffer file handled correctly
8########################################################################
9
10. inc/common.sh
11
12if [ -z "$XTRADB_VERSION" ]; then
13 echo "Requires XtraDB" > $SKIPPED_REASON
14 exit $SKIPPED_EXIT_CODE
15fi
16
17DBLWR=dblwr.ibd
18start_server --innodb_file_per_table --innodb_doublewrite_file=${DBLWR}
19load_dbase_schema incremental_sample
20
21# Workaround for bug #1072695
22IB_ARGS_NO_DEFAULTS_FILE=`echo $IB_ARGS | sed -e 's/--defaults-file=[^ ]* / /'`
23function innobackupex_no_defaults_file ()
24{
25 run_cmd $IB_BIN $IB_ARGS_NO_DEFAULTS_FILE $*
26}
27
28echo "innodb_doublewrite_file=${DBLWR}" >>$topdir/my.cnf
29
30# Adding initial rows
31vlog "Adding initial rows to database..."
32${MYSQL} ${MYSQL_ARGS} -e "insert into test values (1, 1);" incremental_sample
33
34# Full backup
35# backup root directory
36mkdir -p $topdir/backup
37
38vlog "Starting backup"
39full_backup_dir=$topdir/backup/full
40innobackupex --no-timestamp $full_backup_dir
41vlog "Full backup done to directory $full_backup_dir"
42cat $full_backup_dir/backup-my.cnf
43
44# Changing data
45
46vlog "Making changes to database"
47${MYSQL} ${MYSQL_ARGS} -e "create table t2 (a int(11) default null, number int(11) default null) engine=innodb" incremental_sample
48${MYSQL} ${MYSQL_ARGS} -e "insert into test values (10, 1);" incremental_sample
49${MYSQL} ${MYSQL_ARGS} -e "insert into t2 values (10, 1);" incremental_sample
50vlog "Changes done"
51
52# Saving the checksum of original table
53checksum_test_a=`checksum_table incremental_sample test`
54checksum_t2_a=`checksum_table incremental_sample t2`
55vlog "Table 'test' checksum is $checksum_test_a"
56vlog "Table 't2' checksum is $checksum_t2_a"
57
58vlog "Making incremental backup"
59
60vlog "###############"
61vlog "# INCREMENTAL #"
62vlog "###############"
63
64# Incremental backup
65inc_backup_dir=$topdir/backup/inc
66innobackupex --no-timestamp --incremental --incremental-basedir=$full_backup_dir \
67 $inc_backup_dir
68vlog "Incremental backup done to directory $inc_backup_dir"
69
70vlog "Preparing backup"
71# Prepare backup
72vlog "##############"
73vlog "# PREPARE #1 #"
74vlog "##############"
75innobackupex_no_defaults_file --apply-log --redo-only $full_backup_dir
76vlog "Log applied to full backup"
77vlog "##############"
78vlog "# PREPARE #2 #"
79vlog "##############"
80innobackupex_no_defaults_file --apply-log --redo-only --incremental-dir=$inc_backup_dir \
81 $full_backup_dir
82vlog "Delta applied to full backup"
83vlog "##############"
84vlog "# PREPARE #3 #"
85vlog "##############"
86innobackupex_no_defaults_file --apply-log $full_backup_dir
87vlog "Data prepared for restore"
88
89# Destroying mysql data
90stop_server
91rm -rf $mysql_datadir/*
92vlog "Data destroyed"
93
94# Restore backup
95vlog "Copying files"
96vlog "###########"
97vlog "# RESTORE #"
98vlog "###########"
99innobackupex --copy-back $full_backup_dir
100vlog "Data restored"
101
102start_server --innodb_file_per_table --innodb_doublewrite_file=${DBLWR}
103
104vlog "Checking checksums"
105checksum_test_b=`checksum_table incremental_sample test`
106checksum_t2_b=`checksum_table incremental_sample t2`
107
108if [ "$checksum_test_a" != "$checksum_test_b" ]
109then
110 vlog "Checksums for table 'test' are not equal"
111 exit -1
112fi
113
114if [ "$checksum_t2_a" != "$checksum_t2_b" ]
115then
116 vlog "Checksums for table 't2' are not equal"
117 exit -1
118fi
119
120vlog "Checksums are OK"

Subscribers

People subscribed via source and target branches