Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MDEV-11656: 'Data structure corruption' IMPORT TABLESPACE doesn't wor…
…k for encrypted InnoDB tables if space_id changed Problem was that for encryption we use temporary scratch area for reading and writing tablespace pages. But if page was not really decrypted the correct updated page was not moved to scratch area that was then written. This can happen e.g. for page 0 as it is newer encrypted even if encryption is enabled and as we write the contents of old page 0 to tablespace it contained naturally incorrect space_id that is then later noted and error message was written. Updated page with correct space_id was lost. If tablespace is encrypted we use additional temporary scratch area where pages are read for decrypting readptr == crypt_io_buffer != io_buffer. Destination for decryption is a buffer pool block block->frame == dst == io_buffer that is updated. Pages that did not require decryption even when tablespace is marked as encrypted are not copied instead block->frame is set to src == readptr. If tablespace was encrypted we copy updated page to writeptr != io_buffer. This fixes above bug. For encryption we again use temporary scratch area writeptr != io_buffer == dst that is then written to the tablespace (1) For normal tables src == dst == writeptr ut_ad(!encrypted && !page_compressed ? src == dst && dst == writeptr + (i * size):1); (2) For page compressed tables src == dst == writeptr ut_ad(page_compressed && !encrypted ? src == dst && dst == writeptr + (i * size):1); (3) For encrypted tables src != dst != writeptr ut_ad(encrypted ? src != dst && dst != writeptr + (i * size):1);
- Loading branch information
Jan Lindström
committed
Dec 28, 2016
1 parent
d50cf42
commit 283e9cf
Showing
4 changed files
with
342 additions
and
16 deletions.
There are no files selected for viewing
105 changes: 105 additions & 0 deletions
105
mysql-test/suite/encryption/r/innodb-discard-import-change.result
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
call mtr.add_suppression("InnoDB: Table .* tablespace is set as discarded"); | ||
SET GLOBAL innodb_file_format = `Barracuda`; | ||
SET GLOBAL innodb_file_per_table = ON; | ||
SET GLOBAL innodb_compression_algorithm = 1; | ||
create table t1(c1 bigint not null primary key auto_increment, b char(200)) engine=innodb encrypted=yes encryption_key_id=4; | ||
create table t2(c1 bigint not null primary key auto_increment, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; | ||
create table t3(c1 bigint not null primary key auto_increment, b char(200)) engine=innodb page_compressed=yes; | ||
create table t4(c1 bigint not null primary key auto_increment, b char(200)) engine=innodb page_compressed=yes encrypted=yes encryption_key_id=4; | ||
create table t5(c1 bigint not null primary key auto_increment, b char(200)) engine=innodb; | ||
insert into t1 values (NULL, 'verysecretmessage'); | ||
insert into t1(b) select b from t1; | ||
insert into t1(b) select b from t1; | ||
insert into t1(b) select b from t1; | ||
insert into t1(b) select b from t1; | ||
insert into t1(b) select b from t1; | ||
insert into t1(b) select b from t1; | ||
insert into t1(b) select b from t1; | ||
insert into t1(b) select b from t1; | ||
insert into t2 select * from t1; | ||
insert into t3 select * from t1; | ||
insert into t4 select * from t1; | ||
insert into t5 select * from t1; | ||
FLUSH TABLE t1,t2,t3,t4,t5 FOR EXPORT; | ||
backup: t1 | ||
backup: t2 | ||
backup: t3 | ||
backup: t4 | ||
backup: t5 | ||
t1.cfg | ||
t1.frm | ||
t1.ibd | ||
t2.cfg | ||
t2.frm | ||
t2.ibd | ||
t3.cfg | ||
t3.frm | ||
t3.ibd | ||
t4.cfg | ||
t4.frm | ||
t4.ibd | ||
t5.cfg | ||
t5.frm | ||
t5.ibd | ||
UNLOCK TABLES; | ||
ALTER TABLE t1 DISCARD TABLESPACE; | ||
ALTER TABLE t2 DISCARD TABLESPACE; | ||
ALTER TABLE t3 DISCARD TABLESPACE; | ||
ALTER TABLE t4 DISCARD TABLESPACE; | ||
ALTER TABLE t5 DISCARD TABLESPACE; | ||
DROP TABLE t1; | ||
DROP TABLE t3; | ||
DROP TABLE t4; | ||
DROP TABLE t5; | ||
create table t6(a int) engine=innodb; | ||
create table t5(c1 bigint not null primary key auto_increment, b char(200)) engine=innodb; | ||
create table t3(c1 bigint not null primary key auto_increment, b char(200)) engine=innodb page_compressed=yes; | ||
create table t1(c1 bigint not null primary key auto_increment, b char(200)) engine=innodb encrypted=yes encryption_key_id=4; | ||
create table t4(c1 bigint not null primary key auto_increment, b char(200)) engine=innodb page_compressed=yes encrypted=yes encryption_key_id=4; | ||
ALTER TABLE t1 DISCARD TABLESPACE; | ||
ALTER TABLE t3 DISCARD TABLESPACE; | ||
ALTER TABLE t4 DISCARD TABLESPACE; | ||
ALTER TABLE t5 DISCARD TABLESPACE; | ||
restore: t1 .ibd and .cfg files | ||
restore: t2 .ibd and .cfg files | ||
restore: t3 .ibd and .cfg files | ||
restore: t4 .ibd and .cfg files | ||
restore: t5 .ibd and .cfg files | ||
ALTER TABLE t1 IMPORT TABLESPACE; | ||
SHOW CREATE TABLE t1; | ||
Table Create Table | ||
t1 CREATE TABLE `t1` ( | ||
`c1` bigint(20) NOT NULL AUTO_INCREMENT, | ||
`b` char(200) DEFAULT NULL, | ||
PRIMARY KEY (`c1`) | ||
) ENGINE=InnoDB AUTO_INCREMENT=377 DEFAULT CHARSET=latin1 `encrypted`=yes `encryption_key_id`=4 | ||
SELECT COUNT(*) FROM t1; | ||
COUNT(*) | ||
256 | ||
ALTER TABLE t2 IMPORT TABLESPACE; | ||
SELECT COUNT(*) FROM t2; | ||
COUNT(*) | ||
256 | ||
ALTER TABLE t3 IMPORT TABLESPACE; | ||
SELECT COUNT(*) FROM t3; | ||
COUNT(*) | ||
256 | ||
ALTER TABLE t4 IMPORT TABLESPACE; | ||
SELECT COUNT(*) FROM t4; | ||
COUNT(*) | ||
256 | ||
ALTER TABLE t5 IMPORT TABLESPACE; | ||
SELECT COUNT(*) FROM t5; | ||
COUNT(*) | ||
256 | ||
# t1 encrypted expecting NOT FOUND | ||
NOT FOUND /verysecretmessage/ in t1.ibd | ||
# t2 encrypted expecting NOT FOUND | ||
NOT FOUND /verysecretmessage/ in t2.ibd | ||
# t3 page compressed expecting NOT FOUND | ||
NOT FOUND /verysecretmessage/ in t3.ibd | ||
# t4 page compressed and encrypted expecting NOT FOUND | ||
NOT FOUND /verysecretmessage/ in t4.ibd | ||
# t5 normal expecting FOUND | ||
FOUND /verysecretmessage/ in t5.ibd | ||
DROP TABLE t1,t2,t3,t4,t5,t6; |
131 changes: 131 additions & 0 deletions
131
mysql-test/suite/encryption/t/innodb-discard-import-change.test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
-- source include/have_innodb.inc | ||
-- source include/have_file_key_management_plugin.inc | ||
# | ||
# MDEV-11656: 'Data structure corruption' IMPORT TABLESPACE doesn't work for encrypted InnoDB tables if space_id changed | ||
# | ||
|
||
call mtr.add_suppression("InnoDB: Table .* tablespace is set as discarded"); | ||
|
||
--disable_query_log | ||
let $innodb_file_format_orig = `SELECT @@innodb_file_format`; | ||
let $innodb_file_per_table_orig = `SELECT @@innodb_file_per_table`; | ||
let $innodb_compression_algo = `SELECT @@innodb_compression_algorithm`; | ||
--enable_query_log | ||
|
||
--disable_warnings | ||
SET GLOBAL innodb_file_format = `Barracuda`; | ||
SET GLOBAL innodb_file_per_table = ON; | ||
SET GLOBAL innodb_compression_algorithm = 1; | ||
--enable_warnings | ||
|
||
create table t1(c1 bigint not null primary key auto_increment, b char(200)) engine=innodb encrypted=yes encryption_key_id=4; | ||
create table t2(c1 bigint not null primary key auto_increment, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; | ||
create table t3(c1 bigint not null primary key auto_increment, b char(200)) engine=innodb page_compressed=yes; | ||
create table t4(c1 bigint not null primary key auto_increment, b char(200)) engine=innodb page_compressed=yes encrypted=yes encryption_key_id=4; | ||
create table t5(c1 bigint not null primary key auto_increment, b char(200)) engine=innodb; | ||
|
||
insert into t1 values (NULL, 'verysecretmessage'); | ||
insert into t1(b) select b from t1; | ||
insert into t1(b) select b from t1; | ||
insert into t1(b) select b from t1; | ||
insert into t1(b) select b from t1; | ||
insert into t1(b) select b from t1; | ||
insert into t1(b) select b from t1; | ||
insert into t1(b) select b from t1; | ||
insert into t1(b) select b from t1; | ||
insert into t2 select * from t1; | ||
insert into t3 select * from t1; | ||
insert into t4 select * from t1; | ||
insert into t5 select * from t1; | ||
|
||
let MYSQLD_DATADIR =`SELECT @@datadir`; | ||
FLUSH TABLE t1,t2,t3,t4,t5 FOR EXPORT; | ||
perl; | ||
do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; | ||
ib_backup_tablespaces("test", "t1","t2","t3","t4","t5"); | ||
EOF | ||
--list_files $MYSQLD_DATADIR/test | ||
UNLOCK TABLES; | ||
|
||
ALTER TABLE t1 DISCARD TABLESPACE; | ||
ALTER TABLE t2 DISCARD TABLESPACE; | ||
ALTER TABLE t3 DISCARD TABLESPACE; | ||
ALTER TABLE t4 DISCARD TABLESPACE; | ||
ALTER TABLE t5 DISCARD TABLESPACE; | ||
|
||
# | ||
# Now intentionally change space_id for t1,t3,t4,t5 | ||
# | ||
DROP TABLE t1; | ||
DROP TABLE t3; | ||
DROP TABLE t4; | ||
DROP TABLE t5; | ||
|
||
create table t6(a int) engine=innodb; | ||
create table t5(c1 bigint not null primary key auto_increment, b char(200)) engine=innodb; | ||
create table t3(c1 bigint not null primary key auto_increment, b char(200)) engine=innodb page_compressed=yes; | ||
create table t1(c1 bigint not null primary key auto_increment, b char(200)) engine=innodb encrypted=yes encryption_key_id=4; | ||
create table t4(c1 bigint not null primary key auto_increment, b char(200)) engine=innodb page_compressed=yes encrypted=yes encryption_key_id=4; | ||
|
||
ALTER TABLE t1 DISCARD TABLESPACE; | ||
ALTER TABLE t3 DISCARD TABLESPACE; | ||
ALTER TABLE t4 DISCARD TABLESPACE; | ||
ALTER TABLE t5 DISCARD TABLESPACE; | ||
|
||
perl; | ||
do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; | ||
ib_discard_tablespaces("test", "t1","t2","t3","t4","t5"); | ||
ib_restore_tablespaces("test", "t1","t2","t3","t4","t5"); | ||
EOF | ||
|
||
ALTER TABLE t1 IMPORT TABLESPACE; | ||
SHOW CREATE TABLE t1; | ||
SELECT COUNT(*) FROM t1; | ||
ALTER TABLE t2 IMPORT TABLESPACE; | ||
SELECT COUNT(*) FROM t2; | ||
ALTER TABLE t3 IMPORT TABLESPACE; | ||
SELECT COUNT(*) FROM t3; | ||
ALTER TABLE t4 IMPORT TABLESPACE; | ||
SELECT COUNT(*) FROM t4; | ||
ALTER TABLE t5 IMPORT TABLESPACE; | ||
SELECT COUNT(*) FROM t5; | ||
|
||
# | ||
# Verify | ||
# | ||
--let $MYSQLD_TMPDIR = `SELECT @@tmpdir` | ||
--let $MYSQLD_DATADIR = `SELECT @@datadir` | ||
--let SEARCH_RANGE = 10000000 | ||
--let t1_IBD = $MYSQLD_DATADIR/test/t1.ibd | ||
--let t2_IBD = $MYSQLD_DATADIR/test/t2.ibd | ||
--let t3_IBD = $MYSQLD_DATADIR/test/t3.ibd | ||
--let t4_IBD = $MYSQLD_DATADIR/test/t4.ibd | ||
--let t5_IBD = $MYSQLD_DATADIR/test/t5.ibd | ||
--let SEARCH_PATTERN=verysecretmessage | ||
--echo # t1 encrypted expecting NOT FOUND | ||
-- let SEARCH_FILE=$t1_IBD | ||
-- source include/search_pattern_in_file.inc | ||
--echo # t2 encrypted expecting NOT FOUND | ||
-- let SEARCH_FILE=$t2_IBD | ||
-- source include/search_pattern_in_file.inc | ||
--echo # t3 page compressed expecting NOT FOUND | ||
-- let SEARCH_FILE=$t3_IBD | ||
-- source include/search_pattern_in_file.inc | ||
--echo # t4 page compressed and encrypted expecting NOT FOUND | ||
-- let SEARCH_FILE=$t4_IBD | ||
-- source include/search_pattern_in_file.inc | ||
--echo # t5 normal expecting FOUND | ||
-- let SEARCH_FILE=$t5_IBD | ||
-- source include/search_pattern_in_file.inc | ||
|
||
DROP TABLE t1,t2,t3,t4,t5,t6; | ||
|
||
# reset system | ||
--disable_warnings | ||
--disable_query_log | ||
EVAL SET GLOBAL innodb_file_per_table = $innodb_file_per_table_orig; | ||
EVAL SET GLOBAL innodb_file_format = $innodb_file_format_orig; | ||
EVAL SET GLOBAL innodb_compression_algorithm = $innodb_compression_algo; | ||
--enable_query_log | ||
--enable_warnings | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.