diff options
author | Vlad Lesin <vlad_lesin@mail.ru> | 2020-08-20 16:49:40 +0300 |
---|---|---|
committer | Vlad Lesin <vlad_lesin@mail.ru> | 2020-08-20 16:49:40 +0300 |
commit | e322af20513711e57b9e09105a11fc6dd2f7078c (patch) | |
tree | 835332151556232ae32db89a67b519958e7c00b1 | |
parent | 607467bd63db2c6ca64610eb9f4e703711f4dfc6 (diff) | |
download | mariadb-git-bb-10.3-10.3.23-MDEV-22929.tar.gz |
MDEV-22929 MariaBackup option to report and/or continue when corruption is encounteredbb-10.3-10.3.23-MDEV-22929
Ignore innodb page corruption error and continue backup with error
message.
DO NOT MERGE IT until the fix is approved by Engineering team.
-rw-r--r-- | extra/mariabackup/fil_cur.cc | 9 | ||||
-rw-r--r-- | extra/mariabackup/xtrabackup.cc | 12 | ||||
-rw-r--r-- | extra/mariabackup/xtrabackup.h | 2 | ||||
-rw-r--r-- | mysql-test/suite/mariabackup/ignore_page_corruption.result | 10 | ||||
-rw-r--r-- | mysql-test/suite/mariabackup/ignore_page_corruption.test | 74 |
5 files changed, 104 insertions, 3 deletions
diff --git a/extra/mariabackup/fil_cur.cc b/extra/mariabackup/fil_cur.cc index 67d1fb173c0..9a46c17fa2a 100644 --- a/extra/mariabackup/fil_cur.cc +++ b/extra/mariabackup/fil_cur.cc @@ -454,12 +454,17 @@ read_retry: retry_count--; if (retry_count == 0) { + const char *ignore_corruption_warn = opt_ignore_innodb_page_corruption ? + " WARNING!!! The corruption is ignored due to" + " ignore-innodb-page-corruption option, the backup can contain" + " corrupted data." : ""; msg(cursor->thread_n, "Error: failed to read page after " "10 retries. File %s seems to be " - "corrupted.", cursor->abs_path); - ret = XB_FIL_CUR_ERROR; + "corrupted.%s", cursor->abs_path, ignore_corruption_warn); buf_page_print(page, cursor->page_size); + if (!opt_ignore_innodb_page_corruption) + ret = XB_FIL_CUR_ERROR; break; } msg(cursor->thread_n, "Database page corruption detected at page " diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 5246ffbda20..41427eb2576 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -300,6 +300,7 @@ my_bool opt_noversioncheck = FALSE; my_bool opt_no_backup_locks = FALSE; my_bool opt_decompress = FALSE; my_bool opt_remove_original; +my_bool opt_ignore_innodb_page_corruption; my_bool opt_lock_ddl_per_table = FALSE; static my_bool opt_check_privileges; @@ -833,7 +834,9 @@ enum options_xtrabackup OPT_LOCK_DDL_PER_TABLE, OPT_ROCKSDB_DATADIR, OPT_BACKUP_ROCKSDB, - OPT_XTRA_CHECK_PRIVILEGES + OPT_XTRA_CHECK_PRIVILEGES, + + OPT_XB_IGNORE_INNODB_PAGE_CORRUPTION }; struct my_option xb_client_options[]= { @@ -1230,6 +1233,13 @@ struct my_option xb_client_options[]= { " uses old (pre-4.1.1) protocol.", &opt_secure_auth, &opt_secure_auth, 0, GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0}, + + {"ignore-innodb-page-corruption", OPT_XB_IGNORE_INNODB_PAGE_CORRUPTION, + "Continue backup with error message if innodb page corrupted. " + "This option can cause data incosistency in restored backup.", + &opt_ignore_innodb_page_corruption, &opt_ignore_innodb_page_corruption, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + #define MYSQL_CLIENT #include "sslopt-longopts.h" #undef MYSQL_CLIENT diff --git a/extra/mariabackup/xtrabackup.h b/extra/mariabackup/xtrabackup.h index 2dbdd442f95..a87042c10b7 100644 --- a/extra/mariabackup/xtrabackup.h +++ b/extra/mariabackup/xtrabackup.h @@ -110,6 +110,8 @@ extern my_bool opt_remove_original; extern my_bool opt_extended_validation; extern my_bool opt_encrypted_backup; extern my_bool opt_lock_ddl_per_table; +extern my_bool opt_ignore_innodb_page_corruption; + extern char *opt_incremental_history_name; extern char *opt_incremental_history_uuid; diff --git a/mysql-test/suite/mariabackup/ignore_page_corruption.result b/mysql-test/suite/mariabackup/ignore_page_corruption.result new file mode 100644 index 00000000000..fd1a43a20e9 --- /dev/null +++ b/mysql-test/suite/mariabackup/ignore_page_corruption.result @@ -0,0 +1,10 @@ +call mtr.add_suppression("\\[ERROR\\] InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=3\\] in file '.*test.t1\\.ibd' cannot be decrypted."); +call mtr.add_suppression("\\[ERROR\\] InnoDB: Table `test`\\.`t1` has an unreadable root page"); +CREATE TABLE t1(c VARCHAR(128)) ENGINE INNODB; +insert into t1 select repeat('a',100); +# Corrupt the table +# xtrabackup backup must fail due to page corruption +FOUND 1 /Database page corruption detected.*/ in backup.log +# xtrabackup backup must ignore page corruption due to --ignore-innodb-page-corruption option +FOUND 1 /Database page corruption detected.*/ in backup.log +drop table t1; diff --git a/mysql-test/suite/mariabackup/ignore_page_corruption.test b/mysql-test/suite/mariabackup/ignore_page_corruption.test new file mode 100644 index 00000000000..8e067bf15b1 --- /dev/null +++ b/mysql-test/suite/mariabackup/ignore_page_corruption.test @@ -0,0 +1,74 @@ +--source include/innodb_page_size.inc + +call mtr.add_suppression("\\[ERROR\\] InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=3\\] in file '.*test.t1\\.ibd' cannot be decrypted."); +call mtr.add_suppression("\\[ERROR\\] InnoDB: Table `test`\\.`t1` has an unreadable root page"); +CREATE TABLE t1(c VARCHAR(128)) ENGINE INNODB; +insert into t1 select repeat('a',100); + +let MYSQLD_DATADIR=`select @@datadir`; +let INNODB_PAGE_SIZE=`select @@innodb_page_size`; + +--source include/shutdown_mysqld.inc + +--echo # Corrupt the table + +perl; +use strict; +use warnings; +use Fcntl qw(:DEFAULT :seek); +do "$ENV{MTR_SUITE_DIR}/../innodb/include/crc32.pl"; + +my $page_size = $ENV{INNODB_PAGE_SIZE}; + +sysopen IBD_FILE, "$ENV{MYSQLD_DATADIR}/test/t1.ibd", O_RDWR +|| die "Cannot open t1.ibd\n"; +sysread(IBD_FILE, $_, 38) || die "Cannot read t1.ibd\n"; +my $space = unpack("x[34]N", $_); +$space += 10; # generate wrong space id +sysseek(IBD_FILE, $page_size * 3, SEEK_SET) || die "Cannot seek t1.ibd\n"; + +my $head = pack("Nx[18]", 10); # generate wrong page number +my $body = chr(0) x ($page_size - 38 - 8); + +# Calculate innodb_checksum_algorithm=crc32 for the unencrypted page. +# The following bytes are excluded: +# bytes 0..3 (the checksum is stored there) +# bytes 26..37 (encryption key version, post-encryption checksum, tablespace id) +# bytes $page_size-8..$page_size-1 (checksum, LSB of FIL_PAGE_LSN) +my $polynomial = 0x82f63b78; # CRC-32C +my $ck = mycrc32($head, 0, $polynomial) ^ mycrc32($body, 0, $polynomial); + +my $page= pack("N",$ck).$head.pack("NNN",1,$ck,$space).$body.pack("Nx[4]",$ck); +die unless syswrite(IBD_FILE, $page, $page_size) == $page_size; +close IBD_FILE; +EOF + +--source include/start_mysqld.inc + +let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; +let $backuplog=$MYSQLTEST_VARDIR/tmp/backup.log; + +--echo # xtrabackup backup must fail due to page corruption +--disable_result_log +--error 1 +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir > $backuplog; +--enable_result_log + +--let SEARCH_PATTERN=Database page corruption detected.* +--let SEARCH_FILE=$backuplog +--source include/search_pattern_in_file.inc +--rmdir $targetdir +--remove_file $backuplog + +--echo # xtrabackup backup must ignore page corruption due to --ignore-innodb-page-corruption option +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --ignore-innodb-page-corruption --target-dir=$targetdir > $backuplog; +--enable_result_log + +--let SEARCH_PATTERN=Database page corruption detected.* +--let SEARCH_FILE=$backuplog +--source include/search_pattern_in_file.inc +--rmdir $targetdir +--remove_file $backuplog + +drop table t1; |