Commit 0f7732d1 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-19335 adjustment for innodb_checksum_algorithm=full_crc32

When MDEV-12026 introduced innodb_checksum_algorithm=full_crc32 in
MariaDB 10.4, it accidentally added a dependency on buf_page_t::encrypted.
Now that the flag has been removed, we must adjust the page-read routine.

buf_page_io_complete(): When the full_crc32 page checksum matches but the
tablespace ID in the page does not match after decrypting, we should
declare it a decryption failure and suppress the page dump output and
any attempts to re-read the page.
parent c11e5cdd
...@@ -6,6 +6,7 @@ call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9] ...@@ -6,6 +6,7 @@ call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]
call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t1.ibd looks corrupted; key_version=1"); call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t1.ibd looks corrupted; key_version=1");
call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` is corrupted"); call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` is corrupted");
call mtr.add_suppression("File '.*mysql-test.std_data.keysbad3\\.txt' not found"); call mtr.add_suppression("File '.*mysql-test.std_data.keysbad3\\.txt' not found");
call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot decrypt \\[page id: space=");
# Start server with keys2.txt # Start server with keys2.txt
# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt # restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt
SET GLOBAL innodb_file_per_table = ON; SET GLOBAL innodb_file_per_table = ON;
......
...@@ -6,6 +6,7 @@ call mtr.add_suppression("InnoDB: Tablespace for table \`test\`.\`t1\` is set as ...@@ -6,6 +6,7 @@ call mtr.add_suppression("InnoDB: Tablespace for table \`test\`.\`t1\` is set as
call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted"); call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted");
call mtr.add_suppression("InnoDB: Cannot delete tablespace .* because it is not found in the tablespace memory cache"); call mtr.add_suppression("InnoDB: Cannot delete tablespace .* because it is not found in the tablespace memory cache");
call mtr.add_suppression("InnoDB: ALTER TABLE `test`\\.`t1` DISCARD TABLESPACE failed to find tablespace"); call mtr.add_suppression("InnoDB: ALTER TABLE `test`\\.`t1` DISCARD TABLESPACE failed to find tablespace");
call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot decrypt \\[page id: space=");
# restart: --plugin-load-add=file_key_management.so --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt # restart: --plugin-load-add=file_key_management.so --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt
SET GLOBAL innodb_file_per_table = ON; SET GLOBAL innodb_file_per_table = ON;
CREATE TABLE t1 (pk INT PRIMARY KEY, f VARCHAR(8)) ENGINE=InnoDB CREATE TABLE t1 (pk INT PRIMARY KEY, f VARCHAR(8)) ENGINE=InnoDB
......
...@@ -3,6 +3,7 @@ call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page n ...@@ -3,6 +3,7 @@ call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page n
call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]"); call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]");
call mtr.add_suppression("Couldn't load plugins from 'file_key_management"); call mtr.add_suppression("Couldn't load plugins from 'file_key_management");
call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted"); call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted");
call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot decrypt \\[page id: space=");
# restart: --plugin-load-add=file_key_management.so --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt # restart: --plugin-load-add=file_key_management.so --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt
SET GLOBAL innodb_file_per_table = ON; SET GLOBAL innodb_file_per_table = ON;
CREATE TABLE t1 (pk INT PRIMARY KEY, f VARCHAR(8)) ENGINE=InnoDB CREATE TABLE t1 (pk INT PRIMARY KEY, f VARCHAR(8)) ENGINE=InnoDB
......
[crc32]
loose-innodb-checksum-algorithm=crc32
[full_crc32]
loose-innodb-checksum-algorithm=full_crc32
...@@ -16,6 +16,8 @@ call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9] ...@@ -16,6 +16,8 @@ call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]
call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t1.ibd looks corrupted; key_version=1"); call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t1.ibd looks corrupted; key_version=1");
call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` is corrupted"); call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` is corrupted");
call mtr.add_suppression("File '.*mysql-test.std_data.keysbad3\\.txt' not found"); call mtr.add_suppression("File '.*mysql-test.std_data.keysbad3\\.txt' not found");
# for innodb_checksum_algorithm=full_crc32 only
call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot decrypt \\[page id: space=");
--echo # Start server with keys2.txt --echo # Start server with keys2.txt
-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt -- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt
......
[crc32]
loose-innodb-checksum-algorithm=crc32
[full_crc32]
loose-innodb-checksum-algorithm=full_crc32
...@@ -17,6 +17,8 @@ call mtr.add_suppression("InnoDB: Tablespace for table \`test\`.\`t1\` is set as ...@@ -17,6 +17,8 @@ call mtr.add_suppression("InnoDB: Tablespace for table \`test\`.\`t1\` is set as
call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted"); call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted");
call mtr.add_suppression("InnoDB: Cannot delete tablespace .* because it is not found in the tablespace memory cache"); call mtr.add_suppression("InnoDB: Cannot delete tablespace .* because it is not found in the tablespace memory cache");
call mtr.add_suppression("InnoDB: ALTER TABLE `test`\\.`t1` DISCARD TABLESPACE failed to find tablespace"); call mtr.add_suppression("InnoDB: ALTER TABLE `test`\\.`t1` DISCARD TABLESPACE failed to find tablespace");
# for innodb_checksum_algorithm=full_crc32 only
call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot decrypt \\[page id: space=");
--let $restart_parameters=--plugin-load-add=file_key_management.so --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt --let $restart_parameters=--plugin-load-add=file_key_management.so --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt
--source include/restart_mysqld.inc --source include/restart_mysqld.inc
......
[crc32]
loose-innodb-checksum-algorithm=crc32
[full_crc32]
loose-innodb-checksum-algorithm=full_crc32
[crc32]
loose-innodb-checksum-algorithm=crc32
[full_crc32]
loose-innodb-checksum-algorithm=full_crc32
...@@ -13,6 +13,8 @@ call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9] ...@@ -13,6 +13,8 @@ call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]
# Suppression for builds where file_key_management plugin is linked statically # Suppression for builds where file_key_management plugin is linked statically
call mtr.add_suppression("Couldn't load plugins from 'file_key_management"); call mtr.add_suppression("Couldn't load plugins from 'file_key_management");
call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted"); call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted");
# for innodb_checksum_algorithm=full_crc32 only
call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot decrypt \\[page id: space=");
--let $restart_parameters=--plugin-load-add=file_key_management.so --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt --let $restart_parameters=--plugin-load-add=file_key_management.so --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt
--source include/restart_mysqld.inc --source include/restart_mysqld.inc
......
...@@ -5955,7 +5955,7 @@ static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space) ...@@ -5955,7 +5955,7 @@ static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space)
not decrypted and it could be either encrypted and corrupted not decrypted and it could be either encrypted and corrupted
or corrupted or good page. If we decrypted, there page could or corrupted or good page. If we decrypted, there page could
still be corrupted if used key does not match. */ still be corrupted if used key does not match. */
const bool seems_encrypted = (!space->full_crc32() && key_version) const bool seems_encrypted = !space->full_crc32() && key_version
&& space->crypt_data && space->crypt_data
&& space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED; && space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED;
ut_ad(space->purpose != FIL_TYPE_TEMPORARY || space->full_crc32()); ut_ad(space->purpose != FIL_TYPE_TEMPORARY || space->full_crc32());
...@@ -5970,7 +5970,6 @@ static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space) ...@@ -5970,7 +5970,6 @@ static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space)
space->id, dst_frame, space->is_compressed())) { space->id, dst_frame, space->is_compressed())) {
err = DB_PAGE_CORRUPTED; err = DB_PAGE_CORRUPTED;
} }
} else if (buf_page_is_corrupted(true, dst_frame, space->flags)) { } else if (buf_page_is_corrupted(true, dst_frame, space->flags)) {
err = DB_PAGE_CORRUPTED; err = DB_PAGE_CORRUPTED;
} }
...@@ -6085,13 +6084,26 @@ buf_page_io_complete(buf_page_t* bpage, bool dblwr, bool evict) ...@@ -6085,13 +6084,26 @@ buf_page_io_complete(buf_page_t* bpage, bool dblwr, bool evict)
} else if (read_space_id == 0 && read_page_no == 0) { } else if (read_space_id == 0 && read_page_no == 0) {
/* This is likely an uninitialized page. */ /* This is likely an uninitialized page. */
} else if ((bpage->id.space() != TRX_SYS_SPACE } else if (((!space->full_crc32()
|| bpage->id.space() != TRX_SYS_SPACE)
&& bpage->id.space() != read_space_id) && bpage->id.space() != read_space_id)
|| bpage->id.page_no() != read_page_no) { || bpage->id.page_no() != read_page_no) {
/* We did not compare space_id to read_space_id /* We do not compare space_id to read_space_id
in the system tablespace, because the field in the system tablespace unless space->full_crc32(),
was written as garbage before MySQL 4.1.1, because the field was written as garbage before
which did not support innodb_file_per_table. */ MySQL 4.1.1, which introduced support for
innodb_file_per_table. */
if (space->full_crc32()
&& *reinterpret_cast<uint32_t*>
(&frame[FIL_PAGE_FCRC32_KEY_VERSION])
&& space->crypt_data
&& space->crypt_data->type
!= CRYPT_SCHEME_UNENCRYPTED) {
ib::error() << "Cannot decrypt " << bpage->id;
err = DB_DECRYPTION_FAILED;
goto release_page;
}
ib::error() << "Space id and page no stored in " ib::error() << "Space id and page no stored in "
"the page, read in are " "the page, read in are "
...@@ -6165,6 +6177,7 @@ buf_page_io_complete(buf_page_t* bpage, bool dblwr, bool evict) ...@@ -6165,6 +6177,7 @@ buf_page_io_complete(buf_page_t* bpage, bool dblwr, bool evict)
if (err == DB_PAGE_CORRUPTED if (err == DB_PAGE_CORRUPTED
|| err == DB_DECRYPTION_FAILED) { || err == DB_DECRYPTION_FAILED) {
release_page:
const page_id_t corrupt_page_id = bpage->id; const page_id_t corrupt_page_id = bpage->id;
buf_corrupt_page_release(bpage, space); buf_corrupt_page_release(bpage, space);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment