summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2022-11-28 11:56:09 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2022-11-28 11:56:09 +0200
commitbd694bb7b28f64eb36704dd795ae351117ebeea4 (patch)
tree0537262c72dd538eea7bafa3abdf003b3f534146
parentdb14eb16f9977453467ec4765f481bb2f71814ba (diff)
downloadmariadb-git-bd694bb7b28f64eb36704dd795ae351117ebeea4.tar.gz
MDEV-24412 InnoDB: Upgrade after a crash is not supported
recv_log_recover_10_4(): Widen the operand of bitwise and to 64 bits, so that the upgrade check will work when the redo log record is located more than 4 gigabytes from the start of the first file.
-rw-r--r--mysql-test/suite/encryption/r/innodb_encrypt_log_corruption.result10
-rw-r--r--mysql-test/suite/innodb/r/log_corruption.result10
-rw-r--r--mysql-test/suite/innodb/t/log_corruption.test36
-rw-r--r--storage/innobase/log/log0recv.cc2
4 files changed, 55 insertions, 3 deletions
diff --git a/mysql-test/suite/encryption/r/innodb_encrypt_log_corruption.result b/mysql-test/suite/encryption/r/innodb_encrypt_log_corruption.result
index 8d1eb447b03..7563100babb 100644
--- a/mysql-test/suite/encryption/r/innodb_encrypt_log_corruption.result
+++ b/mysql-test/suite/encryption/r/innodb_encrypt_log_corruption.result
@@ -69,6 +69,14 @@ AND support IN ('YES', 'DEFAULT', 'ENABLED');
COUNT(*)
1
FOUND 3 /InnoDB: Upgrading redo log:/ in mysqld.1.err
+# Empty large multi-file redo log from after MariaDB 10.2.2
+# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-force-recovery=5 --innodb-log-file-size=2m
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES
+WHERE engine = 'innodb'
+AND support IN ('YES', 'DEFAULT', 'ENABLED');
+COUNT(*)
+1
+FOUND 4 /InnoDB: Upgrading redo log:/ in mysqld.1.err
# redo log from "after" MariaDB 10.2.2, but with invalid header checksum
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption
SELECT * FROM INFORMATION_SCHEMA.ENGINES
@@ -179,7 +187,7 @@ WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
COUNT(*)
1
-FOUND 5 /InnoDB: Upgrading redo log:/ in mysqld.1.err
+FOUND 6 /InnoDB: Upgrading redo log:/ in mysqld.1.err
# Minimal MariaDB 10.1.21 encrypted redo log
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-force-recovery=5
SELECT COUNT(*) `1` FROM INFORMATION_SCHEMA.ENGINES WHERE engine='innodb'
diff --git a/mysql-test/suite/innodb/r/log_corruption.result b/mysql-test/suite/innodb/r/log_corruption.result
index bf92f77d30c..890e3296164 100644
--- a/mysql-test/suite/innodb/r/log_corruption.result
+++ b/mysql-test/suite/innodb/r/log_corruption.result
@@ -69,6 +69,14 @@ AND support IN ('YES', 'DEFAULT', 'ENABLED');
COUNT(*)
1
FOUND 3 /InnoDB: Upgrading redo log:/ in mysqld.1.err
+# Empty large multi-file redo log from after MariaDB 10.2.2
+# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-force-recovery=5 --innodb-log-file-size=2m
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES
+WHERE engine = 'innodb'
+AND support IN ('YES', 'DEFAULT', 'ENABLED');
+COUNT(*)
+1
+FOUND 4 /InnoDB: Upgrading redo log:/ in mysqld.1.err
# redo log from "after" MariaDB 10.2.2, but with invalid header checksum
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption
SELECT * FROM INFORMATION_SCHEMA.ENGINES
@@ -179,7 +187,7 @@ WHERE engine = 'innodb'
AND support IN ('YES', 'DEFAULT', 'ENABLED');
COUNT(*)
1
-FOUND 5 /InnoDB: Upgrading redo log:/ in mysqld.1.err
+FOUND 6 /InnoDB: Upgrading redo log:/ in mysqld.1.err
# Minimal MariaDB 10.1.21 encrypted redo log
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/log_corruption --innodb-force-recovery=5
SELECT * FROM INFORMATION_SCHEMA.ENGINES
diff --git a/mysql-test/suite/innodb/t/log_corruption.test b/mysql-test/suite/innodb/t/log_corruption.test
index a3ab4510743..27fae80a135 100644
--- a/mysql-test/suite/innodb/t/log_corruption.test
+++ b/mysql-test/suite/innodb/t/log_corruption.test
@@ -291,6 +291,42 @@ AND support IN ('YES', 'DEFAULT', 'ENABLED');
--source include/search_pattern_in_file.inc
--let $restart_parameters= $dirs
+--echo # Empty large multi-file redo log from after MariaDB 10.2.2
+perl;
+do "$ENV{MTR_SUITE_DIR}/../innodb/include/crc32.pl";
+my $polynomial = 0x82f63b78; # CRC-32C
+
+die unless open OUT, "+<", "$ENV{bugdir}/ib_logfile0";
+binmode OUT;
+$_= pack("Nx[5]nx[5]", 1, 0x1286) . "BogoDB 4.3.2.1" . chr(0) x 478;
+print OUT $_, pack("N", mycrc32($_, 0, $polynomial));
+# checkpoint page 1 and all-zero checkpoint 2
+$_= pack("x[13]nCNNx[484]", 0x1286, 12, 2, 0x80c);
+print OUT $_, pack("N", mycrc32($_, 0, $polynomial));
+print OUT chr(0) x 1024;
+die unless seek(OUT, 0x1FFFFFFFF, 0);
+print OUT chr(0);
+close OUT or die;
+die unless open OUT, ">", "$ENV{bugdir}/ib_logfile1";
+binmode OUT;
+die unless seek(OUT, 0x800, 0); # the first 2048 bytes are unused!
+$_= pack("Nnnx[500]", 0x80000944, 12, 12);
+print OUT $_, pack("N", mycrc32($_, 0, $polynomial));
+die unless seek(OUT, 0x1FFFFFFFF, 0);
+print OUT chr(0);
+close OUT or die;
+EOF
+
+--let $restart_parameters= $dirs --innodb-force-recovery=5 --innodb-log-file-size=2m
+--source include/start_mysqld.inc
+SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES
+WHERE engine = 'innodb'
+AND support IN ('YES', 'DEFAULT', 'ENABLED');
+--source include/shutdown_mysqld.inc
+--let SEARCH_PATTERN= InnoDB: Upgrading redo log:
+--source include/search_pattern_in_file.inc
+--let $restart_parameters= $dirs
+
--remove_file $bugdir/ib_logfile0
--move_file $bugdir/ib_logfile $bugdir/ib_logfile0
diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc
index 8db270b2a9b..511ccc5afe6 100644
--- a/storage/innobase/log/log0recv.cc
+++ b/storage/innobase/log/log0recv.cc
@@ -1412,7 +1412,7 @@ static dberr_t recv_log_recover_10_4()
return DB_CORRUPTION;
}
- recv_sys.read(source_offset & ~(OS_FILE_LOG_BLOCK_SIZE - 1),
+ recv_sys.read(source_offset & ~lsn_t(OS_FILE_LOG_BLOCK_SIZE - 1),
{buf, OS_FILE_LOG_BLOCK_SIZE});
ulint crc = log_block_calc_checksum_crc32(buf);