MDEV-19695 Import tablespace doesn't work with ROW_FORMAT=COMPRESSED encrypted tablespace

Problem:
=======
fil_iterate() writes imported tablespace page0 as it is to discarded
tablespace. Space id wasn't even changed. While opening the tablespace,
tablespace fails with space id mismatch error.

Fix:
====
fil_iterate() copies the page0 with discarded space id to imported
tablespace.
parent d7c8423a
CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED ENCRYPTED=YES;
INSERT INTO t1 VALUES(1, repeat('Nesamani', 10));
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`id` int(11) NOT NULL,
`a` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED `ENCRYPTED`=YES
# Wait max 10 min for key encryption threads to encrypt all spaces
t1.frm
t1.ibd
FLUSH TABLES t1 FOR EXPORT;
backup: t1
t1.cfg
t1.frm
t1.ibd
UNLOCK TABLES;
DROP TABLE t1;
CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED ENCRYPTED=YES;
ALTER TABLE t1 DISCARD TABLESPACE;
restore: t1 .ibd and .cfg files
ALTER TABLE t1 IMPORT TABLESPACE;
SELECT COUNT(*) FROM t1;
COUNT(*)
1
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`id` int(11) NOT NULL,
`a` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED `ENCRYPTED`=YES
DROP TABLE t1;
--innodb-encrypt-tables=ON
--innodb-encryption-threads=4
--innodb-tablespaces-encryption
-- source include/have_innodb.inc
-- source include/have_example_key_management_plugin.inc
-- source include/not_valgrind.inc
-- source include/not_embedded.inc
let MYSQLD_DATADIR = `SELECT @@datadir`;
--let t1_IBD = $MYSQLD_DATADIR/test/t1.ibd
CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED ENCRYPTED=YES;
INSERT INTO t1 VALUES(1, repeat('Nesamani', 10));
SELECT COUNT(*) FROM t1;
SHOW CREATE TABLE t1;
--echo # Wait max 10 min for key encryption threads to encrypt all spaces
--let $wait_timeout= 600
--let $wait_condition=SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND ROTATING_OR_FLUSHING <> 0
--source include/wait_condition.inc
--source include/shutdown_mysqld.inc
--source include/start_mysqld.inc
let MYSQLD_DATADIR =`SELECT @@datadir`;
--list_files $MYSQLD_DATADIR/test
FLUSH TABLES t1 FOR EXPORT;
perl;
do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
ib_backup_tablespaces("test", "t1");
EOF
--list_files $MYSQLD_DATADIR/test
UNLOCK TABLES;
DROP TABLE t1;
CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB ROW_FORMAT=COMPRESSED ENCRYPTED=YES;
ALTER TABLE t1 DISCARD TABLESPACE;
perl;
do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl";
ib_discard_tablespaces("test", "t1");
ib_restore_tablespaces("test", "t1");
EOF
ALTER TABLE t1 IMPORT TABLESPACE;
SELECT COUNT(*) FROM t1;
SHOW CREATE TABLE t1;
DROP TABLE t1;
...@@ -3421,7 +3421,11 @@ fil_iterate( ...@@ -3421,7 +3421,11 @@ fil_iterate(
FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION
+ src)) { + src)) {
not_encrypted: not_encrypted:
if (!page_compressed if (block->page.id.page_no() == 0
&& block->page.zip.data) {
block->page.zip.data = src;
frame_changed = true;
} else if (!page_compressed
&& !block->page.zip.data) { && !block->page.zip.data) {
block->frame = src; block->frame = src;
frame_changed = true; frame_changed = true;
...@@ -3513,8 +3517,12 @@ fil_iterate( ...@@ -3513,8 +3517,12 @@ fil_iterate(
} }
if (frame_changed) { if (frame_changed) {
if (block->page.zip.data) {
block->page.zip.data = dst;
} else {
block->frame = dst; block->frame = dst;
} }
}
src = io_buffer + (i * size); src = io_buffer + (i * size);
......
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