diff options
-rw-r--r-- | extra/mariabackup/xtrabackup.cc | 15 | ||||
-rw-r--r-- | mysql-test/suite/mariabackup/innodb_redo_overwrite.opt | 1 | ||||
-rw-r--r-- | mysql-test/suite/mariabackup/innodb_redo_overwrite.result | 27 | ||||
-rw-r--r-- | mysql-test/suite/mariabackup/innodb_redo_overwrite.test | 57 | ||||
-rw-r--r-- | storage/innobase/log/log0recv.cc | 2 |
5 files changed, 99 insertions, 3 deletions
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 6949975f7ef..0915c0fb6d0 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -2689,6 +2689,7 @@ static bool xtrabackup_copy_logfile(bool last = false) ut_a(dst_log_file != NULL); ut_ad(recv_sys.is_initialised()); + bool overwritten_block; lsn_t start_lsn; lsn_t end_lsn; @@ -2714,6 +2715,11 @@ static bool xtrabackup_copy_logfile(bool last = false) } if (lsn == start_lsn) { + overwritten_block= !recv_sys.found_corrupt_log + && log_block_calc_checksum_crc32(log_sys.buf) == + log_block_get_checksum(log_sys.buf) + && log_block_get_hdr_no(log_sys.buf) > + log_block_convert_lsn_to_no(start_lsn); start_lsn = 0; } else { mutex_enter(&recv_sys.mutex); @@ -2724,9 +2730,12 @@ static bool xtrabackup_copy_logfile(bool last = false) log_mutex_exit(); if (!start_lsn) { - die(recv_sys.found_corrupt_log - ? "xtrabackup_copy_logfile() failed: corrupt log." - : "xtrabackup_copy_logfile() failed."); + const char *reason = recv_sys.found_corrupt_log + ? "corrupt log." + : (overwritten_block + ? "redo log block is overwritten, please increase redo log size with innodb_log_file_size parameter." + : "redo log block checksum does not match."); + die("xtrabackup_copy_logfile() failed: %s", reason); return true; } } while (start_lsn == end_lsn); diff --git a/mysql-test/suite/mariabackup/innodb_redo_overwrite.opt b/mysql-test/suite/mariabackup/innodb_redo_overwrite.opt new file mode 100644 index 00000000000..19c08c8c945 --- /dev/null +++ b/mysql-test/suite/mariabackup/innodb_redo_overwrite.opt @@ -0,0 +1 @@ +--loose-innodb-log-file-size=2m diff --git a/mysql-test/suite/mariabackup/innodb_redo_overwrite.result b/mysql-test/suite/mariabackup/innodb_redo_overwrite.result new file mode 100644 index 00000000000..9076dbaa57a --- /dev/null +++ b/mysql-test/suite/mariabackup/innodb_redo_overwrite.result @@ -0,0 +1,27 @@ +CREATE TABLE t(i INT) ENGINE=INNODB; +INSERT INTO t VALUES +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9), +(0), (1), (2), (3), (4), (5), (6), (7), (8), (9); +# Generate enough data to overwrite innodb redo log +# on the next "INSERT INTO t SELECT * FROM t" execution. +INSERT INTO t SELECT * FROM t; +INSERT INTO t SELECT * FROM t; +INSERT INTO t SELECT * FROM t; +INSERT INTO t SELECT * FROM t; +INSERT INTO t SELECT * FROM t; +INSERT INTO t SELECT * FROM t; +INSERT INTO t SELECT * FROM t; +INSERT INTO t SELECT * FROM t; +INSERT INTO t SELECT * FROM t; +# xtrabackup backup +FOUND 1 /failed: redo log block is overwritten/ in backup.log +FOUND 1 /failed: redo log block checksum does not match/ in backup.log +DROP TABLE t; diff --git a/mysql-test/suite/mariabackup/innodb_redo_overwrite.test b/mysql-test/suite/mariabackup/innodb_redo_overwrite.test new file mode 100644 index 00000000000..e27229c5f33 --- /dev/null +++ b/mysql-test/suite/mariabackup/innodb_redo_overwrite.test @@ -0,0 +1,57 @@ +--source include/have_innodb.inc +--source include/have_debug_sync.inc + +CREATE TABLE t(i INT) ENGINE=INNODB; + +INSERT INTO t VALUES + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9), + (0), (1), (2), (3), (4), (5), (6), (7), (8), (9); +--echo # Generate enough data to overwrite innodb redo log +--echo # on the next "INSERT INTO t SELECT * FROM t" execution. +--let $i = 0 +while ($i < 9) { +INSERT INTO t SELECT * FROM t; +--inc $i +} + +--echo # xtrabackup backup +--let $targetdir=$MYSQLTEST_VARDIR/tmp/backup +--let $backuplog=$MYSQLTEST_VARDIR/tmp/backup.log + +--let before_innodb_log_copy_thread_started=INSERT INTO test.t SELECT * FROM test.t + +--disable_result_log +--error 1 +--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --dbug=+d,mariabackup_events > $backuplog +--enable_result_log + +--let SEARCH_PATTERN=failed: redo log block is overwritten +--let SEARCH_FILE=$backuplog +--source include/search_pattern_in_file.inc +--remove_file $backuplog +--rmdir $targetdir + +--let before_innodb_log_copy_thread_started=INSERT INTO test.t VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9) + +--disable_result_log +--error 1 +--exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir --dbug=+d,mariabackup_events,log_checksum_mismatch > $backuplog +--enable_result_log + +--let SEARCH_PATTERN=failed: redo log block checksum does not match +--let SEARCH_FILE=$backuplog +--source include/search_pattern_in_file.inc +--remove_file $backuplog +--rmdir $targetdir + +--let before_innodb_log_copy_thread_started= + +DROP TABLE t; diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 46830db1323..f0c4a80cd1a 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -1218,6 +1218,8 @@ fail: } }); + DBUG_EXECUTE_IF("log_checksum_mismatch", { cksum = crc + 1; }); + if (UNIV_UNLIKELY(crc != cksum)) { ib::error() << "Invalid log block checksum." << " block: " << block_number |