diff options
Diffstat (limited to 'mysql-test/suite/encryption')
230 files changed, 13950 insertions, 0 deletions
diff --git a/mysql-test/suite/encryption/include/have_example_key_management_plugin.inc b/mysql-test/suite/encryption/include/have_example_key_management_plugin.inc new file mode 100644 index 00000000..a87d3256 --- /dev/null +++ b/mysql-test/suite/encryption/include/have_example_key_management_plugin.inc @@ -0,0 +1,4 @@ +if (!$EXAMPLE_KEY_MANAGEMENT_SO) +{ + --skip Needs example_key_management +} diff --git a/mysql-test/suite/encryption/include/have_example_key_management_plugin.opt b/mysql-test/suite/encryption/include/have_example_key_management_plugin.opt new file mode 100644 index 00000000..2c04c73b --- /dev/null +++ b/mysql-test/suite/encryption/include/have_example_key_management_plugin.opt @@ -0,0 +1,3 @@ +--plugin-load-add=$EXAMPLE_KEY_MANAGEMENT_SO +--loose-example-key-management +--skip-innodb-read-only-compressed diff --git a/mysql-test/suite/encryption/include/have_file_key_management_plugin.combinations b/mysql-test/suite/encryption/include/have_file_key_management_plugin.combinations new file mode 100644 index 00000000..2302dc48 --- /dev/null +++ b/mysql-test/suite/encryption/include/have_file_key_management_plugin.combinations @@ -0,0 +1,13 @@ +[cbc] +plugin-load-add=$FILE_KEY_MANAGEMENT_SO +loose-file-key-management +loose-file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys.txt +file-key-management-encryption-algorithm=aes_cbc +--skip-innodb-read-only-compressed + +[ctr] +plugin-load-add=$FILE_KEY_MANAGEMENT_SO +loose-file-key-management +loose-file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys.txt +file-key-management-encryption-algorithm=aes_ctr +--skip-innodb-read-only-compressed diff --git a/mysql-test/suite/encryption/include/have_file_key_management_plugin.inc b/mysql-test/suite/encryption/include/have_file_key_management_plugin.inc new file mode 100644 index 00000000..06fbb510 --- /dev/null +++ b/mysql-test/suite/encryption/include/have_file_key_management_plugin.inc @@ -0,0 +1,4 @@ +if (`SELECT COUNT(*)=0 FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME = 'file_key_management' AND PLUGIN_STATUS='ACTIVE'`) +{ + --skip Test requires file_key_management plugin +} diff --git a/mysql-test/suite/encryption/include/innodb-util.pl b/mysql-test/suite/encryption/include/innodb-util.pl new file mode 100644 index 00000000..241545da --- /dev/null +++ b/mysql-test/suite/encryption/include/innodb-util.pl @@ -0,0 +1,126 @@ +# +# Utility functions to copy files for WL#5522 +# +# All the tables must be in the same database, you can call it like so: +# ib_backup_tablespaces("test", "t1", "blah", ...). + +use File::Copy; +use File::Spec; + +sub ib_normalize_path { + my ($path) = @_; +} + +sub ib_backup_tablespace { + my ($db, $table) = @_; + my $datadir = $ENV{'MYSQLD_DATADIR'}; + my $cfg_file = sprintf("%s.cfg", $table); + my $ibd_file = sprintf("%s.ibd", $table); + my $tmpd = $ENV{'MYSQLTEST_VARDIR'} . "/tmp"; + + my @args = (File::Spec->catfile($datadir, $db, $ibd_file), + File::Spec->catfile($tmpd, $ibd_file)); + + copy(@args) or die "copy @args failed: $!"; + + my @args = (File::Spec->catfile($datadir, $db, $cfg_file), + File::Spec->catfile($tmpd, $cfg_file)); + + copy(@args) or die "copy @args failed: $!"; +} + +sub ib_cleanup { + my ($db, $table) = @_; + my $datadir = $ENV{'MYSQLD_DATADIR'}; + my $cfg_file = sprintf("%s.cfg", $table); + + print "unlink: $cfg_file\n"; + + # These may or may not exist + unlink(File::Spec->catfile($datadir, $db, $cfg_file)); +} + +sub ib_unlink_tablespace { + my ($db, $table) = @_; + my $datadir = $ENV{'MYSQLD_DATADIR'}; + my $ibd_file = sprintf("%s.ibd", $table); + + print "unlink: $ibd_file\n"; + # This may or may not exist + unlink(File::Spec->catfile($datadir, $db, $ibd_file)); + + ib_cleanup($db, $table); +} + +sub ib_backup_tablespaces { + my ($db, @tables) = @_; + + foreach my $table (@tables) { + print "backup: $table\n"; + ib_backup_tablespace($db, $table); + } +} + +sub ib_discard_tablespace { } + +sub ib_discard_tablespaces { } + +sub ib_restore_cfg_file { + my ($tmpd, $datadir, $db, $table) = @_; + my $cfg_file = sprintf("%s.cfg", $table); + + my @args = (File::Spec->catfile($tmpd, $cfg_file), + File::Spec->catfile($datadir, "$db", $cfg_file)); + + copy(@args) or die "copy @args failed: $!"; +} + +sub ib_restore_ibd_file { + my ($tmpd, $datadir, $db, $table) = @_; + my $ibd_file = sprintf("%s.ibd", $table); + + my @args = (File::Spec->catfile($tmpd, $ibd_file), + File::Spec->catfile($datadir, $db, $ibd_file)); + + copy(@args) or die "copy @args failed: $!"; +} + +sub ib_restore_tablespace { + my ($db, $table) = @_; + my $datadir = $ENV{'MYSQLD_DATADIR'}; + my $tmpd = $ENV{'MYSQLTEST_VARDIR'} . "/tmp"; + + ib_restore_cfg_file($tmpd, $datadir, $db, $table); + ib_restore_ibd_file($tmpd, $datadir, $db, $table); +} + +sub ib_restore_tablespaces { + my ($db, @tables) = @_; + + foreach my $table (@tables) { + print "restore: $table .ibd and .cfg files\n"; + ib_restore_tablespace($db, $table); + } +} + +sub ib_restore_cfg_files { + my ($db, @tables) = @_; + my $datadir = $ENV{'MYSQLD_DATADIR'}; + my $tmpd = $ENV{'MYSQLTEST_VARDIR'} . "/tmp"; + + foreach my $table (@tables) { + print "restore: $table .cfg file\n"; + ib_restore_cfg_file($tmpd, $datadir, $db, $table); + } +} + +sub ib_restore_ibd_files { + my ($db, @tables) = @_; + my $datadir = $ENV{'MYSQLD_DATADIR'}; + my $tmpd = $ENV{'MYSQLTEST_VARDIR'} . "/tmp"; + + foreach my $table (@tables) { + print "restore: $table .ibd file\n"; + ib_restore_ibd_file($tmpd, $datadir, $db, $table); + } +} diff --git a/mysql-test/suite/encryption/my.cnf b/mysql-test/suite/encryption/my.cnf new file mode 100644 index 00000000..772daa0f --- /dev/null +++ b/mysql-test/suite/encryption/my.cnf @@ -0,0 +1 @@ +!include include/default_my.cnf diff --git a/mysql-test/suite/encryption/r/aria_tiny.result b/mysql-test/suite/encryption/r/aria_tiny.result new file mode 100644 index 00000000..28f76225 --- /dev/null +++ b/mysql-test/suite/encryption/r/aria_tiny.result @@ -0,0 +1,27 @@ +SET @aria_encrypt= @@aria_encrypt_tables; +SET global aria_encrypt_tables=1; +create table t1 (i int, key(i)) engine=aria; +insert into t1 values (1); +drop table t1; +create table t1 (a int primary key, b int, c int, key(b),key(c)) engine=aria; +alter table t1 disable keys; +insert into t1 select seq,seq,seq from seq_1_to_100; +alter table t1 enable keys; +check table t1; +Table Op Msg_type Msg_text +test.t1 check status OK +drop table t1; +# +# MDEV CHECK on encrypted Aria table complains about "Wrong LSN" +# +CREATE TABLE t1 (f DATE PRIMARY KEY) ENGINE=Aria; +INSERT INTO t1 (f) VALUES ('1995-01-01'),('2000-01-01'); +DELETE FROM t1 WHERE f = '2000-01-01'; +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +CHECK TABLE t1 EXTENDED; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +set global aria_encrypt_tables=@aria_encrypt; diff --git a/mysql-test/suite/encryption/r/bulk_insert.result b/mysql-test/suite/encryption/r/bulk_insert.result new file mode 100644 index 00000000..840cb0cd --- /dev/null +++ b/mysql-test/suite/encryption/r/bulk_insert.result @@ -0,0 +1,7 @@ +SET UNIQUE_CHECKS=0, FOREIGN_KEY_CHECKS=0; +CREATE TABLE t1 ( +`id` int(10) unsigned NOT NULL, +UNIQUE KEY `id` (`id`) +) ENGINE=InnoDB; +INSERT INTO t1 SELECT seq FROM seq_1_to_65536; +DROP TABLE t1; diff --git a/mysql-test/suite/encryption/r/compressed_import_tablespace.result b/mysql-test/suite/encryption/r/compressed_import_tablespace.result new file mode 100644 index 00000000..81d62eb5 --- /dev/null +++ b/mysql-test/suite/encryption/r/compressed_import_tablespace.result @@ -0,0 +1,39 @@ +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 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPRESSED `ENCRYPTED`=YES +# Wait max 10 min for key encryption threads to encrypt all spaces +db.opt +t1.frm +t1.ibd +FLUSH TABLES t1 FOR EXPORT; +backup: t1 +db.opt +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 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPRESSED `ENCRYPTED`=YES +DROP TABLE t1; diff --git a/mysql-test/suite/encryption/r/corrupted_during_recovery.result b/mysql-test/suite/encryption/r/corrupted_during_recovery.result new file mode 100644 index 00000000..2b29bf26 --- /dev/null +++ b/mysql-test/suite/encryption/r/corrupted_during_recovery.result @@ -0,0 +1,19 @@ +CREATE TABLE t1(a BIGINT PRIMARY KEY) ENGINE=InnoDB, ENCRYPTED=YES; +INSERT INTO t1 VALUES(1); +CREATE TABLE t2(a BIGINT PRIMARY KEY) ENGINE=InnoDB, ENCRYPTED=YES; +INSERT INTO t1 VALUES(2); +SET GLOBAL innodb_flush_log_at_trx_commit=1; +INSERT INTO t2 VALUES(2); +# Kill the server +# Corrupt the pages +SELECT * FROM t1; +ERROR 42000: Unknown storage engine 'InnoDB' +SELECT * FROM t1; +ERROR HY000: Table test/t1 is corrupted. Please drop the table and recreate. +SELECT * FROM t2; +a +2 +CHECK TABLE t2; +Table Op Msg_type Msg_text +test.t2 check status OK +DROP TABLE t1, t2; diff --git a/mysql-test/suite/encryption/r/create_or_replace.result b/mysql-test/suite/encryption/r/create_or_replace.result new file mode 100644 index 00000000..69ea1132 --- /dev/null +++ b/mysql-test/suite/encryption/r/create_or_replace.result @@ -0,0 +1,19 @@ +SET @save_threads = @@GLOBAL.innodb_encryption_threads; +SET default_storage_engine = InnoDB; +SET GLOBAL innodb_encryption_threads = 4; +CREATE TABLE `table10_int_autoinc` (`col_int_key` int, pk int auto_increment, `col_int` int, key (`col_int_key` ),primary key (pk)) engine=innodb; +INSERT /*! IGNORE */ INTO table10_int_autoinc VALUES (NULL, NULL, -474021888) , (1, NULL, NULL) , (1141047296, NULL, NULL) , (NULL, NULL, NULL) , (NULL, NULL, 1) , (NULL, NULL, 9) , (0, NULL, 1225785344) , (NULL, NULL, 1574174720) , (2, NULL, NULL) , (6, NULL, 3); +CREATE TABLE `table1_int_autoinc` (`col_int_key` int, pk int auto_increment, `col_int` int,key (`col_int_key` ), primary key (pk)) engine=innodb; +CREATE TABLE `table0_int_autoinc` (`col_int_key` int, pk int auto_increment, `col_int` int, key (`col_int_key` ),primary key (pk)) engine=innodb; +INSERT /*! IGNORE */ INTO table1_int_autoinc VALUES (4, NULL, NULL); +INSERT IGNORE INTO `table0_int_autoinc` ( `col_int_key` ) VALUES ( 1 ), ( 3 ), ( 4 ), ( 1 ); +INSERT IGNORE INTO `table1_int_autoinc` ( `col_int` ) VALUES ( 1 ), ( 0 ), ( 7 ), ( 9 ); +INSERT IGNORE INTO `table10_int_autoinc` ( `col_int` ) VALUES ( 6 ), ( 2 ), ( 3 ), ( 6 ); +connect con1,localhost,root,,test; +connect con2,localhost,root,,test; +disconnect con1; +disconnect con2; +connection default; +drop table create_or_replace_t, table1_int_autoinc, table0_int_autoinc, +table10_int_autoinc; +SET GLOBAL innodb_encryption_threads = @save_threads; diff --git a/mysql-test/suite/encryption/r/create_or_replace_big.result b/mysql-test/suite/encryption/r/create_or_replace_big.result new file mode 100644 index 00000000..2eabab45 --- /dev/null +++ b/mysql-test/suite/encryption/r/create_or_replace_big.result @@ -0,0 +1,20 @@ +SET default_storage_engine = InnoDB; +CREATE TABLE t1 (pk INT PRIMARY KEY, c VARCHAR(256)); +CREATE TABLE t2 AS SELECT * FROM t1; +drop table t1,t2; +SET GLOBAL innodb_encryption_threads = 0; +SET GLOBAL innodb_encryption_threads = 4; +CREATE TABLE `table10_int_autoinc` (`col_int_key` int, pk int auto_increment, `col_int` int, key (`col_int_key` ),primary key (pk)) engine=innodb; +INSERT /*! IGNORE */ INTO table10_int_autoinc VALUES (NULL, NULL, -474021888) , (1, NULL, NULL) , (1141047296, NULL, NULL) , (NULL, NULL, NULL) , (NULL, NULL, 1) , (NULL, NULL, 9) , (0, NULL, 1225785344) , (NULL, NULL, 1574174720) , (2, NULL, NULL) , (6, NULL, 3); +CREATE TABLE `table1_int_autoinc` (`col_int_key` int, pk int auto_increment, `col_int` int,key (`col_int_key` ), primary key (pk)) engine=innodb; +CREATE TABLE `table0_int_autoinc` (`col_int_key` int, pk int auto_increment, `col_int` int, key (`col_int_key` ),primary key (pk)) engine=innodb; +INSERT /*! IGNORE */ INTO table1_int_autoinc VALUES (4, NULL, NULL); +INSERT IGNORE INTO `table0_int_autoinc` ( `col_int_key` ) VALUES ( 1 ), ( 3 ), ( 4 ), ( 1 ); +INSERT IGNORE INTO `table1_int_autoinc` ( `col_int` ) VALUES ( 1 ), ( 0 ), ( 7 ), ( 9 ); +INSERT IGNORE INTO `table10_int_autoinc` ( `col_int` ) VALUES ( 6 ), ( 2 ), ( 3 ), ( 6 ); +# Wait max 10 min for key encryption threads to decrypt all spaces +# Success! +SET GLOBAL innodb_encryption_threads = 0; +SET GLOBAL innodb_encrypt_tables = OFF; +DROP TABLE table0_int_autoinc, table1_int_autoinc, table10_int_autoinc; +# restart diff --git a/mysql-test/suite/encryption/r/debug_key_management.result b/mysql-test/suite/encryption/r/debug_key_management.result new file mode 100644 index 00000000..7fe681d5 --- /dev/null +++ b/mysql-test/suite/encryption/r/debug_key_management.result @@ -0,0 +1,27 @@ +create table t1(a serial) engine=innoDB; +set global innodb_encrypt_tables=ON; +show variables like 'innodb_encrypt%'; +Variable_name Value +innodb_encrypt_log ON +innodb_encrypt_tables ON +innodb_encrypt_temporary_tables OFF +innodb_encryption_rotate_key_age 2 +innodb_encryption_rotation_iops 100 +innodb_encryption_threads 4 +select count(*) from information_schema.innodb_tablespaces_encryption where current_key_version <> 1; +count(*) +0 +set global debug_key_management_version=10; +select count(*) from information_schema.innodb_tablespaces_encryption where current_key_version <> 10; +count(*) +0 +SET GLOBAL innodb_log_checkpoint_now = 1; +SET GLOBAL innodb_flush_log_at_trx_commit = 1; +INSERT INTO t1 VALUES(NULL); +# restart +set global innodb_encrypt_tables=OFF; +set global debug_key_management_version=1; +select * from t1; +a +1 +drop table t1; diff --git a/mysql-test/suite/encryption/r/encrypt_and_grep,undo3.rdiff b/mysql-test/suite/encryption/r/encrypt_and_grep,undo3.rdiff new file mode 100644 index 00000000..210c2a61 --- /dev/null +++ b/mysql-test/suite/encryption/r/encrypt_and_grep,undo3.rdiff @@ -0,0 +1,32 @@ +--- encrypt_and_grep.result 2022-09-02 22:36:21.669650278 +0530 ++++ encrypt_and_grep.reject 2022-11-29 19:01:22.080027528 +0530 +@@ -14,6 +14,9 @@ + SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + NAME + innodb_system ++innodb_undo001 ++innodb_undo002 ++innodb_undo003 + mysql/innodb_index_stats + mysql/innodb_table_stats + mysql/transaction_registry +@@ -35,6 +38,9 @@ + SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; + NAME + innodb_system ++innodb_undo001 ++innodb_undo002 ++innodb_undo003 + mysql/innodb_index_stats + mysql/innodb_table_stats + mysql/transaction_registry +@@ -62,6 +68,9 @@ + SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + NAME + innodb_system ++innodb_undo001 ++innodb_undo002 ++innodb_undo003 + mysql/innodb_index_stats + mysql/innodb_table_stats + mysql/transaction_registry diff --git a/mysql-test/suite/encryption/r/encrypt_and_grep.result b/mysql-test/suite/encryption/r/encrypt_and_grep.result new file mode 100644 index 00000000..72d612ee --- /dev/null +++ b/mysql-test/suite/encryption/r/encrypt_and_grep.result @@ -0,0 +1,80 @@ +SET GLOBAL innodb_file_per_table = ON; +create table t1 (a varchar(255)) engine=innodb encrypted=yes; +create table t2 (a varchar(255)) engine=innodb; +show warnings; +Level Code Message +create table t3 (a varchar(255)) engine=innodb encrypted=no; +insert t1 values (repeat('foobarsecret', 12)); +insert t2 values (repeat('tempsecret', 12)); +insert t3 values (repeat('dummysecret', 12)); +# Wait max 10 min for key encryption threads to encrypt all spaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +NAME +test/t3 +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +NAME +innodb_system +mysql/innodb_index_stats +mysql/innodb_table_stats +mysql/transaction_registry +test/t1 +test/t2 +FLUSH TABLES t1,t2,t3 FOR EXPORT; +# t1 yes on expecting NOT FOUND +NOT FOUND /foobarsecret/ in t1.ibd +# t2 ... on expecting NOT FOUND +NOT FOUND /tempsecret/ in t2.ibd +# t3 no on expecting FOUND +FOUND 12 /dummysecret/ in t3.ibd +# ibdata1 expecting NOT FOUND +NOT FOUND /foobarsecret/ in ibdata1 +UNLOCK TABLES; +# Now turn off encryption and wait for threads to decrypt everything +SET GLOBAL innodb_encrypt_tables = off; +# Wait max 10 min for key encryption threads to decrypt all spaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +NAME +innodb_system +mysql/innodb_index_stats +mysql/innodb_table_stats +mysql/transaction_registry +test/t2 +test/t3 +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +NAME +test/t1 +FLUSH TABLES t1,t2,t3 FOR EXPORT; +# t1 yes on expecting NOT FOUND +NOT FOUND /foobarsecret/ in t1.ibd +# t2 ... default expecting FOUND +FOUND 12 /tempsecret/ in t2.ibd +# t3 no on expecting FOUND +FOUND 12 /dummysecret/ in t3.ibd +# ibdata1 expecting NOT FOUND +NOT FOUND /foobarsecret/ in ibdata1 +UNLOCK TABLES; +# Now turn on encryption and wait for threads to encrypt all spaces +SET GLOBAL innodb_encrypt_tables = on; +# Wait max 10 min for key encryption threads to encrypt all spaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +NAME +test/t3 +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +NAME +innodb_system +mysql/innodb_index_stats +mysql/innodb_table_stats +mysql/transaction_registry +test/t1 +test/t2 +FLUSH TABLES t1,t2,t3 FOR EXPORT; +# t1 yes on expecting NOT FOUND +NOT FOUND /foobarsecret/ in t1.ibd +# t2 ... on expecting NOT FOUND +NOT FOUND /tempsecret/ in t2.ibd +# t3 no on expecting FOUND +FOUND 12 /dummysecret/ in t3.ibd +# ibdata1 expecting NOT FOUND +NOT FOUND /foobarsecret/ in ibdata1 +UNLOCK TABLES; +drop table t1, t2, t3; diff --git a/mysql-test/suite/encryption/r/encryption_force.result b/mysql-test/suite/encryption/r/encryption_force.result new file mode 100644 index 00000000..0526ea14 --- /dev/null +++ b/mysql-test/suite/encryption/r/encryption_force.result @@ -0,0 +1,60 @@ +select @@innodb_encrypt_tables; +@@innodb_encrypt_tables +FORCE +create table t1 (a int) engine=innodb encrypted=yes; +create table t2 (a int) engine=innodb encrypted=default; +create table t3 (a int) engine=innodb encrypted=no; +ERROR HY000: Can't create table `test`.`t3` (errno: 140 "Wrong create options") +create table t4 (a int) engine=innodb encrypted=yes partition by hash(a) partitions 2; +create table t5 (a int) engine=innodb encrypted=no partition by hash(a) partitions 2; +ERROR HY000: Can't create table `test`.`t5` (errno: 140 "Wrong create options") +set global innodb_encrypt_tables='ON'; +create table t3 (a int) engine=innodb encrypted=no; +set global innodb_encrypt_tables='FORCE'; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=no +show create table t4; +Table Create Table +t4 CREATE TABLE `t4` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes + PARTITION BY HASH (`a`) +PARTITIONS 2 +alter table t1 encrypted=no; +ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTED' +alter table t2 encrypted=yes; +alter table t3 encrypted=default; +alter table t4 encrypted=no; +ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTED' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +drop table t1; +drop table t2; +drop table t3; +drop table t4; diff --git a/mysql-test/suite/encryption/r/encryption_key_corruption.result b/mysql-test/suite/encryption/r/encryption_key_corruption.result new file mode 100644 index 00000000..055abd68 --- /dev/null +++ b/mysql-test/suite/encryption/r/encryption_key_corruption.result @@ -0,0 +1,13 @@ +call mtr.add_suppression("InnoDB: .*: Page 0 at offset 0 looks corrupted"); +call mtr.add_suppression("Index for table 'dst' is corrupt; try to repair it"); +call mtr.add_suppression("Page for tablespace .* is index page with id .* but that index is not found from configuration file"); +CREATE TABLE src (pk INT PRIMARY KEY, value INT) ENGINE=INNODB; +INSERT INTO src VALUES (1, 1), (2, 2), (3, 3); +FLUSH TABLES src FOR EXPORT; +UNLOCK TABLES; +DROP TABLE src; +CREATE TABLE dst (pk INT PRIMARY KEY, value INT) ENGINE=INNODB; +ALTER TABLE dst DISCARD TABLESPACE; +ALTER TABLE dst IMPORT TABLESPACE; +ERROR HY000: Index for table 'dst' is corrupt; try to repair it +DROP TABLE dst; diff --git a/mysql-test/suite/encryption/r/file_creation.result b/mysql-test/suite/encryption/r/file_creation.result new file mode 100644 index 00000000..22fe2711 --- /dev/null +++ b/mysql-test/suite/encryption/r/file_creation.result @@ -0,0 +1,26 @@ +SET GLOBAL innodb_encrypt_tables = ON; +SET GLOBAL innodb_encryption_threads = 1; +SET GLOBAL innodb_max_dirty_pages_pct = 99; +SHOW VARIABLES LIKE 'innodb_encrypt%'; +Variable_name Value +innodb_encrypt_log OFF +innodb_encrypt_tables ON +innodb_encrypt_temporary_tables OFF +innodb_encryption_rotate_key_age 1 +innodb_encryption_rotation_iops 100 +innodb_encryption_threads 1 +CREATE TABLE t1(f1 INT NOT NULL, f2 CHAR(255), f3 CHAR(255), +f4 CHAR(255), f5 CHAR(255))ENGINE=INNODB; +INSERT INTO t1 VALUES(1, "mysql", "mariadb", "batman", "superman"); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +# Wait max 10 min for key encryption threads to encrypt all spaces +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize note Table does not support optimize, doing recreate + analyze instead +test.t1 optimize status OK +ALTER TABLE t1 FORCE; +# Kill the server +DROP TABLE t1; diff --git a/mysql-test/suite/encryption/r/filekeys_emptyfile.result b/mysql-test/suite/encryption/r/filekeys_emptyfile.result new file mode 100644 index 00000000..19bca3c3 --- /dev/null +++ b/mysql-test/suite/encryption/r/filekeys_emptyfile.result @@ -0,0 +1,10 @@ +call mtr.add_suppression("System key id 1 is missing at"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 1 /System key id 1 is missing at/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +# Test checks if opening an empty filekeys does not crash the server. diff --git a/mysql-test/suite/encryption/r/filekeys_encfile.result b/mysql-test/suite/encryption/r/filekeys_encfile.result new file mode 100644 index 00000000..e53c7b87 --- /dev/null +++ b/mysql-test/suite/encryption/r/filekeys_encfile.result @@ -0,0 +1,38 @@ +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes `encryption_key_id`=1 +insert t1 values (12345, repeat('1234567890', 20)); +alter table t1 encryption_key_id=2; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes `encryption_key_id`=2 +alter table t1 encryption_key_id=3; +ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTION_KEY_ID' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes `encryption_key_id`=2 +alter table t1 encryption_key_id=33; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes `encryption_key_id`=33 +alter table t1 encryption_key_id=4; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes `encryption_key_id`=4 +drop table t1; diff --git a/mysql-test/suite/encryption/r/filekeys_encfile_bad.result b/mysql-test/suite/encryption/r/filekeys_encfile_bad.result new file mode 100644 index 00000000..59124f2b --- /dev/null +++ b/mysql-test/suite/encryption/r/filekeys_encfile_bad.result @@ -0,0 +1,9 @@ +call mtr.add_suppression("Cannot decrypt .*filekeys-data.enc. Wrong key"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 1 /Cannot decrypt .*filekeys-data.enc. Wrong key/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status diff --git a/mysql-test/suite/encryption/r/filekeys_encfile_badfile.result b/mysql-test/suite/encryption/r/filekeys_encfile_badfile.result new file mode 100644 index 00000000..7e244c2c --- /dev/null +++ b/mysql-test/suite/encryption/r/filekeys_encfile_badfile.result @@ -0,0 +1,9 @@ +call mtr.add_suppression("File 'bad' not found"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 1 /File 'bad' not found/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status diff --git a/mysql-test/suite/encryption/r/filekeys_encfile_file.result b/mysql-test/suite/encryption/r/filekeys_encfile_file.result new file mode 100644 index 00000000..e53c7b87 --- /dev/null +++ b/mysql-test/suite/encryption/r/filekeys_encfile_file.result @@ -0,0 +1,38 @@ +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes `encryption_key_id`=1 +insert t1 values (12345, repeat('1234567890', 20)); +alter table t1 encryption_key_id=2; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes `encryption_key_id`=2 +alter table t1 encryption_key_id=3; +ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTION_KEY_ID' +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes `encryption_key_id`=2 +alter table t1 encryption_key_id=33; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes `encryption_key_id`=33 +alter table t1 encryption_key_id=4; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes `encryption_key_id`=4 +drop table t1; diff --git a/mysql-test/suite/encryption/r/filekeys_encfile_no.result b/mysql-test/suite/encryption/r/filekeys_encfile_no.result new file mode 100644 index 00000000..59124f2b --- /dev/null +++ b/mysql-test/suite/encryption/r/filekeys_encfile_no.result @@ -0,0 +1,9 @@ +call mtr.add_suppression("Cannot decrypt .*filekeys-data.enc. Wrong key"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 1 /Cannot decrypt .*filekeys-data.enc. Wrong key/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status diff --git a/mysql-test/suite/encryption/r/filekeys_nofile.result b/mysql-test/suite/encryption/r/filekeys_nofile.result new file mode 100644 index 00000000..2caf258f --- /dev/null +++ b/mysql-test/suite/encryption/r/filekeys_nofile.result @@ -0,0 +1,9 @@ +call mtr.add_suppression("file-key-management-filename is not set"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 1 /file-key-management-filename is not set/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status diff --git a/mysql-test/suite/encryption/r/filekeys_secret_openssl_rand_128bits.result b/mysql-test/suite/encryption/r/filekeys_secret_openssl_rand_128bits.result new file mode 100644 index 00000000..880245c7 --- /dev/null +++ b/mysql-test/suite/encryption/r/filekeys_secret_openssl_rand_128bits.result @@ -0,0 +1,17 @@ +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes `encryption_key_id`=1 +insert t1 values (12345, repeat('1234567890', 20)); +alter table t1 encryption_key_id=2; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes `encryption_key_id`=2 +drop table t1; +# Test checks if opening an too large secret does not crash the server. diff --git a/mysql-test/suite/encryption/r/filekeys_secret_too_long.result b/mysql-test/suite/encryption/r/filekeys_secret_too_long.result new file mode 100644 index 00000000..bd11e8d9 --- /dev/null +++ b/mysql-test/suite/encryption/r/filekeys_secret_too_long.result @@ -0,0 +1,10 @@ +call mtr.add_suppression("the filekey is too long"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 1 /the filekey is too long/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +# Test checks if opening an too large secret does not crash the server. diff --git a/mysql-test/suite/encryption/r/filekeys_syntax.result b/mysql-test/suite/encryption/r/filekeys_syntax.result new file mode 100644 index 00000000..a7782bce --- /dev/null +++ b/mysql-test/suite/encryption/r/filekeys_syntax.result @@ -0,0 +1,149 @@ +call mtr.add_suppression("File '.*keys.txt' not found"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 1 /File '.*keys.txt' not found/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +install soname 'file_key_management'; +ERROR HY000: Invalid key id at MYSQL_TMP_DIR/keys.txt line 2, column 2 +call mtr.add_suppression("File '.*keys.txt' not found"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 1 /File '.*keys.txt' not found/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +call mtr.add_suppression("Invalid key id"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 1 /Invalid key id/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +install soname 'file_key_management'; +ERROR HY000: Invalid key id at MYSQL_TMP_DIR/keys.txt line 2, column 10 +call mtr.add_suppression("Invalid key id"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 2 /Invalid key id/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +call mtr.add_suppression("Invalid key id"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 2 /Invalid key id/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +install soname 'file_key_management'; +ERROR HY000: Invalid key at MYSQL_TMP_DIR/keys.txt line 2, column 47 +call mtr.add_suppression("Invalid key id"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 2 /Invalid key id/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +call mtr.add_suppression("Invalid key"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 3 /Invalid key/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +install soname 'file_key_management'; +ERROR HY000: Invalid key at MYSQL_TMP_DIR/keys.txt line 2, column 33 +call mtr.add_suppression("Invalid key"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 4 /Invalid key/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +call mtr.add_suppression("Invalid key"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 4 /Invalid key/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +install soname 'file_key_management'; +ERROR HY000: Syntax error at MYSQL_TMP_DIR/keys.txt line 2, column 2 +call mtr.add_suppression("Invalid key"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 4 /Invalid key/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +call mtr.add_suppression("Syntax error"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 1 /Syntax error/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +install soname 'file_key_management'; +ERROR HY000: Syntax error at MYSQL_TMP_DIR/keys.txt line 2, column 1 +call mtr.add_suppression("Syntax error"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 2 /Syntax error/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +call mtr.add_suppression("Syntax error"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 2 /Syntax error/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +install soname 'file_key_management'; +ERROR HY000: System key id 1 is missing at MYSQL_TMP_DIR/keys.txt line 1, column 1 +call mtr.add_suppression("Syntax error"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 2 /Syntax error/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +call mtr.add_suppression("System key id 1"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 1 /System key id 1/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status diff --git a/mysql-test/suite/encryption/r/filekeys_tooshort.result b/mysql-test/suite/encryption/r/filekeys_tooshort.result new file mode 100644 index 00000000..781bde6f --- /dev/null +++ b/mysql-test/suite/encryption/r/filekeys_tooshort.result @@ -0,0 +1,10 @@ +call mtr.add_suppression("Cannot decrypt .*tooshort.enc. Not encrypted"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 1 /Cannot decrypt .*tooshort.enc. Not encrypted/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status +# Test checks if opening an too short filekeys does not crash the server. diff --git a/mysql-test/suite/encryption/r/filekeys_unencfile.result b/mysql-test/suite/encryption/r/filekeys_unencfile.result new file mode 100644 index 00000000..31668348 --- /dev/null +++ b/mysql-test/suite/encryption/r/filekeys_unencfile.result @@ -0,0 +1,9 @@ +call mtr.add_suppression("Cannot decrypt .*keys.txt. Not encrypted"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +FOUND 1 /Cannot decrypt .*keys.txt. Not encrypted/ in mysqld.1.err +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +select plugin_status from information_schema.plugins +where plugin_name = 'file_key_management'; +plugin_status diff --git a/mysql-test/suite/encryption/r/import_4k.result b/mysql-test/suite/encryption/r/import_4k.result new file mode 100644 index 00000000..959e2498 --- /dev/null +++ b/mysql-test/suite/encryption/r/import_4k.result @@ -0,0 +1,10 @@ +set @save_limit = @@GLOBAL.innodb_limit_optimistic_insert_debug; +set global innodb_limit_optimistic_insert_debug=3; +create table t1 (a INT PRIMARY KEY) engine=InnoDB ENCRYPTED=YES; +insert into t1 select * from seq_1_to_6000; +flush table t1 for export; +unlock tables; +alter table t1 discard tablespace; +alter table t1 import tablespace; +set global innodb_limit_optimistic_insert_debug=@save_limit; +drop table t1; diff --git a/mysql-test/suite/encryption/r/innochecksum.result b/mysql-test/suite/encryption/r/innochecksum.result new file mode 100644 index 00000000..7c68164e --- /dev/null +++ b/mysql-test/suite/encryption/r/innochecksum.result @@ -0,0 +1,38 @@ +SET GLOBAL innodb_file_per_table = ON; +set global innodb_compression_algorithm = 1; +# Create and populate a tables +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB ENCRYPTED=YES ENCRYPTION_KEY_ID=4; +CREATE TABLE t2 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED ENCRYPTED=YES ENCRYPTION_KEY_ID=4; +CREATE TABLE t3 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED ENCRYPTED=NO; +CREATE TABLE t4 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB PAGE_COMPRESSED=1; +CREATE TABLE t5 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB PAGE_COMPRESSED=1 ENCRYPTED=YES ENCRYPTION_KEY_ID=4; +CREATE TABLE t6 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB; +# Run innochecksum on t1, check -S does not cause crash for encrypted file +# Run innochecksum on t2 +# Run innochecksum on t3 +# Run innochecksum on t4 +# Run innochecksum on t4 +# Run innochecksum on t5 +# Run innochecksum on t6 +# Backup tables before corrupting +# Corrupt FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION +# Run innochecksum on t2 +# Run innochecksum on t3 +# no encryption corrupting the field should not have effect +# Run innochecksum on t6 +# In new checksum format, checksum calculated for whole page. +# So It should affected. +# Restore the original tables +# Corrupt FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+4 (post encryption checksum) +# Run innochecksum on t2 +# Run innochecksum on t3 +# Run innochecksum on t6 +# Space ID mismatch +# Restore the original tables +# Corrupt FIL_DATA+10 (data) +# Run innochecksum on t2 +# Run innochecksum on t3 +# Run innochecksum on t6 +# Restore the original tables +# restart +DROP TABLE t1, t2, t3, t4, t5, t6; diff --git a/mysql-test/suite/encryption/r/innodb-bad-key-change.result b/mysql-test/suite/encryption/r/innodb-bad-key-change.result new file mode 100644 index 00000000..e2034f14 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-bad-key-change.result @@ -0,0 +1,75 @@ +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` has an unreadable root page"); +call mtr.add_suppression("Table .*t[12].* is corrupted"); +call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[12]\\.ibd' cannot be decrypted; key_version=1"); +call mtr.add_suppression("failed to read \\[page id: space=[1-9][0-9]*, page number=[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("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 +# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt +SET GLOBAL innodb_file_per_table = ON; +CREATE TABLE t1 (c VARCHAR(8)) ENGINE=InnoDB ENCRYPTED=YES ENCRYPTION_KEY_ID=2; +INSERT INTO t1 VALUES ('foobar'); +ALTER TABLE t1 ADD COLUMN c2 INT; +INSERT INTO t1 VALUES ('foobar',2); +SELECT * FROM t1; +c c2 +foobar NULL +foobar 2 +TRUNCATE TABLE t1; +SELECT * FROM t1; +c c2 +INSERT INTO t1 VALUES ('foobar',1); +INSERT INTO t1 VALUES ('foobar',2); +FLUSH TABLE WITH READ LOCK; +SELECT * FROM t1; +c c2 +foobar 1 +foobar 2 + +# Restart server with keysbad3.txt +# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keysbad3.txt +SELECT * FROM t1; +ERROR 42S02: Table 'test.t1' doesn't exist in engine +# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keysbad3.txt +DROP TABLE t1; +# Start server with keys3.txt +# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys3.txt +SET GLOBAL innodb_default_encryption_key_id=5; +CREATE TABLE t2 (c VARCHAR(8), id int not null primary key, b int, key(b)) ENGINE=InnoDB ENCRYPTED=YES; +INSERT INTO t2 VALUES ('foobar',1,2); + +# Restart server with keys2.txt +# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt +SELECT * FROM t2; +ERROR 42S02: Table 'test.t2' doesn't exist in engine +SELECT * FROM t2 where id = 1; +ERROR HY000: Table test/t2 is corrupted. Please drop the table and recreate. +SELECT * FROM t2 where b = 1; +ERROR HY000: Table test/t2 is corrupted. Please drop the table and recreate. +INSERT INTO t2 VALUES ('tmp',3,3); +ERROR HY000: Table test/t2 is corrupted. Please drop the table and recreate. +DELETE FROM t2 where b = 3; +ERROR HY000: Table test/t2 is corrupted. Please drop the table and recreate. +DELETE FROM t2 where id = 3; +ERROR HY000: Table test/t2 is corrupted. Please drop the table and recreate. +UPDATE t2 set b = b +1; +ERROR HY000: Table test/t2 is corrupted. Please drop the table and recreate. +OPTIMIZE TABLE t2; +Table Op Msg_type Msg_text +test.t2 optimize Error Table test/t2 is corrupted. Please drop the table and recreate. +test.t2 optimize error Corrupt +ALTER TABLE t2 ADD COLUMN d INT; +ERROR HY000: Table test/t2 is corrupted. Please drop the table and recreate. +ANALYZE TABLE t2; +Table Op Msg_type Msg_text +test.t2 analyze Error Table test/t2 is corrupted. Please drop the table and recreate. +test.t2 analyze error Corrupt +TRUNCATE TABLE t2; +ERROR HY000: Table test/t2 is corrupted. Please drop the table and recreate. +DROP TABLE t2; + +# Start server with keys2.txt +# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt diff --git a/mysql-test/suite/encryption/r/innodb-bad-key-change2.result b/mysql-test/suite/encryption/r/innodb-bad-key-change2.result new file mode 100644 index 00000000..3cda2bd5 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-bad-key-change2.result @@ -0,0 +1,68 @@ +call mtr.add_suppression("InnoDB: Table `test`\\.`t1` (has an unreadable root page|does not exist.*is trying to rename)"); +call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t1(new)?\\.ibd' cannot be decrypted; key_version=1"); +call mtr.add_suppression("InnoDB: Recovery failed to read page"); +call mtr.add_suppression("Couldn't load plugins from 'file_key_management"); +call mtr.add_suppression("InnoDB: Tablespace for table \`test\`.\`t1\` is set as discarded\\."); +call mtr.add_suppression("Table .*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: 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 --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt +SET GLOBAL innodb_file_per_table = ON; +CREATE TABLE t1 (pk INT PRIMARY KEY, f VARCHAR(8)) ENGINE=InnoDB +ENCRYPTED=YES ENCRYPTION_KEY_ID=4; +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +# restart: --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys3.txt +SELECT * FROM t1; +ERROR 42S02: Table 'test.t1' doesn't exist in engine +SHOW WARNINGS; +Level Code Message +Error 1932 Table 'test.t1' doesn't exist in engine +ALTER TABLE t1 ENGINE=InnoDB; +ERROR HY000: Table test/t1 is corrupted. Please drop the table and recreate. +SHOW WARNINGS; +Level Code Message +Error 1877 Table test/t1 is corrupted. Please drop the table and recreate. +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize Error Table test/t1 is corrupted. Please drop the table and recreate. +test.t1 optimize error Corrupt +SHOW WARNINGS; +Level Code Message +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check Error Table test/t1 is corrupted. Please drop the table and recreate. +test.t1 check error Corrupt +SHOW WARNINGS; +Level Code Message +# restart: --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt +FLUSH TABLES t1 FOR EXPORT; +backup: t1 +UNLOCK TABLES; +# restart: --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys3.txt +ALTER TABLE t1 DISCARD TABLESPACE; +ERROR 42S02: Table 'test.t1' doesn't exist in engine +DROP TABLE t1; +CREATE TABLE t1 (pk INT PRIMARY KEY, f VARCHAR(8)) ENGINE=InnoDB +ENCRYPTED=YES ENCRYPTION_KEY_ID=4; +ALTER TABLE t1 DISCARD TABLESPACE; +restore: t1 .ibd and .cfg files +# restart: --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt +ALTER TABLE t1 DISCARD TABLESPACE; +Warnings: +Warning 1812 Tablespace is missing for table 'test/t1' +restore: t1 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL, + `f` varchar(8) DEFAULT NULL, + PRIMARY KEY (`pk`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `ENCRYPTED`=YES `ENCRYPTION_KEY_ID`=4 +# restart: --innodb-encrypt-tables --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys3.txt +RENAME TABLE t1 TO t1new; +ERROR HY000: Error on rename of './test/t1' to './test/t1new' (errno: 155 "The table does not exist in the storage engine") +ALTER TABLE t1 RENAME TO t1new; +ERROR HY000: Table test/t1 is corrupted. Please drop the table and recreate. +DROP TABLE t1; diff --git a/mysql-test/suite/encryption/r/innodb-bad-key-change3.result b/mysql-test/suite/encryption/r/innodb-bad-key-change3.result new file mode 100644 index 00000000..832cdda1 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-bad-key-change3.result @@ -0,0 +1,40 @@ +call mtr.add_suppression("InnoDB: Tablespace for table .* is set as discarded."); +call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* because the .ibd file is missing. Please refer to .* for how to resolve the issue."); +set global innodb_compression_algorithm = 1; +CREATE TABLE t1 (pk INT PRIMARY KEY, f VARCHAR(255)) ENGINE=InnoDB PAGE_COMPRESSED=1 ENCRYPTED=YES ENCRYPTION_KEY_ID=4; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL, + `f` varchar(255) DEFAULT NULL, + PRIMARY KEY (`pk`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `PAGE_COMPRESSED`=1 `ENCRYPTED`=YES `ENCRYPTION_KEY_ID`=4 +INSERT INTO t1 VALUES (1,'foobar'),(2,'barfoo'); +FLUSH TABLE t1 FOR EXPORT; +# List before copying files +db.opt +t1.cfg +t1.frm +t1.ibd +backup: t1 +UNLOCK TABLES; +ALTER TABLE t1 DISCARD TABLESPACE; +restore: t1 .ibd and .cfg files +# restart +ALTER TABLE t1 IMPORT TABLESPACE; +ERROR HY000: Got error 192 'Table encrypted but decryption failed. This could be because correct encryption management plugin is not loaded, used encryption key is not available or encryption method does not match.' from InnoDB +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL, + `f` varchar(255) DEFAULT NULL, + PRIMARY KEY (`pk`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `PAGE_COMPRESSED`=1 `ENCRYPTED`=YES `ENCRYPTION_KEY_ID`=4 +SELECT * FROM t1; +ERROR HY000: Tablespace has been discarded for table `t1` +# Tablespaces should be still encrypted +# t1 yes on expecting NOT FOUND +NOT FOUND /foobar/ in t1.ibd +DROP TABLE t1; diff --git a/mysql-test/suite/encryption/r/innodb-bad-key-change4.result b/mysql-test/suite/encryption/r/innodb-bad-key-change4.result new file mode 100644 index 00000000..e808d50b --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-bad-key-change4.result @@ -0,0 +1,26 @@ +call mtr.add_suppression("InnoDB: Table `test`\\.`t1` (has an unreadable root page)"); +call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t1\\.ibd' cannot be decrypted; key_version=1"); +call mtr.add_suppression("InnoDB: Recovery failed to read page"); +call mtr.add_suppression("Couldn't load plugins from 'file_key_management"); +call mtr.add_suppression("Table .*t1.* is corrupted"); +call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot decrypt \\[page id: space="); +# restart: --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt +SET GLOBAL innodb_file_per_table = ON; +CREATE TABLE t1 (pk INT PRIMARY KEY, f VARCHAR(8)) ENGINE=InnoDB +ENCRYPTED=YES ENCRYPTION_KEY_ID=4; +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +# restart: --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys3.txt +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize Error Table 'test.t1' doesn't exist in engine +test.t1 optimize status Operation failed +SHOW WARNINGS; +Level Code Message +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check Error Table test/t1 is corrupted. Please drop the table and recreate. +test.t1 check error Corrupt +SHOW WARNINGS; +Level Code Message +# restart: --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt +DROP TABLE t1; diff --git a/mysql-test/suite/encryption/r/innodb-checksum-algorithm,32k.rdiff b/mysql-test/suite/encryption/r/innodb-checksum-algorithm,32k.rdiff new file mode 100644 index 00000000..d8407ce5 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-checksum-algorithm,32k.rdiff @@ -0,0 +1,14 @@ +--- suite/encryption/r/innodb-checksum-algorithm.result ++++ suite/encryption/r/innodb-checksum-algorithm.result +@@ -9,9 +9,9 @@ + SET GLOBAL innodb_checksum_algorithm = crc32; + SET GLOBAL innodb_default_encryption_key_id=4; + create table tce(a serial, b blob, index(b(10))) engine=innodb +-ROW_FORMAT=COMPRESSED encrypted=yes; ++ROW_FORMAT=DYNAMIC encrypted=yes; + create table tc(a serial, b blob, index(b(10))) engine=innodb +-ROW_FORMAT=COMPRESSED encrypted=no; ++ROW_FORMAT=DYNAMIC encrypted=no; + Warnings: + Warning 140 InnoDB: ENCRYPTED=NO implies ENCRYPTION_KEY_ID=1 + create table te(a serial, b blob, index(b(10))) engine=innodb diff --git a/mysql-test/suite/encryption/r/innodb-checksum-algorithm,64k.rdiff b/mysql-test/suite/encryption/r/innodb-checksum-algorithm,64k.rdiff new file mode 100644 index 00000000..d8407ce5 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-checksum-algorithm,64k.rdiff @@ -0,0 +1,14 @@ +--- suite/encryption/r/innodb-checksum-algorithm.result ++++ suite/encryption/r/innodb-checksum-algorithm.result +@@ -9,9 +9,9 @@ + SET GLOBAL innodb_checksum_algorithm = crc32; + SET GLOBAL innodb_default_encryption_key_id=4; + create table tce(a serial, b blob, index(b(10))) engine=innodb +-ROW_FORMAT=COMPRESSED encrypted=yes; ++ROW_FORMAT=DYNAMIC encrypted=yes; + create table tc(a serial, b blob, index(b(10))) engine=innodb +-ROW_FORMAT=COMPRESSED encrypted=no; ++ROW_FORMAT=DYNAMIC encrypted=no; + Warnings: + Warning 140 InnoDB: ENCRYPTED=NO implies ENCRYPTION_KEY_ID=1 + create table te(a serial, b blob, index(b(10))) engine=innodb diff --git a/mysql-test/suite/encryption/r/innodb-checksum-algorithm.result b/mysql-test/suite/encryption/r/innodb-checksum-algorithm.result new file mode 100644 index 00000000..7b97eb6b --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-checksum-algorithm.result @@ -0,0 +1,98 @@ +SET @saved_file_per_table = @@global.innodb_file_per_table; +SET @saved_encrypt_tables = @@global.innodb_encrypt_tables; +SET @saved_encryption_threads = @@global.innodb_encryption_threads; +SET @saved_encryption_key_id = @@global.innodb_default_encryption_key_id; +SET GLOBAL innodb_file_per_table = ON; +SET GLOBAL innodb_encrypt_tables = ON; +SET GLOBAL innodb_encryption_threads = 4; +SET GLOBAL innodb_default_encryption_key_id=4; +create table tce(a serial, b blob, index(b(10))) engine=innodb +ROW_FORMAT=COMPRESSED encrypted=yes; +create table tc(a serial, b blob, index(b(10))) engine=innodb +ROW_FORMAT=COMPRESSED encrypted=no; +Warnings: +Warning 140 InnoDB: ENCRYPTED=NO implies ENCRYPTION_KEY_ID=1 +create table te(a serial, b blob, index(b(10))) engine=innodb +encrypted=yes; +create table t(a serial, b blob, index(b(10))) engine=innodb +encrypted=no; +Warnings: +Warning 140 InnoDB: ENCRYPTED=NO implies ENCRYPTION_KEY_ID=1 +create table tpe(a serial, b blob, index(b(10))) engine=innodb +page_compressed=yes encrypted=yes; +create table tp(a serial, b blob, index(b(10))) engine=innodb +page_compressed=yes encrypted=no; +Warnings: +Warning 140 InnoDB: ENCRYPTED=NO implies ENCRYPTION_KEY_ID=1 +begin; +insert into tce(b) values (repeat('secret',20)); +insert into tc(b) values (repeat('secret',20)); +insert into te(b) values (repeat('secret',20)); +insert into t(b) values (repeat('secret',20)); +insert into tpe(b) values (repeat('secret',20)); +insert into tp(b) values (repeat('secret',20)); +commit; +FLUSH TABLES tce, tc, te, t, tpe, tp FOR EXPORT; +backup: tce +backup: tc +backup: te +backup: t +backup: tpe +backup: tp +db.opt +t.cfg +t.frm +t.ibd +tc.cfg +tc.frm +tc.ibd +tce.cfg +tce.frm +tce.ibd +te.cfg +te.frm +te.ibd +tp.cfg +tp.frm +tp.ibd +tpe.cfg +tpe.frm +tpe.ibd +UNLOCK TABLES; +ALTER TABLE tce DISCARD TABLESPACE; +ALTER TABLE tc DISCARD TABLESPACE; +ALTER TABLE te DISCARD TABLESPACE; +ALTER TABLE t DISCARD TABLESPACE; +ALTER TABLE tpe DISCARD TABLESPACE; +ALTER TABLE tp DISCARD TABLESPACE; +restore: tce .ibd and .cfg files +restore: tc .ibd and .cfg files +restore: te .ibd and .cfg files +restore: t .ibd and .cfg files +restore: tpe .ibd and .cfg files +restore: tp .ibd and .cfg files +ALTER TABLE tce IMPORT TABLESPACE; +update tce set b=substr(b,1); +ALTER TABLE tc IMPORT TABLESPACE; +update tc set b=substr(b,1); +ALTER TABLE te IMPORT TABLESPACE; +update te set b=substr(b,1); +ALTER TABLE t IMPORT TABLESPACE; +update t set b=substr(b,1); +ALTER TABLE tpe IMPORT TABLESPACE; +update tpe set b=substr(b,1); +ALTER TABLE tp IMPORT TABLESPACE; +update tp set b=substr(b,1); +CHECK TABLE tce, tc, te, t, tpe, tp; +Table Op Msg_type Msg_text +test.tce check status OK +test.tc check status OK +test.te check status OK +test.t check status OK +test.tpe check status OK +test.tp check status OK +DROP TABLE tce, tc, te, t, tpe, tp; +SET GLOBAL innodb_file_per_table = @saved_file_per_table; +SET GLOBAL innodb_encrypt_tables = @saved_encrypt_tables; +SET GLOBAL innodb_encryption_threads = @saved_encryption_threads; +SET GLOBAL innodb_default_encryption_key_id = @saved_encryption_key_id; diff --git a/mysql-test/suite/encryption/r/innodb-compressed-blob.result b/mysql-test/suite/encryption/r/innodb-compressed-blob.result new file mode 100644 index 00000000..0dc873b9 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-compressed-blob.result @@ -0,0 +1,28 @@ +call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted; key_version=1"); +call mtr.add_suppression("InnoDB: Recovery failed to read page"); +call mtr.add_suppression("InnoDB: Unable to decompress ..test.t[1-3]\\.ibd\\[page id: space=[1-9][0-9]*, page number=[0-9]+\\]"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` is corrupted"); +# Restart mysqld --file-key-management-filename=keys2.txt +# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt +SET GLOBAL innodb_file_per_table = ON; +set GLOBAL innodb_default_encryption_key_id=4; +create table t1(a int not null primary key, b blob, index(b(10))) engine=innodb row_format=compressed; +create table t2(a int not null primary key, b blob, index(b(10))) engine=innodb row_format=compressed encrypted=yes; +create table t3(a int not null primary key, b blob, index(b(10))) engine=innodb row_format=compressed encrypted=no; +Warnings: +Warning 140 InnoDB: ENCRYPTED=NO implies ENCRYPTION_KEY_ID=1 +insert into t1 values (1, repeat('secret',6000)); +insert into t2 values (1, repeat('secret',6000)); +insert into t3 values (1, repeat('secret',6000)); +# Restart mysqld --file-key-management-filename=keys3.txt +# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys3.txt +select count(*) from t1 FORCE INDEX (b) where b like 'secret%'; +ERROR 42S02: Table 'test.t1' doesn't exist in engine +select count(*) from t2 FORCE INDEX (b) where b like 'secret%'; +ERROR 42S02: Table 'test.t2' doesn't exist in engine +select count(*) from t3 FORCE INDEX (b) where b like 'secret%'; +count(*) +1 +# Restart mysqld --file-key-management-filename=keys2.txt +# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt +drop table t1,t2,t3; diff --git a/mysql-test/suite/encryption/r/innodb-discard-import-change.result b/mysql-test/suite/encryption/r/innodb-discard-import-change.result new file mode 100644 index 00000000..eb0ac13d --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-discard-import-change.result @@ -0,0 +1,104 @@ +call mtr.add_suppression("InnoDB: Table .* tablespace is set as discarded"); +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 +db.opt +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=504 DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `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 289 /verysecretmessage/ in t5.ibd +DROP TABLE t1,t2,t3,t4,t5,t6; diff --git a/mysql-test/suite/encryption/r/innodb-discard-import.result b/mysql-test/suite/encryption/r/innodb-discard-import.result new file mode 100644 index 00000000..9edd7eda --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-discard-import.result @@ -0,0 +1,136 @@ +call mtr.add_suppression("InnoDB: Tablespace for table .* is set as discarded."); +call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* because the .ibd file is missing. Please refer to .* for how to resolve the issue."); +SET GLOBAL innodb_compression_algorithm = 1; +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=4; +show warnings; +Level Code Message +create table t2(c1 bigint not null, b char(200)) engine=innodb page_compressed=1 encrypted=yes encryption_key_id=4; +show warnings; +Level Code Message +create table t3(c1 bigint not null, b char(200)) engine=innodb row_format=compressed encrypted=yes encryption_key_id=4; +show warnings; +Level Code Message +create table t4(c1 bigint not null, b char(200)) engine=innodb page_compressed=1; +show warnings; +Level Code Message +create procedure innodb_insert_proc (repeat_count int) +begin +declare current_num int; +set current_num = 0; +while current_num < repeat_count do +insert into t1 values(current_num, repeat('foobar',30)); +insert into t2 values(current_num, repeat('barfoo',30)); +insert into t3 values(current_num, repeat('tmpres',30)); +insert into t4 values(current_num, repeat('mysql',30)); +set current_num = current_num + 1; +end while; +end// +commit; +set autocommit=0; +call innodb_insert_proc(2000); +commit; +set autocommit=1; +select count(*) from t1; +count(*) +2000 +select count(*) from t2; +count(*) +2000 +select count(*) from t3; +count(*) +2000 +select count(*) from t4; +count(*) +2000 +FLUSH TABLE t1,t2,t3,t4 FOR EXPORT; +# List before copying files +db.opt +t1.cfg +t1.frm +t1.ibd +t2.cfg +t2.frm +t2.ibd +t3.cfg +t3.frm +t3.ibd +t4.cfg +t4.frm +t4.ibd +backup: t1 +backup: t2 +backup: t3 +backup: t4 +db.opt +t1.cfg +t1.frm +t1.ibd +t2.cfg +t2.frm +t2.ibd +t3.cfg +t3.frm +t3.ibd +t4.cfg +t4.frm +t4.ibd +UNLOCK TABLES; +ALTER TABLE t1 DISCARD TABLESPACE; +ALTER TABLE t2 DISCARD TABLESPACE; +ALTER TABLE t3 DISCARD TABLESPACE; +ALTER TABLE t4 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 +ALTER TABLE t1 IMPORT TABLESPACE; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes `encryption_key_id`=4 +SELECT COUNT(*) FROM t1; +COUNT(*) +2000 +ALTER TABLE t2 IMPORT TABLESPACE; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `page_compressed`=1 `encrypted`=yes `encryption_key_id`=4 +SELECT COUNT(*) FROM t2; +COUNT(*) +2000 +ALTER TABLE t3 IMPORT TABLESPACE; +SHOW CREATE TABLE t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPRESSED `encrypted`=yes `encryption_key_id`=4 +SELECT COUNT(*) FROM t3; +COUNT(*) +2000 +ALTER TABLE t4 IMPORT TABLESPACE; +SHOW CREATE TABLE t4; +Table Create Table +t4 CREATE TABLE `t4` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `page_compressed`=1 +SELECT COUNT(*) FROM t4; +COUNT(*) +2000 +# tables should be still either encrypted and/or compressed +# t1 yes on expecting NOT FOUND +NOT FOUND /foobar/ in t1.ibd +# t2 yes on expecting NOT FOUND +NOT FOUND /barfoo/ in t2.ibd +# t3 yes on expecting NOT FOUND +NOT FOUND /tmpres/ in t3.ibd +# t4 yes on expecting NOT FOUND +NOT FOUND /mysql/ in t4.ibd +DROP PROCEDURE innodb_insert_proc; +DROP TABLE t1,t2,t3,t4; diff --git a/mysql-test/suite/encryption/r/innodb-encr-threads.result b/mysql-test/suite/encryption/r/innodb-encr-threads.result new file mode 100644 index 00000000..0178635a --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-encr-threads.result @@ -0,0 +1,7 @@ +create table t1 (i int) engine=innodb; +set global innodb_encryption_threads = 1; +set global innodb_encryption_rotate_key_age = 2; +insert t1 values (1); +drop table t1; +set global innodb_encryption_threads = 0; +set global innodb_encryption_rotate_key_age = 1; diff --git a/mysql-test/suite/encryption/r/innodb-encryption-alter.result b/mysql-test/suite/encryption/r/innodb-encryption-alter.result new file mode 100644 index 00000000..00b30de1 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-encryption-alter.result @@ -0,0 +1,112 @@ +SET GLOBAL innodb_encrypt_tables = ON; +SET GLOBAL innodb_encryption_threads = 4; +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=NO ENCRYPTION_KEY_ID=4; +Warnings: +Warning 140 InnoDB: ENCRYPTED=NO implies ENCRYPTION_KEY_ID=1 +DROP TABLE t1; +set @save_global = @@GLOBAL.innodb_default_encryption_key_id; +set innodb_default_encryption_key_id = 99; +Warnings: +Warning 1210 innodb_default_encryption_key=99 is not available +set global innodb_default_encryption_key_id = 99; +Warnings: +Warning 1210 innodb_default_encryption_key=99 is not available +set global innodb_default_encryption_key_id = @save_global; +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +SHOW WARNINGS; +Level Code Message +Warning 140 InnoDB: ENCRYPTION_KEY_ID 99 not available +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") +Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=YES; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +SHOW WARNINGS; +Level Code Message +Warning 140 InnoDB: ENCRYPTION_KEY_ID 99 not available +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") +Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB +set innodb_default_encryption_key_id = 4; +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=YES; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL AUTO_INCREMENT, + `c` varchar(256) DEFAULT NULL, + PRIMARY KEY (`pk`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `ENCRYPTED`=YES `ENCRYPTION_KEY_ID`=4 +DROP TABLE t1; +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL AUTO_INCREMENT, + `c` varchar(256) DEFAULT NULL, + PRIMARY KEY (`pk`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `ENCRYPTION_KEY_ID`=4 +CREATE TABLE t2 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=NO ENCRYPTION_KEY_ID=1; +ALTER TABLE t1 ENCRYPTION_KEY_ID=99; +ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTION_KEY_ID' +SHOW WARNINGS; +Level Code Message +Warning 140 InnoDB: ENCRYPTION_KEY_ID 99 not available +Error 1478 Table storage engine 'InnoDB' does not support the create option 'ENCRYPTION_KEY_ID' +set innodb_default_encryption_key_id = 1; +drop table t1,t2; +SET GLOBAL innodb_encrypt_tables=OFF; +CREATE TABLE t1 (a int not null primary key) engine=innodb; +ALTER TABLE t1 ENCRYPTION_KEY_ID=4; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `ENCRYPTION_KEY_ID`=4 +DROP TABLE t1; +CREATE TABLE t2 (a int not null primary key) engine=innodb; +ALTER TABLE t2 ENCRYPTION_KEY_ID=4, ALGORITHM=COPY; +SHOW WARNINGS; +Level Code Message +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) NOT NULL, + PRIMARY KEY (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `ENCRYPTION_KEY_ID`=4 +CREATE TABLE t3 (a int not null primary key) engine=innodb ENCRYPTION_KEY_ID=4; +DROP TABLE t3; +SET GLOBAL innodb_encrypt_tables='FORCE'; +CREATE TABLE t1 (a int primary key) engine=innodb encrypted=no; +ERROR HY000: Can't create table `test`.`t1` (errno: 140 "Wrong create options") +SHOW WARNINGS; +Level Code Message +Warning 140 InnoDB: ENCRYPTED=NO cannot be used with innodb_encrypt_tables=FORCE +Error 1005 Can't create table `test`.`t1` (errno: 140 "Wrong create options") +Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB +FLUSH TABLES; +create table t1(f1 int not null, f2 int not null)engine=innodb encrypted=yes; +insert into t1 values(1, 2), (2, 3), (4, 5), (5, 6), (7, 8); +insert into t1 select * from t1; +BEGIN; +INSERT INTO t2 VALUES (1); +connect con1, localhost, root; +SET DEBUG_SYNC = 'row_log_table_apply2_before SIGNAL done WAIT_FOR ever'; +alter table t1 force; +connection default; +SET DEBUG_SYNC = 'now WAIT_FOR done'; +SET GLOBAL innodb_flush_log_at_trx_commit=1; +COMMIT; +disconnect con1; +select * from t1; +f1 f2 +1 2 +2 3 +4 5 +5 6 +7 8 +1 2 +2 3 +4 5 +5 6 +7 8 +drop table t1,t2; diff --git a/mysql-test/suite/encryption/r/innodb-encryption-disable.result b/mysql-test/suite/encryption/r/innodb-encryption-disable.result new file mode 100644 index 00000000..179bc550 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-encryption-disable.result @@ -0,0 +1,32 @@ +call mtr.add_suppression("InnoDB: Table `test`\\.`t[15]` (has an unreadable root page|is corrupted)"); +call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[15]\\.ibd' cannot be decrypted\\."); +call mtr.add_suppression("InnoDB: Recovery failed to read page"); +call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t[15].ibd looks corrupted; key_version=1"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t[15]` is corrupted"); +call mtr.add_suppression("Couldn't load plugins from 'file_key_management"); +# restart: --innodb-encrypt-tables=ON --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt +create table t5 ( +`intcol1` int(32) DEFAULT NULL, +`intcol2` int(32) DEFAULT NULL, +`charcol1` varchar(128) DEFAULT NULL, +`charcol2` varchar(128) DEFAULT NULL, +`charcol3` varchar(128) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; +insert into t5 values (1,2,'maria','db','encryption'); +CREATE TABLE `t1` ( +`intcol1` int(32) DEFAULT NULL, +`intcol2` int(32) DEFAULT NULL, +`charcol1` varchar(128) DEFAULT NULL, +`charcol2` varchar(128) DEFAULT NULL, +`charcol3` varchar(128) DEFAULT NULL +) ENGINE=InnoDB; +insert into t1 values (1,2,'maria','db','encryption'); +alter table t1 encrypted='yes' `encryption_key_id`=1; +# restart: --innodb-encrypt-tables=OFF +select * from t1; +ERROR 42S02: Table 'test.t1' doesn't exist in engine +select * from t5; +ERROR 42S02: Table 'test.t5' doesn't exist in engine +# restart: --innodb-encrypt-tables=ON --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt +drop table t1; +drop table t5; diff --git a/mysql-test/suite/encryption/r/innodb-force-corrupt.result b/mysql-test/suite/encryption/r/innodb-force-corrupt.result new file mode 100644 index 00000000..ad75df95 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-force-corrupt.result @@ -0,0 +1,28 @@ +call mtr.add_suppression("InnoDB: Table `test`\\.`t[13]` (has an unreadable root page|is corrupted)"); +call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=\\d+, page number=[36]\\] in file .*test.t[123]\\.ibd looks corrupted; key_version="); +call mtr.add_suppression("\\[ERROR\\] InnoDB: We detected index corruption in an InnoDB type table"); +call mtr.add_suppression("\\[ERROR\\] (mysqld|mariadbd).*: Index for table 't2' is corrupt; try to repair it"); +SET GLOBAL innodb_file_per_table = ON; +set global innodb_compression_algorithm = 1; +# Create and populate tables to be corrupted +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT,c char(200)) ENGINE=InnoDB encrypted=yes; +CREATE TABLE t2 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT,c char(200)) ENGINE=InnoDB row_format=compressed encrypted=yes; +CREATE TABLE t3 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT, c char(200)) ENGINE=InnoDB page_compressed=yes encrypted=yes; +BEGIN; +INSERT INTO t1 (b,c) VALUES ('corrupt me','secret'); +INSERT INTO t1 (b,c) VALUES ('corrupt me','moresecretmoresecret'); +INSERT INTO t2 select * from t1; +INSERT INTO t3 select * from t1; +COMMIT; +# Backup tables before corrupting +# Corrupt tables +# restart +SELECT * FROM t1; +ERROR 42S02: Table 'test.t1' doesn't exist in engine +SELECT * FROM t2; +Got one of the listed errors +SELECT * FROM t3; +ERROR 42S02: Table 'test.t3' doesn't exist in engine +# Restore the original tables +# restart +DROP TABLE t1,t2,t3; diff --git a/mysql-test/suite/encryption/r/innodb-key-rotation-disable.result b/mysql-test/suite/encryption/r/innodb-key-rotation-disable.result new file mode 100644 index 00000000..4e816bea --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-key-rotation-disable.result @@ -0,0 +1,57 @@ +SET GLOBAL innodb_file_per_table = ON; +set global innodb_compression_algorithm = 1; +create database enctests; +use enctests; +create table t1(a int not null primary key, b char(200)) engine=innodb; +create table t2(a int not null primary key, b char(200)) engine=innodb row_format=compressed; +create table t3(a int not null primary key, b char(200)) engine=innodb page_compressed=yes; +create table t4(a int not null primary key, b char(200)) engine=innodb encrypted=yes; +create table t5(a int not null primary key, b char(200)) engine=innodb encrypted=yes row_format=compressed; +create table t6(a int not null primary key, b char(200)) engine=innodb encrypted=yes page_compressed=yes; +create table t7(a int not null primary key, b char(200)) engine=innodb encrypted=no; +create table t8(a int not null primary key, b char(200)) engine=innodb encrypted=no row_format=compressed; +create table t9(a int not null primary key, b char(200)) engine=innodb encrypted=no page_compressed=yes; +insert into t1 values (1, 'secredmessage'); +insert into t2 values (1, 'secredmessage'); +insert into t3 values (1, 'secredmessagecompressedaaaaaaaaabbbbbbbbbbbbbbccccccccccccccc'); +insert into t4 values (1, 'secredmessage'); +insert into t5 values (1, 'secredmessage'); +insert into t6 values (1, 'secredmessagecompressedaaaaaaaaabbbbbbbbbbbbbbccccccccccccccc'); +insert into t7 values (1, 'publicmessage'); +insert into t8 values (1, 'publicmessage'); +insert into t9 values (1, 'pugliccompressedaaaaaaaaabbbbbbbbbbbbbbccccccccccccccc'); +# should list tables t1-t6 +SELECT NAME,ENCRYPTION_SCHEME,CURRENT_KEY_ID FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'enctests%'; +NAME ENCRYPTION_SCHEME CURRENT_KEY_ID +enctests/t1 1 1 +enctests/t2 1 1 +enctests/t3 1 1 +enctests/t4 1 1 +enctests/t5 1 1 +enctests/t6 1 1 +# should list tables t7-t9 +SELECT NAME,ENCRYPTION_SCHEME,CURRENT_KEY_ID FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 and NAME LIKE 'enctests%'; +NAME ENCRYPTION_SCHEME CURRENT_KEY_ID +enctests/t7 0 1 +enctests/t8 0 1 +enctests/t9 0 1 +# t1 default on expecting NOT FOUND +NOT FOUND /secred/ in t1.ibd +# t2 default on expecting NOT FOUND +NOT FOUND /secred/ in t2.ibd +# t3 default on expecting NOT FOUND +NOT FOUND /secred/ in t3.ibd +# t4 on expecting NOT FOUND +NOT FOUND /secred/ in t4.ibd +# t5 on expecting NOT FOUND +NOT FOUND /secred/ in t5.ibd +# t6 on expecting NOT FOUND +NOT FOUND /secred/ in t6.ibd +# t7 off expecting FOUND +FOUND 1 /public/ in t7.ibd +# t8 row compressed expecting NOT FOUND +FOUND 1 /public/ in t8.ibd +# t9 page compressed expecting NOT FOUND +NOT FOUND /public/ in t9.ibd +# restart +drop database enctests; diff --git a/mysql-test/suite/encryption/r/innodb-missing-key.result b/mysql-test/suite/encryption/r/innodb-missing-key.result new file mode 100644 index 00000000..d5c1e079 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-missing-key.result @@ -0,0 +1,58 @@ +call mtr.add_suppression("InnoDB: Table `test`\\.`t1` has an unreadable root page"); +call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted\\."); +call mtr.add_suppression("InnoDB: Recovery failed to read page"); +call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file .*test.t[12].ibd looks corrupted; key_version=1"); +call mtr.add_suppression("Table .*t1.* is corrupted"); +# Start server with keys2.txt +# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt +CREATE TABLE t1(a int not null primary key auto_increment, b varchar(128)) engine=innodb ENCRYPTED=YES ENCRYPTION_KEY_ID=19; +CREATE TABLE t2(a int not null primary key auto_increment, b varchar(128)) engine=innodb ENCRYPTED=YES ENCRYPTION_KEY_ID=1; +CREATE TABLE t3(a int not null primary key auto_increment, b varchar(128)) engine=innodb ENCRYPTED=NO; +INSERT INTO t1(b) VALUES ('thisissecredmessage'); +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 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; + +# Restart server with keys3.txt +# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys3.txt +set global innodb_encryption_rotate_key_age = 1; +use test; +CREATE TABLE t4(a int not null primary key auto_increment, b varchar(128)) engine=innodb ENCRYPTED=YES ENCRYPTION_KEY_ID=1; +SELECT SLEEP(5); +SLEEP(5) +0 +SELECT COUNT(1) FROM t3; +COUNT(1) +2048 +SELECT COUNT(1) FROM t2; +COUNT(1) +2048 +SELECT COUNT(1) FROM t2,t1 where t2.a = t1.a; +ERROR 42S02: Table 'test.t1' doesn't exist in engine +SELECT COUNT(1) FROM t1 where b = 'ab'; +ERROR HY000: Table test/t1 is corrupted. Please drop the table and recreate. +SELECT COUNT(1) FROM t1; +ERROR HY000: Table test/t1 is corrupted. Please drop the table and recreate. + +# Start server with keys2.txt +# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt +SELECT COUNT(1) FROM t1; +COUNT(1) +2048 +SELECT COUNT(1) FROM t2; +COUNT(1) +2048 +SELECT COUNT(1) FROM t3; +COUNT(1) +2048 +DROP TABLE t1, t2, t3; diff --git a/mysql-test/suite/encryption/r/innodb-page_encryption-32k.result b/mysql-test/suite/encryption/r/innodb-page_encryption-32k.result new file mode 100644 index 00000000..fc49d831 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-page_encryption-32k.result @@ -0,0 +1,128 @@ +create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb; +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=1; +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=3; +ERROR HY000: Can't create table `test`.`innodb_dynamic` (errno: 140 "Wrong create options") +show warnings; +Level Code Message +Warning 140 InnoDB: ENCRYPTION_KEY_ID 3 not available +Error 1005 Can't create table `test`.`innodb_dynamic` (errno: 140 "Wrong create options") +Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=33; +create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant encrypted=yes encryption_key_id=4; +show create table innodb_compact; +Table Create Table +innodb_compact CREATE TABLE `innodb_compact` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPACT `encrypted`=yes `encryption_key_id`=1 +show create table innodb_dynamic; +Table Create Table +innodb_dynamic CREATE TABLE `innodb_dynamic` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC `encrypted`=yes `encryption_key_id`=33 +show create table innodb_redundant; +Table Create Table +innodb_redundant CREATE TABLE `innodb_redundant` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=REDUNDANT `encrypted`=yes `encryption_key_id`=4 +create procedure innodb_insert_proc (repeat_count int) +begin +declare current_num int; +set current_num = 0; +while current_num < repeat_count do +insert into innodb_normal values(current_num, substring(MD5(RAND()), -150)); +set current_num = current_num + 1; +end while; +end// +commit; +set autocommit=0; +call innodb_insert_proc(5000); +commit; +set autocommit=1; +insert into innodb_compact select * from innodb_normal; +insert into innodb_dynamic select * from innodb_normal; +insert into innodb_redundant select * from innodb_normal; +update innodb_compact set c1 = c1 + 1; +update innodb_dynamic set c1 = c1 + 1; +update innodb_redundant set c1 = c1 + 1; +select count(*) from innodb_compact where c1 < 1500000; +count(*) +5000 +select count(*) from innodb_dynamic where c1 < 1500000; +count(*) +5000 +select count(*) from innodb_redundant where c1 < 1500000; +count(*) +5000 +# restart +update innodb_compact set c1 = c1 + 1; +update innodb_dynamic set c1 = c1 + 1; +update innodb_redundant set c1 = c1 + 1; +select count(*) from innodb_compact where c1 < 1500000; +count(*) +5000 +select count(*) from innodb_dynamic where c1 < 1500000; +count(*) +5000 +select count(*) from innodb_redundant where c1 < 1500000; +count(*) +5000 +alter table innodb_compact engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_compact; +Table Create Table +innodb_compact CREATE TABLE `innodb_compact` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPACT +alter table innodb_dynamic engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_dynamic; +Table Create Table +innodb_dynamic CREATE TABLE `innodb_dynamic` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC +alter table innodb_redundant engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_redundant; +Table Create Table +innodb_redundant CREATE TABLE `innodb_redundant` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=REDUNDANT +# restart +show create table innodb_compact; +Table Create Table +innodb_compact CREATE TABLE `innodb_compact` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPACT +show create table innodb_dynamic; +Table Create Table +innodb_dynamic CREATE TABLE `innodb_dynamic` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC +show create table innodb_redundant; +Table Create Table +innodb_redundant CREATE TABLE `innodb_redundant` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=REDUNDANT +update innodb_compact set c1 = c1 + 1; +update innodb_dynamic set c1 = c1 + 1; +update innodb_redundant set c1 = c1 + 1; +select count(*) from innodb_compact where c1 < 1500000; +count(*) +5000 +select count(*) from innodb_dynamic where c1 < 1500000; +count(*) +5000 +select count(*) from innodb_redundant where c1 < 1500000; +count(*) +5000 +drop procedure innodb_insert_proc; +drop table innodb_normal; +drop table innodb_compact; +drop table innodb_dynamic; +drop table innodb_redundant; diff --git a/mysql-test/suite/encryption/r/innodb-page_encryption.result b/mysql-test/suite/encryption/r/innodb-page_encryption.result new file mode 100644 index 00000000..8f27fa7d --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-page_encryption.result @@ -0,0 +1,273 @@ +create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb; +show warnings; +Level Code Message +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=1; +show warnings; +Level Code Message +create table innodb_compressed(c1 bigint not null, b char(200)) engine=innodb row_format=compressed encrypted=yes encryption_key_id=2; +show warnings; +Level Code Message +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=3; +ERROR HY000: Can't create table `test`.`innodb_dynamic` (errno: 140 "Wrong create options") +show warnings; +Level Code Message +Warning 140 InnoDB: ENCRYPTION_KEY_ID 3 not available +Error 1005 Can't create table `test`.`innodb_dynamic` (errno: 140 "Wrong create options") +Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=33; +show warnings; +Level Code Message +create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant encrypted=yes encryption_key_id=4; +show warnings; +Level Code Message +set innodb_default_encryption_key_id = 5; +create table innodb_defkey(c1 bigint not null, b char(200)) engine=innodb encrypted=yes; +show create table innodb_defkey; +Table Create Table +innodb_defkey CREATE TABLE `innodb_defkey` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes `ENCRYPTION_KEY_ID`=5 +show create table innodb_compact; +Table Create Table +innodb_compact CREATE TABLE `innodb_compact` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPACT `encrypted`=yes `encryption_key_id`=1 +show create table innodb_compressed; +Table Create Table +innodb_compressed CREATE TABLE `innodb_compressed` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPRESSED `encrypted`=yes `encryption_key_id`=2 +show create table innodb_dynamic; +Table Create Table +innodb_dynamic CREATE TABLE `innodb_dynamic` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC `encrypted`=yes `encryption_key_id`=33 +show create table innodb_redundant; +Table Create Table +innodb_redundant CREATE TABLE `innodb_redundant` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=REDUNDANT `encrypted`=yes `encryption_key_id`=4 +create procedure innodb_insert_proc (repeat_count int) +begin +declare current_num int; +set current_num = 0; +while current_num < repeat_count do +insert into innodb_normal values(current_num, substring(MD5(RAND()), -64)); +set current_num = current_num + 1; +end while; +end// +commit; +set autocommit=0; +call innodb_insert_proc(2000); +commit; +set autocommit=1; +insert into innodb_compact select * from innodb_normal; +insert into innodb_compressed select * from innodb_normal; +insert into innodb_dynamic select * from innodb_normal; +insert into innodb_redundant select * from innodb_normal; +insert into innodb_defkey select * from innodb_normal; +update innodb_normal set c1 = c1 +1; +update innodb_compact set c1 = c1 + 1; +update innodb_compressed set c1 = c1 + 1; +update innodb_dynamic set c1 = c1 + 1; +update innodb_redundant set c1 = c1 + 1; +update innodb_defkey set c1 = c1 + 1; +select count(*) from innodb_compact where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_compressed where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_dynamic where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_redundant where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_defkey where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_compact t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +select count(*) from innodb_dynamic t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +select count(*) from innodb_compressed t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +select count(*) from innodb_redundant t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +select count(*) from innodb_defkey t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +variable_value >= 0 +1 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; +variable_value >= 0 +1 +# restart +update innodb_normal set c1 = c1 +1; +update innodb_compact set c1 = c1 + 1; +update innodb_compressed set c1 = c1 + 1; +update innodb_dynamic set c1 = c1 + 1; +update innodb_redundant set c1 = c1 + 1; +update innodb_defkey set c1 = c1 + 1; +select count(*) from innodb_compact where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_compressed where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_dynamic where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_redundant where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_defkey where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_compact t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +select count(*) from innodb_dynamic t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +select count(*) from innodb_compressed t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +select count(*) from innodb_redundant t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +select count(*) from innodb_defkey t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +variable_value >= 0 +1 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; +variable_value >= 0 +1 +alter table innodb_compact engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_compact; +Table Create Table +innodb_compact CREATE TABLE `innodb_compact` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPACT +alter table innodb_compressed engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_compressed; +Table Create Table +innodb_compressed CREATE TABLE `innodb_compressed` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPRESSED +alter table innodb_dynamic engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_dynamic; +Table Create Table +innodb_dynamic CREATE TABLE `innodb_dynamic` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC +alter table innodb_redundant engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_redundant; +Table Create Table +innodb_redundant CREATE TABLE `innodb_redundant` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=REDUNDANT +# restart +show create table innodb_compact; +Table Create Table +innodb_compact CREATE TABLE `innodb_compact` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPACT +show create table innodb_compressed; +Table Create Table +innodb_compressed CREATE TABLE `innodb_compressed` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPRESSED +show create table innodb_dynamic; +Table Create Table +innodb_dynamic CREATE TABLE `innodb_dynamic` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC +show create table innodb_redundant; +Table Create Table +innodb_redundant CREATE TABLE `innodb_redundant` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=REDUNDANT +show create table innodb_defkey; +Table Create Table +innodb_defkey CREATE TABLE `innodb_defkey` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes `ENCRYPTION_KEY_ID`=5 +update innodb_normal set c1 = c1 +1; +update innodb_compact set c1 = c1 + 1; +update innodb_compressed set c1 = c1 + 1; +update innodb_dynamic set c1 = c1 + 1; +update innodb_redundant set c1 = c1 + 1; +select count(*) from innodb_compact where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_compressed where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_dynamic where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_redundant where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_compact t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +select count(*) from innodb_dynamic t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +select count(*) from innodb_compressed t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +select count(*) from innodb_redundant t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +variable_value >= 0 +1 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; +variable_value >= 0 +1 +drop procedure innodb_insert_proc; +drop table innodb_normal; +drop table innodb_compact; +drop table innodb_compressed; +drop table innodb_dynamic; +drop table innodb_redundant; +drop table innodb_defkey; diff --git a/mysql-test/suite/encryption/r/innodb-page_encryption_compression.result b/mysql-test/suite/encryption/r/innodb-page_encryption_compression.result new file mode 100644 index 00000000..d9c2cdd4 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-page_encryption_compression.result @@ -0,0 +1,88 @@ +set global innodb_compression_algorithm = 1; +create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb page_compressed=1; +show warnings; +Level Code Message +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=1 page_compressed=1; +show warnings; +Level Code Message +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=2 page_compressed=1; +show warnings; +Level Code Message +show create table innodb_normal; +Table Create Table +innodb_normal CREATE TABLE `innodb_normal` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `page_compressed`=1 +show create table innodb_compact; +Table Create Table +innodb_compact CREATE TABLE `innodb_compact` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPACT `encrypted`=yes `encryption_key_id`=1 `page_compressed`=1 +show create table innodb_dynamic; +Table Create Table +innodb_dynamic CREATE TABLE `innodb_dynamic` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC `encrypted`=yes `encryption_key_id`=2 `page_compressed`=1 +create procedure innodb_insert_proc (repeat_count int) +begin +declare current_num int; +set current_num = 0; +while current_num < repeat_count do +insert into innodb_normal values(current_num, substring(MD5(RAND()), -128)); +set current_num = current_num + 1; +end while; +end// +commit; +begin; +call innodb_insert_proc(2000); +insert into innodb_compact select * from innodb_normal; +insert into innodb_dynamic select * from innodb_normal; +commit; +FLUSH TABLES innodb_compact FOR EXPORT; +UNLOCK TABLES; +FLUSH TABLES innodb_dynamic FOR EXPORT; +UNLOCK TABLES; +select variable_value > 0 from information_schema.global_status +where variable_name = 'INNODB_NUM_PAGES_PAGE_COMPRESSED'; +variable_value > 0 +1 +# restart: --innodb-encrypt-tables=OFF +set global innodb_compression_algorithm = 1; +alter table innodb_normal engine=innodb page_compressed=DEFAULT; +show create table innodb_normal; +Table Create Table +innodb_normal CREATE TABLE `innodb_normal` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +alter table innodb_compact engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT page_compressed=DEFAULT; +show create table innodb_compact; +Table Create Table +innodb_compact CREATE TABLE `innodb_compact` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPACT +alter table innodb_dynamic engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT page_compressed=DEFAULT; +show create table innodb_dynamic; +Table Create Table +innodb_dynamic CREATE TABLE `innodb_dynamic` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC +FLUSH TABLES innodb_normal FOR EXPORT; +UNLOCK TABLES; +FLUSH TABLES innodb_compact FOR EXPORT; +UNLOCK TABLES; +FLUSH TABLES innodb_dynamic FOR EXPORT; +UNLOCK TABLES; +select variable_value > 0 from information_schema.global_status +where variable_name = 'INNODB_NUM_PAGES_PAGE_DECOMPRESSED'; +variable_value > 0 +1 +drop procedure innodb_insert_proc; +drop table innodb_normal; +drop table innodb_compact; +drop table innodb_dynamic; diff --git a/mysql-test/suite/encryption/r/innodb-page_encryption_log_encryption.result b/mysql-test/suite/encryption/r/innodb-page_encryption_log_encryption.result new file mode 100644 index 00000000..ea7547b8 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-page_encryption_log_encryption.result @@ -0,0 +1,130 @@ +create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb; +show warnings; +Level Code Message +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=1; +show warnings; +Level Code Message +create table innodb_compressed(c1 bigint not null, b char(200)) engine=innodb row_format=compressed encrypted=yes encryption_key_id=2; +show warnings; +Level Code Message +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=33; +show warnings; +Level Code Message +create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant encrypted=yes encryption_key_id=4; +show warnings; +Level Code Message +show create table innodb_compact; +Table Create Table +innodb_compact CREATE TABLE `innodb_compact` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPACT `encrypted`=yes `encryption_key_id`=1 +show create table innodb_compressed; +Table Create Table +innodb_compressed CREATE TABLE `innodb_compressed` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPRESSED `encrypted`=yes `encryption_key_id`=2 +show create table innodb_dynamic; +Table Create Table +innodb_dynamic CREATE TABLE `innodb_dynamic` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC `encrypted`=yes `encryption_key_id`=33 +show create table innodb_redundant; +Table Create Table +innodb_redundant CREATE TABLE `innodb_redundant` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=REDUNDANT `encrypted`=yes `encryption_key_id`=4 +FLUSH TABLES innodb_normal FOR EXPORT; +UNLOCK TABLES; +FLUSH TABLES innodb_compact FOR EXPORT; +UNLOCK TABLES; +FLUSH TABLES innodb_compressed FOR EXPORT; +UNLOCK TABLES; +FLUSH TABLES innodb_dynamic FOR EXPORT; +UNLOCK TABLES; +FLUSH TABLES innodb_redundant FOR EXPORT; +UNLOCK TABLES; +select variable_value > 0 from information_schema.global_status +where variable_name = 'INNODB_NUM_PAGES_ENCRYPTED'; +variable_value > 0 +1 +# restart +BEGIN; +INSERT INTO innodb_normal SET c1 = 1; +INSERT INTO innodb_compact SET c1 = 1; +INSERT INTO innodb_compressed SET c1 = 1; +INSERT INTO innodb_dynamic SET c1 = 1; +INSERT INTO innodb_redundant SET c1 = 1; +COMMIT; +FLUSH TABLES innodb_normal FOR EXPORT; +UNLOCK TABLES; +FLUSH TABLES innodb_compact FOR EXPORT; +UNLOCK TABLES; +FLUSH TABLES innodb_compressed FOR EXPORT; +UNLOCK TABLES; +FLUSH TABLES innodb_dynamic FOR EXPORT; +UNLOCK TABLES; +FLUSH TABLES innodb_redundant FOR EXPORT; +UNLOCK TABLES; +select variable_name from information_schema.global_status +where variable_value > 0 and variable_name +IN ('INNODB_NUM_PAGES_ENCRYPTED','INNODB_NUM_PAGES_DECRYPTED'); +variable_name +INNODB_NUM_PAGES_ENCRYPTED +INNODB_NUM_PAGES_DECRYPTED +SET GLOBAL innodb_encrypt_tables=OFF; +alter table innodb_compact engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_compact; +Table Create Table +innodb_compact CREATE TABLE `innodb_compact` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPACT +alter table innodb_compressed engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_compressed; +Table Create Table +innodb_compressed CREATE TABLE `innodb_compressed` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPRESSED +alter table innodb_dynamic engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_dynamic; +Table Create Table +innodb_dynamic CREATE TABLE `innodb_dynamic` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC +alter table innodb_redundant engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_redundant; +Table Create Table +innodb_redundant CREATE TABLE `innodb_redundant` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=REDUNDANT +FLUSH TABLES innodb_normal FOR EXPORT; +UNLOCK TABLES; +FLUSH TABLES innodb_compact FOR EXPORT; +UNLOCK TABLES; +FLUSH TABLES innodb_compressed FOR EXPORT; +UNLOCK TABLES; +FLUSH TABLES innodb_dynamic FOR EXPORT; +UNLOCK TABLES; +FLUSH TABLES innodb_redundant FOR EXPORT; +UNLOCK TABLES; +drop table innodb_normal; +drop table innodb_compact; +drop table innodb_compressed; +drop table innodb_dynamic; +drop table innodb_redundant; +CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=InnoDB ENCRYPTION_KEY_ID=2 ENCRYPTED=YES; +INSERT INTO t1 VALUES (1),(2); +# Restarting server... +# restart +SELECT * FROM t1; +pk +1 +2 +DROP TABLE t1; diff --git a/mysql-test/suite/encryption/r/innodb-read-only.result b/mysql-test/suite/encryption/r/innodb-read-only.result new file mode 100644 index 00000000..35ba28db --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-read-only.result @@ -0,0 +1,4 @@ +# Wait max 10 min for key encryption threads to encrypt all spaces +# Success! +# restart: --innodb-read-only=1 --innodb-encrypt-tables=1 +# All done diff --git a/mysql-test/suite/encryption/r/innodb-redo-badkey.result b/mysql-test/suite/encryption/r/innodb-redo-badkey.result new file mode 100644 index 00000000..34fd043a --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-redo-badkey.result @@ -0,0 +1,44 @@ +call mtr.add_suppression("Plugin 'file_key_management'"); +call mtr.add_suppression("Plugin 'InnoDB' init function returned error."); +call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[1-4]\\.ibd' cannot be decrypted; key_version=1"); +call mtr.add_suppression("InnoDB: File '.*test/t[1234]\\.ibd' is corrupted"); +call mtr.add_suppression("InnoDB: Recovery failed to read page"); +call mtr.add_suppression("InnoDB: Unable to decompress .*.test.t[12]\\.ibd\\[page id: space=[1-9][0-9]*, page number=[0-9]+\\]"); +call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed read of file '.*test.t[12]\\.ibd'"); +call mtr.add_suppression("InnoDB: Failed to read page .* from file '.*'"); +call mtr.add_suppression("InnoDB: OPT_PAGE_CHECKSUM mismatch"); +call mtr.add_suppression("InnoDB: Set innodb_force_recovery=1 to ignore corruption"); +call mtr.add_suppression("InnoDB: (Unable to apply log to|Discarding log for) corrupted page "); +call mtr.add_suppression("InnoDB: Plugin initialization aborted"); +call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed"); +call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot decrypt \\[page id: space="); +# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt +# Wait max 10 min for key encryption threads to encrypt all spaces +SET GLOBAL innodb_file_per_table = ON; +create table t1(a int not null primary key auto_increment, c char(250), b blob, index(b(10))) engine=innodb row_format=compressed encrypted=yes encryption_key_id=4; +create table t2(a int not null primary key auto_increment, c char(250), b blob, index(b(10))) engine=innodb row_format=compressed; +create table t3(a int not null primary key auto_increment, c char(250), b blob, index(b(10))) engine=innodb encrypted=yes encryption_key_id=4; +create table t4(a int not null primary key auto_increment, c char(250), b blob, index(b(10))) engine=innodb; +begin; +insert into t2 select * from t1; +insert into t3 select * from t1; +insert into t4 select * from t1; +commit; +SET GLOBAL innodb_flush_log_at_trx_commit=1; +begin; +update t1 set c = repeat('secret3', 20); +update t2 set c = repeat('secret4', 20); +update t3 set c = repeat('secret4', 20); +update t4 set c = repeat('secret4', 20); +insert into t1 (c,b) values (repeat('secret5',20), repeat('secret6',6000)); +insert into t2 (c,b) values (repeat('secret7',20), repeat('secret8',6000)); +insert into t3 (c,b) values (repeat('secret9',20), repeat('secre10',6000)); +insert into t4 (c,b) values (repeat('secre11',20), repeat('secre12',6000)); +COMMIT; +# Kill the server +# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt +# Kill the server +# restart: --innodb-force-recovery=1 +# Kill the server +# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt +drop table t1, t2,t3,t4; diff --git a/mysql-test/suite/encryption/r/innodb-redo-nokeys.result b/mysql-test/suite/encryption/r/innodb-redo-nokeys.result new file mode 100644 index 00000000..b7d6eb50 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-redo-nokeys.result @@ -0,0 +1,47 @@ +call mtr.add_suppression("mariadbd.*: File "); +call mtr.add_suppression("Plugin 'file_key_management' "); +call mtr.add_suppression("InnoDB: Recovery cannot access file"); +call mtr.add_suppression("InnoDB: Plugin initialization aborted"); +call mtr.add_suppression("Plugin 'InnoDB' init function returned error\\."); +call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed."); +call mtr.add_suppression("InnoDB: (Unable to apply log to|Discarding log for) corrupted page "); +call mtr.add_suppression("InnoDB: Cannot apply log to \\[page id: space=[1-9][0-9]*, page number=0\\] of corrupted file '.*test.t[1-5]\\.ibd'"); +call mtr.add_suppression("InnoDB: Failed to read page .* from file '.*'"); +call mtr.add_suppression("InnoDB: OPT_PAGE_CHECKSUM mismatch"); +call mtr.add_suppression("InnoDB: Missing FILE_CHECKPOINT"); +call mtr.add_suppression("InnoDB: Log scan aborted at LSN"); +call mtr.add_suppression("InnoDB: Set innodb_force_recovery=1 to ignore corruption"); +call mtr.add_suppression("InnoDB: Encryption key is not found for"); +# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt +SET GLOBAL innodb_file_per_table = ON; +create table t1(a int not null primary key auto_increment, c char(200), b blob, index(b(10))) engine=innodb row_format=compressed encrypted=yes encryption_key_id=20; +create table t2(a int not null primary key auto_increment, c char(200), b blob, index(b(10))) engine=innodb row_format=compressed encrypted=yes; +create table t3(a int not null primary key auto_increment, c char(200), b blob, index(b(10))) engine=innodb encrypted=yes encryption_key_id=20; +create table t4(a int not null primary key auto_increment, c char(200), b blob, index(b(10))) engine=innodb encrypted=yes; +begin; +insert into t2 select * from t1; +insert into t3 select * from t1; +insert into t4 select * from t1; +commit; +CREATE TABLE t5 (a VARCHAR(8)) ENGINE=InnoDB ENCRYPTED=YES; +SET GLOBAL innodb_flush_log_at_trx_commit=1; +begin; +update t1 set c = repeat('secret3', 20); +update t2 set c = repeat('secret4', 20); +update t3 set c = repeat('secret4', 20); +update t4 set c = repeat('secret4', 20); +insert into t1 (c,b) values (repeat('secret5',20), repeat('secret6',6000)); +insert into t2 (c,b) values (repeat('secret7',20), repeat('secret8',6000)); +insert into t3 (c,b) values (repeat('secret9',20), repeat('secre10',6000)); +insert into t4 (c,b) values (repeat('secre11',20), repeat('secre12',6000)); +INSERT INTO t5 VALUES ('foo'),('bar'); +COMMIT; +# Kill the server +# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys-not-found.txt +SELECT * FROM INFORMATION_SCHEMA.ENGINES +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +FOUND 1 /\[ERROR\] InnoDB: Encryption key is not found for .*test.t1.ibd/ in mysqld.1.err +# restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt +drop table t1,t2,t3,t4,t5; diff --git a/mysql-test/suite/encryption/r/innodb-remove-encryption,undo3.rdiff b/mysql-test/suite/encryption/r/innodb-remove-encryption,undo3.rdiff new file mode 100644 index 00000000..421c962b --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-remove-encryption,undo3.rdiff @@ -0,0 +1,32 @@ +--- innodb-remove-encryption.result 2022-09-02 20:44:59.960430396 +0530 ++++ innodb-remove-encryption,undo3.reject 2022-11-29 19:02:24.813094277 +0530 +@@ -13,6 +13,9 @@ + SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + NAME + innodb_system ++innodb_undo001 ++innodb_undo002 ++innodb_undo003 + mysql/innodb_index_stats + mysql/innodb_table_stats + mysql/transaction_registry +@@ -24,6 +27,9 @@ + SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; + NAME + innodb_system ++innodb_undo001 ++innodb_undo002 ++innodb_undo003 + mysql/innodb_index_stats + mysql/innodb_table_stats + mysql/transaction_registry +@@ -36,6 +42,9 @@ + SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; + NAME + innodb_system ++innodb_undo001 ++innodb_undo002 ++innodb_undo003 + mysql/innodb_index_stats + mysql/innodb_table_stats + mysql/transaction_registry diff --git a/mysql-test/suite/encryption/r/innodb-remove-encryption.result b/mysql-test/suite/encryption/r/innodb-remove-encryption.result new file mode 100644 index 00000000..e241d213 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-remove-encryption.result @@ -0,0 +1,46 @@ +set global innodb_file_per_table=OFF; +call mtr.add_suppression("(mysqld|mariadbd).*: file-key-management-filename is not set"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error."); +call mtr.add_suppression("Plugin 'file_key_management' registration as a ENCRYPTION failed."); +flush tables; +create table t1(a int not null primary key, b char(200)) engine=innodb; + +# Restart server with encryption +# restart: --plugin-load-add=file_key_management --loose-file-key-management --loose-file-key-management-filename=MYSQL_TEST_DIR/std_data/keys.txt --file-key-management-encryption-algorithm=aes_cbc --innodb-encrypt-tables=ON --innodb-encryption-threads=4 --innodb-tablespaces-encryption --innodb-encryption-rotate-key-age=15 +# Wait until encryption threads have encrypted all tablespaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +NAME +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +NAME +innodb_system +mysql/innodb_index_stats +mysql/innodb_table_stats +mysql/transaction_registry +# Success! +SELECT * from t1; +a b +# Now turn off encryption and wait for threads to decrypt all tablespaces +SET GLOBAL innodb_encrypt_tables = off; +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +NAME +innodb_system +mysql/innodb_index_stats +mysql/innodb_table_stats +mysql/transaction_registry +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +NAME +# Success! + +# Restart server with no encryption setup, there should be no crashes +# restart: --skip-file-key-management --innodb-encrypt-tables=OFF --innodb-encryption-threads=0 --innodb-tablespaces-encryption +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +NAME +innodb_system +mysql/innodb_index_stats +mysql/innodb_table_stats +mysql/transaction_registry +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +NAME +SELECT * from t1; +a b +DROP TABLE t1; diff --git a/mysql-test/suite/encryption/r/innodb-spatial-index,full_crc32.rdiff b/mysql-test/suite/encryption/r/innodb-spatial-index,full_crc32.rdiff new file mode 100644 index 00000000..2f58318b --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-spatial-index,full_crc32.rdiff @@ -0,0 +1,36 @@ +--- innodb-spatial-index.result ++++ innodb-spatial-index.result +@@ -1,23 +1,27 @@ + CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, + c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB + ENCRYPTED=YES; +-Got one of the listed errors ++INSERT INTO t1(c, coordinate) values('mysql', ST_GeomFromText('POINT(903994614 180726515)')); ++# restart ++INSERT INTO t1(c, coordinate) values('mariadb', ST_GeomFromText('POINT(903994614 180726515)')); ++DROP TABLE t1; + CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, + c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB; + ALTER TABLE t1 ENCRYPTED=YES; +-Got one of the listed errors + DROP TABLE t1; + CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, + c VARCHAR(256), coordinate POINT NOT NULL) + PAGE_COMPRESSED=YES, ENCRYPTED=YES ENGINE=INNODB; + ALTER TABLE t1 ADD SPATIAL INDEX b1(coordinate), ALGORITHM=COPY; +-Got one of the listed errors + ALTER TABLE t1 ADD SPATIAL INDEX b2(coordinate), FORCE, ALGORITHM=INPLACE; +-Got one of the listed errors ++Warnings: ++Note 1831 Duplicate index `b2`. This is deprecated and will be disallowed in a future release + ALTER TABLE t1 ADD SPATIAL INDEX(coordinate); +-Got one of the listed errors ++Warnings: ++Note 1831 Duplicate index `coordinate`. This is deprecated and will be disallowed in a future release + CREATE SPATIAL INDEX b3 on t1(coordinate); +-Got one of the listed errors ++Warnings: ++Note 1831 Duplicate index `b3`. This is deprecated and will be disallowed in a future release + DROP TABLE t1; + CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, + c VARCHAR(256), coordinate POINT NOT NULL) ENCRYPTED=DEFAULT ENGINE=INNODB; diff --git a/mysql-test/suite/encryption/r/innodb-spatial-index,strict_full_crc32.rdiff b/mysql-test/suite/encryption/r/innodb-spatial-index,strict_full_crc32.rdiff new file mode 100644 index 00000000..2f58318b --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-spatial-index,strict_full_crc32.rdiff @@ -0,0 +1,36 @@ +--- innodb-spatial-index.result ++++ innodb-spatial-index.result +@@ -1,23 +1,27 @@ + CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, + c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB + ENCRYPTED=YES; +-Got one of the listed errors ++INSERT INTO t1(c, coordinate) values('mysql', ST_GeomFromText('POINT(903994614 180726515)')); ++# restart ++INSERT INTO t1(c, coordinate) values('mariadb', ST_GeomFromText('POINT(903994614 180726515)')); ++DROP TABLE t1; + CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, + c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB; + ALTER TABLE t1 ENCRYPTED=YES; +-Got one of the listed errors + DROP TABLE t1; + CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, + c VARCHAR(256), coordinate POINT NOT NULL) + PAGE_COMPRESSED=YES, ENCRYPTED=YES ENGINE=INNODB; + ALTER TABLE t1 ADD SPATIAL INDEX b1(coordinate), ALGORITHM=COPY; +-Got one of the listed errors + ALTER TABLE t1 ADD SPATIAL INDEX b2(coordinate), FORCE, ALGORITHM=INPLACE; +-Got one of the listed errors ++Warnings: ++Note 1831 Duplicate index `b2`. This is deprecated and will be disallowed in a future release + ALTER TABLE t1 ADD SPATIAL INDEX(coordinate); +-Got one of the listed errors ++Warnings: ++Note 1831 Duplicate index `coordinate`. This is deprecated and will be disallowed in a future release + CREATE SPATIAL INDEX b3 on t1(coordinate); +-Got one of the listed errors ++Warnings: ++Note 1831 Duplicate index `b3`. This is deprecated and will be disallowed in a future release + DROP TABLE t1; + CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, + c VARCHAR(256), coordinate POINT NOT NULL) ENCRYPTED=DEFAULT ENGINE=INNODB; diff --git a/mysql-test/suite/encryption/r/innodb-spatial-index.result b/mysql-test/suite/encryption/r/innodb-spatial-index.result new file mode 100644 index 00000000..66c3edcd --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb-spatial-index.result @@ -0,0 +1,48 @@ +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, +c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB +ENCRYPTED=YES; +Got one of the listed errors +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, +c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB; +ALTER TABLE t1 ENCRYPTED=YES; +Got one of the listed errors +DROP TABLE t1; +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, +c VARCHAR(256), coordinate POINT NOT NULL) +PAGE_COMPRESSED=YES, ENCRYPTED=YES ENGINE=INNODB; +ALTER TABLE t1 ADD SPATIAL INDEX b1(coordinate), ALGORITHM=COPY; +Got one of the listed errors +ALTER TABLE t1 ADD SPATIAL INDEX b2(coordinate), FORCE, ALGORITHM=INPLACE; +Got one of the listed errors +ALTER TABLE t1 ADD SPATIAL INDEX(coordinate); +Got one of the listed errors +CREATE SPATIAL INDEX b3 on t1(coordinate); +Got one of the listed errors +DROP TABLE t1; +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, +c VARCHAR(256), coordinate POINT NOT NULL) ENCRYPTED=DEFAULT ENGINE=INNODB; +CREATE SPATIAL INDEX b on t1(coordinate); +INSERT INTO t1 values(1, 'secret', ST_GeomFromText('POINT(903994614 180726515)')); +ALTER TABLE t1 DROP INDEX b; +INSERT INTO t1 values(2, 'secret', ST_GeomFromText('POINT(903994614 180726515)')); +ALTER TABLE t1 ADD SPATIAL INDEX b(coordinate); +INSERT INTO t1 values(3, 'secret', ST_GeomFromText('POINT(903994614 180726515)')); +DROP TABLE t1; +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, +c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB; +CREATE TABLE t2 (pk INT PRIMARY KEY AUTO_INCREMENT, +c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB PAGE_COMPRESSED=YES; +INSERT INTO t1 values(1, 'secret', ST_GeomFromText('POINT(903994614 180726515)')); +INSERT INTO t2 values(1, 'secret', ST_GeomFromText('POINT(903994614 180726515)')); +# Success! +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION > 0; +NAME +innodb_system +mysql/innodb_index_stats +mysql/innodb_table_stats +mysql/transaction_registry +test/t1 +test/t2 +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +NAME +DROP TABLE t1, t2; diff --git a/mysql-test/suite/encryption/r/innodb_encrypt_freed,undo3.rdiff b/mysql-test/suite/encryption/r/innodb_encrypt_freed,undo3.rdiff new file mode 100644 index 00000000..36eea901 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb_encrypt_freed,undo3.rdiff @@ -0,0 +1,62 @@ +--- innodb_encrypt_freed.result 2021-03-23 15:44:14.466377983 +0530 ++++ innodb_encrypt_freed,undo3.reject 2022-11-29 19:04:24.987010571 +0530 +@@ -14,6 +14,9 @@ + SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + NAME + innodb_system ++innodb_undo001 ++innodb_undo002 ++innodb_undo003 + mysql/innodb_index_stats + mysql/innodb_table_stats + mysql/transaction_registry +@@ -29,6 +32,9 @@ + SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; + NAME + innodb_system ++innodb_undo001 ++innodb_undo002 ++innodb_undo003 + mysql/innodb_index_stats + mysql/innodb_table_stats + mysql/transaction_registry +@@ -40,6 +46,9 @@ + SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + NAME + innodb_system ++innodb_undo001 ++innodb_undo002 ++innodb_undo003 + mysql/innodb_index_stats + mysql/innodb_table_stats + mysql/transaction_registry +@@ -55,6 +64,9 @@ + SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + NAME + innodb_system ++innodb_undo001 ++innodb_undo002 ++innodb_undo003 + mysql/innodb_index_stats + mysql/innodb_table_stats + mysql/transaction_registry +@@ -70,6 +82,9 @@ + SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; + NAME + innodb_system ++innodb_undo001 ++innodb_undo002 ++innodb_undo003 + mysql/innodb_index_stats + mysql/innodb_table_stats + mysql/transaction_registry +@@ -87,6 +102,9 @@ + SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + NAME + innodb_system ++innodb_undo001 ++innodb_undo002 ++innodb_undo003 + mysql/innodb_index_stats + mysql/innodb_table_stats + mysql/transaction_registry diff --git a/mysql-test/suite/encryption/r/innodb_encrypt_freed.result b/mysql-test/suite/encryption/r/innodb_encrypt_freed.result new file mode 100644 index 00000000..cdcdd177 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb_encrypt_freed.result @@ -0,0 +1,96 @@ +SHOW VARIABLES LIKE 'innodb_encrypt%'; +Variable_name Value +innodb_encrypt_log ON +innodb_encrypt_tables ON +innodb_encrypt_temporary_tables OFF +innodb_encryption_rotate_key_age 1 +innodb_encryption_rotation_iops 100 +innodb_encryption_threads 1 +SET GLOBAL innodb_encrypt_tables = ON; +CREATE TABLE t1(f1 BIGINT PRIMARY KEY, f2 int not null, +f3 int not null, index(f1), index idx_1(f2), +index(f2, f3)) ENGINE=InnoDB; +# Wait max 10 min for key encryption threads to encrypt all spaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +NAME +innodb_system +mysql/innodb_index_stats +mysql/innodb_table_stats +mysql/transaction_registry +test/t1 +CREATE TABLE t2 (f1 int not null)engine=innodb; +# restart: --debug=d,ib_log_checkpoint_avoid +connect con1,localhost,root,,,; +begin; +insert into t2 values(1); +connection default; +set global innodb_encrypt_tables = OFF; +# Wait max 10 min for key encryption threads to decrypt all spaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +NAME +innodb_system +mysql/innodb_index_stats +mysql/innodb_table_stats +mysql/transaction_registry +test/t1 +test/t2 +alter table t1 drop index idx_1; +set global innodb_encrypt_tables = ON; +# Wait max 10 min for key encryption threads to encrypt all spaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +NAME +innodb_system +mysql/innodb_index_stats +mysql/innodb_table_stats +mysql/transaction_registry +test/t1 +test/t2 +disconnect con1; +# restart: --debug=d,ib_log_checkpoint_avoid +drop table t1, t2; +CREATE TABLE t1(f1 BIGINT PRIMARY KEY, f2 int not null, +f3 int not null, index(f1), index idx_1(f2), +index(f2, f3)) ENGINE=InnoDB; +# Wait max 10 min for key encryption threads to encrypt all spaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +NAME +innodb_system +mysql/innodb_index_stats +mysql/innodb_table_stats +mysql/transaction_registry +test/t1 +CREATE TABLE t2 (f1 int not null)engine=innodb; +# restart: --debug=d,ib_log_checkpoint_avoid +connect con1,localhost,root,,,; +begin; +insert into t2 values(1); +connection default; +set global innodb_encrypt_tables = OFF; +# Wait max 10 min for key encryption threads to decrypt all spaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +NAME +innodb_system +mysql/innodb_index_stats +mysql/innodb_table_stats +mysql/transaction_registry +test/t1 +test/t2 +alter table t1 drop index idx_1; +disconnect con1; +# restart: --debug=d,ib_log_checkpoint_avoid +connect con1,localhost,root,,,; +begin; +insert into t2 values(1); +connection default; +set global innodb_encrypt_tables = ON; +# Wait max 10 min for key encryption threads to encrypt all spaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +NAME +innodb_system +mysql/innodb_index_stats +mysql/innodb_table_stats +mysql/transaction_registry +test/t1 +test/t2 +disconnect con1; +drop table t2, t1; diff --git a/mysql-test/suite/encryption/r/innodb_encrypt_key_rotation_age,undo3.rdiff b/mysql-test/suite/encryption/r/innodb_encrypt_key_rotation_age,undo3.rdiff new file mode 100644 index 00000000..476b0b3f --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb_encrypt_key_rotation_age,undo3.rdiff @@ -0,0 +1,52 @@ +--- innodb_encrypt_key_rotation_age.result 2022-06-02 16:15:08.395122720 +0530 ++++ innodb_encrypt_key_rotation_age,undo3.reject 2022-11-29 19:06:07.964542115 +0530 +@@ -12,6 +12,9 @@ + SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + NAME + innodb_system ++innodb_undo001 ++innodb_undo002 ++innodb_undo003 + mysql/innodb_index_stats + mysql/innodb_table_stats + mysql/transaction_registry +@@ -27,6 +30,9 @@ + SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + NAME + innodb_system ++innodb_undo001 ++innodb_undo002 ++innodb_undo003 + mysql/innodb_index_stats + mysql/innodb_table_stats + mysql/transaction_registry +@@ -39,6 +45,9 @@ + SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; + NAME + innodb_system ++innodb_undo001 ++innodb_undo002 ++innodb_undo003 + mysql/innodb_index_stats + mysql/innodb_table_stats + mysql/transaction_registry +@@ -59,6 +68,9 @@ + SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + NAME + innodb_system ++innodb_undo001 ++innodb_undo002 ++innodb_undo003 + mysql/innodb_index_stats + mysql/innodb_table_stats + mysql/transaction_registry +@@ -71,6 +83,9 @@ + SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + NAME + innodb_system ++innodb_undo001 ++innodb_undo002 ++innodb_undo003 + mysql/innodb_index_stats + mysql/innodb_table_stats + mysql/transaction_registry diff --git a/mysql-test/suite/encryption/r/innodb_encrypt_key_rotation_age.result b/mysql-test/suite/encryption/r/innodb_encrypt_key_rotation_age.result new file mode 100644 index 00000000..3dfa449d --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb_encrypt_key_rotation_age.result @@ -0,0 +1,80 @@ +CREATE TABLE t1 (f1 INT, f2 VARCHAR(256))engine=innodb; +INSERT INTO t1 VALUES(1, 'MariaDB'), (2, 'Robot'), (3, 'Science'); +INSERT INTO t1 SELECT * FROM t1; +CREATE TABLE t2(f1 INT, f2 VARCHAR(256))engine=innodb; +INSERT INTO t2 SELECT * FROM t1; +CREATE TABLE t3(f1 INT, f2 VARCHAR(256))engine=innodb encrypted=yes; +INSERT INTO t3 SELECT * FROM t1; +# Restart the server with encryption +# Wait until encryption threads have encrypted all tablespaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +NAME +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +NAME +innodb_system +mysql/innodb_index_stats +mysql/innodb_table_stats +mysql/transaction_registry +test/t1 +test/t2 +test/t3 +# Restart the server with innodb_encryption_rotate_key_age= 0 +create table t4 (f1 int not null)engine=innodb encrypted=NO; +# Wait until encryption threads have encrypted all tablespaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +NAME +test/t4 +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +NAME +innodb_system +mysql/innodb_index_stats +mysql/innodb_table_stats +mysql/transaction_registry +test/t1 +test/t2 +test/t3 +# Disable encryption when innodb_encryption_rotate_key_age is 0 +set global innodb_encrypt_tables = OFF; +# Wait until encryption threads to decrypt all unencrypted tablespaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +NAME +innodb_system +mysql/innodb_index_stats +mysql/innodb_table_stats +mysql/transaction_registry +test/t1 +test/t2 +test/t4 +# Display only encrypted create tables (t3) +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +NAME +test/t3 +# Enable encryption when innodb_encryption_rotate_key_age is 0 +set global innodb_encrypt_tables = ON; +# Wait until encryption threads to encrypt all unencrypted tablespaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +NAME +test/t4 +# Display only unencrypted create tables (t4) +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +NAME +innodb_system +mysql/innodb_index_stats +mysql/innodb_table_stats +mysql/transaction_registry +test/t1 +test/t2 +test/t3 +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +NAME +test/t4 +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +NAME +innodb_system +mysql/innodb_index_stats +mysql/innodb_table_stats +mysql/transaction_registry +test/t1 +test/t2 +test/t3 +DROP TABLE t4, t3, t2, t1; diff --git a/mysql-test/suite/encryption/r/innodb_encrypt_log.result b/mysql-test/suite/encryption/r/innodb_encrypt_log.result new file mode 100644 index 00000000..5c6c7eba --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb_encrypt_log.result @@ -0,0 +1,61 @@ +# +# MDEV-9011: Redo log encryption does not work +# +# +# MDEV-9422 Encrypted redo log checksum errors +# on restart after killing busy server instance +# +CREATE TABLE t0 ( +pk bigint auto_increment, +col_int int, +col_int_key int, +col_char char(12), +col_char_key char(12), +primary key (pk), +key (col_int_key), +key (col_char_key) +) ENGINE=InnoDB ENCRYPTED=YES ENCRYPTION_KEY_ID=1; +CREATE TEMPORARY TABLE t LIKE t0; +Warnings: +Warning 1478 Ignoring encryption parameter during temporary table creation. +INSERT INTO t VALUES +(NULL,1,1,'private','secret'),(NULL,2,2,'sacred','success'), +(NULL,3,3,'story','secure'),(NULL,4,4,'security','sacrament'); +SET GLOBAL innodb_flush_log_at_trx_commit=1; +INSERT INTO t0 +SELECT NULL, t1.col_int, t1.col_int_key, t1.col_char, t1.col_char_key +FROM t t1, t t2, t t3, t t4, t t5; +# Kill the server +# ibdata1 expecting NOT FOUND +NOT FOUND /private|secret|sacr(ed|ament)|success|story|secur(e|ity)/ in ibdata1 +# t0.ibd expecting NOT FOUND +NOT FOUND /private|secret|sacr(ed|ament)|success|story|secur(e|ity)/ in t0.ibd +# ib_logfile0 expecting NOT FOUND +NOT FOUND /private|secret|sacr(ed|ament)|success|story|secur(e|ity)/ in ib_logfile0 +# Restart without redo log encryption +# restart: --skip-innodb-encrypt-log +SELECT COUNT(*) FROM t0; +COUNT(*) +1024 +CHECK TABLE t0; +Table Op Msg_type Msg_text +test.t0 check status OK +SET GLOBAL innodb_flush_log_at_trx_commit=1; +INSERT INTO t0 VALUES(NULL, 5, 5, 'public', 'gossip'); +# Kill the server +# ib_logfile0 expecting NOT FOUND +NOT FOUND /private|secret|sacr(ed|ament)|success|story|secur(e|ity)/ in ib_logfile0 +# ib_logfile0 expecting FOUND +FOUND 1 /(public|gossip).*/ in ib_logfile0 +# ibdata1 expecting NOT FOUND +NOT FOUND /private|secret|sacr(ed|ament)|success|story|secur(e|ity)|public|gossip/ in ibdata1 +# t0.ibd expecting NOT FOUND +NOT FOUND /private|secret|sacr(ed|ament)|success|story|secur(e|ity)|public|gossip/ in t0.ibd +# restart +SELECT COUNT(*) FROM t0; +COUNT(*) +1025 +CHECK TABLE t0; +Table Op Msg_type Msg_text +test.t0 check status OK +DROP TABLE t0; diff --git a/mysql-test/suite/encryption/r/innodb_encrypt_log_corruption.result b/mysql-test/suite/encryption/r/innodb_encrypt_log_corruption.result new file mode 100644 index 00000000..3c3e4831 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb_encrypt_log_corruption.result @@ -0,0 +1,203 @@ +# redo log from before MariaDB 10.2.2/MySQL 5.7.9 +# 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 +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +FOUND 1 /InnoDB: Upgrade after a crash is not supported. This redo log was created before MariaDB 10\.2\.2\./ in mysqld.1.err +# redo log from before MariaDB 10.2.2, with corrupted log checkpoint +# 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 +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +FOUND 1 /InnoDB: Upgrade after a crash is not supported. This redo log was created before MariaDB 10\.2\.2, and we did not find a valid checkpoint/ in mysqld.1.err +# redo log from before MariaDB 10.2.2, with corrupted log block +# 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 +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +FOUND 1 /InnoDB: Upgrade after a crash is not supported. This redo log was created before MariaDB 10\.2\.2, and we did not find a valid checkpoint/ in mysqld.1.err +# empty redo log from before 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=4m +SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +COUNT(*) +1 +FOUND 1 /InnoDB: Upgrading redo log:/ in mysqld.1.err +# Corrupted multi-file redo log from before 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=4m +SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +COUNT(*) +0 +FOUND 1 /InnoDB: Upgrade after a crash is not supported. This redo log was created before MariaDB 10\.2\.2, and it appears corrupted/ in mysqld.1.err +# Empty multi-file redo log (wrong offset) from before 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=4m +SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +COUNT(*) +0 +FOUND 3 /Upgrade after a crash is not supported. This redo log was created before MariaDB 10\.2\.2, and we did not find a valid checkpoint\./ in mysqld.1.err +# Multi-file redo log with size mismatch from after MariaDB 10.2.2 +# Corrupted 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=4m +SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +COUNT(*) +0 +FOUND 3 /Upgrade after a crash is not supported. This redo log was created before MariaDB 10\.2\.2, and we did not find a valid checkpoint\./ in mysqld.1.err +FOUND 1 /InnoDB: No valid checkpoint was found; the log was created with BogoDB 1\.2\.3\.4\./ in mysqld.1.err +# 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=4m +SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +COUNT(*) +0 +FOUND 1 /InnoDB: Log file .*ib_logfile1 is of different size 2097152 bytes than other log files 1048576 bytes!/ in mysqld.1.err +FOUND 2 /InnoDB: No valid checkpoint was found; the log was created with BogoDB 1\.2\.3\.4\./ in mysqld.1.err +# Empty 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=4m +SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +COUNT(*) +0 +FOUND 3 /InnoDB: No valid checkpoint was found; the log was created with BogoDB 1\.2\.3\.4\./ 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 +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +FOUND 1 /InnoDB: Log file .*ib_logfile1 is of different size 2097152 bytes than other log files 4194304 bytes!/ in mysqld.1.err +FOUND 1 /InnoDB: Invalid log header checksum/ in mysqld.1.err +# distant future redo log format, with valid 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 +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +FOUND 1 /InnoDB: Unsupported redo log format. The redo log was created with malicious intentions, or perhaps\./ in mysqld.1.err +# valid header, but old-format checkpoint blocks +# 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 +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +FOUND 1 /InnoDB: No valid checkpoint was found; the log was created with malicious intentions, or perhaps\./ in mysqld.1.err +# valid header, valid checkpoint 1, all-zero (invalid) checkpoint 2, invalid block checksum +# 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 +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +FOUND 2 /InnoDB: Invalid log header checksum/ in mysqld.1.err +FOUND 1 /InnoDB: Upgrade after a crash is not supported\. The redo log was created with malicious intentions, or perhaps, and it appears corrupted\./ in mysqld.1.err +# same, but with current-version header +# 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 +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +FOUND 3 /InnoDB: Invalid log header checksum/ in mysqld.1.err +# --innodb-force-recovery=6 (skip the entire 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=6 +SELECT * FROM INFORMATION_SCHEMA.ENGINES +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +InnoDB YES Supports transactions, row-level locking, foreign keys and encryption for tables YES YES YES +FOUND 1 /\[Note\] InnoDB: log sequence number 0.*; transaction id 0/ in mysqld.1.err +# valid header, valid checkpoint 1, all-zero (invalid) checkpoint 2, invalid block number +# 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 +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +# --innodb-force-recovery=6 (skip the entire 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=6 +SELECT * FROM INFORMATION_SCHEMA.ENGINES +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +InnoDB YES Supports transactions, row-level locking, foreign keys and encryption for tables YES YES YES +# Test a corrupted MLOG_FILE_NAME record. +# valid header, valid checkpoint 1, all-zero (invalid) checkpoint 2 +# 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 +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +FOUND 1 /\[ERROR\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with MariaDB 10\.3\.1\./ in mysqld.1.err +# Test a corrupted MLOG_FILE_NAME record. +# valid header, invalid checkpoint 1, valid checkpoint 2, invalid block +# 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 +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +NOT FOUND /InnoDB: Invalid log header checksum +--source include/search_pattern_in_file.inc +let SEARCH_PATTERN=\[ERROR\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with MariaDB 10\.3\.1, and it appears corrupted\./ in mysqld.1.err +# valid header, invalid checkpoint 1, valid checkpoint 2, invalid log record +# 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 +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +FOUND 2 /\[ERROR\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with MariaDB 10\.3\.1\./ in mysqld.1.err +# 10.2 missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT +# 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 +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +FOUND 1 /\[ERROR\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with ibbackup was here!!!1!\./ in mysqld.1.err +# 10.3 missing MLOG_FILE_NAME or MLOG_FILE_DELETE before MLOG_CHECKPOINT +# 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 +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +FOUND 3 /\[ERROR\] InnoDB: Upgrade after a crash is not supported\. The redo log was created with MariaDB 10\.3\.1\./ in mysqld.1.err +# Empty 10.3 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 --innodb-log-file-size=4m +SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +COUNT(*) +1 +FOUND 1 /InnoDB: log sequence number 1213964\b.*; transaction id 0/ in mysqld.1.err +# Empty 10.2 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 --innodb-log-file-size=4m +SELECT COUNT(*) FROM INFORMATION_SCHEMA.ENGINES +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +COUNT(*) +1 +FOUND 3 /InnoDB: Upgrading redo log:/ in mysqld.1.err +# Empty 10.5 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 --innodb-log-file-size=4m +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 +# 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' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +1 +1 +NOT FOUND /InnoDB: Encrypting redo log/ in mysqld.1.err +# restart +ib_buffer_pool +ib_logfile0 +ibdata1 diff --git a/mysql-test/suite/encryption/r/innodb_encrypt_temporary_tables.result b/mysql-test/suite/encryption/r/innodb_encrypt_temporary_tables.result new file mode 100644 index 00000000..541680ae --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb_encrypt_temporary_tables.result @@ -0,0 +1,22 @@ +SELECT variable_value into @old_encrypted FROM information_schema.global_status +WHERE variable_name = 'innodb_encryption_n_temp_blocks_encrypted'; +SELECT variable_value into @old_decrypted FROM information_schema.global_status +WHERE variable_name = 'innodb_encryption_n_temp_blocks_decrypted'; +CREATE TEMPORARY TABLE t1(f1 CHAR(200), f2 CHAR(200)) ENGINE=InnoDB; +INSERT INTO t1 (f1,f2) SELECT '', '' FROM seq_1_to_8192; +CREATE TEMPORARY TABLE t2(f1 CHAR(100), f2 CHAR(200), f3 CHAR(200))ENGINE=InnoDB; +INSERT INTO t2 (f1,f2,f3) SELECT '', '', '' FROM seq_1_to_8192; +SELECT COUNT(*) FROM t1; +COUNT(*) +8192 +SELECT COUNT(*) FROM t2; +COUNT(*) +8192 +SELECT variable_value > @old_encrypted FROM information_schema.global_status +WHERE variable_name = 'innodb_encryption_n_temp_blocks_encrypted'; +variable_value > @old_encrypted +1 +SELECT variable_value > @old_decrypted FROM information_schema.global_status +WHERE variable_name = 'innodb_encryption_n_temp_blocks_decrypted'; +variable_value > @old_decrypted +1 diff --git a/mysql-test/suite/encryption/r/innodb_encryption-page-compression.result b/mysql-test/suite/encryption/r/innodb_encryption-page-compression.result new file mode 100644 index 00000000..1a40dbdf --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb_encryption-page-compression.result @@ -0,0 +1,187 @@ +SET GLOBAL innodb_encryption_threads = 4; +set global innodb_compression_algorithm = 1; +create table innodb_normal (c1 int, b char(20)) engine=innodb; +show warnings; +Level Code Message +create table innodb_page_compressed1 (c1 int, b char(20)) engine=innodb page_compressed=1 page_compression_level=1; +show warnings; +Level Code Message +show create table innodb_page_compressed1; +Table Create Table +innodb_page_compressed1 CREATE TABLE `innodb_page_compressed1` ( + `c1` int(11) DEFAULT NULL, + `b` char(20) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `page_compressed`=1 `page_compression_level`=1 +create table innodb_page_compressed2 (c1 int, b char(20)) engine=innodb page_compressed=1 page_compression_level=2; +show warnings; +Level Code Message +show create table innodb_page_compressed2; +Table Create Table +innodb_page_compressed2 CREATE TABLE `innodb_page_compressed2` ( + `c1` int(11) DEFAULT NULL, + `b` char(20) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `page_compressed`=1 `page_compression_level`=2 +create table innodb_page_compressed3 (c1 int, b char(20)) engine=innodb page_compressed=1 page_compression_level=3; +show warnings; +Level Code Message +show create table innodb_page_compressed3; +Table Create Table +innodb_page_compressed3 CREATE TABLE `innodb_page_compressed3` ( + `c1` int(11) DEFAULT NULL, + `b` char(20) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `page_compressed`=1 `page_compression_level`=3 +create table innodb_page_compressed4 (c1 int, b char(20)) engine=innodb page_compressed=1 page_compression_level=4; +show warnings; +Level Code Message +show create table innodb_page_compressed4; +Table Create Table +innodb_page_compressed4 CREATE TABLE `innodb_page_compressed4` ( + `c1` int(11) DEFAULT NULL, + `b` char(20) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `page_compressed`=1 `page_compression_level`=4 +create table innodb_page_compressed5 (c1 int, b char(20)) engine=innodb page_compressed=1 page_compression_level=5; +show warnings; +Level Code Message +show create table innodb_page_compressed5; +Table Create Table +innodb_page_compressed5 CREATE TABLE `innodb_page_compressed5` ( + `c1` int(11) DEFAULT NULL, + `b` char(20) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `page_compressed`=1 `page_compression_level`=5 +create table innodb_page_compressed6 (c1 int, b char(20)) engine=innodb page_compressed=1 page_compression_level=6; +show warnings; +Level Code Message +show create table innodb_page_compressed6; +Table Create Table +innodb_page_compressed6 CREATE TABLE `innodb_page_compressed6` ( + `c1` int(11) DEFAULT NULL, + `b` char(20) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `page_compressed`=1 `page_compression_level`=6 +create table innodb_page_compressed7 (c1 int, b char(20)) engine=innodb page_compressed=1 page_compression_level=7; +show warnings; +Level Code Message +show create table innodb_page_compressed7; +Table Create Table +innodb_page_compressed7 CREATE TABLE `innodb_page_compressed7` ( + `c1` int(11) DEFAULT NULL, + `b` char(20) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `page_compressed`=1 `page_compression_level`=7 +create table innodb_page_compressed8 (c1 int, b char(20)) engine=innodb page_compressed=1 page_compression_level=8; +show warnings; +Level Code Message +show create table innodb_page_compressed8; +Table Create Table +innodb_page_compressed8 CREATE TABLE `innodb_page_compressed8` ( + `c1` int(11) DEFAULT NULL, + `b` char(20) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `page_compressed`=1 `page_compression_level`=8 +create table innodb_page_compressed9 (c1 int, b char(20)) engine=innodb page_compressed=1 page_compression_level=9; +show warnings; +Level Code Message +show create table innodb_page_compressed9; +Table Create Table +innodb_page_compressed9 CREATE TABLE `innodb_page_compressed9` ( + `c1` int(11) DEFAULT NULL, + `b` char(20) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `page_compressed`=1 `page_compression_level`=9 +create procedure innodb_insert_proc (repeat_count int) +begin +declare current_num int; +set current_num = 0; +while current_num < repeat_count do +insert into innodb_normal values(current_num,'testing..'); +set current_num = current_num + 1; +end while; +end// +commit; +begin; +call innodb_insert_proc(2000); +insert into innodb_page_compressed1 select * from innodb_normal; +insert into innodb_page_compressed2 select * from innodb_normal; +insert into innodb_page_compressed3 select * from innodb_normal; +insert into innodb_page_compressed4 select * from innodb_normal; +insert into innodb_page_compressed5 select * from innodb_normal; +insert into innodb_page_compressed6 select * from innodb_normal; +insert into innodb_page_compressed7 select * from innodb_normal; +insert into innodb_page_compressed8 select * from innodb_normal; +insert into innodb_page_compressed9 select * from innodb_normal; +commit; +select count(*) from innodb_page_compressed1 where c1 < 500000; +count(*) +2000 +select count(*) from innodb_page_compressed2 where c1 < 500000; +count(*) +2000 +select count(*) from innodb_page_compressed3 where c1 < 500000; +count(*) +2000 +select count(*) from innodb_page_compressed4 where c1 < 500000; +count(*) +2000 +select count(*) from innodb_page_compressed5 where c1 < 500000; +count(*) +2000 +select count(*) from innodb_page_compressed6 where c1 < 500000; +count(*) +2000 +select count(*) from innodb_page_compressed7 where c1 < 500000; +count(*) +2000 +select count(*) from innodb_page_compressed8 where c1 < 500000; +count(*) +2000 +select count(*) from innodb_page_compressed9 where c1 < 500000; +count(*) +2000 +flush tables innodb_page_compressed1, innodb_page_compressed2, +innodb_page_compressed3, innodb_page_compressed4, +innodb_page_compressed5, innodb_page_compressed6, +innodb_page_compressed7, innodb_page_compressed8, +innodb_page_compressed9 for export; +unlock tables; +# Wait until dirty pages are compressed and encrypted +SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +variable_value > 0 +1 +SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_compressed'; +variable_value > 0 +1 +# restart +SET GLOBAL innodb_encryption_threads = 4; +SET GLOBAL innodb_encrypt_tables = off; +update innodb_page_compressed1 set c1 = c1 + 1; +update innodb_page_compressed2 set c1 = c1 + 1; +update innodb_page_compressed3 set c1 = c1 + 1; +update innodb_page_compressed4 set c1 = c1 + 1; +update innodb_page_compressed5 set c1 = c1 + 1; +update innodb_page_compressed6 set c1 = c1 + 1; +update innodb_page_compressed7 set c1 = c1 + 1; +update innodb_page_compressed8 set c1 = c1 + 1; +update innodb_page_compressed9 set c1 = c1 + 1; +flush tables innodb_page_compressed1, innodb_page_compressed2, +innodb_page_compressed3, innodb_page_compressed4, +innodb_page_compressed5, innodb_page_compressed6, +innodb_page_compressed7, innodb_page_compressed8, +innodb_page_compressed9 for export; +unlock tables; +# Wait until dirty pages are compressed and encrypted 2 +SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; +variable_value > 0 +1 +SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_compressed'; +variable_value > 0 +1 +SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_decompressed'; +variable_value > 0 +1 +drop procedure innodb_insert_proc; +drop table innodb_normal; +drop table innodb_page_compressed1; +drop table innodb_page_compressed2; +drop table innodb_page_compressed3; +drop table innodb_page_compressed4; +drop table innodb_page_compressed5; +drop table innodb_page_compressed6; +drop table innodb_page_compressed7; +drop table innodb_page_compressed8; +drop table innodb_page_compressed9; diff --git a/mysql-test/suite/encryption/r/innodb_encryption.result b/mysql-test/suite/encryption/r/innodb_encryption.result new file mode 100644 index 00000000..3b1552be --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb_encryption.result @@ -0,0 +1,72 @@ +SET @start_global_value = @@global.innodb_encryption_threads; +SHOW VARIABLES LIKE 'innodb_encrypt%'; +Variable_name Value +innodb_encrypt_log ON +innodb_encrypt_tables ON +innodb_encrypt_temporary_tables OFF +innodb_encryption_rotate_key_age 15 +innodb_encryption_rotation_iops 100 +innodb_encryption_threads 4 +SET GLOBAL innodb_encrypt_tables = ON; +# Wait max 10 min for key encryption threads to encrypt all spaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +NAME +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +NAME +innodb_system +# Success! +# Now turn off encryption and wait for threads to decrypt everything +SET GLOBAL innodb_encrypt_tables = off; +# Wait max 10 min for key encryption threads to decrypt all spaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +NAME +innodb_system +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +NAME +# Success! +# Shutdown innodb_encryption_threads +SET GLOBAL innodb_encryption_threads=0; +# Turn on encryption +# since threads are off tables should remain unencrypted +SET GLOBAL innodb_encrypt_tables = on; +# Wait 15s to check that nothing gets encrypted +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +NAME +innodb_system +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +NAME +# Success! +# Startup innodb_encryption_threads +SET GLOBAL innodb_encryption_threads=@start_global_value; +# Wait max 10 min for key encryption threads to encrypt all spaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +NAME +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +NAME +innodb_system +# Success! +# Restart mysqld --innodb_encrypt_tables=0 --innodb_encryption_threads=0 +# restart: --innodb_encrypt_tables=0 --innodb_encryption_threads=0 +SHOW VARIABLES LIKE 'innodb_encrypt%'; +Variable_name Value +innodb_encrypt_log ON +innodb_encrypt_tables OFF +innodb_encrypt_temporary_tables OFF +innodb_encryption_rotate_key_age 15 +innodb_encryption_rotation_iops 100 +innodb_encryption_threads 0 +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +NAME +innodb_system +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +NAME diff --git a/mysql-test/suite/encryption/r/innodb_encryption_discard_import.result b/mysql-test/suite/encryption/r/innodb_encryption_discard_import.result new file mode 100644 index 00000000..7ee30423 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb_encryption_discard_import.result @@ -0,0 +1,127 @@ +CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB encrypted=yes; +CREATE TABLE t2 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB; +CREATE TABLE t3 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB row_format=compressed encrypted=yes; +create procedure innodb_insert_proc (repeat_count int) +begin +declare current_num int; +set current_num = 0; +while current_num < repeat_count do +insert into t1 values (current_num,repeat('foobar',42)); +insert into t2 values (current_num,repeat('temp', 42)); +insert into t3 values (current_num,repeat('barfoo',42)); +set current_num = current_num + 1; +end while; +end// +commit; +set autocommit=0; +call innodb_insert_proc(10000); +commit; +set autocommit=1; +# Wait max 10 min for key encryption threads to encrypt all spaces +# tablespaces should be now encrypted +# t1 yes on expecting NOT FOUND +NOT FOUND /foobar/ in t1.ibd +# t2 ... on expecting NOT FOUND +NOT FOUND /temp/ in t2.ibd +# t3 ... on expecting NOT FOUND +NOT FOUND /barfoo/ in t3.ibd +# restart +db.opt +t1.frm +t1.ibd +t2.frm +t2.ibd +t3.frm +t3.ibd +FLUSH TABLES t1, t2, t3 FOR EXPORT; +backup: t1 +backup: t2 +backup: t3 +db.opt +t1.cfg +t1.frm +t1.ibd +t2.cfg +t2.frm +t2.ibd +t3.cfg +t3.frm +t3.ibd +UNLOCK TABLES; +ALTER TABLE t1 DISCARD TABLESPACE; +ALTER TABLE t2 DISCARD TABLESPACE; +ALTER TABLE t3 DISCARD TABLESPACE; +restore: t1 .ibd and .cfg files +restore: t2 .ibd and .cfg files +restore: t3 .ibd and .cfg files +ALTER TABLE t1 IMPORT TABLESPACE; +SELECT COUNT(1) FROM t1; +COUNT(1) +10000 +ALTER TABLE t2 IMPORT TABLESPACE; +SELECT COUNT(1) FROM t2; +COUNT(1) +10000 +ALTER TABLE t3 IMPORT TABLESPACE; +SELECT COUNT(1) FROM t3; +COUNT(1) +10000 +# tablespaces should remain encrypted after import +# t1 yes on expecting NOT FOUND +NOT FOUND /foobar/ in t1.ibd +# t2 ... on expecting NOT FOUND +NOT FOUND /temp/ in t2.ibd +# t3 ... on expecting NOT FOUND +NOT FOUND /barfoo/ in t3.ibd +# restart +ALTER TABLE t1 ENGINE InnoDB; +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 COLLATE=latin1_swedish_ci `encrypted`=yes +ALTER TABLE t2 ENGINE InnoDB; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(11) NOT NULL, + `a` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +ALTER TABLE t3 ENGINE InnoDB; +SHOW CREATE TABLE t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `id` int(11) NOT NULL, + `a` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPRESSED `encrypted`=yes +# Restarting server +# restart +# Done restarting server +# Verify that tables are still usable +SELECT COUNT(1) FROM t1; +COUNT(1) +10000 +SELECT COUNT(1) FROM t2; +COUNT(1) +10000 +SELECT COUNT(1) FROM t3; +COUNT(1) +10000 +# Tablespaces should be encrypted after restart +# t1 yes on expecting NOT FOUND +NOT FOUND /foobar/ in t1.ibd +# t2 ... on expecting NOT FOUND +NOT FOUND /temp/ in t2.ibd +# t3 ... on expecting NOT FOUND +NOT FOUND /barfoo/ in t3.ibd +# restart +# Wait max 10 min for key encryption threads to encrypt all spaces +# Success! +# Restart mysqld --innodb_encrypt_tables=0 --innodb_encryption_threads=0 +# restart: --innodb_encrypt_tables=0 --innodb_encryption_threads=0 +DROP PROCEDURE innodb_insert_proc; +DROP TABLE t1, t2, t3; diff --git a/mysql-test/suite/encryption/r/innodb_encryption_filekeys.result b/mysql-test/suite/encryption/r/innodb_encryption_filekeys.result new file mode 100644 index 00000000..b4b07dbe --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb_encryption_filekeys.result @@ -0,0 +1,60 @@ +SET GLOBAL innodb_encrypt_tables = OFF; +SET GLOBAL innodb_encryption_threads = 4; +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `pk` int(11) NOT NULL AUTO_INCREMENT, + `c` varchar(256) DEFAULT NULL, + PRIMARY KEY (`pk`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +CREATE TABLE t2 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=YES; +CREATE TABLE t3 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=NO; +CREATE TABLE t4 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=YES ENCRYPTION_KEY_ID=4; +SET GLOBAL innodb_encrypt_tables = on; +# Wait max 10 min for key encryption threads to encrypt required all spaces +# Success! +SELECT COUNT(1) FROM t1; +COUNT(1) +10 +SELECT COUNT(1) FROM t2; +COUNT(1) +10 +SELECT COUNT(1) FROM t3; +COUNT(1) +10 +SELECT COUNT(1) FROM t4; +COUNT(1) +10 +SET GLOBAL innodb_encrypt_tables = off; +# Wait max 10 min for key encryption threads to decrypt all required spaces +# Success! +SET GLOBAL innodb_encrypt_tables = ON; +set GLOBAL innodb_default_encryption_key_id=4; +CREATE TABLE t5 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB; +SHOW CREATE TABLE t5; +Table Create Table +t5 CREATE TABLE `t5` ( + `pk` int(11) NOT NULL AUTO_INCREMENT, + `c` varchar(256) DEFAULT NULL, + PRIMARY KEY (`pk`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +INSERT INTO t5 select * from t1; +# Wait max 10 min for key encryption threads to encrypt required all spaces +# Success! +SELECT COUNT(1) FROM t1; +COUNT(1) +10 +SELECT COUNT(1) FROM t2; +COUNT(1) +10 +SELECT COUNT(1) FROM t3; +COUNT(1) +10 +SELECT COUNT(1) FROM t4; +COUNT(1) +10 +SELECT COUNT(1) FROM t5; +COUNT(1) +10 +drop table t1,t2,t3,t4, t5; diff --git a/mysql-test/suite/encryption/r/innodb_encryption_is.result b/mysql-test/suite/encryption/r/innodb_encryption_is.result new file mode 100644 index 00000000..0ce4a11f --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb_encryption_is.result @@ -0,0 +1,12 @@ +CREATE TABLE t1 (c VARCHAR(8)) ENGINE=InnoDB ENCRYPTED=YES ENCRYPTION_KEY_ID=1; +CREATE TABLE t2 (c VARCHAR(8)) ENGINE=InnoDB ENCRYPTED=YES ENCRYPTION_KEY_ID=2; +INSERT INTO t1 VALUES ('foobar'); +INSERT INTO t2 VALUES ('foobar'); +SELECT NAME, ENCRYPTION_SCHEME, MIN_KEY_VERSION, CURRENT_KEY_VERSION, +CURRENT_KEY_ID +FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION +WHERE NAME LIKE '%t1' OR NAME LIKE '%t2'; +NAME ENCRYPTION_SCHEME MIN_KEY_VERSION CURRENT_KEY_VERSION CURRENT_KEY_ID +test/t1 1 1 1 1 +test/t2 1 1 1 2 +DROP TABLE t1, t2; diff --git a/mysql-test/suite/encryption/r/innodb_encryption_row_compressed.result b/mysql-test/suite/encryption/r/innodb_encryption_row_compressed.result new file mode 100644 index 00000000..46c170dd --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb_encryption_row_compressed.result @@ -0,0 +1,151 @@ +create table innodb_compressed1(c1 bigint not null primary key, d int, a varchar(20), b char(200)) engine=innodb row_format=compressed encrypted=yes; +create table innodb_compressed2(c1 bigint not null primary key, d int, a varchar(20), b char(200)) engine=innodb row_format=compressed key_block_size=1 encrypted=yes; +create table innodb_compressed3(c1 bigint not null primary key, d int, a varchar(20), b char(200)) engine=innodb row_format=compressed key_block_size=2 encrypted=yes; +create table innodb_compressed4(c1 bigint not null primary key, d int, a varchar(20), b char(200)) engine=innodb row_format=compressed key_block_size=4 encrypted=yes; +insert into innodb_compressed1 values (1, 20, 'private', 'evenmoreprivate'); +insert into innodb_compressed1 values (2, 20, 'private', 'evenmoreprivate'); +insert into innodb_compressed1 values (3, 30, 'private', 'evenmoreprivate'); +insert into innodb_compressed1 values (4, 30, 'private', 'evenmoreprivate'); +insert into innodb_compressed1 values (5, 30, 'private', 'evenmoreprivate'); +insert into innodb_compressed1 values (6, 30, 'private', 'evenmoreprivate'); +insert into innodb_compressed1 values (7, 30, 'private', 'evenmoreprivate'); +insert into innodb_compressed1 values (8, 20, 'private', 'evenmoreprivate'); +insert into innodb_compressed1 values (9, 20, 'private', 'evenmoreprivate'); +insert into innodb_compressed1 values (10, 20, 'private', 'evenmoreprivate'); +insert into innodb_compressed2 select * from innodb_compressed1; +insert into innodb_compressed3 select * from innodb_compressed1; +insert into innodb_compressed4 select * from innodb_compressed1; +# restart +# t1 yes on expecting NOT FOUND +NOT FOUND /private/ in innodb_compressed1.ibd +# t2 yes on expecting NOT FOUND +NOT FOUND /private/ in innodb_compressed2.ibd +# t3 yes on expecting NOT FOUND +NOT FOUND /private/ in innodb_compressed3.ibd +# t4 yes on expecting NOT FOUND +NOT FOUND /private/ in innodb_compressed4.ibd +select * from innodb_compressed1 where d = 20; +c1 d a b +1 20 private evenmoreprivate +2 20 private evenmoreprivate +8 20 private evenmoreprivate +9 20 private evenmoreprivate +10 20 private evenmoreprivate +select * from innodb_compressed1 where d = 30; +c1 d a b +3 30 private evenmoreprivate +4 30 private evenmoreprivate +5 30 private evenmoreprivate +6 30 private evenmoreprivate +7 30 private evenmoreprivate +select * from innodb_compressed2 where d = 20; +c1 d a b +1 20 private evenmoreprivate +2 20 private evenmoreprivate +8 20 private evenmoreprivate +9 20 private evenmoreprivate +10 20 private evenmoreprivate +select * from innodb_compressed2 where d = 30; +c1 d a b +3 30 private evenmoreprivate +4 30 private evenmoreprivate +5 30 private evenmoreprivate +6 30 private evenmoreprivate +7 30 private evenmoreprivate +select * from innodb_compressed3 where d = 20; +c1 d a b +1 20 private evenmoreprivate +2 20 private evenmoreprivate +8 20 private evenmoreprivate +9 20 private evenmoreprivate +10 20 private evenmoreprivate +select * from innodb_compressed3 where d = 30; +c1 d a b +3 30 private evenmoreprivate +4 30 private evenmoreprivate +5 30 private evenmoreprivate +6 30 private evenmoreprivate +7 30 private evenmoreprivate +select * from innodb_compressed4 where d = 20; +c1 d a b +1 20 private evenmoreprivate +2 20 private evenmoreprivate +8 20 private evenmoreprivate +9 20 private evenmoreprivate +10 20 private evenmoreprivate +select * from innodb_compressed4 where d = 30; +c1 d a b +3 30 private evenmoreprivate +4 30 private evenmoreprivate +5 30 private evenmoreprivate +6 30 private evenmoreprivate +7 30 private evenmoreprivate +update innodb_compressed1 set d = d + 10 where d = 30; +update innodb_compressed2 set d = d + 10 where d = 30; +update innodb_compressed3 set d = d + 10 where d = 30; +update innodb_compressed4 set d = d + 10 where d = 30; +insert into innodb_compressed1 values (20, 60, 'newprivate', 'newevenmoreprivate'); +insert into innodb_compressed2 values (20, 60, 'newprivate', 'newevenmoreprivate'); +insert into innodb_compressed3 values (20, 60, 'newprivate', 'newevenmoreprivate'); +insert into innodb_compressed4 values (20, 60, 'newprivate', 'newevenmoreprivate'); +# t1 yes on expecting NOT FOUND +NOT FOUND /private/ in innodb_compressed1.ibd +# t2 yes on expecting NOT FOUND +NOT FOUND /private/ in innodb_compressed2.ibd +# t3 yes on expecting NOT FOUND +NOT FOUND /private/ in innodb_compressed3.ibd +# t4 yes on expecting NOT FOUND +NOT FOUND /private/ in innodb_compressed4.ibd +# restart +select * from innodb_compressed1 where d = 40; +c1 d a b +3 40 private evenmoreprivate +4 40 private evenmoreprivate +5 40 private evenmoreprivate +6 40 private evenmoreprivate +7 40 private evenmoreprivate +select * from innodb_compressed1 where d = 60; +c1 d a b +20 60 newprivate newevenmoreprivate +select * from innodb_compressed2 where d = 40; +c1 d a b +3 40 private evenmoreprivate +4 40 private evenmoreprivate +5 40 private evenmoreprivate +6 40 private evenmoreprivate +7 40 private evenmoreprivate +select * from innodb_compressed2 where d = 60; +c1 d a b +20 60 newprivate newevenmoreprivate +select * from innodb_compressed3 where d = 40; +c1 d a b +3 40 private evenmoreprivate +4 40 private evenmoreprivate +5 40 private evenmoreprivate +6 40 private evenmoreprivate +7 40 private evenmoreprivate +select * from innodb_compressed3 where d = 60; +c1 d a b +20 60 newprivate newevenmoreprivate +select * from innodb_compressed4 where d = 40; +c1 d a b +3 40 private evenmoreprivate +4 40 private evenmoreprivate +5 40 private evenmoreprivate +6 40 private evenmoreprivate +7 40 private evenmoreprivate +select * from innodb_compressed4 where d = 60; +c1 d a b +20 60 newprivate newevenmoreprivate +# t1 yes on expecting NOT FOUND +NOT FOUND /private/ in innodb_compressed1.ibd +# t2 yes on expecting NOT FOUND +NOT FOUND /private/ in innodb_compressed2.ibd +# t3 yes on expecting NOT FOUND +NOT FOUND /private/ in innodb_compressed3.ibd +# t4 yes on expecting NOT FOUND +NOT FOUND /private/ in innodb_compressed4.ibd +drop table innodb_compressed1; +drop table innodb_compressed2; +drop table innodb_compressed3; +drop table innodb_compressed4; diff --git a/mysql-test/suite/encryption/r/innodb_encryption_tables.result b/mysql-test/suite/encryption/r/innodb_encryption_tables.result new file mode 100644 index 00000000..9298e34a --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb_encryption_tables.result @@ -0,0 +1,158 @@ +create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb; +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact; +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic; +create table innodb_compressed(c1 bigint not null, b char(200)) engine=innodb row_format=compressed; +create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant; +show warnings; +Level Code Message +show create table innodb_normal; +Table Create Table +innodb_normal CREATE TABLE `innodb_normal` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +show create table innodb_compact; +Table Create Table +innodb_compact CREATE TABLE `innodb_compact` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPACT +show create table innodb_dynamic; +Table Create Table +innodb_dynamic CREATE TABLE `innodb_dynamic` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=DYNAMIC +show create table innodb_compressed; +Table Create Table +innodb_compressed CREATE TABLE `innodb_compressed` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPRESSED +show create table innodb_redundant; +Table Create Table +innodb_redundant CREATE TABLE `innodb_redundant` ( + `c1` bigint(20) NOT NULL, + `b` char(200) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=REDUNDANT +create procedure innodb_insert_proc (repeat_count int) +begin +declare current_num int; +set current_num = 0; +while current_num < repeat_count do +insert into innodb_normal values(current_num, substring(MD5(RAND()), -64)); +set current_num = current_num + 1; +end while; +end// +commit; +set autocommit=0; +call innodb_insert_proc(2000); +commit; +set autocommit=1; +insert into innodb_compact select * from innodb_normal; +insert into innodb_dynamic select * from innodb_normal; +insert into innodb_compressed select * from innodb_normal; +insert into innodb_redundant select * from innodb_normal; +update innodb_normal set c1 = c1 + 1; +update innodb_compact set c1 = c1 + 1; +update innodb_dynamic set c1 = c1 + 1; +update innodb_compressed set c1 = c1 + 1; +update innodb_redundant set c1 = c1 + 1; +select count(*) from innodb_normal; +count(*) +2000 +select count(*) from innodb_compact where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_dynamic where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_compressed where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_redundant where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_compact t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +select count(*) from innodb_dynamic t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +select count(*) from innodb_compressed t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +select count(*) from innodb_redundant t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +variable_value >= 0 +1 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; +variable_value >= 0 +1 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_compressed'; +variable_value >= 0 +1 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_decompressed'; +variable_value >= 0 +1 +# restart +update innodb_normal set c1 = c1 + 1; +update innodb_compact set c1 = c1 + 1; +update innodb_dynamic set c1 = c1 + 1; +update innodb_compressed set c1 = c1 + 1; +update innodb_redundant set c1 = c1 + 1; +select count(*) from innodb_normal; +count(*) +2000 +select count(*) from innodb_compact where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_dynamic where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_compressed where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_redundant where c1 < 1500000; +count(*) +2000 +select count(*) from innodb_compact t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +select count(*) from innodb_dynamic t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +select count(*) from innodb_compressed t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +select count(*) from innodb_redundant t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +count(*) +2000 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +variable_value >= 0 +1 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; +variable_value >= 0 +1 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_compressed'; +variable_value >= 0 +1 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_decompressed'; +variable_value >= 0 +1 +drop procedure innodb_insert_proc; +drop table innodb_normal; +drop table innodb_compact; +drop table innodb_dynamic; +drop table innodb_compressed; +drop table innodb_redundant; diff --git a/mysql-test/suite/encryption/r/innodb_first_page.result b/mysql-test/suite/encryption/r/innodb_first_page.result new file mode 100644 index 00000000..cf576947 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb_first_page.result @@ -0,0 +1,4 @@ +# restart +create table t1 (a int); +# restart +drop table t1; diff --git a/mysql-test/suite/encryption/r/innodb_import.result b/mysql-test/suite/encryption/r/innodb_import.result new file mode 100644 index 00000000..54b95ab2 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb_import.result @@ -0,0 +1,22 @@ +# +# MDEV-26131 SEGV in ha_innobase::discard_or_import_tablespace +# +CREATE TABLE t1(f1 int,f2 text)ENGINE=InnoDB; +INSERT INTO t1 VALUES(1, "InnoDB"); +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 ADD KEY idx (f2(13)); +ALTER TABLE t2 DISCARD TABLESPACE; +FLUSH TABLES t1 FOR EXPORT; +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; +ERROR HY000: Internal error: Drop all secondary indexes before importing table test/t2 when .cfg file is missing. +ALTER TABLE t2 DROP KEY idx; +Warnings: +Warning 1814 Tablespace has been discarded for table `t2` +ALTER TABLE t2 IMPORT TABLESPACE; +Warnings: +Warning 1810 IO Read error: (2, No such file or directory) Error opening './test/t2.cfg', will attempt to import without schema verification +SELECT * FROM t2; +f1 f2 +1 InnoDB +DROP TABLE t1, t2; diff --git a/mysql-test/suite/encryption/r/innodb_onlinealter_encryption.result b/mysql-test/suite/encryption/r/innodb_onlinealter_encryption.result new file mode 100644 index 00000000..d6e32989 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb_onlinealter_encryption.result @@ -0,0 +1,140 @@ +CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB encrypted=yes; +CREATE TABLE t2 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB; +CREATE TABLE t3 (id INT, a VARCHAR(255)) ENGINE=InnoDB encrypted=yes; +CREATE TABLE t4 (id INT, a VARCHAR(255)) engine=InnoDB; +CREATE TABLE t5 (id INT NOT NULL PRIMARY KEY, a TEXT(500), b VARCHAR(255), FULLTEXT(b)) ENGINE=InnoDB encrypted=yes; +CREATE TABLE t6 (id INT, a TEXT(500), b VARCHAR(255), FULLTEXT(b)) ENGINE=InnoDB; +CREATE TABLE t7 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB row_format=compressed encrypted=yes; +create procedure innodb_insert_proc (repeat_count int) +begin +declare current_num int; +set current_num = 0; +while current_num < repeat_count do +insert into t1 values (current_num,repeat('foobar',12)); +insert into t2 values (current_num,repeat('tempsecret', 12)); +insert into t3 values (current_num,repeat('barfoo',42)); +insert into t4 values (current_num,repeat('repeat',42)); +insert into t5 values (current_num,substring('A BC DEF GHIJ KLM NOPQRS TUV WXYZ 012 3456789', rand()*36+1, 100), repeat('author new',22)); +insert into t6 values (current_num,substring('A BC DEF GHIJ KLM NOPQRS TUV WXYZ 012 3456789', rand()*36+1, 100), repeat('mangled old',22)); +insert into t7 values (current_num,repeat('mysql',42)); +set current_num = current_num + 1; +end while; +end// +commit; +set autocommit=0; +call innodb_insert_proc(1500); +commit; +set autocommit=1; +# Wait max 10 min for key encryption threads to encrypt all spaces +# t1 yes on expecting NOT FOUND +NOT FOUND /foobar/ in t1.ibd +# t2 ... on expecting NOT FOUND +NOT FOUND /tempsecret/ in t2.ibd +# t3 ... on expecting NOT FOUND +NOT FOUND /barfoo/ in t3.ibd +# t4 ... on expecting NOT FOUND +NOT FOUND /repeat/ in t4.ibd +# t5 ... on expecting NOT FOUND +NOT FOUND /author/ in t5.ibd +# t6 ... on expecting NOT FOUND +NOT FOUND /mangled/ in t6.ibd +# t7 ... on expecting NOT FOUND +NOT FOUND /mysql/ in t7.ibd +# restart +SET GLOBAL innodb_file_per_table = ON; +ALTER TABLE t1 ADD COLUMN b int default 2; +ALTER TABLE t2 ADD COLUMN b int default 2; +ALTER TABLE t7 ADD COLUMN b int default 2; +ALTER TABLE t1 ADD KEY a(a), ADD KEY b(b); +ALTER TABLE t2 ADD KEY a(a), ADD KEY b(b); +ALTER TABLE t3 ADD COLUMN c int default 5; +ALTER TABLE t4 ADD COLUMN c int default 5; +ALTER TABLE t3 ADD KEY (a), ADD KEY c(c); +ALTER TABLE t4 ADD KEY (a), ADD KEY c(c); +ALTER TABLE t5 ADD FULLTEXT(a); +ALTER TABLE t6 ADD FULLTEXT(a); +ALTER TABLE t7 ADD KEY a(a), ADD key b(b); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL, + `a` varchar(255) DEFAULT NULL, + `b` int(11) DEFAULT 2, + PRIMARY KEY (`id`), + KEY `a` (`a`), + KEY `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `id` int(11) NOT NULL, + `a` varchar(255) DEFAULT NULL, + `b` int(11) DEFAULT 2, + PRIMARY KEY (`id`), + KEY `a` (`a`), + KEY `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SHOW CREATE TABLE t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `id` int(11) DEFAULT NULL, + `a` varchar(255) DEFAULT NULL, + `c` int(11) DEFAULT 5, + KEY `a` (`a`), + KEY `c` (`c`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes +SHOW CREATE TABLE t4; +Table Create Table +t4 CREATE TABLE `t4` ( + `id` int(11) DEFAULT NULL, + `a` varchar(255) DEFAULT NULL, + `c` int(11) DEFAULT 5, + KEY `a` (`a`), + KEY `c` (`c`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SHOW CREATE TABLE t5; +Table Create Table +t5 CREATE TABLE `t5` ( + `id` int(11) NOT NULL, + `a` text DEFAULT NULL, + `b` varchar(255) DEFAULT NULL, + PRIMARY KEY (`id`), + FULLTEXT KEY `b` (`b`), + FULLTEXT KEY `a` (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci `encrypted`=yes +SHOW CREATE TABLE t6; +Table Create Table +t6 CREATE TABLE `t6` ( + `id` int(11) DEFAULT NULL, + `a` text DEFAULT NULL, + `b` varchar(255) DEFAULT NULL, + FULLTEXT KEY `b` (`b`), + FULLTEXT KEY `a` (`a`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SHOW CREATE TABLE t7; +Table Create Table +t7 CREATE TABLE `t7` ( + `id` int(11) NOT NULL, + `a` varchar(255) DEFAULT NULL, + `b` int(11) DEFAULT 2, + PRIMARY KEY (`id`), + KEY `a` (`a`), + KEY `b` (`b`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci ROW_FORMAT=COMPRESSED `encrypted`=yes +# t1 yes on expecting NOT FOUND +NOT FOUND /foobar/ in t1.ibd +# t2 ... on expecting NOT FOUND +NOT FOUND /tempsecret/ in t2.ibd +# t3 ... on expecting NOT FOUND +NOT FOUND /barfoo/ in t3.ibd +# t4 ... on expecting NOT FOUND +NOT FOUND /repeat/ in t4.ibd +# t5 ... on expecting NOT FOUND +NOT FOUND /author/ in t5.ibd +# t6 ... on expecting NOT FOUND +NOT FOUND /mangled/ in t6.ibd +# t7 ... on expecting NOT FOUND +NOT FOUND /mysql/ in t7.ibd +# restart +DROP PROCEDURE innodb_insert_proc; +DROP TABLE t1, t2, t3, t4, t5, t6, t7; diff --git a/mysql-test/suite/encryption/r/innodb_page_encryption_key_change.result b/mysql-test/suite/encryption/r/innodb_page_encryption_key_change.result new file mode 100644 index 00000000..2b661d53 --- /dev/null +++ b/mysql-test/suite/encryption/r/innodb_page_encryption_key_change.result @@ -0,0 +1,149 @@ +# restart: --loose-file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt +create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb; +show warnings; +Level Code Message +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=2; +show warnings; +Level Code Message +create table innodb_compressed(c1 bigint not null, b char(200)) engine=innodb row_format=compressed encrypted=yes encryption_key_id=3; +show warnings; +Level Code Message +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=4; +show warnings; +Level Code Message +create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant encrypted=yes encryption_key_id=5; +show warnings; +Level Code Message +insert into innodb_normal values (1,'test1'),(2,'foo'),(3,'bar'),(4,'mariadb'); +insert into innodb_compact select * from innodb_normal; +insert into innodb_compressed select * from innodb_normal; +insert into innodb_dynamic select * from innodb_normal; +insert into innodb_redundant select * from innodb_normal; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +variable_value >= 0 +1 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; +variable_value >= 0 +1 +alter table innodb_compact engine=innodb encryption_key_id = 6; +alter table innodb_compressed engine=innodb encryption_key_id = 6; +alter table innodb_dynamic engine=innodb encryption_key_id = 6; +alter table innodb_redundant engine=innodb encryption_key_id = 6; +select * from innodb_normal; +c1 b +1 test1 +2 foo +3 bar +4 mariadb +select * from innodb_compact; +c1 b +1 test1 +2 foo +3 bar +4 mariadb +select * from innodb_compressed; +c1 b +1 test1 +2 foo +3 bar +4 mariadb +select * from innodb_dynamic; +c1 b +1 test1 +2 foo +3 bar +4 mariadb +select * from innodb_redundant; +c1 b +1 test1 +2 foo +3 bar +4 mariadb +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +variable_value >= 0 +1 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; +variable_value >= 0 +1 +# restart: --loose-file-key-management-filename=MYSQL_TEST_DIR/std_data/keys3.txt +select * from innodb_normal; +c1 b +1 test1 +2 foo +3 bar +4 mariadb +select * from innodb_compact; +c1 b +1 test1 +2 foo +3 bar +4 mariadb +select * from innodb_compressed; +c1 b +1 test1 +2 foo +3 bar +4 mariadb +select * from innodb_dynamic; +c1 b +1 test1 +2 foo +3 bar +4 mariadb +select * from innodb_redundant; +c1 b +1 test1 +2 foo +3 bar +4 mariadb +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +variable_value >= 0 +1 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; +variable_value >= 0 +1 +alter table innodb_compact engine=innodb encryption_key_id = 2; +alter table innodb_compressed engine=innodb encryption_key_id = 3; +alter table innodb_dynamic engine=innodb encryption_key_id = 4; +alter table innodb_redundant engine=innodb encryption_key_id = 5; +select * from innodb_normal; +c1 b +1 test1 +2 foo +3 bar +4 mariadb +select * from innodb_compact; +c1 b +1 test1 +2 foo +3 bar +4 mariadb +select * from innodb_compressed; +c1 b +1 test1 +2 foo +3 bar +4 mariadb +select * from innodb_dynamic; +c1 b +1 test1 +2 foo +3 bar +4 mariadb +select * from innodb_redundant; +c1 b +1 test1 +2 foo +3 bar +4 mariadb +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +variable_value >= 0 +1 +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; +variable_value >= 0 +1 +drop table innodb_normal; +drop table innodb_compact; +drop table innodb_compressed; +drop table innodb_dynamic; +drop table innodb_redundant; diff --git a/mysql-test/suite/encryption/r/instant_alter_import.result b/mysql-test/suite/encryption/r/instant_alter_import.result new file mode 100644 index 00000000..cb6e7ea7 --- /dev/null +++ b/mysql-test/suite/encryption/r/instant_alter_import.result @@ -0,0 +1,24 @@ +SET GLOBAL innodb_encrypt_tables = ON; +SET GLOBAL innodb_encryption_threads = 4; +CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT, i2 INT, i1 INT) +ENGINE=INNODB ENCRYPTED=YES ENCRYPTION_KEY_ID=4; +INSERT INTO t1 (i2) SELECT 4 FROM seq_1_to_1024; +ALTER TABLE t1 DROP COLUMN i2, ALGORITHM=INSTANT; +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 DISCARD TABLESPACE; +FLUSH TABLE t1 FOR EXPORT; +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; +DROP TABLE t2, t1; +CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT, i2 INT, i1 INT) +ENGINE=INNODB ENCRYPTED=YES ENCRYPTION_KEY_ID=4 PAGE_COMPRESSED=1; +INSERT INTO t1 (i2) SELECT 4 FROM seq_1_to_1024; +ALTER TABLE t1 DROP COLUMN i2, ALGORITHM=INSTANT; +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 DISCARD TABLESPACE; +FLUSH TABLE t1 FOR EXPORT; +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; +DROP TABLE t2, t1; +SET GLOBAL innodb_encrypt_tables = OFF; +SET GLOBAL innodb_encryption_threads = 0; diff --git a/mysql-test/suite/encryption/r/key_version_rotation.result b/mysql-test/suite/encryption/r/key_version_rotation.result new file mode 100644 index 00000000..afc0a0dd --- /dev/null +++ b/mysql-test/suite/encryption/r/key_version_rotation.result @@ -0,0 +1,20 @@ +create table t1(f1 int not null)engine=innodb; +create table t2(f1 int not null)engine=innodb; +insert into t1 select * from seq_1_to_100; +insert into t2 select * from seq_1_to_100; +# restart: --innodb_encrypt_tables=0 --innodb_encryption_threads=1 --innodb_encryption_rotate_key_age=9 +# Enable encryption +set global innodb_encrypt_tables=ON; +# Create a new table and it is added to rotation list +create table t3(f1 int not null)engine=innodb; +insert into t3 select * from seq_1_to_100; +# Increase the version and it should set rotation +# variable for the encryption plugin +set global debug_key_management_version=10; +select @@debug_key_management_version; +@@debug_key_management_version +10 +# Decrease the key version and Disable the encryption +set global debug_key_management_version=1; +set global innodb_encrypt_tables=off; +DROP TABLE t1, t2, t3; diff --git a/mysql-test/suite/encryption/r/second_plugin-12863.result b/mysql-test/suite/encryption/r/second_plugin-12863.result new file mode 100644 index 00000000..8775b1b8 --- /dev/null +++ b/mysql-test/suite/encryption/r/second_plugin-12863.result @@ -0,0 +1,7 @@ +call mtr.add_suppression('debug.key.management'); +install soname 'debug_key_management'; +ERROR HY000: Can't initialize function 'debug_key_management'; Plugin initialization function failed. +create table t1 (a varchar(255)) engine=innodb encrypted=yes; +create table t2 (a varchar(255)) engine=innodb; +create table t3 (a varchar(255)) engine=innodb encrypted=no; +drop table t1, t2, t3; diff --git a/mysql-test/suite/encryption/r/tempfiles.result b/mysql-test/suite/encryption/r/tempfiles.result new file mode 100644 index 00000000..1c3172a1 --- /dev/null +++ b/mysql-test/suite/encryption/r/tempfiles.result @@ -0,0 +1,109 @@ +select @@encrypt_tmp_files; +@@encrypt_tmp_files +1 +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES(1),(2); +DELETE FROM t1 WHERE a=1; +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +create table t1 (v varchar(10), c char(10), t text, key(v), key(c), key(t(10))); +insert into t1 (v) select concat(char(ascii('a')+s2.seq),repeat(' ',s1.seq)) +from seq_0_to_9 as s1, seq_0_to_26 as s2; +update t1 set c=v, t=v; +select sql_big_result t,count(t) from t1 group by t limit 10; +t count(t) +a 10 +b 10 +c 10 +d 10 +e 10 +f 10 +g 10 +h 10 +i 10 +j 10 +drop table t1; +reset master; +set @save_binlog_cache_size=@@global.binlog_cache_size; +set global binlog_cache_size=8192; +connect con1, localhost, root; +create table t1 (a text) engine=innodb; +start transaction; +insert t1 select repeat(seq, 1000) from seq_1_to_15; +commit; +start transaction; +insert t1 select repeat(seq, 1000) from seq_1_to_8; +commit; +disconnect con1; +connect con2, localhost, root; +create table t2 (a text) engine=innodb; +start transaction; +insert t2 select repeat(seq, 1000) from seq_1_to_15; +savepoint foo; +insert t2 select repeat(seq, 1000) from seq_16_to_30; +rollback to savepoint foo; +insert t2 select repeat(seq, 1000) from seq_31_to_40; +commit; +disconnect con2; +connection default; +flush binary logs; +drop table t1, t2; +set @@global.binlog_cache_size=@save_binlog_cache_size; +select left(a, 10) from t1; +left(a, 10) +1111111111 +2222222222 +3333333333 +4444444444 +5555555555 +6666666666 +7777777777 +8888888888 +9999999999 +1010101010 +1111111111 +1212121212 +1313131313 +1414141414 +1515151515 +1111111111 +2222222222 +3333333333 +4444444444 +5555555555 +6666666666 +7777777777 +8888888888 +select left(a, 10) from t2; +left(a, 10) +1111111111 +2222222222 +3333333333 +4444444444 +5555555555 +6666666666 +7777777777 +8888888888 +9999999999 +1010101010 +1111111111 +1212121212 +1313131313 +1414141414 +1515151515 +3131313131 +3232323232 +3333333333 +3434343434 +3535353535 +3636363636 +3737373737 +3838383838 +3939393939 +4040404040 +drop table t1, t2; diff --git a/mysql-test/suite/encryption/r/tempfiles_encrypted.result b/mysql-test/suite/encryption/r/tempfiles_encrypted.result new file mode 100644 index 00000000..d0dadb6d --- /dev/null +++ b/mysql-test/suite/encryption/r/tempfiles_encrypted.result @@ -0,0 +1,4539 @@ +# +# Tests when the temporary files are encrypted +# +select @@encrypt_tmp_files; +@@encrypt_tmp_files +1 +drop table if exists t1,t2; +drop view if exists v1; +# ######################################################################## +# # Parser tests +# ######################################################################## +# +# Check what happens when one attempts to use window function without OVER clause +create table t1 (a int, b int); +insert into t1 values (1,1),(2,2); +select row_number() from t1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'from t1' at line 1 +select rank() from t1; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'from t1' at line 1 +# Attempt to use window function in the WHERE clause +select * from t1 where 1=rank() over (order by a); +ERROR HY000: Window function is allowed only in SELECT list and ORDER BY clause +select * from t1 where 1>row_number() over (partition by b order by a); +ERROR HY000: Window function is allowed only in SELECT list and ORDER BY clause +drop table t1; +# ######################################################################## +# # Functionality tests +# ######################################################################## +# +# Check if ROW_NUMBER() works in basic cases +create table t1(a int, b int, x char(32)); +insert into t1 values (2, 10, 'xx'); +insert into t1 values (2, 10, 'zz'); +insert into t1 values (2, 20, 'yy'); +insert into t1 values (3, 10, 'xxx'); +insert into t1 values (3, 20, 'vvv'); +select a, row_number() over (partition by a order by b) from t1; +a row_number() over (partition by a order by b) +2 1 +2 2 +2 3 +3 1 +3 2 +select a, b, x, row_number() over (partition by a order by x) from t1; +a b x row_number() over (partition by a order by x) +2 10 xx 1 +2 20 yy 2 +2 10 zz 3 +3 20 vvv 1 +3 10 xxx 2 +drop table t1; +create table t1 (pk int primary key, a int, b int); +insert into t1 values +(1, 10, 22), +(2, 11, 21), +(3, 12, 20), +(4, 13, 19), +(5, 14, 18); +select +pk, a, b, +row_number() over (order by a), +row_number() over (order by b) +from t1 +order by b; +pk a b row_number() over (order by a) row_number() over (order by b) +5 14 18 5 1 +4 13 19 4 2 +3 12 20 3 3 +2 11 21 2 4 +1 10 22 1 5 +drop table t1; +# +# Try RANK() function +# +create table t2 ( +pk int primary key, +a int +); +insert into t2 values +( 1 , 0), +( 2 , 0), +( 3 , 1), +( 4 , 1), +( 8 , 2), +( 5 , 2), +( 6 , 2), +( 7 , 2), +( 9 , 4), +(10 , 4); +select pk, a, rank() over (order by a) from t2; +pk a rank() over (order by a) +1 0 1 +10 4 9 +2 0 1 +3 1 3 +4 1 3 +5 2 5 +6 2 5 +7 2 5 +8 2 5 +9 4 9 +select pk, a, rank() over (order by a desc) from t2; +pk a rank() over (order by a desc) +1 0 9 +10 4 1 +2 0 9 +3 1 7 +4 1 7 +5 2 3 +6 2 3 +7 2 3 +8 2 3 +9 4 1 +drop table t2; +# +# Try Aggregates as window functions. With frames. +# +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (pk int, c int); +insert into t1 select a+1,1 from t0; +update t1 set c=2 where pk not in (1,2,3,4); +select * from t1; +pk c +1 1 +2 1 +3 1 +4 1 +5 2 +6 2 +7 2 +8 2 +9 2 +10 2 +select +pk, c, +count(*) over (partition by c order by pk +rows between 2 preceding and 2 following) as CNT +from t1; +pk c CNT +1 1 3 +2 1 4 +3 1 4 +4 1 3 +5 2 3 +6 2 4 +7 2 5 +8 2 5 +9 2 4 +10 2 3 +select +pk, c, +count(*) over (partition by c order by pk +rows between 1 preceding and 2 following) as CNT +from t1; +pk c CNT +1 1 3 +2 1 4 +3 1 3 +4 1 2 +5 2 3 +6 2 4 +7 2 4 +8 2 4 +9 2 3 +10 2 2 +select +pk, c, +count(*) over (partition by c order by pk +rows between 2 preceding and current row) as CNT +from t1; +pk c CNT +1 1 1 +2 1 2 +3 1 3 +4 1 3 +5 2 1 +6 2 2 +7 2 3 +8 2 3 +9 2 3 +10 2 3 +select +pk,c, +count(*) over (partition by c order by pk rows +between 1 following and 2 following) as CNT +from t1; +pk c CNT +1 1 2 +2 1 2 +3 1 1 +4 1 0 +5 2 2 +6 2 2 +7 2 2 +8 2 2 +9 2 1 +10 2 0 +select +pk,c, +count(*) over (partition by c order by pk rows +between 2 preceding and 1 preceding) as CNT +from t1; +pk c CNT +1 1 0 +2 1 1 +3 1 2 +4 1 2 +5 2 0 +6 2 1 +7 2 2 +8 2 2 +9 2 2 +10 2 2 +select +pk, c, +count(*) over (partition by c order by pk +rows between current row and 1 following) as CNT +from t1; +pk c CNT +1 1 2 +2 1 2 +3 1 2 +4 1 1 +5 2 2 +6 2 2 +7 2 2 +8 2 2 +9 2 2 +10 2 1 +# Check ORDER BY DESC +select +pk, c, +count(*) over (partition by c order by pk desc +rows between 2 preceding and 2 following) as CNT +from t1; +pk c CNT +4 1 3 +3 1 4 +2 1 4 +1 1 3 +10 2 3 +9 2 4 +8 2 5 +7 2 5 +6 2 4 +5 2 3 +drop table t0,t1; +# +# Resolution of window names +# +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (pk int, c int); +insert into t1 select a+1,1 from t0; +update t1 set c=2 where pk not in (1,2,3,4); +select * from t1; +pk c +1 1 +2 1 +3 1 +4 1 +5 2 +6 2 +7 2 +8 2 +9 2 +10 2 +select +pk, c, +count(*) over w1 as CNT +from t1 +window w1 as (partition by c order by pk +rows between 2 preceding and 2 following); +pk c CNT +1 1 3 +2 1 4 +3 1 4 +4 1 3 +5 2 3 +6 2 4 +7 2 5 +8 2 5 +9 2 4 +10 2 3 +select +pk, c, +count(*) over (w1 rows between 2 preceding and 2 following) as CNT +from t1 +window w1 as (partition by c order by pk); +pk c CNT +1 1 3 +2 1 4 +3 1 4 +4 1 3 +5 2 3 +6 2 4 +7 2 5 +8 2 5 +9 2 4 +10 2 3 +select +pk, c, +count(*) over (w1 order by pk rows between 2 preceding and 2 following) as CNT +from t1 +window w1 as (partition by c); +pk c CNT +1 1 3 +2 1 4 +3 1 4 +4 1 3 +5 2 3 +6 2 4 +7 2 5 +8 2 5 +9 2 4 +10 2 3 +select +pk, c, +count(*) over (w2 rows between 2 preceding and 2 following) as CNT +from t1 +window w1 as (partition by c), w2 as (w1 order by pk); +pk c CNT +1 1 3 +2 1 4 +3 1 4 +4 1 3 +5 2 3 +6 2 4 +7 2 5 +8 2 5 +9 2 4 +10 2 3 +select +pk, c, +count(*) over w3 as CNT +from t1 +window +w1 as (partition by c), +w2 as (w1 order by pk), +w3 as (w2 rows between 2 preceding and 2 following); +pk c CNT +1 1 3 +2 1 4 +3 1 4 +4 1 3 +5 2 3 +6 2 4 +7 2 5 +8 2 5 +9 2 4 +10 2 3 +select +pk, c, +count(*) over w as CNT +from t1 +window w1 as (partition by c order by pk +rows between 2 preceding and 2 following); +ERROR HY000: Window specification with name 'w' is not defined +select +pk, c, +count(*) over (w2 rows between 2 preceding and 2 following) as CNT +from t1 +window w1 as (partition by c), w1 as (order by pk); +ERROR HY000: Multiple window specifications with the same name 'w1' +select +pk, c, +count(*) over (w2 rows between 2 preceding and 2 following) as CNT +from t1 +window w1 as (partition by c), w2 as (w partition by c order by pk); +ERROR HY000: Window specification with name 'w' is not defined +select +pk, c, +count(*) over (w2 rows between 2 preceding and 2 following) as CNT +from t1 +window w1 as (partition by c), w2 as (w1 partition by c order by pk); +ERROR HY000: Window specification referencing another one 'w1' cannot contain partition list +select +pk, c, +count(*) over (w2 rows between 2 preceding and 2 following) as CNT +from t1 +window w1 as (partition by c order by pk), w2 as (w1 order by pk); +ERROR HY000: Referenced window specification 'w1' already contains order list +select +pk, c, +count(*) over w3 as CNT +from t1 +window +w1 as (partition by c), +w2 as (w1 order by pk rows between 3 preceding and 2 following), +w3 as (w2 rows between 2 preceding and 2 following); +ERROR HY000: Referenced window specification 'w2' cannot contain window frame +select +pk, c, +count(*) over w1 as CNT +from t1 +window w1 as (partition by c order by pk +rows between unbounded following and 2 following); +ERROR HY000: Unacceptable combination of window frame bound specifications +select +pk, c, +count(*) over (w1 rows between 2 preceding and unbounded preceding) as CNT +from t1 +window w1 as (partition by c order by pk); +ERROR HY000: Unacceptable combination of window frame bound specifications +select +pk, c, +count(*) over (w1 order by pk rows between current row and 2 preceding) as CNT +from t1 +window w1 as (partition by c); +ERROR HY000: Unacceptable combination of window frame bound specifications +select +pk, c, +count(*) over (w2 rows between 2 following and current row) as CNT +from t1 +window w1 as (partition by c), w2 as (w1 order by pk); +ERROR HY000: Unacceptable combination of window frame bound specifications +select +pk, c +from t1 where rank() over w1 > 2 +window w1 as (partition by c order by pk); +ERROR HY000: Window function is allowed only in SELECT list and ORDER BY clause +select +c, max(pk) as m +from t1 +group by c + rank() over w1 +window w1 as (order by m); +ERROR HY000: Window function is allowed only in SELECT list and ORDER BY clause +select +c, max(pk) as m, rank() over w1 as r +from t1 +group by c+r +window w1 as (order by m); +ERROR HY000: Window function is allowed only in SELECT list and ORDER BY clause +select +c, max(pk) as m, rank() over w1 as r +from t1 +group by c having c+r > 3 +window w1 as (order by m); +ERROR HY000: Window function is allowed only in SELECT list and ORDER BY clause +select +c, max(pk) as m, rank() over w1 as r, +rank() over (partition by r+1 order by m) +from t1 +group by c +window w1 as (order by m); +ERROR HY000: Window function is not allowed in window specification +select +c, max(pk) as m, rank() over w1 as r, +rank() over (partition by m order by r) +from t1 +group by c +window w1 as (order by m); +ERROR HY000: Window function is not allowed in window specification +select +c, max(pk) as m, rank() over w1 as r, dense_rank() over w2 as dr +from t1 +group by c +window w1 as (order by m), w2 as (partition by r order by m); +ERROR HY000: Window function is not allowed in window specification +select +pk, c, +row_number() over (partition by c order by pk +range between unbounded preceding and current row) as r +from t1; +ERROR HY000: Window frame is not allowed with 'row_number' +select +pk, c, +rank() over w1 as r +from t1 +window w1 as (partition by c order by pk +rows between 2 preceding and 2 following); +ERROR HY000: Window frame is not allowed with 'rank' +select +pk, c, +dense_rank() over (partition by c order by pk +rows between 1 preceding and 1 following) as r +from t1; +ERROR HY000: Window frame is not allowed with 'dense_rank' +select +pk, c, +rank() over w1 as r +from t1 +window w1 as (partition by c); +ERROR HY000: No order list in window specification for 'rank' +select +pk, c, +dense_rank() over (partition by c) as r +from t1; +ERROR HY000: No order list in window specification for 'dense_rank' +drop table t0,t1; +# +# MDEV-9634: Window function produces incorrect value +# +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t2 (part_id int, pk int, a int); +insert into t2 select +if(a<5, 0, 1), a, if(a<5, NULL, 1) from t0; +select * from t2; +part_id pk a +0 0 NULL +0 1 NULL +0 2 NULL +0 3 NULL +0 4 NULL +1 5 1 +1 6 1 +1 7 1 +1 8 1 +1 9 1 +select +part_id, pk, a, +count(a) over (partition by part_id order by pk +rows between 1 preceding and 1 following) as CNT +from t2; +part_id pk a CNT +0 0 NULL 0 +0 1 NULL 0 +0 2 NULL 0 +0 3 NULL 0 +0 4 NULL 0 +1 5 1 2 +1 6 1 3 +1 7 1 3 +1 8 1 3 +1 9 1 2 +drop table t0, t2; +# +# RANGE-type bounds +# +create table t3 ( +pk int, +val int +); +insert into t3 values +(0, 1), +(1, 1), +(2, 1), +(3, 2), +(4, 2), +(5, 2), +(6, 2); +select +val, +count(val) over (order by val +range between current row and +current row) +as CNT +from t3; +val CNT +1 3 +1 3 +1 3 +2 4 +2 4 +2 4 +2 4 +insert into t3 values +(7, 3), +(8, 3); +select +val, +count(val) over (order by val +range between current row and +current row) +as CNT +from t3; +val CNT +1 3 +1 3 +1 3 +2 4 +2 4 +2 4 +2 4 +3 2 +3 2 +drop table t3; +# Now, check with PARTITION BY +create table t4 ( +part_id int, +pk int, +val int +); +insert into t4 values +(1234, 100, 1), +(1234, 101, 1), +(1234, 102, 1), +(1234, 103, 2), +(1234, 104, 2), +(1234, 105, 2), +(1234, 106, 2), +(1234, 107, 3), +(1234, 108, 3), +(5678, 200, 1), +(5678, 201, 1), +(5678, 202, 1), +(5678, 203, 2), +(5678, 204, 2), +(5678, 205, 2), +(5678, 206, 2), +(5678, 207, 3), +(5678, 208, 3); +select +part_id, +val, +count(val) over (partition by part_id +order by val +range between current row and +current row) +as CNT +from t4; +part_id val CNT +1234 1 3 +1234 1 3 +1234 1 3 +1234 2 4 +1234 2 4 +1234 2 4 +1234 2 4 +1234 3 2 +1234 3 2 +5678 1 3 +5678 1 3 +5678 1 3 +5678 2 4 +5678 2 4 +5678 2 4 +5678 2 4 +5678 3 2 +5678 3 2 +# +# Try RANGE UNBOUNDED PRECEDING | FOLLOWING +# +select +part_id, +val, +count(val) over (partition by part_id +order by val +range between unbounded preceding and +current row) +as CNT +from t4; +part_id val CNT +1234 1 3 +1234 1 3 +1234 1 3 +1234 2 7 +1234 2 7 +1234 2 7 +1234 2 7 +1234 3 9 +1234 3 9 +5678 1 3 +5678 1 3 +5678 1 3 +5678 2 7 +5678 2 7 +5678 2 7 +5678 2 7 +5678 3 9 +5678 3 9 +select +part_id, +val, +count(val) over (partition by part_id +order by val +range between current row and +unbounded following) +as CNT +from t4; +part_id val CNT +1234 1 9 +1234 1 9 +1234 1 9 +1234 2 6 +1234 2 6 +1234 2 6 +1234 2 6 +1234 3 2 +1234 3 2 +5678 1 9 +5678 1 9 +5678 1 9 +5678 2 6 +5678 2 6 +5678 2 6 +5678 2 6 +5678 3 2 +5678 3 2 +select +part_id, +val, +count(val) over (partition by part_id +order by val +range between unbounded preceding and +unbounded following) +as CNT +from t4; +part_id val CNT +1234 1 9 +1234 1 9 +1234 1 9 +1234 2 9 +1234 2 9 +1234 2 9 +1234 2 9 +1234 3 9 +1234 3 9 +5678 1 9 +5678 1 9 +5678 1 9 +5678 2 9 +5678 2 9 +5678 2 9 +5678 2 9 +5678 3 9 +5678 3 9 +drop table t4; +# +# MDEV-9695: Wrong window frame when using RANGE BETWEEN N FOLLOWING AND PRECEDING +# +create table t1 (pk int, a int, b int); +insert into t1 values +( 1 , 0, 1), +( 2 , 0, 2), +( 3 , 1, 4), +( 4 , 1, 8), +( 5 , 2, 32), +( 6 , 2, 64), +( 7 , 2, 128), +( 8 , 2, 16); +select pk, a, b, +bit_or(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) as bit_or +from t1; +pk a b bit_or +1 0 1 3 +2 0 2 3 +3 1 4 12 +4 1 8 12 +5 2 32 96 +6 2 64 224 +7 2 128 208 +8 2 16 144 +# Extra ROWS n PRECEDING tests +select pk, a, b, +bit_or(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) as bit_or +from t1; +pk a b bit_or +1 0 1 0 +2 0 2 1 +3 1 4 0 +4 1 8 4 +5 2 32 0 +6 2 64 32 +7 2 128 64 +8 2 16 128 +drop table t1; +create table t2 ( +pk int, +a int, +b int +); +insert into t2 values +( 1, 0, 1), +( 2, 0, 2), +( 3, 0, 4), +( 4, 0, 8), +( 5, 1, 16), +( 6, 1, 32), +( 7, 1, 64), +( 8, 1, 128), +( 9, 2, 256), +(10, 2, 512), +(11, 2, 1024), +(12, 2, 2048); +select pk, a, b, +bit_or(b) over (partition by a order by pk ROWS BETWEEN 1 PRECEDING AND 1 PRECEDING) as bit_or +from t2; +pk a b bit_or +1 0 1 0 +2 0 2 1 +3 0 4 2 +4 0 8 4 +5 1 16 0 +6 1 32 16 +7 1 64 32 +8 1 128 64 +9 2 256 0 +10 2 512 256 +11 2 1024 512 +12 2 2048 1024 +select pk, a, b, +bit_or(b) over (partition by a order by pk ROWS BETWEEN 2 PRECEDING AND 2 PRECEDING) as bit_or +from t2; +pk a b bit_or +1 0 1 0 +2 0 2 0 +3 0 4 1 +4 0 8 2 +5 1 16 0 +6 1 32 0 +7 1 64 16 +8 1 128 32 +9 2 256 0 +10 2 512 0 +11 2 1024 256 +12 2 2048 512 +select pk, a, b, +bit_or(b) over (partition by a order by pk ROWS BETWEEN 2 PRECEDING AND 1 PRECEDING) as bit_or +from t2; +pk a b bit_or +1 0 1 0 +2 0 2 1 +3 0 4 3 +4 0 8 6 +5 1 16 0 +6 1 32 16 +7 1 64 48 +8 1 128 96 +9 2 256 0 +10 2 512 256 +11 2 1024 768 +12 2 2048 1536 +# Check CURRENT ROW +select pk, a, b, +bit_or(b) over (partition by a order by pk ROWS BETWEEN CURRENT ROW AND CURRENT ROW) as bit_or +from t2; +pk a b bit_or +1 0 1 1 +2 0 2 2 +3 0 4 4 +4 0 8 8 +5 1 16 16 +6 1 32 32 +7 1 64 64 +8 1 128 128 +9 2 256 256 +10 2 512 512 +11 2 1024 1024 +12 2 2048 2048 +drop table t2; +# +# Try RANGE PRECEDING|FOLLWING n +# +create table t1 ( +part_id int, +pk int, +a int +); +insert into t1 values +(10, 1, 1), +(10, 2, 2), +(10, 3, 4), +(10, 4, 8), +(10, 5,26), +(10, 6,27), +(10, 7,40), +(10, 8,71), +(10, 9,72); +select +pk, a, +count(a) over (ORDER BY a +RANGE BETWEEN UNBOUNDED PRECEDING +AND 10 FOLLOWING) as cnt +from t1; +pk a cnt +1 1 4 +2 2 4 +3 4 4 +4 8 4 +5 26 6 +6 27 6 +7 40 7 +8 71 9 +9 72 9 +select +pk, a, +count(a) over (ORDER BY a DESC +RANGE BETWEEN UNBOUNDED PRECEDING +AND 10 FOLLOWING) as cnt +from t1; +pk a cnt +9 72 2 +8 71 2 +7 40 3 +6 27 5 +5 26 5 +4 8 9 +3 4 9 +2 2 9 +1 1 9 +select +pk, a, +count(a) over (ORDER BY a +RANGE BETWEEN UNBOUNDED PRECEDING +AND 1 FOLLOWING) as cnt +from t1; +pk a cnt +1 1 2 +2 2 2 +3 4 3 +4 8 4 +5 26 6 +6 27 6 +7 40 7 +8 71 9 +9 72 9 +select +pk, a, +count(a) over (ORDER BY a +RANGE BETWEEN UNBOUNDED PRECEDING +AND 10 PRECEDING) as cnt +from t1; +pk a cnt +1 1 0 +2 2 0 +3 4 0 +4 8 0 +5 26 4 +6 27 4 +7 40 6 +8 71 7 +9 72 7 +select +pk, a, +count(a) over (ORDER BY a DESC +RANGE BETWEEN UNBOUNDED PRECEDING +AND 10 PRECEDING) as cnt +from t1; +pk a cnt +9 72 0 +8 71 0 +7 40 2 +6 27 3 +5 26 3 +4 8 5 +3 4 5 +2 2 5 +1 1 5 +select +pk, a, +count(a) over (ORDER BY a +RANGE BETWEEN UNBOUNDED PRECEDING +AND 1 PRECEDING) as cnt +from t1; +pk a cnt +1 1 0 +2 2 1 +3 4 2 +4 8 3 +5 26 4 +6 27 5 +7 40 6 +8 71 7 +9 72 8 +select +pk, a, +count(a) over (ORDER BY a +RANGE BETWEEN 1 PRECEDING +AND CURRENT ROW) as cnt +from t1; +pk a cnt +1 1 1 +2 2 2 +3 4 1 +4 8 1 +5 26 1 +6 27 2 +7 40 1 +8 71 1 +9 72 2 +select +pk, a, +count(a) over (ORDER BY a DESC +RANGE BETWEEN 1 PRECEDING +AND CURRENT ROW) as cnt +from t1; +pk a cnt +9 72 1 +8 71 2 +7 40 1 +6 27 1 +5 26 2 +4 8 1 +3 4 1 +2 2 1 +1 1 2 +select +pk, a, +count(a) over (ORDER BY a +RANGE BETWEEN 1 FOLLOWING +AND 3 FOLLOWING) as cnt +from t1; +pk a cnt +1 1 2 +2 2 1 +3 4 0 +4 8 0 +5 26 1 +6 27 0 +7 40 0 +8 71 1 +9 72 0 +# Try CURRENT ROW with[out] DESC +select +pk, a, +count(a) over (ORDER BY a +RANGE BETWEEN CURRENT ROW +AND 1 FOLLOWING) as cnt +from t1; +pk a cnt +1 1 2 +2 2 1 +3 4 1 +4 8 1 +5 26 2 +6 27 1 +7 40 1 +8 71 2 +9 72 1 +select +pk, a, +count(a) over (order by a desc +range between current row +and 1 following) as cnt +from t1; +pk a cnt +9 72 2 +8 71 1 +7 40 1 +6 27 2 +5 26 1 +4 8 1 +3 4 1 +2 2 2 +1 1 1 +insert into t1 select 22, pk, a from t1; +select +part_id, pk, a, +count(a) over (PARTITION BY part_id +ORDER BY a +RANGE BETWEEN UNBOUNDED PRECEDING +AND 10 FOLLOWING) as cnt +from t1; +part_id pk a cnt +10 1 1 4 +10 2 2 4 +10 3 4 4 +10 4 8 4 +10 5 26 6 +10 6 27 6 +10 7 40 7 +10 8 71 9 +10 9 72 9 +22 1 1 4 +22 2 2 4 +22 3 4 4 +22 4 8 4 +22 5 26 6 +22 6 27 6 +22 7 40 7 +22 8 71 9 +22 9 72 9 +select +pk, a, +count(a) over (PARTITION BY part_id +ORDER BY a +RANGE BETWEEN UNBOUNDED PRECEDING +AND 1 PRECEDING) as cnt +from t1; +pk a cnt +1 1 0 +2 2 1 +3 4 2 +4 8 3 +5 26 4 +6 27 5 +7 40 6 +8 71 7 +9 72 8 +1 1 0 +2 2 1 +3 4 2 +4 8 3 +5 26 4 +6 27 5 +7 40 6 +8 71 7 +9 72 8 +drop table t1; +# Try a RANGE frame over non-integer datatype: +create table t1 ( +col1 int, +a decimal(5,3) +); +insert into t1 values (1, 0.45); +insert into t1 values (1, 0.5); +insert into t1 values (1, 0.55); +insert into t1 values (1, 1.21); +insert into t1 values (1, 1.22); +insert into t1 values (1, 3.33); +select +a, +count(col1) over (order by a +range between 0.1 preceding +and 0.1 following) +from t1; +a count(col1) over (order by a +range between 0.1 preceding +and 0.1 following) +0.450 3 +0.500 3 +0.550 3 +1.210 2 +1.220 2 +3.330 1 +drop table t1; +# +# RANGE-type frames and NULL values +# +create table t1 ( +pk int, +a int, +b int +); +insert into t1 values (1, NULL,1); +insert into t1 values (2, NULL,1); +insert into t1 values (3, NULL,1); +insert into t1 values (4, 10 ,1); +insert into t1 values (5, 11 ,1); +insert into t1 values (6, 12 ,1); +insert into t1 values (7, 13 ,1); +insert into t1 values (8, 14 ,1); +select +pk, a, +count(b) over (order by a +range between 2 preceding +and 2 following) as CNT +from t1 +order by a, pk; +pk a CNT +1 NULL 3 +2 NULL 3 +3 NULL 3 +4 10 3 +5 11 4 +6 12 5 +7 13 4 +8 14 3 +drop table t1; +# +# Try ranges that have bound1 > bound2. The standard actually allows them +# +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (pk int, c int); +insert into t1 select a+1,1 from t0; +update t1 set c=2 where pk not in (1,2,3,4); +select * from t1; +pk c +1 1 +2 1 +3 1 +4 1 +5 2 +6 2 +7 2 +8 2 +9 2 +10 2 +select +pk, c, +count(*) over (partition by c +order by pk +rows between 1 preceding +and 2 preceding) +as cnt +from t1; +pk c cnt +1 1 0 +2 1 0 +3 1 0 +4 1 0 +5 2 0 +6 2 0 +7 2 0 +8 2 0 +9 2 0 +10 2 0 +select +pk, c, +sum(c) over (partition by c +order by pk +rows between 1 preceding +and 2 preceding) +as sum +from t1; +pk c sum +1 1 NULL +2 1 NULL +3 1 NULL +4 1 NULL +5 2 NULL +6 2 NULL +7 2 NULL +8 2 NULL +9 2 NULL +10 2 NULL +select +pk, c, +sum(c) over (partition by c +order by pk +rows between 2 following +and 1 following) +as sum +from t1; +pk c sum +1 1 NULL +2 1 NULL +3 1 NULL +4 1 NULL +5 2 NULL +6 2 NULL +7 2 NULL +8 2 NULL +9 2 NULL +10 2 NULL +select +pk, c, +count(*) over (partition by c +order by pk +range between 1 preceding +and 2 preceding) +as cnt +from t1; +pk c cnt +1 1 0 +2 1 0 +3 1 0 +4 1 0 +5 2 0 +6 2 0 +7 2 0 +8 2 0 +9 2 0 +10 2 0 +drop table t0, t1; +# +# Error checking for frame bounds +# +create table t1 (a int, b int, c varchar(32)); +insert into t1 values (1,1,'foo'); +insert into t1 values (2,2,'bar'); +select +count(*) over (order by a,b +range between unbounded preceding and current row) +from t1; +ERROR HY000: RANGE-type frame requires ORDER BY clause with single sort key +select +count(*) over (order by c +range between unbounded preceding and current row) +from t1; +ERROR HY000: Numeric datatype is required for RANGE-type frame +select +count(*) over (order by a +range between 'abcd' preceding and current row) +from t1; +ERROR HY000: Numeric datatype is required for RANGE-type frame +select +count(*) over (order by a +range between current row and 'foo' following) +from t1; +ERROR HY000: Numeric datatype is required for RANGE-type frame +# Try range frame with invalid bounds +select +count(*) over (order by a +rows between 0.5 preceding and current row) +from t1; +ERROR HY000: Integer is required for ROWS-type frame +select +count(*) over (order by a +rows between current row and 3.14 following) +from t1; +ERROR HY000: Integer is required for ROWS-type frame +# +# EXCLUDE clause is parsed but not supported +# +select +count(*) over (order by a +rows between 1 preceding and 1 following +exclude current row) +from t1; +ERROR HY000: Frame exclusion is not supported yet +select +count(*) over (order by a +range between 1 preceding and 1 following +exclude ties) +from t1; +ERROR HY000: Frame exclusion is not supported yet +select +count(*) over (order by a +range between 1 preceding and 1 following +exclude group) +from t1; +ERROR HY000: Frame exclusion is not supported yet +select +count(*) over (order by a +rows between 1 preceding and 1 following +exclude no others) +from t1; +count(*) over (order by a +rows between 1 preceding and 1 following +exclude no others) +2 +2 +drop table t1; +# +# Window function in grouping query +# +create table t1 ( +username varchar(32), +amount int +); +insert into t1 values +('user1',1), +('user1',5), +('user1',3), +('user2',10), +('user2',20), +('user2',30); +select +username, +sum(amount) as s, +rank() over (order by s desc) +from t1 +group by username; +username s rank() over (order by s desc) +user1 9 2 +user2 60 1 +drop table t1; +# +# mdev-9719: Window function in prepared statement +# +create table t1(a int, b int, x char(32)); +insert into t1 values (2, 10, 'xx'); +insert into t1 values (2, 10, 'zz'); +insert into t1 values (2, 20, 'yy'); +insert into t1 values (3, 10, 'xxx'); +insert into t1 values (3, 20, 'vvv'); +prepare stmt from 'select a, row_number() over (partition by a order by b) from t1'; +execute stmt; +a row_number() over (partition by a order by b) +2 1 +2 2 +2 3 +3 1 +3 2 +drop table t1; +# +# mdev-9754: Window name resolution in prepared statement +# +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (pk int, c int); +insert into t1 select a+1,1 from t0; +update t1 set c=2 where pk not in (1,2,3,4); +select * from t1; +pk c +1 1 +2 1 +3 1 +4 1 +5 2 +6 2 +7 2 +8 2 +9 2 +10 2 +prepare stmt from +'select + pk, c, + count(*) over w1 as CNT +from t1 +window w1 as (partition by c order by pk + rows between 2 preceding and 2 following)'; +execute stmt; +pk c CNT +1 1 3 +2 1 4 +3 1 4 +4 1 3 +5 2 3 +6 2 4 +7 2 5 +8 2 5 +9 2 4 +10 2 3 +drop table t0,t1; +# +# EXPLAIN FORMAT=JSON support for window functions +# +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +explain format=json select rank() over (order by a) from t0; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "window_functions_computation": { + "sorts": [ + { + "filesort": { + "sort_key": "t0.a" + } + } + ], + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t0", + "access_type": "ALL", + "rows": 10, + "filtered": 100 + } + } + ] + } + } + } +} +create table t1 (a int, b int, c int); +insert into t1 select a,a,a from t0; +explain format=json +select +a, +rank() over (order by sum(b)) +from t1 +group by a; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "filesort": { + "sort_key": "t1.a", + "window_functions_computation": { + "sorts": [ + { + "filesort": { + "sort_key": "sum(t1.b)" + } + } + ], + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 10, + "filtered": 100 + } + } + ] + } + } + } + } +} +explain format=json +select +a, +rank() over (order by sum(b)) +from t1 +group by a +order by null; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "window_functions_computation": { + "sorts": [ + { + "filesort": { + "sort_key": "sum(t1.b)" + } + } + ], + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 10, + "filtered": 100 + } + } + ] + } + } + } +} +# +# Check how window function works together with GROUP BY and HAVING +# +select b,max(a) as MX, rank() over (order by b) from t1 group by b having MX in (3,5,7); +b MX rank() over (order by b) +3 3 1 +5 5 2 +7 7 3 +explain format=json +select b,max(a) as MX, rank() over (order by b) from t1 group by b having MX in (3,5,7); +EXPLAIN +{ + "query_block": { + "select_id": 1, + "having_condition": "MX in (3,5,7)", + "filesort": { + "sort_key": "t1.b", + "window_functions_computation": { + "sorts": [ + { + "filesort": { + "sort_key": "t1.b" + } + } + ], + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 10, + "filtered": 100 + } + } + ] + } + } + } + } +} +drop table t1; +drop table t0; +# +# Building ordering index for window functions +# +create table t1 ( +pk int primary key, +a int, +b int, +c int +); +insert into t1 values +(101 , 0, 10, 1), +(102 , 0, 10, 2), +(103 , 1, 10, 3), +(104 , 1, 10, 4), +(108 , 2, 10, 5), +(105 , 2, 20, 6), +(106 , 2, 20, 7), +(107 , 2, 20, 8), +(109 , 4, 20, 9), +(110 , 4, 20, 10), +(111 , 5, NULL, 11), +(112 , 5, 1, 12), +(113 , 5, NULL, 13), +(114 , 5, NULL, 14), +(115 , 5, NULL, 15), +(116 , 6, 1, NULL), +(117 , 6, 1, 10), +(118 , 6, 1, 1), +(119 , 6, 1, NULL), +(120 , 6, 1, NULL), +(121 , 6, 1, NULL), +(122 , 6, 1, 2), +(123 , 6, 1, 20), +(124 , 6, 1, -10), +(125 , 6, 1, NULL), +(126 , 6, 1, NULL), +(127 , 6, 1, NULL); +select sum(b) over (partition by a order by b,pk +rows between unbounded preceding and current row) as c1, +avg(b) over (w1 rows between 1 preceding and 1 following) as c2, +sum(c) over (w2 rows between 1 preceding and 1 following) as c5, +avg(b) over (w1 rows between 5 preceding and 5 following) as c3, +sum(b) over (w1 rows between 1 preceding and 1 following) as c4 +from t1 +window w1 as (partition by a order by b,pk), +w2 as (partition by b order by c,pk); +c1 c2 c5 c3 c4 +1 1.0000 42 1.0000 1 +1 1.0000 NULL 1.0000 2 +10 1.0000 NULL 1.0000 3 +10 10.0000 3 10.0000 20 +10 10.0000 9 10.0000 20 +10 15.0000 9 17.5000 30 +11 1.0000 NULL 1.0000 3 +12 1.0000 -10 1.0000 2 +2 1.0000 24 1.0000 3 +20 10.0000 12 10.0000 20 +20 10.0000 6 10.0000 20 +20 20.0000 27 20.0000 40 +3 1.0000 -7 1.0000 3 +30 16.6667 13 17.5000 50 +4 1.0000 NULL 1.0000 3 +40 20.0000 19 20.0000 40 +5 1.0000 NULL 1.0000 3 +50 20.0000 21 17.5000 60 +6 1.0000 NULL 1.0000 3 +7 1.0000 13 1.0000 3 +70 20.0000 24 17.5000 40 +8 1.0000 32 1.0000 3 +9 1.0000 -9 1.0000 3 +NULL 1.0000 29 1.0000 1 +NULL NULL 24 1.0000 NULL +NULL NULL 38 1.0000 NULL +NULL NULL 42 1.0000 NULL +drop table t1; +# +# MDEV-9848: Window functions: reuse sorting and/or scanning +# +create table t1 (a int, b int, c int); +insert into t1 values +(1,3,1), +(2,2,1), +(3,1,1); +# Check using counters +flush status; +select +rank() over (partition by c order by a), +rank() over (partition by c order by b) +from t1; +rank() over (partition by c order by a) rank() over (partition by c order by b) +1 3 +2 2 +3 1 +show status like '%sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 0 +Sort_range 0 +Sort_rows 6 +Sort_scan 2 +flush status; +select +rank() over (partition by c order by a), +rank() over (partition by c order by a) +from t1; +rank() over (partition by c order by a) rank() over (partition by c order by a) +1 1 +2 2 +3 3 +show status like '%sort%'; +Variable_name Value +Sort_merge_passes 0 +Sort_priority_queue_sorts 0 +Sort_range 0 +Sort_rows 3 +Sort_scan 1 +explain format=json +select +rank() over (partition by c order by a), +rank() over (partition by c order by a) +from t1; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "window_functions_computation": { + "sorts": [ + { + "filesort": { + "sort_key": "t1.c, t1.a" + } + } + ], + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 3, + "filtered": 100 + } + } + ] + } + } + } +} +explain format=json +select +rank() over (order by a), +row_number() over (order by a) +from t1; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "window_functions_computation": { + "sorts": [ + { + "filesort": { + "sort_key": "t1.a" + } + } + ], + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 3, + "filtered": 100 + } + } + ] + } + } + } +} +explain format=json +select +rank() over (partition by c order by a), +count(*) over (partition by c) +from t1; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "window_functions_computation": { + "sorts": [ + { + "filesort": { + "sort_key": "t1.c, t1.a" + } + } + ], + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 3, + "filtered": 100 + } + } + ] + } + } + } +} +explain format=json +select +count(*) over (partition by c), +rank() over (partition by c order by a) +from t1; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "window_functions_computation": { + "sorts": [ + { + "filesort": { + "sort_key": "t1.c, t1.a" + } + } + ], + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 3, + "filtered": 100 + } + } + ] + } + } + } +} +drop table t1; +# +# MDEV-9847: Window functions: crash with big_tables=1 +# +create table t1(a int); +insert into t1 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +set tmp_memory_table_size=0; +select rank() over (order by a) from t1; +rank() over (order by a) +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +set tmp_memory_table_size=default; +drop table t1; +# +# Check if "ORDER BY window_func" works +# +create table t1 (s1 int, s2 char(5)); +insert into t1 values (1,'a'); +insert into t1 values (null,null); +insert into t1 values (1,null); +insert into t1 values (null,'a'); +insert into t1 values (2,'b'); +insert into t1 values (-1,''); +explain format=json +select *, row_number() over (order by s1, s2) as X from t1 order by X desc; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "filesort": { + "sort_key": "row_number() over ( order by t1.s1,t1.s2) desc", + "window_functions_computation": { + "sorts": [ + { + "filesort": { + "sort_key": "t1.s1, t1.s2" + } + } + ], + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 6, + "filtered": 100 + } + } + ] + } + } + } + } +} +select *, row_number() over (order by s1, s2) as X from t1 order by X desc; +s1 s2 X +2 b 6 +1 a 5 +1 NULL 4 +-1 3 +NULL a 2 +NULL NULL 1 +drop table t1; +# +# Try window functions that are not directly present in the select list +# +create table t1 (a int, b int); +insert into t1 values +(1,3), +(2,2), +(3,1); +select +a, b, +rank() over (order by a), rank() over (order by b), +rank() over (order by a) - rank() over (order by b) as diff +from +t1; +a b rank() over (order by a) rank() over (order by b) diff +1 3 1 3 -2 +2 2 2 2 0 +3 1 3 1 2 +drop table t1; +create table t1 (i int); +insert into t1 values (1),(2); +SELECT MAX(i) OVER (PARTITION BY (i)) FROM t1; +MAX(i) OVER (PARTITION BY (i)) +1 +2 +drop table t1; +# +# Check the 0 in ROWS 0 PRECEDING +# +create table t1 ( +part_id int, +pk int, +a int +); +insert into t1 values (1, 1, 1); +insert into t1 values (1, 2, 2); +insert into t1 values (1, 3, 4); +insert into t1 values (1, 4, 8); +select +pk, a, +sum(a) over (order by pk rows between 0 preceding and current row) +from t1; +pk a sum(a) over (order by pk rows between 0 preceding and current row) +1 1 1 +2 2 2 +3 4 4 +4 8 8 +select +pk, a, +sum(a) over (order by pk rows between 1 preceding and 0 preceding) +from t1; +pk a sum(a) over (order by pk rows between 1 preceding and 0 preceding) +1 1 1 +2 2 3 +3 4 6 +4 8 12 +insert into t1 values (200, 1, 1); +insert into t1 values (200, 2, 2); +insert into t1 values (200, 3, 4); +insert into t1 values (200, 4, 8); +select +part_id, pk, a, +sum(a) over (partition by part_id order by pk rows between 0 preceding and current row) +from t1; +part_id pk a sum(a) over (partition by part_id order by pk rows between 0 preceding and current row) +1 1 1 1 +1 2 2 2 +1 3 4 4 +1 4 8 8 +200 1 1 1 +200 2 2 2 +200 3 4 4 +200 4 8 8 +select +part_id, pk, a, +sum(a) over (partition by part_id order by pk rows between 1 preceding and 0 preceding) +from t1; +part_id pk a sum(a) over (partition by part_id order by pk rows between 1 preceding and 0 preceding) +1 1 1 1 +1 2 2 3 +1 3 4 6 +1 4 8 12 +200 1 1 1 +200 2 2 3 +200 3 4 6 +200 4 8 12 +drop table t1; +# +# MDEV-9780, The "DISTINCT must not bet converted into GROUP BY when +# window functions are present" part +# +create table t1 (part_id int, a int); +insert into t1 values +(100, 1), +(100, 2), +(100, 2), +(100, 3), +(2000, 1), +(2000, 2), +(2000, 3), +(2000, 3), +(2000, 3); +select rank() over (partition by part_id order by a) from t1; +rank() over (partition by part_id order by a) +1 +2 +2 +4 +1 +2 +3 +3 +3 +select distinct rank() over (partition by part_id order by a) from t1; +rank() over (partition by part_id order by a) +1 +2 +4 +3 +explain format=json +select distinct rank() over (partition by part_id order by a) from t1; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "duplicate_removal": { + "window_functions_computation": { + "sorts": [ + { + "filesort": { + "sort_key": "t1.part_id, t1.a" + } + } + ], + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 9, + "filtered": 100 + } + } + ] + } + } + } + } +} +drop table t1; +# +# MDEV-9893: Window functions with different ORDER BY lists, +# one of these lists containing an expression +# +create table t1 (s1 int, s2 char(5)); +insert into t1 values (1,'a'); +insert into t1 values (null,null); +insert into t1 values (3,null); +insert into t1 values (4,'a'); +insert into t1 values (2,'b'); +insert into t1 values (-1,''); +select +*, +ROW_NUMBER() OVER (order by s1), +CUME_DIST() OVER (order by -s1) +from t1; +s1 s2 ROW_NUMBER() OVER (order by s1) CUME_DIST() OVER (order by -s1) +-1 2 1.0000000000 +1 a 3 0.8333333333 +2 b 4 0.6666666667 +3 NULL 5 0.5000000000 +4 a 6 0.3333333333 +NULL NULL 1 0.1666666667 +drop table t1; +# +# MDEV-9925: Wrong result with aggregate function as a window function +# +create table t1 (i int); +insert into t1 values (1),(2); +select i, sum(i) over (partition by i) from t1; +i sum(i) over (partition by i) +1 1 +2 2 +drop table t1; +# +# MDEV-9922: Assertion `!join->only_const_tables() && fsort' failed in int create_sort_index +# +create view v1 as select 1 as i; +select rank() over (order by i) from v1; +rank() over (order by i) +1 +drop view v1; +# +# MDEV-10097: Assertion `count > 0' failed in Item_sum_sum::add_helper(bool) +# +CREATE TABLE `orders` ( +`o_orderkey` int(11) NOT NULL, +`o_custkey` int(11) DEFAULT NULL, +PRIMARY KEY (`o_orderkey`) +) DEFAULT CHARSET=latin1; +INSERT INTO `orders` VALUES (59908,242); +INSERT INTO `orders` VALUES (59940,238); +SELECT o_custkey, avg(o_custkey) OVER (PARTITION BY abs(o_custkey) +ORDER BY o_custkey +RANGE BETWEEN 15 FOLLOWING +AND 15 FOLLOWING) from orders; +o_custkey avg(o_custkey) OVER (PARTITION BY abs(o_custkey) +ORDER BY o_custkey +RANGE BETWEEN 15 FOLLOWING +AND 15 FOLLOWING) +238 NULL +242 NULL +DROP table orders; +# +# MDEV-10842: window functions with the same order column +# but different directions +# +create table t1 ( +pk int primary key, +a int, +b int, +c char(10) +); +insert into t1 values +( 1, 0, 1, 'one'), +( 2, 0, 2, 'two'), +( 3, 0, 3, 'three'), +( 4, 1, 1, 'one'), +( 5, 1, 1, 'two'), +( 6, 1, 2, 'three'), +( 7, 2, NULL, 'n_one'), +( 8, 2, 1, 'n_two'), +( 9, 2, 2, 'n_three'), +(10, 2, 0, 'n_four'), +(11, 2, 10, NULL); +select pk, +row_number() over (order by pk desc) as r_desc, +row_number() over (order by pk asc) as r_asc +from t1; +pk r_desc r_asc +11 1 11 +10 2 10 +9 3 9 +8 4 8 +7 5 7 +6 6 6 +5 7 5 +4 8 4 +3 9 3 +2 10 2 +1 11 1 +drop table t1; +# +# MDEV-10874: two window functions with compatible sorting +# +create table t1 ( +pk int primary key, +a int, +b int, +c char(10), +d decimal(10, 3), +e real +); +insert into t1 values +( 1, 0, 1, 'one', 0.1, 0.001), +( 2, 0, 2, 'two', 0.2, 0.002), +( 3, 0, 3, 'three', 0.3, 0.003), +( 4, 1, 2, 'three', 0.4, 0.004), +( 5, 1, 1, 'two', 0.5, 0.005), +( 6, 1, 1, 'one', 0.6, 0.006), +( 7, 2, NULL, 'n_one', 0.5, 0.007), +( 8, 2, 1, 'n_two', NULL, 0.008), +( 9, 2, 2, NULL, 0.7, 0.009), +(10, 2, 0, 'n_four', 0.8, 0.010), +(11, 2, 10, NULL, 0.9, NULL); +select pk, a, d, +sum(d) over (partition by a order by pk +ROWS between 1 preceding and current row) as sum_1, +sum(d) over (order by a +ROWS BETWEEN 1 preceding and 2 following) as sum_2 +from t1; +pk a d sum_1 sum_2 +1 0 0.100 0.100 0.600 +2 0 0.200 0.300 1.000 +3 0 0.300 0.500 1.400 +4 1 0.400 0.400 1.800 +5 1 0.500 0.900 2.000 +6 1 0.600 1.100 1.600 +7 2 0.500 0.500 1.800 +8 2 NULL 0.500 2.000 +9 2 0.700 0.700 2.400 +10 2 0.800 1.500 2.400 +11 2 0.900 1.700 1.700 +explain format=json +select pk, a, d, +sum(d) over (partition by a order by pk +ROWS between 1 preceding and current row) as sum_1, +sum(d) over (order by a +ROWS BETWEEN 1 preceding and 2 following) as sum_2 +from t1; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "window_functions_computation": { + "sorts": [ + { + "filesort": { + "sort_key": "t1.a, t1.pk" + } + } + ], + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 11, + "filtered": 100 + } + } + ] + } + } + } +} +select pk, a, d, +sum(d) over (partition by a order by pk desc +ROWS between 1 preceding and current row) as sum_1, +sum(d) over (order by a +ROWS BETWEEN 1 preceding and 2 following) as sum_2 +from t1; +pk a d sum_1 sum_2 +3 0 0.300 0.300 0.600 +2 0 0.200 0.500 1.200 +1 0 0.100 0.300 1.400 +6 1 0.600 0.600 1.600 +5 1 0.500 1.100 2.400 +4 1 0.400 0.900 2.600 +11 2 0.900 0.900 2.800 +10 2 0.800 1.700 2.400 +9 2 0.700 1.500 2.000 +8 2 NULL 0.700 1.200 +7 2 0.500 0.500 0.500 +drop table t1; +# +# MDEV-9941: two window functions with compatible partitions +# +create table t1 ( +a int, +b int, +c int +); +insert into t1 values +(10, 1, 1), +(10, 3, 10), +(10, 1, 10), +(10, 3, 100), +(10, 5, 1000), +(10, 1, 100); +explain format=json +select +a,b,c, +row_number() over (partition by a), +row_number() over (partition by a, b) +from t1; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "window_functions_computation": { + "sorts": [ + { + "filesort": { + "sort_key": "t1.a, t1.b" + } + } + ], + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 6, + "filtered": 100 + } + } + ] + } + } + } +} +drop table t1; +# +# MDEV-10815: Window Function Expressions Wrong Results +# +create table t(a decimal(35,10), b int); +insert into t(a,b) values(1,1); +insert into t(a,b) values(2,1); +insert into t(a,b) values(0,1); +insert into t(a,b) values(1, 2); +insert into t(a,b) values(1.5,2); +insert into t(a,b) values(3, 2); +insert into t(a,b) values(4.5,2); +select a, b, +sum(t.a) over (partition by t.b order by a) as simple_sum, +sum(t.a) over (partition by t.b order by a) + 1 as sum_and_const, +sum(t.b) over (partition by t.b order by a) + sum(t.a) over (partition by t.b order by a) as sum_and_sum +from t +order by t.b, t.a; +a b simple_sum sum_and_const sum_and_sum +0.0000000000 1 0.0000000000 1.0000000000 1.0000000000 +1.0000000000 1 1.0000000000 2.0000000000 3.0000000000 +2.0000000000 1 3.0000000000 4.0000000000 6.0000000000 +1.0000000000 2 1.0000000000 2.0000000000 3.0000000000 +1.5000000000 2 2.5000000000 3.5000000000 6.5000000000 +3.0000000000 2 5.5000000000 6.5000000000 11.5000000000 +4.5000000000 2 10.0000000000 11.0000000000 18.0000000000 +drop table t; +# +# MDEV-10669: Crash in SELECT with window function used +# +create table t(a decimal(35,10), b int); +insert into t(a,b) values(1,1); +insert into t(a,b) values(2,1); +insert into t(a,b) values(0,1); +SELECT (CASE WHEN sum(t.a) over (partition by t.b)=0 THEN null ELSE null END) AS a FROM t; +a +NULL +NULL +NULL +SELECT ifnull(((t.a) / CASE WHEN sum(t.a) over(partition by t.b) =0 then null else null end) ,0) from t; +ifnull(((t.a) / CASE WHEN sum(t.a) over(partition by t.b) =0 then null else null end) ,0) +0.00000000000000 +0.00000000000000 +0.00000000000000 +SELECT sum(t.a) over (partition by t.b order by a), +sqrt(ifnull((sum(t.a) over (partition by t.b order by a)), 0)) +from t; +sum(t.a) over (partition by t.b order by a) sqrt(ifnull((sum(t.a) over (partition by t.b order by a)), 0)) +0.0000000000 0 +1.0000000000 1 +3.0000000000 1.7320508075688772 +drop table t; +# +# MDEV-10868: view definitions with window functions +# +create table t0 (a int); +insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +create table t1 (pk int, c int); +insert into t1 select a+1,1 from t0; +update t1 set c=2 where pk not in (1,2,3,4); +select * from t1; +pk c +1 1 +2 1 +3 1 +4 1 +5 2 +6 2 +7 2 +8 2 +9 2 +10 2 +select pk, c, c/count(*) over (partition by c order by pk +rows between 1 preceding and 2 following) as CNT +from t1; +pk c CNT +1 1 0.3333 +2 1 0.2500 +3 1 0.3333 +4 1 0.5000 +5 2 0.6667 +6 2 0.5000 +7 2 0.5000 +8 2 0.5000 +9 2 0.6667 +10 2 1.0000 +create view v1 as select pk, c, c/count(*) over (partition by c order by pk +rows between 1 preceding and 2 following) as CNT +from t1; +show create view v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`pk` AS `pk`,`t1`.`c` AS `c`,`t1`.`c` / count(0) over ( partition by `t1`.`c` order by `t1`.`pk` rows between 1 preceding and 2 following ) AS `CNT` from `t1` latin1 latin1_swedish_ci +select * from v1; +pk c CNT +1 1 0.3333 +2 1 0.2500 +3 1 0.3333 +4 1 0.5000 +5 2 0.6667 +6 2 0.5000 +7 2 0.5000 +8 2 0.5000 +9 2 0.6667 +10 2 1.0000 +select pk, c, c/count(*) over w1 as CNT from t1 +window w1 as (partition by c order by pk rows between 1 preceding and 2 following); +pk c CNT +1 1 0.3333 +2 1 0.2500 +3 1 0.3333 +4 1 0.5000 +5 2 0.6667 +6 2 0.5000 +7 2 0.5000 +8 2 0.5000 +9 2 0.6667 +10 2 1.0000 +create view v2 as select pk, c, c/count(*) over w1 as CNT from t1 +window w1 as (partition by c order by pk rows between 1 preceding and 2 following); +show create view v2; +View Create View character_set_client collation_connection +v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `t1`.`pk` AS `pk`,`t1`.`c` AS `c`,`t1`.`c` / count(0) over ( partition by `t1`.`c` order by `t1`.`pk` rows between 1 preceding and 2 following ) AS `CNT` from `t1` latin1 latin1_swedish_ci +select * from v2; +pk c CNT +1 1 0.3333 +2 1 0.2500 +3 1 0.3333 +4 1 0.5000 +5 2 0.6667 +6 2 0.5000 +7 2 0.5000 +8 2 0.5000 +9 2 0.6667 +10 2 1.0000 +select pk, c, c/count(*) over w1 as CNT from t1 +window w1 as (partition by c order by pk rows unbounded preceding); +pk c CNT +1 1 1.0000 +2 1 0.5000 +3 1 0.3333 +4 1 0.2500 +5 2 2.0000 +6 2 1.0000 +7 2 0.6667 +8 2 0.5000 +9 2 0.4000 +10 2 0.3333 +create view v3 as select pk, c, c/count(*) over w1 as CNT from t1 +window w1 as (partition by c order by pk rows unbounded preceding); +show create view v3; +View Create View character_set_client collation_connection +v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `t1`.`pk` AS `pk`,`t1`.`c` AS `c`,`t1`.`c` / count(0) over ( partition by `t1`.`c` order by `t1`.`pk` rows between unbounded preceding and current row ) AS `CNT` from `t1` latin1 latin1_swedish_ci +select * from v3; +pk c CNT +1 1 1.0000 +2 1 0.5000 +3 1 0.3333 +4 1 0.2500 +5 2 2.0000 +6 2 1.0000 +7 2 0.6667 +8 2 0.5000 +9 2 0.4000 +10 2 0.3333 +select pk, c, c/count(*) over (partition by c order by pk +range between 3 preceding and current row) as CNT +from t1; +pk c CNT +1 1 1.0000 +2 1 0.5000 +3 1 0.3333 +4 1 0.2500 +5 2 2.0000 +6 2 1.0000 +7 2 0.6667 +8 2 0.5000 +9 2 0.5000 +10 2 0.5000 +create view v4 as select pk, c, c/count(*) over (partition by c order by pk +range between 3 preceding and current row) as CNT +from t1; +show create view v4; +View Create View character_set_client collation_connection +v4 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v4` AS select `t1`.`pk` AS `pk`,`t1`.`c` AS `c`,`t1`.`c` / count(0) over ( partition by `t1`.`c` order by `t1`.`pk` range between 3 preceding and current row ) AS `CNT` from `t1` latin1 latin1_swedish_ci +select * from v4; +pk c CNT +1 1 1.0000 +2 1 0.5000 +3 1 0.3333 +4 1 0.2500 +5 2 2.0000 +6 2 1.0000 +7 2 0.6667 +8 2 0.5000 +9 2 0.5000 +10 2 0.5000 +drop view v1,v2,v3,v4; +drop table t0,t1; +# +# MDEV-10875: window function in subquery +# +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (3),(1); +CREATE TABLE t2 (c VARCHAR(8)); +INSERT INTO t2 VALUES ('foo'),('bar'),('foo'); +SELECT COUNT(*) OVER (PARTITION BY c) FROM t2; +COUNT(*) OVER (PARTITION BY c) +1 +2 +2 +SELECT * FROM t1 WHERE i IN ( SELECT COUNT(*) OVER (PARTITION BY c) FROM t2 ); +i +1 +DROP TABLE t1, t2; +# +# MDEV-9976: window function without PARTITION BY and ORDER BY +# +CREATE TABLE t1 (id int, a int); +INSERT INTO t1 VALUES +(1,1000), (2,1100), (3,1800), (4,1500), (5,1700), (6,1200), +(7,2000), (8,2100), (9,1600); +SELECT id, sum(a) OVER (PARTITION BY id +ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) +FROM t1; +id sum(a) OVER (PARTITION BY id +1 1000 +2 1100 +3 1800 +4 1500 +5 1700 +6 1200 +7 2000 +8 2100 +9 1600 +ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) +SELECT id, sum(a) OVER (ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) +FROM t1; +id sum(a) OVER (ROWS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING) +1 14000 +2 13000 +3 5900 +4 10700 +5 7600 +6 11900 +7 4100 +8 2100 +9 9200 +DROP TABLE t1; +# +# MDEV-11867: window function with aggregation +# over the result of grouping +# +create table t1 ( +username varchar(32), +amount int +); +insert into t1 values +('user1',1), +('user1',5), +('user1',3), +('user2',10), +('user2',20), +('user2',30); +select username, sum(amount) as s, avg(sum(amount)) over (order by s desc) +from t1 +group by username; +username s avg(sum(amount)) over (order by s desc) +user1 9 34.5000 +user2 60 60.0000 +select username, sum(amount), avg(sum(amount)) over (order by sum(amount) desc) +from t1 +group by username; +username sum(amount) avg(sum(amount)) over (order by sum(amount) desc) +user1 9 34.5000 +user2 60 60.0000 +drop table t1; +# +# MDEV-11594: window function over implicit grouping +# +create table t1 (id int); +insert into t1 values (1), (2), (3), (2); +select sum(id) over (order by sum(id)) from t1; +sum(id) over (order by sum(id)) +1 +select sum(sum(id)) over (order by sum(id)) from t1; +sum(sum(id)) over (order by sum(id)) +8 +drop table t1; +# +# MDEV-9923: integer constant in order by list +# of window specification +# +create table t1 (id int); +insert into t1 values (1), (2), (3), (2); +select rank() over (order by 1) from t1; +rank() over (order by 1) +1 +1 +1 +1 +select rank() over (order by 2) from t1; +rank() over (order by 2) +1 +1 +1 +1 +select rank() over (partition by id order by 2) from t1; +rank() over (partition by id order by 2) +1 +1 +1 +1 +drop table t1; +# +# MDEV-10660: view using a simple window function +# +create table t1 (id int); +insert into t1 values (1), (2), (3), (2); +create view v1(id,rnk) as +select id, rank() over (order by id) from t1; +show create view v1; +View Create View character_set_client collation_connection +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`id` AS `id`,rank() over ( order by `t1`.`id`) AS `rnk` from `t1` latin1 latin1_swedish_ci +select id, rank() over (order by id) from t1; +id rank() over (order by id) +1 1 +2 2 +2 2 +3 4 +select * from v1; +id rnk +1 1 +2 2 +2 2 +3 4 +drop view v1; +drop table t1; +# +# MDEV-11138: window function in the query without tables +# +select row_number() over (); +row_number() over () +1 +select count(*) over (); +count(*) over () +1 +select sum(5) over (); +sum(5) over () +5 +select row_number() over (), sum(5) over (); +row_number() over () sum(5) over () +1 5 +select row_number() over (order by 2); +row_number() over (order by 2) +1 +select row_number() over (partition by 2); +row_number() over (partition by 2) +1 +select row_number() over (partition by 4 order by 1+2); +row_number() over (partition by 4 order by 1+2) +1 +# +# MDEV-11999: execution of prepared statement for +# tableless query with window functions +# +prepare stmt from +"select row_number() over (partition by 4 order by 1+2)"; +execute stmt; +row_number() over (partition by 4 order by 1+2) +1 +execute stmt; +row_number() over (partition by 4 order by 1+2) +1 +deallocate prepare stmt; +# +# MDEV-11745: window function with min/max +# +create table t1 (i int, b int); +insert into t1 values +(1,1),(2,1),(3,1),(4,4),(5,4),(6,4),(7,8),(8,8),(9,8),(10,8); +select b, min(i) over (partition by b) as f +from t1 as tt +order by i; +b f +1 1 +1 1 +1 1 +4 4 +4 4 +4 4 +8 7 +8 7 +8 7 +8 7 +select b, min(i) over (partition by b) as f +from (select * from t1) as tt +order by i; +b f +1 1 +1 1 +1 1 +4 4 +4 4 +4 4 +8 7 +8 7 +8 7 +8 7 +select b, min(i+10) over (partition by b) as f +from t1 as tt +order by i; +b f +1 11 +1 11 +1 11 +4 14 +4 14 +4 14 +8 17 +8 17 +8 17 +8 17 +select b, min(i) over (partition by b) as f +from (select i+10 as i, b from t1) as tt +order by i; +b f +1 11 +1 11 +1 11 +4 14 +4 14 +4 14 +8 17 +8 17 +8 17 +8 17 +select b, min(i+20) over (partition by b) as f +from (select i+10 as i, b from t1) as tt +order by i; +b f +1 31 +1 31 +1 31 +4 34 +4 34 +4 34 +8 37 +8 37 +8 37 +8 37 +select b, max(i) over (partition by b) as f +from t1 as tt +order by i; +b f +1 3 +1 3 +1 3 +4 6 +4 6 +4 6 +8 10 +8 10 +8 10 +8 10 +select b, max(i) over (partition by b) as f +from (select * from t1) as tt +order by i; +b f +1 3 +1 3 +1 3 +4 6 +4 6 +4 6 +8 10 +8 10 +8 10 +8 10 +select b, max(i+10) over (partition by b) as f +from t1 as tt +order by i; +b f +1 13 +1 13 +1 13 +4 16 +4 16 +4 16 +8 20 +8 20 +8 20 +8 20 +select b, max(i) over (partition by b) as f +from (select i+10 as i, b from t1) as tt +order by i; +b f +1 13 +1 13 +1 13 +4 16 +4 16 +4 16 +8 20 +8 20 +8 20 +8 20 +select b, max(i+20) over (partition by b) as f +from (select i+10 as i, b from t1) as tt +order by i; +b f +1 33 +1 33 +1 33 +4 36 +4 36 +4 36 +8 40 +8 40 +8 40 +8 40 +select max(i), max(i), sum(i), count(i) +from t1 as tt +group by b; +max(i) max(i) sum(i) count(i) +3 3 6 3 +6 6 15 3 +10 10 34 4 +select max(i), min(sum(i)) over (partition by count(i)) f +from t1 as tt +group by b; +max(i) f +3 6 +6 6 +10 34 +select max(i), min(sum(i)) over (partition by count(i)) f +from (select * from t1) as tt +group by b; +max(i) f +3 6 +6 6 +10 34 +select max(i+10), min(sum(i)+10) over (partition by count(i)) f +from t1 as tt +group by b; +max(i+10) f +13 16 +16 16 +20 44 +select max(i), max(i), sum(i), count(i) +from (select i+10 as i, b from t1) as tt +group by b; +max(i) max(i) sum(i) count(i) +13 13 36 3 +16 16 45 3 +20 20 74 4 +select max(i), min(sum(i)) over (partition by count(i)) f +from (select i+10 as i, b from t1) as tt +group by b; +max(i) f +13 36 +16 36 +20 74 +select max(i), min(i), min(max(i)-min(i)) over (partition by count(i)) f +from (select i+10 as i, b from t1) as tt +group by b; +max(i) min(i) f +13 11 2 +16 14 2 +20 17 3 +drop table t1; +# +# MDEV-12015: window function over select with WHERE +# that is always FALSE +# +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (3), (1), (2); +SELECT i, ROW_NUMBER() OVER () FROM t1 WHERE 1 = 2; +i ROW_NUMBER() OVER () +SELECT i, COUNT(*) OVER () FROM t1 WHERE 1 = 2; +i COUNT(*) OVER () +DROP TABLE t1; +# +# MDEV-12051: window function in query with implicit grouping +# on always empty set +# +create table t1 (a int, b varchar(8)); +insert into t1 values (1,'foo'),(2,'bar'); +select max(a), row_number() over () from t1 where a > 10; +max(a) row_number() over () +NULL 1 +select max(a), sum(max(a)) over () from t1 where a > 10; +max(a) sum(max(a)) over () +NULL NULL +select max(a), sum(max(a)) over (partition by max(a)) from t1 where a > 10; +max(a) sum(max(a)) over (partition by max(a)) +NULL NULL +select max(a), row_number() over () from t1 where 1 = 2; +max(a) row_number() over () +NULL 1 +select max(a), sum(max(a)) over () from t1 where 1 = 2; +max(a) sum(max(a)) over () +NULL NULL +select max(a), sum(max(a)) over (partition by max(a)) from t1 where 1 = 2; +max(a) sum(max(a)) over (partition by max(a)) +NULL NULL +select max(a), row_number() over () from t1 where 1 = 2 +having max(a) is not null; +max(a) row_number() over () +select max(a), sum(max(a)) over () from t1 where 1 = 2 +having max(a) is not null; +max(a) sum(max(a)) over () +drop table t1; +# +# MDEV-10885: window function in query with implicit grouping +# with constant condition evaluated to false +# +CREATE TABLE t1 (a INT, b VARCHAR(8)); +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); +CREATE TABLE t2 (c INT); +INSERT INTO t2 VALUES (3),(4); +CREATE TABLE t3 (d INT); +INSERT INTO t3 VALUES (5),(6); +SELECT MAX(a), ROW_NUMBER() OVER (PARTITION BY MAX(a)) FROM t1 +WHERE EXISTS ( SELECT * FROM t2 WHERE c IN ( SELECT MAX(d) FROM t3 ) ); +MAX(a) ROW_NUMBER() OVER (PARTITION BY MAX(a)) +NULL 1 +SELECT MAX(a), COUNT(MAX(a)) OVER (PARTITION BY MAX(a)) FROM t1 +WHERE EXISTS ( SELECT * FROM t2 WHERE c IN ( SELECT MAX(d) FROM t3 ) ); +MAX(a) COUNT(MAX(a)) OVER (PARTITION BY MAX(a)) +NULL 0 +SELECT MAX(a), SUM(MAX(a)) OVER (PARTITION BY MAX(a)) FROM t1 +WHERE EXISTS ( SELECT * FROM t2 WHERE c IN ( SELECT MAX(d) FROM t3 ) ); +MAX(a) SUM(MAX(a)) OVER (PARTITION BY MAX(a)) +NULL NULL +SELECT MAX(a), ROW_NUMBER() OVER (PARTITION BY MAX(a)) FROM t1 +WHERE EXISTS ( SELECT * FROM t2 WHERE c IN ( SELECT MAX(d) FROM t3 ) ) +HAVING MAX(a) IS NOT NULL; +MAX(a) ROW_NUMBER() OVER (PARTITION BY MAX(a)) +SELECT a, MAX(a), ROW_NUMBER() OVER (PARTITION BY b) FROM t1 +WHERE EXISTS ( SELECT * FROM t2 WHERE c IN ( SELECT MAX(d) FROM t3 ) ); +a MAX(a) ROW_NUMBER() OVER (PARTITION BY b) +NULL NULL 1 +SELECT a, COUNT(a), AVG(a) OVER (PARTITION BY b) FROM t1 +WHERE EXISTS ( SELECT * FROM t2 WHERE c IN ( SELECT MAX(d) FROM t3 ) ); +a COUNT(a) AVG(a) OVER (PARTITION BY b) +NULL 0 NULL +SELECT a, MAX(a), AVG(a) OVER (PARTITION BY b) FROM t1 +WHERE EXISTS ( SELECT * FROM t2 WHERE c IN ( SELECT MAX(d) FROM t3 ) ); +a MAX(a) AVG(a) OVER (PARTITION BY b) +NULL NULL NULL +DROP TABLE t1,t2,t3; +# +# MDEV-10859: Wrong result of aggregate window function in query +# with HAVING and no ORDER BY +# +create table empsalary (depname varchar(32), empno smallint primary key, salary int); +insert into empsalary values +('develop', 1, 5000), ('develop', 2, 4000),('sales', 3, '6000'),('sales', 4, 5000); +SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary; +depname empno salary avg(salary) OVER (PARTITION BY depname) +develop 1 5000 4500.0000 +develop 2 4000 4500.0000 +sales 3 6000 5500.0000 +sales 4 5000 5500.0000 +SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary ORDER BY depname; +depname empno salary avg(salary) OVER (PARTITION BY depname) +develop 1 5000 4500.0000 +develop 2 4000 4500.0000 +sales 3 6000 5500.0000 +sales 4 5000 5500.0000 +# +# These last 2 should have the same row results, ignoring order. +# +SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary HAVING empno > 1; +depname empno salary avg(salary) OVER (PARTITION BY depname) +develop 2 4000 4000.0000 +sales 3 6000 5500.0000 +sales 4 5000 5500.0000 +SELECT depname, empno, salary, avg(salary) OVER (PARTITION BY depname) FROM empsalary HAVING empno > 1 ORDER BY depname; +depname empno salary avg(salary) OVER (PARTITION BY depname) +develop 2 4000 4000.0000 +sales 3 6000 5500.0000 +sales 4 5000 5500.0000 +drop table empsalary; +# +# MDEV-11868: min(distinct) over () returns wrong value +# +create table TDEC (CDEC int, RNUM int); +create view VDEC as select * from TDEC; +insert into TDEC (CDEC) values (null),(-1),(0),(1),(0),(10); +select TDEC.CDEC, min(TDEC.CDEC) over () from TDEC; +CDEC min(TDEC.CDEC) over () +NULL -1 +-1 -1 +0 -1 +0 -1 +1 -1 +10 -1 +select VDEC.CDEC, min(VDEC.CDEC) over () from VDEC; +CDEC min(VDEC.CDEC) over () +NULL -1 +-1 -1 +0 -1 +0 -1 +1 -1 +10 -1 +select TDEC.CDEC, max(TDEC.CDEC) over () from TDEC; +CDEC max(TDEC.CDEC) over () +NULL 10 +-1 10 +0 10 +0 10 +1 10 +10 10 +select VDEC.CDEC, max(VDEC.CDEC) over () from VDEC; +CDEC max(VDEC.CDEC) over () +NULL 10 +-1 10 +0 10 +0 10 +1 10 +10 10 +select TDEC.CDEC, min(distinct TDEC.CDEC) over () from TDEC; +CDEC min(distinct TDEC.CDEC) over () +NULL -1 +-1 -1 +0 -1 +0 -1 +1 -1 +10 -1 +select VDEC.CDEC, min(distinct VDEC.CDEC) over () from VDEC; +CDEC min(distinct VDEC.CDEC) over () +NULL -1 +-1 -1 +0 -1 +0 -1 +1 -1 +10 -1 +select TDEC.CDEC, max(distinct TDEC.CDEC) over () from TDEC; +CDEC max(distinct TDEC.CDEC) over () +NULL 10 +-1 10 +0 10 +0 10 +1 10 +10 10 +select VDEC.CDEC, max(distinct VDEC.CDEC) over () from VDEC; +CDEC max(distinct VDEC.CDEC) over () +NULL 10 +-1 10 +0 10 +0 10 +1 10 +10 10 +# +# These should be removed once support for them is added. +# +select TDEC.CDEC, count(distinct TDEC.CDEC) over () from TDEC; +ERROR 42000: This version of MariaDB doesn't yet support 'COUNT(DISTINCT) aggregate as window function' +select VDEC.CDEC, count(distinct VDEC.CDEC) over () from VDEC; +ERROR 42000: This version of MariaDB doesn't yet support 'COUNT(DISTINCT) aggregate as window function' +select TDEC.CDEC, sum(distinct TDEC.CDEC) over () from TDEC; +ERROR 42000: This version of MariaDB doesn't yet support 'SUM(DISTINCT) aggregate as window function' +select VDEC.CDEC, sum(distinct VDEC.CDEC) over () from VDEC; +ERROR 42000: This version of MariaDB doesn't yet support 'SUM(DISTINCT) aggregate as window function' +select TDEC.CDEC, avg(distinct TDEC.CDEC) over () from TDEC; +ERROR 42000: This version of MariaDB doesn't yet support 'AVG(DISTINCT) aggregate as window function' +select VDEC.CDEC, avg(distinct VDEC.CDEC) over () from VDEC; +ERROR 42000: This version of MariaDB doesn't yet support 'AVG(DISTINCT) aggregate as window function' +select TDEC.CDEC, GROUP_CONCAT(TDEC.CDEC) over () from TDEC; +ERROR 42000: This version of MariaDB doesn't yet support 'GROUP_CONCAT() aggregate as window function' +select VDEC.CDEC, GROUP_CONCAT(distinct VDEC.CDEC) over () from VDEC; +ERROR 42000: This version of MariaDB doesn't yet support 'GROUP_CONCAT() aggregate as window function' +drop table TDEC; +drop view VDEC; +# +# MDEV-10700: 10.2.2 windowing function returns incorrect result +# +create table t(a int,b int, c int , d int); +insert into t(a,b,c,d) values(1, rand(10)*1000, rand(10)*1000, rand(10)*1000); +insert into t(a,b,c,d) values(1, rand(10)*1000, rand(10)*1000, rand(10)*1000); +replace into t(a,b,c,d) select 1, rand(10)*1000, rand(10)*1000, rand(10)*1000 from t t1, t t2, t t3, t t4, t t5, t t6, t t7, t t8, t t9, t t10, t t11, t t12, t t13, t t14, t t15, t t16, t t17; +select count(distinct s) from (select sum(d) over(partition by a,b,c) as s from t) Z where s > 0; +count(distinct s) +993 +select count(distinct s) from (select sum(d) as s from t group by a,b,c) Z where s > 0; +count(distinct s) +993 +select count(distinct s) from (select sum(d) over(partition by a,b) as s from t) Z where s > 0; +count(distinct s) +993 +select count(distinct s) from (select sum(d) as s from t group by a,b) Z where s > 0; +count(distinct s) +993 +select count(distinct s) from (select sum(d) over(partition by a) as s from t) Z where s > 0; +count(distinct s) +1 +select count(distinct s) from (select sum(d) as s from t group by a) Z where s > 0; +count(distinct s) +1 +drop table t; +# +# MDEV-9924: window function in query with group by optimized away +# +create table t1 (i int); +insert into t1 values (2),(3),(1); +select row_number() over () from t1 group by 1+2; +row_number() over () +1 +select max(i), row_number() over () from t1 group by 1+2; +max(i) row_number() over () +3 1 +select rank() over (order by max(i)) from t1 group by 1+2; +rank() over (order by max(i)) +1 +select i, row_number() over () from t1 group by 1+2; +i row_number() over () +2 1 +select i, rank() over (order by i) rnk from t1 group by 1+2; +i rnk +2 1 +drop table t1; +# +# MDEV-11907: window function as the second operand of division +# +create table t1 (pk int, c int); +insert into t1 values (1,1),(2,1),(3,1),(4,1),(5,2); +set @sql_mode_save= @@sql_mode; +set sql_mode='ERROR_FOR_DIVISION_BY_ZERO'; +select pk, c, c/count(*) over +(partition by c order by pk +rows between 1 preceding and 2 following) as CNT +from t1; +pk c CNT +1 1 0.3333 +2 1 0.2500 +3 1 0.3333 +4 1 0.5000 +5 2 2.0000 +show warnings; +Level Code Message +set sql_mode=@sql_mode_save; +drop table t1; +# +# MDEV-12336: several functions over a window function +# +create table t1 (name varchar(10), cnt int); +insert into t1 values ('Fred', 23), ('Fred', 35), ('Joe', 10); +select q.name, q.row_cnt, +round( 100 * ( q.row_cnt / +sum(q.row_cnt) over +( +order by q.name +rows between +unbounded preceding and +unbounded following +) +),2 +) pct_of_total +from +( +select name, count(*) row_cnt, sum(cnt) sum_cnt +from t1 +group by 1 +) q; +name row_cnt pct_of_total +Fred 2 66.67 +Joe 1 33.33 +drop table t1; +# +# MDEV-11990: window function over min/max aggregation +# +create table t1 (id int); +insert into t1 values (1), (2), (3), (2), (4), (2); +select sum(max(id)) over (order by max(id)) from t1; +sum(max(id)) over (order by max(id)) +4 +explain +select sum(max(id)) over (order by max(id)) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 6 Using temporary +create index idx on t1(id); +select sum(max(id)) over (order by max(id)) from t1; +sum(max(id)) over (order by max(id)) +4 +explain +select sum(max(id)) over (order by max(id)) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL No tables used +select sum(max(id)) over (order by max(id)) from t1 where id < 3; +sum(max(id)) over (order by max(id)) +2 +select count(max(id)) over (order by max(id)) from t1 where id < 3; +count(max(id)) over (order by max(id)) +1 +select max(id), rank() over (order by max(id)) from t1 where id < 3; +max(id) rank() over (order by max(id)) +2 1 +drop table t1; +# +# main.win failure post MDEV-12336 +# +create table t(a decimal(35,10), b int); +insert into t values (1, 10), (2, 20), (3, 30); +prepare stmt from "SELECT (CASE WHEN sum(t.a) over (partition by t.b)=1 THEN 1000 ELSE 300 END) AS a FROM t"; +execute stmt; +a +1000 +300 +300 +drop table t; +# +# MDEV-12851 case with window functions query crashes server +# +create table t1(dt datetime); +insert into t1 values ('2017-05-17'), ('2017-05-18'); +select dt, +case when (max(dt) over (order by dt rows between 1 following and 1 following) is null) +then '9999-12-31 12:00:00' + else max(dt) over (order by dt rows between 1 following and 1 following) +end x, +case when (max(dt) over (order by dt rows between 1 following and 1 following) is not null) +then '9999-12-31 12:00:00' + else max(dt) over (order by dt rows between 1 following and 1 following) +end x +from t1; +dt x x +2017-05-17 00:00:00 2017-05-18 00:00:00 9999-12-31 12:00:00 +2017-05-18 00:00:00 9999-12-31 12:00:00 NULL +drop table t1; +create table t1(i int); +insert into t1 values (null),(1),(2); +select max(i) over (order by i), +max(i) over (order by i) is null, +max(i) over (order by i) is not null +from t1; +max(i) over (order by i) max(i) over (order by i) is null max(i) over (order by i) is not null +NULL 1 0 +1 0 1 +2 0 1 +drop table t1; +# +# MDEV-13189: Window functions crash when using INTERVAL function +# +create table t1(i int); +insert into t1 values (1),(2),(10),(20),(30); +select sum(i) over (order by i), interval(sum(i) over (order by i), 10, 20) +from t1; +sum(i) over (order by i) interval(sum(i) over (order by i), 10, 20) +1 0 +3 0 +13 1 +33 2 +63 2 +drop table t1; +# +# MDEV-13352: Server crashes in st_join_table::remove_duplicates +# +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1),(2); +SELECT DISTINCT ROW_NUMBER() OVER(), i FROM t1 WHERE 0; +ROW_NUMBER() OVER() i +SELECT ROW_NUMBER() OVER(), i FROM t1 WHERE 0; +ROW_NUMBER() OVER() i +DROP TABLE t1; +# +# MDEV-13344: Server crashes in in AGGR_OP::put_record on subquery +# with window function and constant table +# (Testcase only) +# +CREATE TABLE t1 (c CHAR(8)) ENGINE=MyISAM; +INSERT IGNORE INTO t1 VALUES ('foo'); +SELECT ('bar',1) IN ( SELECT c, ROW_NUMBER() OVER (PARTITION BY c) FROM t1); +('bar',1) IN ( SELECT c, ROW_NUMBER() OVER (PARTITION BY c) FROM t1) +0 +DROP TABLE t1; +# +# MDEV-13351: Server crashes in st_select_lex::set_explain_type upon UNION with window function +# +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1),(2); +SELECT Nth_value(i,1) OVER() FROM t1 +UNION ALL +( SELECT Nth_value(i,2) OVER() FROM t1 LIMIT 0 ) +; +Nth_value(i,1) OVER() +1 +1 +DROP TABLE t1; +# +# A regression after MDEV-13351: +# MDEV-13374 : Server crashes in first_linear_tab / st_select_lex::set_explain_type +# upon UNION with aggregate function +# +CREATE TABLE t1 (i INT) ENGINE=MyISAM; +INSERT INTO t1 VALUES (1),(2); +SELECT i AS fld FROM t1 UNION SELECT COUNT(*) AS fld FROM t1; +fld +1 +2 +DROP TABLE t1; +# +# MDEV-13240 Wrong warning with MAX(datetime_field) OVER (...) +# +CREATE TABLE t1 (dt DATETIME); +INSERT INTO t1 VALUES ('2017-05-17'); +SELECT MAX(dt) OVER (ORDER BY dt ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING) FROM t1; +MAX(dt) OVER (ORDER BY dt ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING) +NULL +DROP TABLE t1; +# +# MDEV-13358 FIRST_VALUE throws SQL Error (1292): Incorrect datetime value +# +CREATE TABLE IF NOT EXISTS `fv_test` ( +`SOME_DATE` datetime NOT NULL +); +INSERT INTO `fv_test` (`SOME_DATE`) VALUES ('2017-07-20 12:47:56'); +CREATE TABLE fv_result +SELECT +FIRST_VALUE(SOME_DATE) OVER(ORDER BY SOME_DATE DESC) AS somedate +FROM fv_test; +SHOW CREATE TABLE fv_result; +Table Create Table +fv_result CREATE TABLE `fv_result` ( + `somedate` datetime DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT * FROM fv_result; +somedate +2017-07-20 12:47:56 +DROP TABLE fv_test, fv_result; +# +# MDEV-13649: Server crashes in set_field_to_null_with_conversions or in Field::set_notnull +# +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (0),(1),(2); +SELECT LEAD(a) OVER (PARTITION BY a ORDER BY a) as lead, +a AND LEAD(a) OVER (PARTITION BY a ORDER BY a) AS a_and_lead_part +FROM t1; +lead a_and_lead_part +NULL 0 +NULL NULL +NULL NULL +SELECT a OR LEAD(a) OVER (ORDER BY a) AS a_or_lead_order +FROM t1 +ORDER BY a; +a_or_lead_order +1 +1 +1 +SELECT a AND LEAD(a) OVER (ORDER BY a) AS a_and_lead_order +FROM t1 +ORDER BY a; +a_and_lead_order +0 +1 +NULL +SELECT a XOR LEAD(a) OVER (ORDER BY a) AS a_xor_lead_order +FROM t1 +ORDER BY a; +a_xor_lead_order +1 +0 +NULL +SELECT NOT LEAD(a) OVER (ORDER BY a) AS not_lead_order +FROM t1 +ORDER BY a; +not_lead_order +0 +0 +NULL +SELECT LEAD(a) OVER (ORDER BY a) is not null AS is_not_null_lead_order +FROM t1 +ORDER BY a; +is_not_null_lead_order +1 +1 +0 +drop table t1; +# +# MDEV-13354: Server crashes in find_field_in_tables upon PS with window function and subquery +# +CREATE TABLE t1 (i INT, a char); +INSERT INTO t1 VALUES (1, 'a'),(2, 'b'); +PREPARE stmt FROM "SELECT row_number() over (partition by i order by i), i FROM (SELECT * from t1) as sq"; +EXECUTE stmt; +row_number() over (partition by i order by i) i +1 1 +1 2 +DROP TABLE t1; +# +# MDEV-13384: "window" seems like a reserved column name but it's not listed as one +# +# Currently we allow window as an identifier, except for table aliases. +# +CREATE TABLE door (id INT, window VARCHAR(10)); +SELECT id +FROM door as window; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'window' at line 2 +SELECT id, window +FROM door; +id window +SELECT id, window +FROM door as window; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'window' at line 2 +DROP TABLE door; +# +# MDEV-13352: Server crashes in st_join_table::remove_duplicates +# +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1),(2); +SELECT DISTINCT ROW_NUMBER() OVER(), i FROM t1 WHERE 0; +ROW_NUMBER() OVER() i +SELECT ROW_NUMBER() OVER(), i FROM t1 WHERE 0; +ROW_NUMBER() OVER() i +DROP TABLE t1; +# +# MDEV-15853: Assertion `tab->filesort_result == 0' failed +# +CREATE TABLE t1 ( a1 int); +insert into t1 values (1),(2),(3); +CREATE TABLE t2 (b1 int, a1 int, a2 int); +insert into t2 values (1,2,3),(2,3,4),(3,4,5); +SELECT COUNT(DISTINCT t2.a2), +rank() OVER (ORDER BY t2.b1) +FROM t2 ,t1 GROUP BY t2.b1 ORDER BY t1.a1; +COUNT(DISTINCT t2.a2) rank() OVER (ORDER BY t2.b1) +1 1 +1 2 +1 3 +DROP TABLE t1,t2; +# +# MDEV-16990: server crashes in base_list_iterator::next +# +CREATE TABLE t1(i int); +insert into t1 values (1),(2); +SELECT DISTINCT row_number() OVER (), MAX(1) FROM t1; +row_number() OVER () MAX(1) +1 1 +SELECT DISTINCT BIT_AND(0) OVER (), MAX(1) FROM t1; +BIT_AND(0) OVER () MAX(1) +0 1 +drop table t1; +# +# MDEV-17525: Window functions not working in ONLY_FULL_GROUP_BY mode +# +CREATE TABLE t1 (name CHAR(10), test CHAR(10), score TINYINT); +INSERT INTO t1 VALUES +('Chun', 'SQL', 75), ('Chun', 'Tuning', 73), +('Esben', 'SQL', 43), ('Esben', 'Tuning', 31), +('Kaolin', 'SQL', 56), ('Kaolin', 'Tuning', 88), +('Tatiana', 'SQL', 87), ('Tatiana', 'Tuning', 83); +SET @save_sql_mode= @@sql_mode; +SET sql_mode = 'ONLY_FULL_GROUP_BY'; +SELECT name, test, score, +AVG(score) OVER (PARTITION BY test) AS average_by_test +FROM t1 +ORDER BY test, name; +name test score average_by_test +Chun SQL 75 65.2500 +Esben SQL 43 65.2500 +Kaolin SQL 56 65.2500 +Tatiana SQL 87 65.2500 +Chun Tuning 73 68.7500 +Esben Tuning 31 68.7500 +Kaolin Tuning 88 68.7500 +Tatiana Tuning 83 68.7500 +set @@sql_mode= @save_sql_mode; +SELECT name, test, score, +AVG(score) OVER (PARTITION BY test) AS average_by_test +FROM t1 +ORDER BY test, name; +name test score average_by_test +Chun SQL 75 65.2500 +Esben SQL 43 65.2500 +Kaolin SQL 56 65.2500 +Tatiana SQL 87 65.2500 +Chun Tuning 73 68.7500 +Esben Tuning 31 68.7500 +Kaolin Tuning 88 68.7500 +Tatiana Tuning 83 68.7500 +drop table t1; +# +# MDEV-12575: Server crash in AGGR_OP::put_record or in JOIN_CACHE::free +# or Invalid write in JOIN::make_aggr_tables_info +# +SELECT DISTINCT BIT_OR(100) OVER () FROM dual +GROUP BY LEFT('2018-08-24', 100) order by 1+2; +BIT_OR(100) OVER () +100 +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1),(2); +SELECT * FROM ( +SELECT +ROW_NUMBER() OVER(), i, sum(i) +FROM t1 +WHERE 1=0 +limit 0 +) AS sq; +ROW_NUMBER() OVER() i sum(i) +SELECT * FROM ( +SELECT +ROW_NUMBER() OVER(), i, sum(i) +FROM t1 +WHERE 1=0 +GROUP BY i +) AS sq; +ROW_NUMBER() OVER() i sum(i) +drop table t1; +create table t1 (a int); +explain +select distinct 1, row_number() over (order by 1) from t1 where a=0 group by a with rollup; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +select distinct 1, row_number() over (order by 1) from t1 where a=0 group by a with rollup; +1 row_number() over (order by 1) +drop table t1; +explain +SELECT DISTINCT BIT_OR(100) OVER () FROM dual +GROUP BY LEFT('2018-08-24', 100) WITH ROLLUP +HAVING @A := 'qwerty'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +SELECT DISTINCT BIT_OR(100) OVER () FROM dual +GROUP BY LEFT('2018-08-24', 100) WITH ROLLUP +HAVING @A := 'qwerty'; +BIT_OR(100) OVER () +explain +SELECT DISTINCT BIT_OR(100) OVER () FROM dual +GROUP BY LEFT('2018-08-24', 100) +HAVING @A := 'qwerty'; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +SELECT DISTINCT BIT_OR(100) OVER () FROM dual +GROUP BY LEFT('2018-08-24', 100) +HAVING @A := 'qwerty'; +BIT_OR(100) OVER () +create table t1 (a int); +explain +SELECT DISTINCT BIT_OR(100) OVER () FROM t1 +GROUP BY LEFT('2018-08-24', 100) having 1=1 limit 0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Zero limit +drop table t1; +# +# MDEV-13170: Database service (MySQL) stops after update with trigger +# +CREATE TABLE t1 ( t1_id int, point_id int, ml_id int, UNIQUE KEY t1_ml_u (ml_id,point_id)) ; +INSERT INTO t1 VALUES (1,1,8884),(2,1,8885); +CREATE TABLE t2 ( db_time datetime, au_nr int, col_id int, new_val int); +CREATE TABLE t3 (id1 int, id2 int, d1 int); +CREATE TRIGGER t1_aurtrg AFTER UPDATE ON t1 FOR EACH ROW begin +CREATE OR REPLACE TEMPORARY TABLE trg_u AS +WITH l AS +(SELECT a.*, +Max(t2.col_id) over (PARTITION BY a.d1), +Max(t2.new_val) over (PARTITION BY a.d1) +FROM +(SELECT d1 , id1, id2 FROM t3) a +JOIN t2 ON (a.d1=t2.db_time AND a.id1=t2.au_nr)) +SELECT 1; +END;// +update t1 set ml_id=8884 where point_id=1; +ERROR 23000: Duplicate entry '8884-1' for key 't1_ml_u' +update t1 set ml_id=8884 where point_id=1; +ERROR 23000: Duplicate entry '8884-1' for key 't1_ml_u' +drop table t1, t2,t3; +CREATE TABLE t1 (i INT, a char); +INSERT INTO t1 VALUES (1, 'a'),(2, 'b'); +create view v1 as select * from t1; +PREPARE stmt FROM "SELECT i, row_number() over (partition by i order by i) FROM v1"; +execute stmt; +i row_number() over (partition by i order by i) +1 1 +2 1 +deallocate prepare stmt; +drop table t1; +drop view v1; +# +# MDEV-17676: Assertion `inited==NONE || (inited==RND && scan)' failed in handler::ha_rnd_init +# +CREATE TABLE t1 (b1 text NOT NULL); +INSERT INTO t1 VALUES ('2'),('1'); +EXPLAIN +SELECT DISTINCT MIN(b1) OVER () FROM t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using temporary +SELECT DISTINCT MIN(b1) OVER () FROM t1; +MIN(b1) OVER () +1 +drop table t1; +# +# MDEV-15424: Unreasonal SQL Error (1356) on select from view +# +create table t1 (id int, n1 int); +insert into t1 values (1,1), (2,1), (3,2), (4,4); +create view v1 as SELECT ifnull(max(n1) over (partition by n1),'aaa') FROM t1; +explain select * from v1; +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4 +2 DERIVED t1 ALL NULL NULL NULL NULL 4 Using temporary +select * from v1; +ifnull(max(n1) over (partition by n1),'aaa') +1 +1 +2 +4 +drop table t1; +drop view v1; +# +# MDEV-18431: Select max + row_number giving incorrect result +# +create table t1 (id int, v int); +insert into t1 values (1, 1), (1,2), (1,3), (2, 1), (2, 2); +select e.id, +(select max(t1.v) from t1 where t1.id=e.id) as a, +row_number() over (partition by e.id order by e.v) as b, +(select max(t1.v) from t1 where t1.id=e.id) + (row_number() over (partition by e.id order by e.v)) as sum_a_b +from t1 e; +id a b sum_a_b +1 3 1 4 +1 3 2 5 +1 3 3 6 +2 2 1 3 +2 2 2 4 +drop table t1; +# +# MDEV-15837: Assertion `item1->type() == Item::FIELD_ITEM && item2->type() == Item::FIELD_ITEM' +# failed in compare_order_elements function +# +CREATE TABLE t1 (a1 int); +insert into t1 values (1),(2),(3); +SELECT rank() OVER (ORDER BY 1), ROW_NUMBER() OVER (ORDER BY (EXPORT_SET(5,'Y','N',',',4))) FROM t1; +rank() OVER (ORDER BY 1) ROW_NUMBER() OVER (ORDER BY (EXPORT_SET(5,'Y','N',',',4))) +1 1 +1 2 +1 3 +drop table t1; +# +# MDEV-17781: Server crashes in next_linear_tab +# +CREATE TABLE t1 (i1 int); +explain +(SELECT AVG(0) OVER (), MAX('2') FROM t1) +UNION ALL +(SELECT AVG(0) OVER (), MAX('2') FROM t1); +id select_type table type possible_keys key key_len ref rows Extra +1 PRIMARY NULL NULL NULL NULL NULL NULL NULL No tables used +2 UNION NULL NULL NULL NULL NULL NULL NULL No tables used +(SELECT AVG(0) OVER (), MAX('2') FROM t1) +UNION ALL +(SELECT AVG(0) OVER (), MAX('2') FROM t1); +AVG(0) OVER () MAX('2') +0.0000 NULL +0.0000 NULL +drop table t1; +# +# MDEV-14791: Crash with order by expression containing window functions +# +CREATE TABLE t1 (b1 int, b2 int); +INSERT INTO t1 VALUES (1,1),(0,0); +explain +SELECT b1 from t1 order by row_number() over (ORDER BY b2) + 1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +SELECT b1 from t1 order by row_number() over (ORDER BY b2) + 1; +b1 +0 +1 +explain +SELECT b1 from t1 order by row_number() over (ORDER BY b2); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort +SELECT b1 from t1 order by row_number() over (ORDER BY b2); +b1 +0 +1 +DROP TABLE t1; +CREATE TABLE t1 (a int, b int, c int); +INSERT INTO t1 VALUES (2,3,207), (1,21,909), (7,13,312), (8,64,248); +explain +SELECT * FROM t1 ORDER BY max(t1.a) over (partition by c); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort +SELECT * FROM t1 ORDER BY max(t1.a) over (partition by c); +a b c +1 21 909 +2 3 207 +7 13 312 +8 64 248 +explain +SELECT max(t1.a) over (partition by c) as x, b, c from t1 order by max(t1.a) over (partition by c); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort +SELECT max(t1.a) over (partition by c) as x, b, c from t1 order by max(t1.a) over (partition by c); +x b c +1 21 909 +2 3 207 +7 13 312 +8 64 248 +drop table t1; +# +# MDEV-18373: DENSE_RANK is not calculated correctly +# +create table t1 (a int, b int); +insert into t1 values (60, 1515),(60, 2000),(70, 2000),(55, 1600); +select b, dense_rank() over (order by sum(a)) from t1 group by b; +b dense_rank() over (order by sum(a)) +1515 2 +1600 1 +2000 3 +select b, dense_rank() over (order by sum(a)+1) from t1 group by b; +b dense_rank() over (order by sum(a)+1) +1515 2 +1600 1 +2000 3 +select b, row_number() over (partition by sum(a)) from t1 group by b; +b row_number() over (partition by sum(a)) +1515 1 +1600 1 +2000 1 +select b, row_number() over (partition by sum(a)+1) from t1 group by b; +b row_number() over (partition by sum(a)+1) +1515 1 +1600 1 +2000 1 +drop table t1; +# +# MDEV-18015: Assertion `global_status_var.global_memory_used == 0' failed when using UDF, +# window functions and views +# +create table t1 (id int, n1 int); +insert into t1 values (1,1),(2,1),(3,2),(4,4); +explain +select max(n1) over (partition by 'abc') from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary +select max(n1) over (partition by 'abc') from t1; +max(n1) over (partition by 'abc') +4 +4 +4 +4 +explain +select rank() over (partition by 'abc' order by 'xyz') from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary +select rank() over (partition by 'abc' order by 'xyz') from t1; +rank() over (partition by 'abc' order by 'xyz') +1 +1 +1 +1 +drop table t1; +# +# MDEV-19380: ASAN heap-use-after-free in Protocol::net_store_data +# +CREATE TABLE t1 (i int); +INSERT INTO t1 VALUES (1),(2),(3); +SELECT (SELECT MIN('foo') OVER() FROM t1 LIMIT 1) as x; +x +foo +drop table t1; +# +# MDEV-16579: Wrong result of query using DISTINCT COUNT(*) OVER (*) +# +CREATE TABLE t1 (i int) ; +INSERT INTO t1 VALUES (1),(0),(1),(2),(0),(1),(2),(1),(2); +SELECT DISTINCT COUNT(*) OVER (), MOD(MIN(i),2) FROM t1 GROUP BY i ; +COUNT(*) OVER () MOD(MIN(i),2) +3 0 +3 1 +drop table t1; +# +# MDEV-21318: Wrong results with window functions and implicit grouping +# +CREATE TABLE t1 (a INT); +# +# With empty const table +# The expected result here is 1, NULL +# +explain +SELECT row_number() over(), sum(1) FROM t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 0 Const row not found; Using temporary +SELECT row_number() over(), sum(1) FROM t1; +row_number() over() sum(1) +1 NULL +insert into t1 values (2); +# +# Const table has 1 row, but still impossible where +# The expected result here is 1, NULL +# +EXPLAIN SELECT row_number() over(), sum(1) FROM t1 where a=1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables +SELECT row_number() over(), sum(1) FROM t1 where a=1; +row_number() over() sum(1) +1 NULL +# +# Impossible HAVING +# Empty result is expected +# +EXPLAIN SELECT row_number() over(), sum(1) FROM t1 where a=1 having 1=0; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible HAVING +SELECT row_number() over(), sum(1) FROM t1 where a=1 having 1=0; +row_number() over() sum(1) +# +# const table has 1 row, no impossible where +# The expected result here is 1, 2 +# +EXPLAIN SELECT row_number() over(), sum(a) FROM t1 where a=2; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 Using temporary +SELECT row_number() over(), sum(a) FROM t1 where a=2; +row_number() over() sum(a) +1 2 +drop table t1; +# +# Impossible Where +# +create table t1(a int); +insert into t1 values (1); +# +# Expected result is NULL, 0, NULL +# +EXPLAIN SELECT MAX(a) OVER (), COUNT(a), abs(a) FROM t1 WHERE FALSE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +SELECT MAX(a) OVER (), COUNT(a), abs(a) FROM t1 WHERE FALSE; +MAX(a) OVER () COUNT(a) abs(a) +NULL 0 NULL +# +# Expected result is 1, 0, NULL +# +EXPLAIN +SELECT MAX(1) OVER (), COUNT(a), abs(a) FROM t1 WHERE FALSE; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE +SELECT MAX(1) OVER (), COUNT(a), abs(a) FROM t1 WHERE FALSE; +MAX(1) OVER () COUNT(a) abs(a) +1 0 NULL +drop table t1; +# +# MDEV-22461: JOIN::make_aggr_tables_info(): Assertion `select_options & (1ULL << 17)' failed. +# +CREATE TEMPORARY TABLE t0 (a INT PRIMARY KEY ) ; +INSERT INTO t0 VALUES (1),(2),(3); +SELECT a FROM t0 +WHERE a < 8 +GROUP BY 1.5 +WINDOW v2 AS ( PARTITION BY a ORDER BY a DESC ); +a +1 +SELECT a, ROW_NUMBER() OVER v2 +FROM t0 +WHERE a < 8 +GROUP BY 1.5 +WINDOW v2 AS ( PARTITION BY a ORDER BY a DESC ); +a ROW_NUMBER() OVER v2 +1 1 +drop table t0; +# +# MDEV-16230:Server crashes when Analyze format=json is run with a window function with +# empty PARTITION BY and ORDER BY clauses +# +CREATE TABLE t1(a INT, b INT); +INSERT INTO t1 VALUES (1,1),(2,2),(3,3); +ANALYZE FORMAT=JSON SELECT row_number() OVER() FROM t1; +ANALYZE +{ + "query_optimization": { + "r_total_time_ms": "REPLACED" + }, + "query_block": { + "select_id": 1, + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "window_functions_computation": { + "sorts": [ + { + "filesort": { + "sort_key": "`row_number() OVER()`", + "r_loops": 1, + "r_total_time_ms": "REPLACED", + "r_used_priority_queue": false, + "r_output_rows": 3, + "r_buffer_size": "REPLACED", + "r_sort_mode": "sort_key,rowid" + } + } + ], + "temporary_table": { + "nested_loop": [ + { + "table": { + "table_name": "t1", + "access_type": "ALL", + "r_loops": 1, + "rows": 3, + "r_rows": 3, + "r_table_time_ms": "REPLACED", + "r_other_time_ms": "REPLACED", + "r_engine_stats": REPLACED, + "filtered": 100, + "r_filtered": 100 + } + } + ] + } + } + } +} +SELECT row_number() OVER() FROM t1; +row_number() OVER() +1 +2 +3 +DROP TABLE t1; +# +# MDEV-22984: Throw an error when arguments to window functions are window functions +# +CREATE TABLE t1(a INT, b INT); +INSERT INTO t1 VALUES (1,1), (2,2), (3,3); +SELECT NTILE(MAX(a) OVER (PARTITION BY a)) OVER (PARTITION BY a ORDER BY b) FROM t1; +ERROR HY000: Window functions can not be used as arguments to group functions. +SELECT FIRST_VALUE(MAX(a) OVER (PARTITION BY a)) OVER (ORDER BY a) AS x FROM t1 GROUP BY a; +ERROR HY000: Window functions can not be used as arguments to group functions. +DROP TABLE t1; +# +# MDEV-12059: Assertion `precision > 0' failed with a window function or window aggregate function +# +CREATE TABLE t1 (d DECIMAL(1,0) UNSIGNED); +INSERT INTO t1 VALUES (1),(2); +SELECT MIN(d) OVER () FROM t1; +MIN(d) OVER () +1 +1 +DROP TABLE t1; +# +# MDEV-22463: Element_type &Bounds_checked_array<Item *>::operator[](size_t) [Element_type = Item *]: +# Assertion `n < m_size' failed +# +CREATE TABLE t1 (a INT, b INT, c INT, d INT, e INT, f INT, g int, h INT, i INT); +INSERT INTO t1 SELECT seq,seq,seq,seq, seq,seq,seq,seq,seq FROM seq_1_to_5; +SELECT ROW_NUMBER() OVER w2 FROM t1 WINDOW w2 AS (PARTITION BY -1,0,1,2,3,4,5,6); +ROW_NUMBER() OVER w2 +1 +2 +3 +4 +5 +SELECT a FROM t1 ORDER BY ROW_NUMBER() OVER (PARTITION BY -1,1,0,2,3,4,5,6,7,8); +a +1 +2 +3 +4 +5 +SELECT a,b FROM t1 WINDOW w2 AS (PARTITION BY -1,1,0,2,3,4); +a b +1 1 +2 2 +3 3 +4 4 +5 5 +SELECT ROW_NUMBER() OVER w2 FROM t1 WINDOW w2 AS (PARTITION BY -1,0,1,2,3,4,5,6); +ROW_NUMBER() OVER w2 +1 +2 +3 +4 +5 +DROP TABLE t1; +# +# MDEV-18916: crash in Window_spec::print_partition() with decimals +# +SELECT cast((rank() over w1) as decimal (53,56)); +ERROR 42000: Too big scale specified for 'rank() over w1'. Maximum is 38 +SELECT cast((rank() over w1) as decimal (53,30)); +ERROR HY000: Window specification with name 'w1' is not defined +# +# MDEV-15180: server crashed with NTH_VALUE() +# +CREATE TABLE t1 (i1 int, a int); +INSERT INTO t1 VALUES (1, 1), (2, 2),(3, 3); +CREATE TABLE t2 (i2 int); +INSERT INTO t2 VALUES (1),(2),(5),(1),(7),(4),(3); +CREATE VIEW v1 AS (SELECT * FROM t1,t2 WHERE t1.i1=t2.i2) ; +SELECT NTH_VALUE(i1, i1) OVER (PARTITION BY i1) FROM v1; +NTH_VALUE(i1, i1) OVER (PARTITION BY i1) +1 +1 +NULL +NULL +DROP VIEW v1; +DROP TABLE t1,t2; +# +# MDEV-25032 Window functions without column references get removed from ORDER BY +# +create table t1 (id int, score double); +insert into t1 values +(1, 5), +(1, 6), +(1, 6), +(1, 6), +(1, 7), +(1, 8.1), +(1, 9), +(1, 10); +select id, row_number() over () rn +from t1 +order by rn desc; +id rn +1 8 +1 7 +1 6 +1 5 +1 4 +1 3 +1 2 +1 1 +drop table t1; +# +# MDEV-25630: Crash with window function in left expr of IN subquery +# +CREATE TABLE t1 (i int); +INSERT INTO t1 VALUES (1),(2),(3); +SELECT lag(i) over (ORDER BY i) IN ( SELECT 1 FROM t1 a) FROM t1; +lag(i) over (ORDER BY i) IN ( SELECT 1 FROM t1 a) +NULL +1 +0 +DROP TABLE t1; +CREATE TABLE t1 (i int); +INSERT INTO t1 VALUES (1),(2),(3); +SELECT sum(i) over () IN ( SELECT 1 FROM t1 a) FROM t1; +sum(i) over () IN ( SELECT 1 FROM t1 a) +0 +0 +0 +DROP TABLE t1; +# +# MDEV-25565: 2-nd call of SP with SELECT from view / derived table / CTE +# returning the result of calculation of 2 window +# functions that use the same window specification +# +create table t1 (a int); +insert into t1 values (3), (7), (1), (7), (1), (1), (3), (1), (5); +create view v2 as select a from t1 group by a; +create view v1 as select * from v2; +create procedure sp1() select v1.a, +sum(v1.a) over (partition by v1.a order by v1.a) as k, +avg(v1.a) over (partition by v1.a order by v1.a) as m +from v1; +call sp1(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp1(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "select v1.a, +sum(v1.a) over (partition by v1.a order by v1.a) as k, +avg(v1.a) over (partition by v1.a order by v1.a) as m +from v1"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +create procedure sp2() select * from +( select dt1.a, +sum(dt1.a) over (partition by dt1.a order by dt1.a) as k, +avg(dt1.a) over (partition by dt1.a order by dt1.a) as m +from (select * from v2) as dt1 +) as dt; +call sp2(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp2(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "select * from +( select dt1.a, +sum(dt1.a) over (partition by dt1.a order by dt1.a) as k, +avg(dt1.a) over (partition by dt1.a order by dt1.a) as m +from (select * from v2) as dt1 +) as dt"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +create procedure sp3() select * from +( select dt1.a, +sum(dt1.a) over (partition by dt1.a order by dt1.a) as k, +avg(dt1.a) over (partition by dt1.a order by dt1.a) as m +from ( select * from (select * from t1 group by a) as dt2 ) as dt1 +) as dt; +call sp3(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp3(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "select * from +( select dt1.a, +sum(dt1.a) over (partition by dt1.a order by dt1.a) as k, +avg(dt1.a) over (partition by dt1.a order by dt1.a) as m +from ( select * from (select * from t1 group by a) as dt2 ) as dt1 +) as dt"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +create procedure sp4() with cte1 as (select * from (select * from t1 group by a) as dt2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte; +call sp4(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp4(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "with cte1 as (select * from (select * from t1 group by a) as dt2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +create procedure sp5() with cte1 as (select * from v2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte; +call sp5(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp5(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "with cte1 as (select * from v2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +create procedure sp6() with +cte1 as (with cte2 as (select * from t1 group by a) select * from cte2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte; +call sp6(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp6(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "with +cte1 as (with cte2 as (select * from t1 group by a) select * from cte2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +create procedure sp7() with +cte2 as (select * from v1), +cte1 as (select * from cte2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte; +call sp7(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +call sp7(); +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +prepare stmt from "with +cte2 as (select * from v1), +cte1 as (select * from cte2), +cte as +( select cte1.a, +sum(cte1.a) over (partition by cte1.a order by cte1.a) as k, +avg(cte1.a) over (partition by cte1.a order by cte1.a) as m +from cte1 ) +select * from cte"; +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +execute stmt; +a k m +1 1 1.0000 +3 3 3.0000 +5 5 5.0000 +7 7 7.0000 +deallocate prepare stmt; +drop procedure sp1; +drop procedure sp2; +drop procedure sp3; +drop procedure sp4; +drop procedure sp5; +drop procedure sp6; +drop procedure sp7; +drop view v1,v2; +drop table t1; +# +# MDEV-17785: Window functions not working in ONLY_FULL_GROUP_BY mode +# +CREATE TABLE t1(a VARCHAR(10), b int); +INSERT INTO t1 VALUES +('Maths', 60),('Maths', 60), +('Maths', 70),('Maths', 55), +('Biology', 60), ('Biology', 70); +SET @save_sql_mode= @@sql_mode; +SET sql_mode = 'ONLY_FULL_GROUP_BY'; +SELECT +RANK() OVER (PARTITION BY a ORDER BY b) AS rank, +a, b FROM t1 ORDER BY a, b DESC; +rank a b +2 Biology 70 +1 Biology 60 +4 Maths 70 +2 Maths 60 +2 Maths 60 +1 Maths 55 +SET sql_mode= @save_sql_mode; +DROP TABLE t1; +CREATE TABLE t1(i int,j int); +INSERT INTO t1 VALUES (1,1), (1,5),(1,4), (2,2),(2,5), (3,3),(4,4); +INSERT INTO t1 VALUES (1,1), (1,5),(1,4), (2,2),(2,5), (3,3),(4,4); +SELECT i, LAST_VALUE(COUNT(i)) OVER (PARTITION BY i ORDER BY j) FROM t1 GROUP BY i; +i LAST_VALUE(COUNT(i)) OVER (PARTITION BY i ORDER BY j) +1 6 +2 4 +3 2 +4 2 +DROP TABLE t1; +# +# MDEV-15208: server crashed, when using ORDER BY with window function and UNION +# +CREATE TABLE t1 (a INT); +INSERT INTO t1 VALUES (1),(1),(1),(1),(1),(2),(2),(2),(2),(2),(2); +SELECT 1 UNION SELECT a FROM t1 ORDER BY (row_number() over ()); +ERROR HY000: Expression #1 of ORDER BY contains aggregate function and applies to a UNION +DROP TABLE t1; +# +# MDEV-19398: Assertion `item1->type() == Item::FIELD_ITEM && +# item2->type() == Item::FIELD_ITEM' failed in compare_order_elements +# +CREATE TABLE t1 ( id varchar(10)); +INSERT INTO t1 values (1),(2),(3); +SELECT +dense_rank() over (ORDER BY avg(1)+3), +rank() over (ORDER BY avg(1)) +FROM t1 +GROUP BY nullif(id, 15532); +dense_rank() over (ORDER BY avg(1)+3) rank() over (ORDER BY avg(1)) +1 1 +1 1 +1 1 +SELECT +dense_rank() over (ORDER BY avg(1)), +rank() over (ORDER BY avg(1)) +FROM t1 +GROUP BY nullif(id, 15532); +dense_rank() over (ORDER BY avg(1)) rank() over (ORDER BY avg(1)) +1 1 +1 1 +1 1 +drop table t1; +CREATE TABLE t1 ( a char(25), b text); +INSERT INTO t1 VALUES ('foo','bar'); +SELECT +SUM(b) OVER (PARTITION BY a), +ROW_NUMBER() OVER (PARTITION BY b) +FROM t1 +GROUP BY +LEFT((SYSDATE()), 'foo') +WITH ROLLUP; +SUM(b) OVER (PARTITION BY a) ROW_NUMBER() OVER (PARTITION BY b) +0 1 +0 2 +Warnings: +Warning 1292 Truncated incorrect INTEGER value: 'foo' +Warning 1292 Truncated incorrect INTEGER value: 'foo' +Warning 1292 Truncated incorrect INTEGER value: 'foo' +Warning 1292 Truncated incorrect DOUBLE value: 'bar' +Warning 1292 Truncated incorrect DOUBLE value: 'bar' +drop table t1; +# +# +# End of 10.2 tests +# +# +# MDEV-16489 when lead() returns null on a datetime field, the result is treated as the literal string '[NULL]' +# +CREATE TABLE t1 (d datetime); +INSERT INTO t1 VALUES ('2018-01-01 00:00:00'),('2018-02-01 00:00:00'); +SELECT *, LEAD(d) OVER (ORDER BY d) AS x FROM t1; +d x +2018-01-01 00:00:00 2018-02-01 00:00:00 +2018-02-01 00:00:00 NULL +DROP TABLE t1; +CREATE TABLE t1 (d time); +INSERT INTO t1 VALUES ('00:00:01'),('00:00:02'); +SELECT *, LEAD(d) OVER (ORDER BY d) AS x FROM t1; +d x +00:00:01 00:00:02 +00:00:02 NULL +DROP TABLE t1; +# +# MDEV-20351 Window function BIT_OR() OVER (..) return a wrong data type +# +CREATE TABLE t1 (pk INT, a INT, b BIGINT UNSIGNED); +INSERT INTO t1 VALUES (1, 0, 1), (2, 0, 18446744073709551615); +CREATE TABLE t2 AS +SELECT pk, a, bit_or(b) AS bit_or FROM t1 GROUP BY pk; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `pk` int(11) DEFAULT NULL, + `a` int(11) DEFAULT NULL, + `bit_or` bigint(21) unsigned NOT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT * FROM t1; +pk a b +1 0 1 +2 0 18446744073709551615 +DROP TABLE t2; +CREATE OR REPLACE TABLE t2 AS +SELECT pk, a, BIT_OR(b) OVER (PARTITION BY a ORDER BY pk ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING) AS bit_or +FROM t1; +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `pk` int(11) DEFAULT NULL, + `a` int(11) DEFAULT NULL, + `bit_or` bigint(21) unsigned NOT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci +SELECT * FROM t2; +pk a bit_or +1 0 18446744073709551615 +2 0 18446744073709551615 +DROP TABLE t2; +DROP TABLE t1; +# +# MDEV-15178: Filesort::make_sortorder: Assertion `pos->field != __null | +# +CREATE TABLE t1 (i1 int, a int); +INSERT INTO t1 VALUES (1, 1), (2, 2),(3, 3); +CREATE TABLE t2 (i2 int); +INSERT INTO t2 VALUES (1),(2),(5),(1),(7),(4),(3); +SELECT +a, +RANK() OVER (ORDER BY SUM(DISTINCT i1)) +FROM +t1, t2 WHERE t2.i2 = t1.i1 +GROUP BY +a; +a RANK() OVER (ORDER BY SUM(DISTINCT i1)) +1 1 +2 2 +3 3 +DROP TABLE t1, t2; +# +# MDEV-17014: Crash server using ROW_NUMBER() OVER (PARTITION ..) +# +CREATE TABLE t1 (UID BIGINT); +CREATE TABLE t2 (UID BIGINT); +CREATE TABLE t3 (UID BIGINT); +insert into t1 VALUES (1),(2); +insert into t2 VALUES (1),(2); +insert into t3 VALUES (1),(2); +SELECT +ROW_NUMBER() OVER (PARTITION BY GROUP_CONCAT(TT1.UID)) +FROM t1 TT1, +t2 TT2, +t3 TT3 +WHERE TT3.UID = TT1.UID AND TT2.UID = TT3.UID +GROUP BY TT1.UID +; +ROW_NUMBER() OVER (PARTITION BY GROUP_CONCAT(TT1.UID)) +1 +1 +DROP TABLE t1, t2, t3; +# +# End of 10.3 tests +# +# +# MDEV-16722: Assertion `type() != NULL_ITEM' failed +# +create table t1 (a int); +insert into t1 values (1),(2),(3); +SELECT row_number() OVER (order by a) FROM t1 order by NAME_CONST('myname',NULL); +row_number() OVER (order by a) +1 +2 +3 +drop table t1; +# +# MDEV-28206 SIGSEGV in Item_field::fix_fields when using LEAD...OVER +# +CREATE TABLE t(c1 INT); +CREATE FUNCTION f() RETURNS INT READS SQL DATA BEGIN +DECLARE v INT; +SELECT 1 INTO v FROM (SELECT c1,COALESCE(LEAD(a2.c1) OVER (PARTITION BY a2.c1 ORDER BY a2.c1),a2.c1) AS a1 FROM (t a2 JOIN t a3 USING (c1))) a4; +RETURN 1; +END// +SELECT f(),f(); +f() f() +1 1 +EXECUTE IMMEDIATE "SELECT LEAD(c1) OVER (ORDER BY c1) FROM t NATURAL JOIN t AS a;"; +LEAD(c1) OVER (ORDER BY c1) +EXECUTE IMMEDIATE "SELECT SUM(c1) OVER (ORDER BY c1) FROM t NATURAL JOIN t AS a;"; +SUM(c1) OVER (ORDER BY c1) +EXECUTE IMMEDIATE "SELECT LEAD(c) OVER (ORDER BY c) FROM (SELECT 1 AS c) AS a NATURAL JOIN (SELECT 1 AS c) AS b;"; +LEAD(c) OVER (ORDER BY c) +NULL +DROP FUNCTION f; +DROP TABLE t; +# +# End of 10.6 tests +# +# +# MDEV-23867: select crash in compute_window_func +# +set @save_sort_buffer_size=@@sort_buffer_size; +set sort_buffer_size= 2000; +CREATE TABLE t1( a INT, b INT, c INT); +INSERT INTO t1 select seq, seq, seq from seq_1_to_5000; +CREATE TABLE t2( a INT, b INT, c INT); +INSERT INTO t2 SELECT a, b, ROW_NUMBER() OVER (PARTITION BY b) FROM t1; +SELECT COUNT(*), MAX(c) FROM t2; +COUNT(*) MAX(c) +5000 1 +CREATE TABLE t3( a INT, b INT, c INT); +INSERT INTO t3 SELECT a, b, SUM(a) OVER () FROM t1; +SELECT COUNT(*), MAX(c) FROM t3; +COUNT(*) MAX(c) +5000 12502500 +set @@sort_buffer_size=@save_sort_buffer_size; +DROP TABLE t1,t2,t3; +# end of 10.2 test +# +# MDEV-22556: Incorrect result for window function when using encrypt-tmp-files=ON +# +set @save_sort_buffer_size=@@sort_buffer_size; +set sort_buffer_size= 2000; +create table t1( a DECIMAL(12,0) DEFAULT NULL, b VARCHAR(20) DEFAULT NULL, c DECIMAL(12,0) DEFAULT NULL)engine=INNODB; +insert into t1 select seq, seq, seq from seq_1_to_5000; +select count(*) from (select a, b, c, ROW_NUMBER() OVER (PARTITION BY a) FROM t1)q; +count(*) +5000 +set @@sort_buffer_size=@save_sort_buffer_size; +drop table t1; +# End of 10.4 tests diff --git a/mysql-test/suite/encryption/suite.pm b/mysql-test/suite/encryption/suite.pm new file mode 100644 index 00000000..bfd7ec71 --- /dev/null +++ b/mysql-test/suite/encryption/suite.pm @@ -0,0 +1,16 @@ +package My::Suite::Encryption; + +@ISA = qw(My::Suite); + +sub skip_combinations { + my @combinations; + + $skip{'include/have_file_key_management_plugin.combinations'} = [ 'ctr' ] + unless $::mysqld_variables{'version-ssl-library'} =~ /OpenSSL (\S+)/ + and $1 ge "1.0.1"; + + %skip; +} + +bless { }; + diff --git a/mysql-test/suite/encryption/t/aria_tiny.test b/mysql-test/suite/encryption/t/aria_tiny.test new file mode 100644 index 00000000..337720ee --- /dev/null +++ b/mysql-test/suite/encryption/t/aria_tiny.test @@ -0,0 +1,43 @@ +--source include/have_file_key_management_plugin.inc +--source include/have_sequence.inc + +SET @aria_encrypt= @@aria_encrypt_tables; +SET global aria_encrypt_tables=1; +# +# MDEV-8022 Assertion `rc == 0' failed in ma_encrypt on dropping an encrypted Aria table +# + +create table t1 (i int, key(i)) engine=aria; +insert into t1 values (1); +drop table t1; + +# +# MDEV-17913 Encrypted transactional Aria tables remain corrupt after crash +# recovery, automatic repair does not work +# +# We are using a simplifed version of the test here. This works thanks to +# the extended check table code that also checks if LSN's are reasonable. +# + +create table t1 (a int primary key, b int, c int, key(b),key(c)) engine=aria; +alter table t1 disable keys; +insert into t1 select seq,seq,seq from seq_1_to_100; +alter table t1 enable keys; +check table t1; +drop table t1; + +--echo # +--echo # MDEV CHECK on encrypted Aria table complains about "Wrong LSN" +--echo # + +CREATE TABLE t1 (f DATE PRIMARY KEY) ENGINE=Aria; +INSERT INTO t1 (f) VALUES ('1995-01-01'),('2000-01-01'); +DELETE FROM t1 WHERE f = '2000-01-01'; +OPTIMIZE TABLE t1; +CHECK TABLE t1 EXTENDED; +DROP TABLE t1; + +# +# Cleanup +# +set global aria_encrypt_tables=@aria_encrypt; diff --git a/mysql-test/suite/encryption/t/bulk_insert.opt b/mysql-test/suite/encryption/t/bulk_insert.opt new file mode 100644 index 00000000..95455f5f --- /dev/null +++ b/mysql-test/suite/encryption/t/bulk_insert.opt @@ -0,0 +1 @@ +--innodb_encrypt_log=1 diff --git a/mysql-test/suite/encryption/t/bulk_insert.test b/mysql-test/suite/encryption/t/bulk_insert.test new file mode 100644 index 00000000..ce7804cb --- /dev/null +++ b/mysql-test/suite/encryption/t/bulk_insert.test @@ -0,0 +1,11 @@ +--source include/have_innodb.inc +--source include/have_sequence.inc +--source include/have_file_key_management_plugin.inc + +SET UNIQUE_CHECKS=0, FOREIGN_KEY_CHECKS=0; +CREATE TABLE t1 ( + `id` int(10) unsigned NOT NULL, + UNIQUE KEY `id` (`id`) +) ENGINE=InnoDB; +INSERT INTO t1 SELECT seq FROM seq_1_to_65536; +DROP TABLE t1; diff --git a/mysql-test/suite/encryption/t/compressed_import_tablespace.opt b/mysql-test/suite/encryption/t/compressed_import_tablespace.opt new file mode 100644 index 00000000..a9893ed4 --- /dev/null +++ b/mysql-test/suite/encryption/t/compressed_import_tablespace.opt @@ -0,0 +1,3 @@ +--innodb-encrypt-tables=ON +--innodb-encryption-threads=4 +--innodb-tablespaces-encryption diff --git a/mysql-test/suite/encryption/t/compressed_import_tablespace.test b/mysql-test/suite/encryption/t/compressed_import_tablespace.test new file mode 100644 index 00000000..e79fdb17 --- /dev/null +++ b/mysql-test/suite/encryption/t/compressed_import_tablespace.test @@ -0,0 +1,45 @@ +-- 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 + +let $restart_noprint=2; +--source include/restart_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; diff --git a/mysql-test/suite/encryption/t/corrupted_during_recovery.combinations b/mysql-test/suite/encryption/t/corrupted_during_recovery.combinations new file mode 100644 index 00000000..9ac914f2 --- /dev/null +++ b/mysql-test/suite/encryption/t/corrupted_during_recovery.combinations @@ -0,0 +1,7 @@ +[strict_crc32] +--innodb-checksum-algorithm=strict_crc32 +--skip-innodb-doublewrite + +[strict_full_crc32] +--innodb-checksum-algorithm=strict_full_crc32 +--skip-innodb-doublewrite diff --git a/mysql-test/suite/encryption/t/corrupted_during_recovery.test b/mysql-test/suite/encryption/t/corrupted_during_recovery.test new file mode 100644 index 00000000..e4a31a0b --- /dev/null +++ b/mysql-test/suite/encryption/t/corrupted_during_recovery.test @@ -0,0 +1,68 @@ +--source include/have_innodb.inc +--source include/have_file_key_management_plugin.inc + +--disable_query_log +call mtr.add_suppression("InnoDB: Plugin initialization aborted"); +call mtr.add_suppression("Plugin 'InnoDB' init function returned error"); +call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed"); +call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed read of file '.*test.t1\\.ibd' page"); +call mtr.add_suppression("InnoDB: Failed to read page [123] from file '.*test.t1\\.ibd': Table is compressed or encrypted but uncompress or decrypt failed"); +call mtr.add_suppression("InnoDB: The page \\[page id: space=\\d+, page number=3\\] in file '.*test.t1\\.ibd' cannot be decrypted"); +call mtr.add_suppression("InnoDB: Table in tablespace \\d+ encrypted. However key management plugin or used key_version \\d+ is not found or used encryption algorithm or method does not match. Can't continue opening the table."); +call mtr.add_suppression("InnoDB: (Unable to apply log to|Discarding log for) corrupted page "); +--enable_query_log + +let INNODB_PAGE_SIZE=`select @@innodb_page_size`; +CREATE TABLE t1(a BIGINT PRIMARY KEY) ENGINE=InnoDB, ENCRYPTED=YES; +INSERT INTO t1 VALUES(1); +# Force a redo log checkpoint. +let $restart_noprint=2; +--source include/restart_mysqld.inc +--source ../../suite/innodb/include/no_checkpoint_start.inc +CREATE TABLE t2(a BIGINT PRIMARY KEY) ENGINE=InnoDB, ENCRYPTED=YES; +INSERT INTO t1 VALUES(2); +SET GLOBAL innodb_flush_log_at_trx_commit=1; +INSERT INTO t2 VALUES(2); + +--let CLEANUP_IF_CHECKPOINT=DROP TABLE t1,t2; +--source ../../suite/innodb/include/no_checkpoint_end.inc + +--echo # Corrupt the pages + +perl; +my $ps = $ENV{INNODB_PAGE_SIZE}; + +my $file = "$ENV{MYSQLD_DATADIR}/test/t1.ibd"; +open(FILE, "+<$file") || die "Unable to open $file"; +binmode FILE; +my $offset = ($ENV{INNODB_CHECKSUM_ALGORITHM} =~ /full_crc32/) ? 26 : 0; +seek (FILE, $ENV{INNODB_PAGE_SIZE} * 3 + $offset, SEEK_SET) or die "seek"; +print FILE "junk"; +close FILE or die "close"; + +$file = "$ENV{MYSQLD_DATADIR}/test/t2.ibd"; +open(FILE, "+<$file") || die "Unable to open $file"; +binmode FILE; +# Corrupt pages 1 to 3. MLOG_INIT_FILE_PAGE2 should protect us! +# Unfortunately, we are not immune to page 0 corruption. +seek (FILE, $ps, SEEK_SET) or die "seek"; +print FILE chr(0xff) x ($ps * 3); +close FILE or die "close"; +EOF + +--source include/start_mysqld.inc +--error ER_UNKNOWN_STORAGE_ENGINE +SELECT * FROM t1; +--disable_query_log +call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t[1].ibd looks corrupted; key_version="); +call mtr.add_suppression("Table .*t1.* is corrupted. Please drop the table and recreate."); +--enable_query_log +let $restart_parameters=--innodb_force_recovery=1 --skip-innodb-buffer-pool-load-at-startup; +--source include/restart_mysqld.inc + +--error ER_TABLE_CORRUPT +SELECT * FROM t1; +SELECT * FROM t2; +CHECK TABLE t2; + +DROP TABLE t1, t2; diff --git a/mysql-test/suite/encryption/t/create_or_replace.opt b/mysql-test/suite/encryption/t/create_or_replace.opt new file mode 100644 index 00000000..66892f34 --- /dev/null +++ b/mysql-test/suite/encryption/t/create_or_replace.opt @@ -0,0 +1 @@ +--innodb-encrypt-tables diff --git a/mysql-test/suite/encryption/t/create_or_replace.test b/mysql-test/suite/encryption/t/create_or_replace.test new file mode 100644 index 00000000..2ebd599d --- /dev/null +++ b/mysql-test/suite/encryption/t/create_or_replace.test @@ -0,0 +1,78 @@ +--source include/have_innodb.inc +--source include/have_file_key_management_plugin.inc +--source include/count_sessions.inc + +SET @save_threads = @@GLOBAL.innodb_encryption_threads; + +SET default_storage_engine = InnoDB; + +# +# MDEV-8173: InnoDB; Failing assertion: crypt_data->type == 1 +# + +SET GLOBAL innodb_encryption_threads = 4; + +CREATE TABLE `table10_int_autoinc` (`col_int_key` int, pk int auto_increment, `col_int` int, key (`col_int_key` ),primary key (pk)) engine=innodb; +INSERT /*! IGNORE */ INTO table10_int_autoinc VALUES (NULL, NULL, -474021888) , (1, NULL, NULL) , (1141047296, NULL, NULL) , (NULL, NULL, NULL) , (NULL, NULL, 1) , (NULL, NULL, 9) , (0, NULL, 1225785344) , (NULL, NULL, 1574174720) , (2, NULL, NULL) , (6, NULL, 3); + +CREATE TABLE `table1_int_autoinc` (`col_int_key` int, pk int auto_increment, `col_int` int,key (`col_int_key` ), primary key (pk)) engine=innodb; + +CREATE TABLE `table0_int_autoinc` (`col_int_key` int, pk int auto_increment, `col_int` int, key (`col_int_key` ),primary key (pk)) engine=innodb; + +INSERT /*! IGNORE */ INTO table1_int_autoinc VALUES (4, NULL, NULL); +INSERT IGNORE INTO `table0_int_autoinc` ( `col_int_key` ) VALUES ( 1 ), ( 3 ), ( 4 ), ( 1 ); +INSERT IGNORE INTO `table1_int_autoinc` ( `col_int` ) VALUES ( 1 ), ( 0 ), ( 7 ), ( 9 ); +INSERT IGNORE INTO `table10_int_autoinc` ( `col_int` ) VALUES ( 6 ), ( 2 ), ( 3 ), ( 6 ); + +--connect (con1,localhost,root,,test) +--connect (con2,localhost,root,,test) + +--disable_query_log + +let $i = 100; +while ($i) +{ +connection con1; +send SET GLOBAL innodb_encrypt_tables = ON; +connection default; +CREATE OR REPLACE TABLE `create_or_replace_t` AS SELECT * FROM `table1_int_autoinc`; +connection con2; +send CREATE OR REPLACE TABLE `create_or_replace_t` AS SELECT * FROM `table10_int_autoinc`; +connection default; +send CREATE OR REPLACE TABLE `create_or_replace_t` AS SELECT * FROM `table0_int_autoinc`; +connection con1; +--reap; +send SET GLOBAL innodb_encrypt_tables = OFF; +connection con2; +--reap; +connection default; +--reap; +send CREATE OR REPLACE TABLE `create_or_replace_t` AS SELECT * FROM `table1_int_autoinc`; +connection con2; +send CREATE OR REPLACE TABLE `create_or_replace_t` AS SELECT * FROM `table10_int_autoinc`; +connection con1; +--reap; +send SET GLOBAL innodb_encrypt_tables = ON; +connection default; +--reap; +send CREATE OR REPLACE TABLE `create_or_replace_t` AS SELECT * FROM `table1_int_autoinc`; +connection con2; +--reap; +CREATE OR REPLACE TABLE `create_or_replace_t` AS SELECT * FROM `table10_int_autoinc`; +CREATE OR REPLACE TABLE `create_or_replace_t` AS SELECT * FROM `table0_int_autoinc`; +connection con1; +--reap; +connection default; +--reap; +dec $i; +} + +--enable_query_log +disconnect con1; +disconnect con2; +connection default; +drop table create_or_replace_t, table1_int_autoinc, table0_int_autoinc, +table10_int_autoinc; + +SET GLOBAL innodb_encryption_threads = @save_threads; +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/encryption/t/create_or_replace_big.opt b/mysql-test/suite/encryption/t/create_or_replace_big.opt new file mode 100644 index 00000000..7d3f2da7 --- /dev/null +++ b/mysql-test/suite/encryption/t/create_or_replace_big.opt @@ -0,0 +1 @@ +--innodb-tablespaces-encryption diff --git a/mysql-test/suite/encryption/t/create_or_replace_big.test b/mysql-test/suite/encryption/t/create_or_replace_big.test new file mode 100644 index 00000000..133bdfa3 --- /dev/null +++ b/mysql-test/suite/encryption/t/create_or_replace_big.test @@ -0,0 +1,86 @@ +--source include/have_innodb.inc +--source include/have_file_key_management_plugin.inc +--source include/not_embedded.inc +# This is needed for longer testcase timeout at least P7/P8 +--source include/big_test.inc + +# +# MDEV-8164: Server crashes in pfs_mutex_enter_func after fil_crypt_is_closing or alike +# +SET default_storage_engine = InnoDB; + +CREATE TABLE t1 (pk INT PRIMARY KEY, c VARCHAR(256)); +CREATE TABLE t2 AS SELECT * FROM t1; + +--disable_abort_on_error +--disable_warnings +--disable_query_log + +let $i = 40; +while ($i) +{ +SET GLOBAL innodb_encrypt_tables = ON; +SET GLOBAL innodb_encryption_threads = 1; +CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2; +CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1; +SET GLOBAL innodb_encryption_rotation_iops = 100; +SET GLOBAL innodb_encrypt_tables = OFF; +CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1; +CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2; +dec $i; +} + +--enable_abort_on_error +--enable_warnings +--enable_query_log + +drop table t1,t2; +SET GLOBAL innodb_encryption_threads = 0; + +# +# MDEV-8173: InnoDB; Failing assertion: crypt_data->type == 1 +# + +SET GLOBAL innodb_encryption_threads = 4; + +CREATE TABLE `table10_int_autoinc` (`col_int_key` int, pk int auto_increment, `col_int` int, key (`col_int_key` ),primary key (pk)) engine=innodb; +INSERT /*! IGNORE */ INTO table10_int_autoinc VALUES (NULL, NULL, -474021888) , (1, NULL, NULL) , (1141047296, NULL, NULL) , (NULL, NULL, NULL) , (NULL, NULL, 1) , (NULL, NULL, 9) , (0, NULL, 1225785344) , (NULL, NULL, 1574174720) , (2, NULL, NULL) , (6, NULL, 3); + +CREATE TABLE `table1_int_autoinc` (`col_int_key` int, pk int auto_increment, `col_int` int,key (`col_int_key` ), primary key (pk)) engine=innodb; + +CREATE TABLE `table0_int_autoinc` (`col_int_key` int, pk int auto_increment, `col_int` int, key (`col_int_key` ),primary key (pk)) engine=innodb; + +INSERT /*! IGNORE */ INTO table1_int_autoinc VALUES (4, NULL, NULL); +INSERT IGNORE INTO `table0_int_autoinc` ( `col_int_key` ) VALUES ( 1 ), ( 3 ), ( 4 ), ( 1 ); +INSERT IGNORE INTO `table1_int_autoinc` ( `col_int` ) VALUES ( 1 ), ( 0 ), ( 7 ), ( 9 ); +INSERT IGNORE INTO `table10_int_autoinc` ( `col_int` ) VALUES ( 6 ), ( 2 ), ( 3 ), ( 6 ); + +--echo # Wait max 10 min for key encryption threads to decrypt all spaces +let $cnt=600; +while ($cnt) +{ + let $success=`SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0`; + if ($success) + { + let $cnt=0; + } + if (!$success) + { + real_sleep 1; + dec $cnt; + } +} +if (!$success) +{ + SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION; + SHOW STATUS LIKE 'innodb_encryption%'; + -- die Timeout waiting for encryption threads +} +--echo # Success! + +SET GLOBAL innodb_encryption_threads = 0; +SET GLOBAL innodb_encrypt_tables = OFF; + +DROP TABLE table0_int_autoinc, table1_int_autoinc, table10_int_autoinc; + +-- source include/restart_mysqld.inc diff --git a/mysql-test/suite/encryption/t/debug_key_management.opt b/mysql-test/suite/encryption/t/debug_key_management.opt new file mode 100644 index 00000000..5c283bbe --- /dev/null +++ b/mysql-test/suite/encryption/t/debug_key_management.opt @@ -0,0 +1,5 @@ +--innodb-encrypt-log=ON +--innodb-encryption-rotate-key-age=2 +--innodb-encryption-threads=4 +--innodb-tablespaces-encryption +--plugin-load-add=$DEBUG_KEY_MANAGEMENT_SO diff --git a/mysql-test/suite/encryption/t/debug_key_management.test b/mysql-test/suite/encryption/t/debug_key_management.test new file mode 100644 index 00000000..45a93040 --- /dev/null +++ b/mysql-test/suite/encryption/t/debug_key_management.test @@ -0,0 +1,42 @@ +-- source include/have_innodb.inc +-- source include/have_debug.inc +-- source include/innodb_undo_tablespaces.inc +-- source include/not_embedded.inc + +if (`select count(*) = 0 from information_schema.plugins + where plugin_name = 'debug_key_management' and plugin_status='active'`) +{ + --skip Needs debug_key_management +} + +create table t1(a serial) engine=innoDB; + +set global innodb_encrypt_tables=ON; +show variables like 'innodb_encrypt%'; + +--let $tables_count= `select count(*) + 1 + @@global.innodb_undo_tablespaces from information_schema.tables where engine = 'InnoDB'` +let $wait_condition= select count(*) = $tables_count from information_schema.innodb_tablespaces_encryption where current_key_version=1; +--source include/wait_condition.inc + +select count(*) from information_schema.innodb_tablespaces_encryption where current_key_version <> 1; +set global debug_key_management_version=10; + +let $wait_condition= select count(*) = $tables_count from information_schema.innodb_tablespaces_encryption where current_key_version=10; +--source include/wait_condition.inc +select count(*) from information_schema.innodb_tablespaces_encryption where current_key_version <> 10; + +# Test redo log key rotation and crash recovery. +SET GLOBAL innodb_log_checkpoint_now = 1; +SET GLOBAL innodb_flush_log_at_trx_commit = 1; +INSERT INTO t1 VALUES(NULL); +let $shutdown_timeout = 0; +-- source include/restart_mysqld.inc + +# Note that we expect that key_version is increasing so disable encryption before reset + +set global innodb_encrypt_tables=OFF; +set global debug_key_management_version=1; + +select * from t1; + +drop table t1; diff --git a/mysql-test/suite/encryption/t/encrypt_and_grep.opt b/mysql-test/suite/encryption/t/encrypt_and_grep.opt new file mode 100644 index 00000000..c50ec719 --- /dev/null +++ b/mysql-test/suite/encryption/t/encrypt_and_grep.opt @@ -0,0 +1,7 @@ +--innodb-encrypt-tables=ON +--innodb-encrypt-log=ON +--innodb-encryption-rotate-key-age=15 +--innodb-encryption-threads=4 +--innodb-tablespaces-encryption + + diff --git a/mysql-test/suite/encryption/t/encrypt_and_grep.test b/mysql-test/suite/encryption/t/encrypt_and_grep.test new file mode 100644 index 00000000..687f14e8 --- /dev/null +++ b/mysql-test/suite/encryption/t/encrypt_and_grep.test @@ -0,0 +1,128 @@ +-- source include/have_innodb.inc +-- source include/innodb_undo_tablespaces.inc +-- source include/have_file_key_management_plugin.inc + +# +# MDEV-8138: strange results from encrypt-and-grep test +# +--let $MYSQLD_DATADIR=`select @@datadir` +--let ib1_IBD = $MYSQLD_DATADIR/ibdata1 +--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 SEARCH_RANGE = 10000000 + +SET GLOBAL innodb_file_per_table = ON; + +create table t1 (a varchar(255)) engine=innodb encrypted=yes; +create table t2 (a varchar(255)) engine=innodb; +show warnings; +create table t3 (a varchar(255)) engine=innodb encrypted=no; + +insert t1 values (repeat('foobarsecret', 12)); +insert t2 values (repeat('tempsecret', 12)); +insert t3 values (repeat('dummysecret', 12)); + +--echo # Wait max 10 min for key encryption threads to encrypt all spaces +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 +--source include/wait_condition.inc + +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + +FLUSH TABLES t1,t2,t3 FOR EXPORT; + +--let SEARCH_PATTERN=foobarsecret +--echo # t1 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t1_IBD +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=tempsecret +--echo # t2 ... on expecting NOT FOUND +-- let SEARCH_FILE=$t2_IBD +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=dummysecret +--echo # t3 no on expecting FOUND +-- let SEARCH_FILE=$t3_IBD +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=foobarsecret +--echo # ibdata1 expecting NOT FOUND +-- let SEARCH_FILE=$ib1_IBD +-- source include/search_pattern_in_file.inc + +UNLOCK TABLES; + +--echo # Now turn off encryption and wait for threads to decrypt everything + +SET GLOBAL innodb_encrypt_tables = off; + +--echo # Wait max 10 min for key encryption threads to decrypt all spaces +--let $wait_timeout= 600 +--let $tables_count= `select count(*) + @@global.innodb_undo_tablespaces from information_schema.tables where engine = 'InnoDB'` + +--let $wait_condition=SELECT COUNT(*) = $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND CURRENT_KEY_VERSION = 0; +--source include/wait_condition.inc + +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + +FLUSH TABLES t1,t2,t3 FOR EXPORT; + +--let SEARCH_PATTERN=foobarsecret +--echo # t1 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t1_IBD +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=tempsecret +--echo # t2 ... default expecting FOUND +-- let SEARCH_FILE=$t2_IBD +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=dummysecret +--echo # t3 no on expecting FOUND +-- let SEARCH_FILE=$t3_IBD +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=foobarsecret +--echo # ibdata1 expecting NOT FOUND +-- let SEARCH_FILE=$ib1_IBD +-- source include/search_pattern_in_file.inc + +UNLOCK TABLES; + +--echo # Now turn on encryption and wait for threads to encrypt all spaces +SET GLOBAL innodb_encrypt_tables = on; + +--echo # Wait max 10 min for key encryption threads to encrypt all spaces +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +--source include/wait_condition.inc + +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + +FLUSH TABLES t1,t2,t3 FOR EXPORT; + +--let SEARCH_PATTERN=foobarsecret +--echo # t1 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t1_IBD +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=tempsecret +--echo # t2 ... on expecting NOT FOUND +-- let SEARCH_FILE=$t2_IBD +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=dummysecret +--echo # t3 no on expecting FOUND +-- let SEARCH_FILE=$t3_IBD +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=foobarsecret +--echo # ibdata1 expecting NOT FOUND +-- let SEARCH_FILE=$ib1_IBD +-- source include/search_pattern_in_file.inc + +UNLOCK TABLES; + +drop table t1, t2, t3; diff --git a/mysql-test/suite/encryption/t/encryption_force.opt b/mysql-test/suite/encryption/t/encryption_force.opt new file mode 100644 index 00000000..c9e53287 --- /dev/null +++ b/mysql-test/suite/encryption/t/encryption_force.opt @@ -0,0 +1,2 @@ +--innodb-encrypt-tables=FORCE +--innodb-encrypt-log=ON diff --git a/mysql-test/suite/encryption/t/encryption_force.test b/mysql-test/suite/encryption/t/encryption_force.test new file mode 100644 index 00000000..3c6f0391 --- /dev/null +++ b/mysql-test/suite/encryption/t/encryption_force.test @@ -0,0 +1,39 @@ +-- source include/have_innodb.inc +-- source include/have_partition.inc +-- source include/have_example_key_management_plugin.inc + +select @@innodb_encrypt_tables; + +create table t1 (a int) engine=innodb encrypted=yes; +create table t2 (a int) engine=innodb encrypted=default; +--error ER_CANT_CREATE_TABLE +create table t3 (a int) engine=innodb encrypted=no; + +create table t4 (a int) engine=innodb encrypted=yes partition by hash(a) partitions 2; +--error ER_CANT_CREATE_TABLE +create table t5 (a int) engine=innodb encrypted=no partition by hash(a) partitions 2; + +set global innodb_encrypt_tables='ON'; +create table t3 (a int) engine=innodb encrypted=no; +set global innodb_encrypt_tables='FORCE'; + +show create table t1; +show create table t2; +show create table t3; +show create table t4; + +--error ER_ILLEGAL_HA_CREATE_OPTION +alter table t1 encrypted=no; +alter table t2 encrypted=yes; +alter table t3 encrypted=default; +--error ER_ILLEGAL_HA_CREATE_OPTION +alter table t4 encrypted=no; + +show create table t1; +show create table t2; +show create table t3; + +drop table t1; +drop table t2; +drop table t3; +drop table t4; diff --git a/mysql-test/suite/encryption/t/encryption_key_corruption.combinations b/mysql-test/suite/encryption/t/encryption_key_corruption.combinations new file mode 100644 index 00000000..979b2acd --- /dev/null +++ b/mysql-test/suite/encryption/t/encryption_key_corruption.combinations @@ -0,0 +1,4 @@ +[crc32] +innodb-checksum-algorithm=crc32 +[full_crc32] +innodb-checksum-algorithm=full_crc32 diff --git a/mysql-test/suite/encryption/t/encryption_key_corruption.opt b/mysql-test/suite/encryption/t/encryption_key_corruption.opt new file mode 100644 index 00000000..682d06d5 --- /dev/null +++ b/mysql-test/suite/encryption/t/encryption_key_corruption.opt @@ -0,0 +1 @@ +--innodb-encrypt-tables=1 diff --git a/mysql-test/suite/encryption/t/encryption_key_corruption.test b/mysql-test/suite/encryption/t/encryption_key_corruption.test new file mode 100644 index 00000000..9b4bd172 --- /dev/null +++ b/mysql-test/suite/encryption/t/encryption_key_corruption.test @@ -0,0 +1,44 @@ +--source include/have_innodb.inc +--source include/have_example_key_management_plugin.inc + +call mtr.add_suppression("InnoDB: .*: Page 0 at offset 0 looks corrupted"); +call mtr.add_suppression("Index for table 'dst' is corrupt; try to repair it"); +call mtr.add_suppression("Page for tablespace .* is index page with id .* but that index is not found from configuration file"); + +let MYSQLD_DATADIR = `SELECT @@datadir`; + + +CREATE TABLE src (pk INT PRIMARY KEY, value INT) ENGINE=INNODB; +INSERT INTO src VALUES (1, 1), (2, 2), (3, 3); + +FLUSH TABLES src FOR EXPORT; + +--copy_file $MYSQLD_DATADIR/test/src.ibd $MYSQLD_DATADIR/test/tmp.ibd +--copy_file $MYSQLD_DATADIR/test/src.cfg $MYSQLD_DATADIR/test/tmp.cfg + +perl; +use strict; +die unless open(FILE, "+<$ENV{MYSQLD_DATADIR}/test/tmp.ibd"); +binmode FILE; +die unless seek(FILE, 3 * 16384 + 26, 0); +print FILE pack("N", 0x00000000); +close(FILE); +EOF + +UNLOCK TABLES; + +DROP TABLE src; + +CREATE TABLE dst (pk INT PRIMARY KEY, value INT) ENGINE=INNODB; +ALTER TABLE dst DISCARD TABLESPACE; + +--copy_file $MYSQLD_DATADIR/test/tmp.ibd $MYSQLD_DATADIR/test/dst.ibd +--copy_file $MYSQLD_DATADIR/test/tmp.cfg $MYSQLD_DATADIR/test/dst.cfg + +--error ER_NOT_KEYFILE +ALTER TABLE dst IMPORT TABLESPACE; + +DROP TABLE dst; + +--remove_file $MYSQLD_DATADIR/test/tmp.ibd +--remove_file $MYSQLD_DATADIR/test/tmp.cfg diff --git a/mysql-test/suite/encryption/t/file_creation.opt b/mysql-test/suite/encryption/t/file_creation.opt new file mode 100644 index 00000000..7d3f2da7 --- /dev/null +++ b/mysql-test/suite/encryption/t/file_creation.opt @@ -0,0 +1 @@ +--innodb-tablespaces-encryption diff --git a/mysql-test/suite/encryption/t/file_creation.test b/mysql-test/suite/encryption/t/file_creation.test new file mode 100644 index 00000000..6b012683 --- /dev/null +++ b/mysql-test/suite/encryption/t/file_creation.test @@ -0,0 +1,41 @@ +--source include/have_innodb.inc +--source include/have_example_key_management_plugin.inc +let $restart_noprint=2; +# embedded does not support restart +-- source include/not_embedded.inc + +# +# MDEV-19348 MariaBackup prepare fails with InnoDB: Database page corruption +# on disk or a failed file read +# + +SET GLOBAL innodb_encrypt_tables = ON; +SET GLOBAL innodb_encryption_threads = 1; +SET GLOBAL innodb_max_dirty_pages_pct = 99; +SHOW VARIABLES LIKE 'innodb_encrypt%'; + +CREATE TABLE t1(f1 INT NOT NULL, f2 CHAR(255), f3 CHAR(255), + f4 CHAR(255), f5 CHAR(255))ENGINE=INNODB; + +INSERT INTO t1 VALUES(1, "mysql", "mariadb", "batman", "superman"); +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; +INSERT INTO t1 SELECT * FROM t1; + +--let $tables_count= `select count(*) + 1 from information_schema.tables where engine = 'InnoDB'` + +--echo # Wait max 10 min for key encryption threads to encrypt all spaces +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc + +OPTIMIZE TABLE t1; + +--source ../../suite/innodb/include/no_checkpoint_start.inc +ALTER TABLE t1 FORCE; +--let CLEANUP_IF_CHECKPOINT=DROP TABLE t1; +--source ../../suite/innodb/include/no_checkpoint_end.inc + +--source include/start_mysqld.inc +DROP TABLE t1; diff --git a/mysql-test/suite/encryption/t/filekeys-data-too-long.key b/mysql-test/suite/encryption/t/filekeys-data-too-long.key new file mode 100644 index 00000000..ba1624fb --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys-data-too-long.key @@ -0,0 +1,4 @@ +secretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecret +secretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecret +secretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecretsecret + diff --git a/mysql-test/suite/encryption/t/filekeys-data.enc b/mysql-test/suite/encryption/t/filekeys-data.enc Binary files differnew file mode 100644 index 00000000..a8adb2f9 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys-data.enc diff --git a/mysql-test/suite/encryption/t/filekeys-data.key b/mysql-test/suite/encryption/t/filekeys-data.key new file mode 100644 index 00000000..85fcd1fb --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys-data.key @@ -0,0 +1,2 @@ +secret + diff --git a/mysql-test/suite/encryption/t/filekeys-tooshort.enc b/mysql-test/suite/encryption/t/filekeys-tooshort.enc new file mode 100644 index 00000000..9849236c --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys-tooshort.enc @@ -0,0 +1 @@ +Salted__
\ No newline at end of file diff --git a/mysql-test/suite/encryption/t/filekeys_badtest.inc b/mysql-test/suite/encryption/t/filekeys_badtest.inc new file mode 100644 index 00000000..60ac9f0e --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_badtest.inc @@ -0,0 +1,17 @@ +-- source include/not_embedded.inc +-- source include/have_innodb.inc +-- source filekeys_plugin.inc + +--eval call mtr.add_suppression("$SEARCH_PATTERN") +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); + +--let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err +--source include/search_pattern_in_file.inc + +--error ER_CANT_CREATE_TABLE +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; + +select plugin_status from information_schema.plugins + where plugin_name = 'file_key_management'; + diff --git a/mysql-test/suite/encryption/t/filekeys_emptyfile.opt b/mysql-test/suite/encryption/t/filekeys_emptyfile.opt new file mode 100644 index 00000000..7c5f6d05 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_emptyfile.opt @@ -0,0 +1 @@ +--loose-file-key-management-filename=$MYSQL_TEST_DIR/std_data/empty_file diff --git a/mysql-test/suite/encryption/t/filekeys_emptyfile.test b/mysql-test/suite/encryption/t/filekeys_emptyfile.test new file mode 100644 index 00000000..39f2ccf2 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_emptyfile.test @@ -0,0 +1,4 @@ +let SEARCH_PATTERN=System key id 1 is missing at; +source filekeys_badtest.inc; + +--echo # Test checks if opening an empty filekeys does not crash the server. diff --git a/mysql-test/suite/encryption/t/filekeys_encfile.opt b/mysql-test/suite/encryption/t/filekeys_encfile.opt new file mode 100644 index 00000000..651cc0f4 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_encfile.opt @@ -0,0 +1,2 @@ +--loose-file-key-management-filekey=secret +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data.enc diff --git a/mysql-test/suite/encryption/t/filekeys_encfile.test b/mysql-test/suite/encryption/t/filekeys_encfile.test new file mode 100644 index 00000000..a0611a38 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_encfile.test @@ -0,0 +1 @@ +source filekeys_goodtest.inc; diff --git a/mysql-test/suite/encryption/t/filekeys_encfile_bad.opt b/mysql-test/suite/encryption/t/filekeys_encfile_bad.opt new file mode 100644 index 00000000..6ece8c6b --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_encfile_bad.opt @@ -0,0 +1,2 @@ +--loose-file-key-management-filekey=bad +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data.enc diff --git a/mysql-test/suite/encryption/t/filekeys_encfile_bad.test b/mysql-test/suite/encryption/t/filekeys_encfile_bad.test new file mode 100644 index 00000000..51ab14c5 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_encfile_bad.test @@ -0,0 +1,2 @@ +let SEARCH_PATTERN=Cannot decrypt .*filekeys-data.enc. Wrong key; +source filekeys_badtest.inc; diff --git a/mysql-test/suite/encryption/t/filekeys_encfile_badfile.opt b/mysql-test/suite/encryption/t/filekeys_encfile_badfile.opt new file mode 100644 index 00000000..374a4139 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_encfile_badfile.opt @@ -0,0 +1,2 @@ +--loose-file-key-management-filekey=FILE:bad +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data.enc diff --git a/mysql-test/suite/encryption/t/filekeys_encfile_badfile.test b/mysql-test/suite/encryption/t/filekeys_encfile_badfile.test new file mode 100644 index 00000000..e0b07ac6 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_encfile_badfile.test @@ -0,0 +1,2 @@ +let SEARCH_PATTERN=File 'bad' not found; +source filekeys_badtest.inc; diff --git a/mysql-test/suite/encryption/t/filekeys_encfile_file.opt b/mysql-test/suite/encryption/t/filekeys_encfile_file.opt new file mode 100644 index 00000000..df2d3d52 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_encfile_file.opt @@ -0,0 +1,2 @@ +--loose-file-key-management-filekey=FILE:$MTR_SUITE_DIR/t/filekeys-data.key +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data.enc diff --git a/mysql-test/suite/encryption/t/filekeys_encfile_file.test b/mysql-test/suite/encryption/t/filekeys_encfile_file.test new file mode 100644 index 00000000..a0611a38 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_encfile_file.test @@ -0,0 +1 @@ +source filekeys_goodtest.inc; diff --git a/mysql-test/suite/encryption/t/filekeys_encfile_no.opt b/mysql-test/suite/encryption/t/filekeys_encfile_no.opt new file mode 100644 index 00000000..68264e5c --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_encfile_no.opt @@ -0,0 +1 @@ +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data.enc diff --git a/mysql-test/suite/encryption/t/filekeys_encfile_no.test b/mysql-test/suite/encryption/t/filekeys_encfile_no.test new file mode 100644 index 00000000..51ab14c5 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_encfile_no.test @@ -0,0 +1,2 @@ +let SEARCH_PATTERN=Cannot decrypt .*filekeys-data.enc. Wrong key; +source filekeys_badtest.inc; diff --git a/mysql-test/suite/encryption/t/filekeys_goodtest.inc b/mysql-test/suite/encryption/t/filekeys_goodtest.inc new file mode 100644 index 00000000..25206079 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_goodtest.inc @@ -0,0 +1,18 @@ +-- source include/have_innodb.inc +-- source filekeys_plugin.inc + +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +show create table t1; +insert t1 values (12345, repeat('1234567890', 20)); + +alter table t1 encryption_key_id=2; +show create table t1; +--error ER_ILLEGAL_HA_CREATE_OPTION +alter table t1 encryption_key_id=3; +show create table t1; +alter table t1 encryption_key_id=33; +show create table t1; +alter table t1 encryption_key_id=4; +show create table t1; + +drop table t1; diff --git a/mysql-test/suite/encryption/t/filekeys_nofile.test b/mysql-test/suite/encryption/t/filekeys_nofile.test new file mode 100644 index 00000000..46f5cd46 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_nofile.test @@ -0,0 +1,2 @@ +let SEARCH_PATTERN=file-key-management-filename is not set; +source filekeys_badtest.inc; diff --git a/mysql-test/suite/encryption/t/filekeys_plugin.inc b/mysql-test/suite/encryption/t/filekeys_plugin.inc new file mode 100644 index 00000000..a9bde3b0 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_plugin.inc @@ -0,0 +1,4 @@ +if (!$FILE_KEY_MANAGEMENT_SO) +{ + --skip Needs dynamic file_key_management plugin +} diff --git a/mysql-test/suite/encryption/t/filekeys_plugin.opt b/mysql-test/suite/encryption/t/filekeys_plugin.opt new file mode 100644 index 00000000..b42e6266 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_plugin.opt @@ -0,0 +1 @@ +--plugin-load-add=$FILE_KEY_MANAGEMENT_SO diff --git a/mysql-test/suite/encryption/t/filekeys_plugin_exists.inc b/mysql-test/suite/encryption/t/filekeys_plugin_exists.inc new file mode 100644 index 00000000..a9bde3b0 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_plugin_exists.inc @@ -0,0 +1,4 @@ +if (!$FILE_KEY_MANAGEMENT_SO) +{ + --skip Needs dynamic file_key_management plugin +} diff --git a/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.enc b/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.enc new file mode 100644 index 00000000..3257ff7d --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.enc @@ -0,0 +1,4 @@ +Salted__åÒ4¶À0-6„LÊÆÀ ìsK?p\õa’m8ž¸N?q œnŠ<ø¹*g¯•(•Å|F‰Š±ø/õɳ! +öœ kok6ÄðŸÙy7t67ôD#¢gæ´„¤Ê—«¤Ô£ãþiyu²*iÅ#•Æˆ82#6à ¶›.C8ÛÏ;7þBÔ£¥ˆ‚ +0À / +üÀw¤Ú0w"xÔ±Qu04ÿðxËkj®{ÅÛÃW΢¹Ìå3CÀ5Õœ¦¼Âᔪ÷·¯ÑåPù$=«Ò²
\ No newline at end of file diff --git a/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.key b/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.key new file mode 100644 index 00000000..bba639ae --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.key @@ -0,0 +1 @@ +c9518399cbec2b5edf773e06d1b934b90ec0f46ae455b8f1e001b5629ef31a513b83e676bf654c08ba98659461410e5e040e46237a7d50b40bd9bb90576f841275506e61523e5e9a0beb7641127ed2d946395b6fee7ff5263a9019cbe71bd907bf1ac6365940fa391086830a4e6c1d2972b99505467ef31cfb46d0cb7ab8f4f1 diff --git a/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.opt b/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.opt new file mode 100644 index 00000000..9dee47bb --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.opt @@ -0,0 +1,3 @@ +--loose-file-key-management-filekey=FILE:$MTR_SUITE_DIR/t/filekeys_secret_openssl_rand_128bits.key +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys_secret_openssl_rand_128bits.enc + diff --git a/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.test b/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.test new file mode 100644 index 00000000..60718d21 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_secret_openssl_rand_128bits.test @@ -0,0 +1,13 @@ +-- source include/have_innodb.inc +-- source filekeys_plugin.inc + +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=1; +show create table t1; +insert t1 values (12345, repeat('1234567890', 20)); + +alter table t1 encryption_key_id=2; +show create table t1; + +drop table t1; + +--echo # Test checks if opening an too large secret does not crash the server. diff --git a/mysql-test/suite/encryption/t/filekeys_secret_too_long.opt b/mysql-test/suite/encryption/t/filekeys_secret_too_long.opt new file mode 100644 index 00000000..c3f95019 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_secret_too_long.opt @@ -0,0 +1,3 @@ +--loose-file-key-management-filekey=FILE:$MTR_SUITE_DIR/t/filekeys-data-too-long.key +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data.enc + diff --git a/mysql-test/suite/encryption/t/filekeys_secret_too_long.test b/mysql-test/suite/encryption/t/filekeys_secret_too_long.test new file mode 100644 index 00000000..0032e94d --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_secret_too_long.test @@ -0,0 +1,4 @@ +let SEARCH_PATTERN=the filekey is too long; +source filekeys_badtest.inc; + +--echo # Test checks if opening an too large secret does not crash the server. diff --git a/mysql-test/suite/encryption/t/filekeys_syntax.opt b/mysql-test/suite/encryption/t/filekeys_syntax.opt new file mode 100644 index 00000000..4be6601b --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_syntax.opt @@ -0,0 +1 @@ +--loose-file-key-management-filename=$MYSQL_TMP_DIR/keys.txt diff --git a/mysql-test/suite/encryption/t/filekeys_syntax.test b/mysql-test/suite/encryption/t/filekeys_syntax.test new file mode 100644 index 00000000..61db6ad7 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_syntax.test @@ -0,0 +1,109 @@ +# +# first test - missing key file +# +let SEARCH_PATTERN=File '.*keys.txt' not found; +source filekeys_badtest.inc; + +# +# key id= 0 +# +write_file $MYSQL_TMP_DIR/keys.txt; +1;11111111111111111111111111111111 +0;00000000000000000000000000000000 +2;22222222222222222222222222222222 +EOF +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +--error 2 +install soname 'file_key_management'; +source filekeys_badtest.inc; +let SEARCH_PATTERN=Invalid key id; +source filekeys_badtest.inc; + +# +# id too big +# +remove_file $MYSQL_TMP_DIR/keys.txt; +write_file $MYSQL_TMP_DIR/keys.txt; +1;11111111111111111111111111111111 +4294967299;00000000000000000000000000000000 +2;22222222222222222222222222222222 +EOF +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +--error 2 +install soname 'file_key_management'; +source filekeys_badtest.inc; +let SEARCH_PATTERN=Invalid key id; +source filekeys_badtest.inc; +# +# wrong key length (not 16, 24, 23 bytes) +# +remove_file $MYSQL_TMP_DIR/keys.txt; +write_file $MYSQL_TMP_DIR/keys.txt; +1;11111111111111111111111111111111 +3;00000000000000000000000000000000111122223333 +2;22222222222222222222222222222222 +EOF +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +--error 2 +install soname 'file_key_management'; +source filekeys_badtest.inc; +let SEARCH_PATTERN=Invalid key; +source filekeys_badtest.inc; +# +# wrong key length (not an even number of digits) +# +remove_file $MYSQL_TMP_DIR/keys.txt; +write_file $MYSQL_TMP_DIR/keys.txt; +1;11111111111111111111111111111111 +3;0000000000000000000000000000000 +2;22222222222222222222222222222222 +EOF +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +--error 2 +install soname 'file_key_management'; +source filekeys_badtest.inc; +let SEARCH_PATTERN=Invalid key; +source filekeys_badtest.inc; +# +# no semicolon +# +remove_file $MYSQL_TMP_DIR/keys.txt; +write_file $MYSQL_TMP_DIR/keys.txt; +1;11111111111111111111111111111111 +3:0000000000000000000000000000000 +2;22222222222222222222222222222222 +EOF +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +--error 2 +install soname 'file_key_management'; +source filekeys_badtest.inc; +let SEARCH_PATTERN=Syntax error; +source filekeys_badtest.inc; +# +# another syntax error +# +remove_file $MYSQL_TMP_DIR/keys.txt; +write_file $MYSQL_TMP_DIR/keys.txt; +1;11111111111111111111111111111111 +syntax error +2;22222222222222222222222222222222 +EOF +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +--error 2 +install soname 'file_key_management'; +source filekeys_badtest.inc; +let SEARCH_PATTERN=Syntax error; +source filekeys_badtest.inc; +# +# no key id 1 +# +remove_file $MYSQL_TMP_DIR/keys.txt; +write_file $MYSQL_TMP_DIR/keys.txt; +3;22222222222222222222222222222222 +EOF +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +--error 2 +install soname 'file_key_management'; +source filekeys_badtest.inc; +let SEARCH_PATTERN=System key id 1; +source filekeys_badtest.inc; diff --git a/mysql-test/suite/encryption/t/filekeys_tooshort.opt b/mysql-test/suite/encryption/t/filekeys_tooshort.opt new file mode 100644 index 00000000..8999becc --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_tooshort.opt @@ -0,0 +1,3 @@ +--loose-file-key-management-filekey=secret +--loose-file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-tooshort.enc + diff --git a/mysql-test/suite/encryption/t/filekeys_tooshort.test b/mysql-test/suite/encryption/t/filekeys_tooshort.test new file mode 100644 index 00000000..b0e89675 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_tooshort.test @@ -0,0 +1,4 @@ +let SEARCH_PATTERN=Cannot decrypt .*tooshort.enc. Not encrypted; +source filekeys_badtest.inc; + +--echo # Test checks if opening an too short filekeys does not crash the server. diff --git a/mysql-test/suite/encryption/t/filekeys_unencfile.opt b/mysql-test/suite/encryption/t/filekeys_unencfile.opt new file mode 100644 index 00000000..b7e207c0 --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_unencfile.opt @@ -0,0 +1,2 @@ +--loose-file-key-management-filekey=bad +--loose-file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys.txt diff --git a/mysql-test/suite/encryption/t/filekeys_unencfile.test b/mysql-test/suite/encryption/t/filekeys_unencfile.test new file mode 100644 index 00000000..2567c29f --- /dev/null +++ b/mysql-test/suite/encryption/t/filekeys_unencfile.test @@ -0,0 +1,2 @@ +let SEARCH_PATTERN=Cannot decrypt .*keys.txt. Not encrypted; +source filekeys_badtest.inc; diff --git a/mysql-test/suite/encryption/t/import_4k.opt b/mysql-test/suite/encryption/t/import_4k.opt new file mode 100644 index 00000000..e5b58602 --- /dev/null +++ b/mysql-test/suite/encryption/t/import_4k.opt @@ -0,0 +1 @@ +--innodb-page-size=4k diff --git a/mysql-test/suite/encryption/t/import_4k.test b/mysql-test/suite/encryption/t/import_4k.test new file mode 100644 index 00000000..aef7c702 --- /dev/null +++ b/mysql-test/suite/encryption/t/import_4k.test @@ -0,0 +1,20 @@ +--source include/have_innodb.inc +--source include/have_sequence.inc +--source include/have_example_key_management_plugin.inc +--source include/have_debug.inc + +set @save_limit = @@GLOBAL.innodb_limit_optimistic_insert_debug; +set global innodb_limit_optimistic_insert_debug=3; +create table t1 (a INT PRIMARY KEY) engine=InnoDB ENCRYPTED=YES; +insert into t1 select * from seq_1_to_6000; +flush table t1 for export; +--let $datadir= `select @@datadir` +--copy_file $datadir/test/t1.ibd $datadir/t1.ibd +--copy_file $datadir/test/t1.cfg $datadir/t1.cfg +unlock tables; +alter table t1 discard tablespace; +--move_file $datadir/t1.ibd $datadir/test/t1.ibd +--move_file $datadir/t1.cfg $datadir/test/t1.cfg +alter table t1 import tablespace; +set global innodb_limit_optimistic_insert_debug=@save_limit; +drop table t1; diff --git a/mysql-test/suite/encryption/t/innochecksum.test b/mysql-test/suite/encryption/t/innochecksum.test new file mode 100644 index 00000000..516bc073 --- /dev/null +++ b/mysql-test/suite/encryption/t/innochecksum.test @@ -0,0 +1,303 @@ +# +# MDEV-8773: InnoDB innochecksum does not work with encrypted or page compressed tables +# + +# Don't test under embedded as we restart server +-- source include/not_embedded.inc +# Require InnoDB +-- source include/have_innodb.inc +-- source include/have_file_key_management_plugin.inc +-- source include/innodb_page_size_small.inc +-- source include/innodb_checksum_algorithm.inc +-- source include/maybe_debug.inc + +if (!$INNOCHECKSUM) { + --echo Need innochecksum binary + --die Need innochecksum binary +} + +--disable_query_log +# This may be triggered on a slow system or one that lacks native AIO. +call mtr.add_suppression("InnoDB: Trying to delete tablespace.*pending operations"); +if ($have_debug) { +SET GLOBAL DEBUG_DBUG='+d,ib_log_checkpoint_avoid_hard'; +call mtr.add_suppression("InnoDB: Crash recovery is broken due to insufficient innodb_log_file_size"); +} +--enable_query_log + +let $checksum_algorithm = `SELECT @@innodb_checksum_algorithm`; +SET GLOBAL innodb_file_per_table = ON; +# zlib +set global innodb_compression_algorithm = 1; + + +--echo # Create and populate a tables +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB ENCRYPTED=YES ENCRYPTION_KEY_ID=4; +CREATE TABLE t2 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED ENCRYPTED=YES ENCRYPTION_KEY_ID=4; +CREATE TABLE t3 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB ROW_FORMAT=COMPRESSED ENCRYPTED=NO; +CREATE TABLE t4 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB PAGE_COMPRESSED=1; +CREATE TABLE t5 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB PAGE_COMPRESSED=1 ENCRYPTED=YES ENCRYPTION_KEY_ID=4; +CREATE TABLE t6 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT) ENGINE=InnoDB; + +--disable_query_log +--let $i = 1000 +begin; +while ($i) +{ + INSERT INTO t1 (b) VALUES (REPEAT('abcdefghijklmnopqrstuvwxyz', 100)); + dec $i; +} +INSERT INTO t2 SELECT * FROM t1; +INSERT INTO t3 SELECT * FROM t1; +INSERT INTO t4 SELECT * FROM t1; +INSERT INTO t5 SELECT * FROM t1; +INSERT INTO t6 SELECT * FROM t1; +commit; +--enable_query_log + +let $MYSQLD_DATADIR=`select @@datadir`; +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 t6_IBD = $MYSQLD_DATADIR/test/t6.ibd; + +let INNODB_PAGE_SIZE=`select @@innodb_page_size`; +let MYSQLD_DATADIR=`select @@datadir`; + +--source include/shutdown_mysqld.inc + +-- disable_result_log +--echo # Run innochecksum on t1, check -S does not cause crash for encrypted file +--exec $INNOCHECKSUM -S $t1_IBD + +--echo # Run innochecksum on t2 + +--exec $INNOCHECKSUM $t2_IBD + +--echo # Run innochecksum on t3 + +--exec $INNOCHECKSUM $t3_IBD + +--echo # Run innochecksum on t4 + +--exec $INNOCHECKSUM $t4_IBD + +--echo # Run innochecksum on t4 + +--exec $INNOCHECKSUM $t4_IBD + +--echo # Run innochecksum on t5 + +--exec $INNOCHECKSUM $t5_IBD + +--echo # Run innochecksum on t6 + +--exec $INNOCHECKSUM $t6_IBD + +--enable_result_log + +--echo # Backup tables before corrupting +--copy_file $MYSQLD_DATADIR/test/t1.ibd $MYSQLD_DATADIR/test/t1.ibd.backup +--copy_file $MYSQLD_DATADIR/test/t2.ibd $MYSQLD_DATADIR/test/t2.ibd.backup +--copy_file $MYSQLD_DATADIR/test/t3.ibd $MYSQLD_DATADIR/test/t3.ibd.backup +--copy_file $MYSQLD_DATADIR/test/t4.ibd $MYSQLD_DATADIR/test/t4.ibd.backup +--copy_file $MYSQLD_DATADIR/test/t5.ibd $MYSQLD_DATADIR/test/t5.ibd.backup +--copy_file $MYSQLD_DATADIR/test/t6.ibd $MYSQLD_DATADIR/test/t6.ibd.backup + +# +# MDEV-11939: innochecksum mistakes a file for an encrypted one +# + +--echo # Corrupt FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + +perl; +open(FILE, "+<", "$ENV{MYSQLD_DATADIR}/test/t1.ibd") or die "open"; +binmode FILE; +seek(FILE, $ENV{'INNODB_PAGE_SIZE'} * 3 + 26, SEEK_SET) or die "seek"; +print FILE pack("H*", "c00lcafedeadb017"); +close FILE or die "close"; +open(FILE, "+<", "$ENV{MYSQLD_DATADIR}/test/t2.ibd") or die "open"; +binmode FILE; +seek(FILE, $ENV{'INNODB_PAGE_SIZE'} * 3 + 26, SEEK_SET) or die "seek"; +print FILE pack("H*", "c00lcafedeadb017"); +close FILE or die "close"; +open(FILE, "+<", "$ENV{MYSQLD_DATADIR}/test/t3.ibd") or die "open"; +binmode FILE; +seek(FILE, $ENV{'INNODB_PAGE_SIZE'} * 3 + 26, SEEK_SET) or die "seek"; +print FILE pack("H*", "c00lcafedeadb017"); +close FILE or die "close"; +open(FILE, "+<", "$ENV{MYSQLD_DATADIR}/test/t6.ibd") or die "open"; +binmode FILE; +seek(FILE, $ENV{'INNODB_PAGE_SIZE'} * 3 + 26, SEEK_SET) or die "seek"; +print FILE pack("H*", "c00lcafedeadb017"); +close FILE or die "close"; +EOF + +-- disable_result_log +--error 1 +--exec $INNOCHECKSUM $t1_IBD + +--echo # Run innochecksum on t2 + +--error 1 +--exec $INNOCHECKSUM $t2_IBD + +--echo # Run innochecksum on t3 +--echo # no encryption corrupting the field should not have effect +--exec $INNOCHECKSUM $t3_IBD + +--echo # Run innochecksum on t6 +--echo # In new checksum format, checksum calculated for whole page. +--echo # So It should affected. +let $error_code = 0; +if ($checksum_algorithm == "full_crc32") +{ + let $error_code = 1; +} + +if ($checksum_algorithm == "strict_full_crc32") +{ + let $error_code = 1; +} + +--error $error_code +--exec $INNOCHECKSUM $t6_IBD + +--enable_result_log + +--echo # Restore the original tables +--remove_file $MYSQLD_DATADIR/test/t1.ibd +--remove_file $MYSQLD_DATADIR/test/t2.ibd +--remove_file $MYSQLD_DATADIR/test/t3.ibd +--remove_file $MYSQLD_DATADIR/test/t4.ibd +--remove_file $MYSQLD_DATADIR/test/t5.ibd +--remove_file $MYSQLD_DATADIR/test/t6.ibd +--copy_file $MYSQLD_DATADIR/test/t1.ibd.backup $MYSQLD_DATADIR/test/t1.ibd +--copy_file $MYSQLD_DATADIR/test/t2.ibd.backup $MYSQLD_DATADIR/test/t2.ibd +--copy_file $MYSQLD_DATADIR/test/t3.ibd.backup $MYSQLD_DATADIR/test/t3.ibd +--copy_file $MYSQLD_DATADIR/test/t4.ibd.backup $MYSQLD_DATADIR/test/t4.ibd +--copy_file $MYSQLD_DATADIR/test/t5.ibd.backup $MYSQLD_DATADIR/test/t5.ibd +--copy_file $MYSQLD_DATADIR/test/t6.ibd.backup $MYSQLD_DATADIR/test/t6.ibd + +--echo # Corrupt FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION+4 (post encryption checksum) + +perl; +open(FILE, "+<", "$ENV{MYSQLD_DATADIR}/test/t1.ibd") or die "open"; +binmode FILE; +seek(FILE, $ENV{'INNODB_PAGE_SIZE'} * 3 + 30, SEEK_SET) or die "seek"; +print FILE pack("H*", "c00lcafedeadb017"); +close FILE or die "close"; +open(FILE, "+<", "$ENV{MYSQLD_DATADIR}/test/t2.ibd") or die "open"; +binmode FILE; +seek(FILE, $ENV{'INNODB_PAGE_SIZE'} * 3 + 30, SEEK_SET) or die "seek"; +print FILE pack("H*", "c00lcafedeadb017"); +close FILE or die "close"; +open(FILE, "+<", "$ENV{MYSQLD_DATADIR}/test/t3.ibd") or die "open"; +binmode FILE; +seek(FILE, $ENV{'INNODB_PAGE_SIZE'} * 3 + 30, SEEK_SET) or die "seek"; +print FILE pack("H*", "c00lcafedeadb017"); +close FILE or die "close"; +open(FILE, "+<", "$ENV{MYSQLD_DATADIR}/test/t6.ibd") or die "open"; +binmode FILE; +seek(FILE, $ENV{'INNODB_PAGE_SIZE'} * 3 + 30, SEEK_SET) or die "seek"; +print FILE pack("H*", "c00lcafedeadb017"); +close FILE or die "close"; +EOF + +-- disable_result_log +--error 1 +--exec $INNOCHECKSUM $t1_IBD + +--echo # Run innochecksum on t2 +--error 1 +--exec $INNOCHECKSUM $t2_IBD + +--echo # Run innochecksum on t3 +--error 1 +--exec $INNOCHECKSUM $t3_IBD + +--echo # Run innochecksum on t6 +--echo # Space ID mismatch +--error 1 +--exec $INNOCHECKSUM $t6_IBD + +--enable_result_log + +--echo # Restore the original tables +--remove_file $MYSQLD_DATADIR/test/t1.ibd +--remove_file $MYSQLD_DATADIR/test/t2.ibd +--remove_file $MYSQLD_DATADIR/test/t3.ibd +--remove_file $MYSQLD_DATADIR/test/t4.ibd +--remove_file $MYSQLD_DATADIR/test/t5.ibd +--remove_file $MYSQLD_DATADIR/test/t6.ibd +--copy_file $MYSQLD_DATADIR/test/t1.ibd.backup $MYSQLD_DATADIR/test/t1.ibd +--copy_file $MYSQLD_DATADIR/test/t2.ibd.backup $MYSQLD_DATADIR/test/t2.ibd +--copy_file $MYSQLD_DATADIR/test/t3.ibd.backup $MYSQLD_DATADIR/test/t3.ibd +--copy_file $MYSQLD_DATADIR/test/t4.ibd.backup $MYSQLD_DATADIR/test/t4.ibd +--copy_file $MYSQLD_DATADIR/test/t5.ibd.backup $MYSQLD_DATADIR/test/t5.ibd +--copy_file $MYSQLD_DATADIR/test/t6.ibd.backup $MYSQLD_DATADIR/test/t6.ibd + +--echo # Corrupt FIL_DATA+10 (data) + +perl; +open(FILE, "+<", "$ENV{MYSQLD_DATADIR}/test/t1.ibd") or die "open"; +binmode FILE; +seek(FILE, $ENV{'INNODB_PAGE_SIZE'} * 3 + 48, SEEK_SET) or die "seek"; +print FILE pack("H*", "c00lcafedeadb017"); +close FILE or die "close"; +open(FILE, "+<", "$ENV{MYSQLD_DATADIR}/test/t2.ibd") or die "open"; +binmode FILE; +seek(FILE, $ENV{'INNODB_PAGE_SIZE'} * 3 + 48, SEEK_SET) or die "seek"; +print FILE pack("H*", "c00lcafedeadb017"); +close FILE or die "close"; +open(FILE, "+<", "$ENV{MYSQLD_DATADIR}/test/t3.ibd") or die "open"; +binmode FILE; +seek(FILE, $ENV{'INNODB_PAGE_SIZE'} * 3 + 48, SEEK_SET) or die "seek"; +print FILE pack("H*", "c00lcafedeadb017"); +close FILE or die "close"; +open(FILE, "+<", "$ENV{MYSQLD_DATADIR}/test/t6.ibd") or die "open"; +binmode FILE; +seek(FILE, $ENV{'INNODB_PAGE_SIZE'} * 3 + 48, SEEK_SET) or die "seek"; +print FILE pack("H*", "c00lcafedeadb017"); +close FILE or die "close"; +EOF + +if (0 && $have_debug) { # these messages sometimes fail to appear +--let SEARCH_FILE= $MYSQLTEST_VARDIR/log/mysqld.1.err +--let SEARCH_PATTERN= InnoDB: Crash recovery is broken due to insufficient innodb_log_file_size; last checkpoint LSN=\\d+, current LSN=\\d+\\. Shutdown is in progress\\..*InnoDB: Crash recovery was broken.* +--echo # FOUND 1 is expected for both. +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN= InnoDB: Crash recovery was broken +--source include/search_pattern_in_file.inc +} + +-- disable_result_log +--error 1 +--exec $INNOCHECKSUM $t1_IBD + +--echo # Run innochecksum on t2 +--error 1 +--exec $INNOCHECKSUM $t2_IBD + +--echo # Run innochecksum on t3 +--error 1 +--exec $INNOCHECKSUM $t3_IBD + +--echo # Run innochecksum on t6 +--error 1 +--exec $INNOCHECKSUM $t6_IBD + +--enable_result_log + +--echo # Restore the original tables +--move_file $MYSQLD_DATADIR/test/t1.ibd.backup $MYSQLD_DATADIR/test/t1.ibd +--move_file $MYSQLD_DATADIR/test/t2.ibd.backup $MYSQLD_DATADIR/test/t2.ibd +--move_file $MYSQLD_DATADIR/test/t3.ibd.backup $MYSQLD_DATADIR/test/t3.ibd +--move_file $MYSQLD_DATADIR/test/t4.ibd.backup $MYSQLD_DATADIR/test/t4.ibd +--move_file $MYSQLD_DATADIR/test/t5.ibd.backup $MYSQLD_DATADIR/test/t5.ibd +--move_file $MYSQLD_DATADIR/test/t6.ibd.backup $MYSQLD_DATADIR/test/t6.ibd + +--source include/start_mysqld.inc +DROP TABLE t1, t2, t3, t4, t5, t6; diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change.combinations b/mysql-test/suite/encryption/t/innodb-bad-key-change.combinations new file mode 100644 index 00000000..72938059 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change.combinations @@ -0,0 +1,5 @@ +[strict_crc32] +--innodb-checksum-algorithm=strict_crc32 + +[strict_full_crc32] +--innodb-checksum-algorithm=strict_full_crc32 diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change.opt b/mysql-test/suite/encryption/t/innodb-bad-key-change.opt new file mode 100644 index 00000000..d14f3bcb --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change.opt @@ -0,0 +1 @@ +--skip-innodb-fast-shutdown diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change.test b/mysql-test/suite/encryption/t/innodb-bad-key-change.test new file mode 100644 index 00000000..05a3b5f4 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change.test @@ -0,0 +1,112 @@ +-- source include/have_innodb.inc +-- source include/have_file_key_management_plugin.inc +# embedded does not support restart +-- source include/not_embedded.inc + +# +# MDEV-8588: Assertion failure in file ha_innodb.cc line 21140 if at least one encrypted +# table exists and encryption service is not available. +# + +call mtr.add_suppression("Plugin 'file_key_management' init function returned error"); +call mtr.add_suppression("Plugin 'file_key_management' registration.*failed"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` has an unreadable root page"); +call mtr.add_suppression("Table .*t[12].* is corrupted"); +call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[12]\\.ibd' cannot be decrypted; key_version=1"); +call mtr.add_suppression("failed to read \\[page id: space=[1-9][0-9]*, page number=[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("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 +-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt +-- source include/restart_mysqld.inc + +SET GLOBAL innodb_file_per_table = ON; + +CREATE TABLE t1 (c VARCHAR(8)) ENGINE=InnoDB ENCRYPTED=YES ENCRYPTION_KEY_ID=2; +INSERT INTO t1 VALUES ('foobar'); +ALTER TABLE t1 ADD COLUMN c2 INT; +INSERT INTO t1 VALUES ('foobar',2); +SELECT * FROM t1; +TRUNCATE TABLE t1; +SELECT * FROM t1; +INSERT INTO t1 VALUES ('foobar',1); +INSERT INTO t1 VALUES ('foobar',2); +FLUSH TABLE WITH READ LOCK; +SELECT * FROM t1; + +--echo +--echo # Restart server with keysbad3.txt +-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keysbad3.txt +-- source include/restart_mysqld.inc + +--disable_warnings +--error ER_NO_SUCH_TABLE_IN_ENGINE +SELECT * FROM t1; +--enable_warnings + +-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keysbad3.txt +-- source include/restart_mysqld.inc + +--replace_regex /key_id [1-9][0-9]*/\1 / +DROP TABLE t1; + +# +# MDEV-8591: Database page corruption on disk or a failed space, Assertion failure in file buf0buf.cc +# line 2856 on querying a table using wrong default encryption key +# + +--echo # Start server with keys3.txt +-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys3.txt +-- source include/restart_mysqld.inc + +SET GLOBAL innodb_default_encryption_key_id=5; +CREATE TABLE t2 (c VARCHAR(8), id int not null primary key, b int, key(b)) ENGINE=InnoDB ENCRYPTED=YES; +INSERT INTO t2 VALUES ('foobar',1,2); + +--echo +--echo # Restart server with keys2.txt +-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt +-- source include/restart_mysqld.inc + +--disable_warnings +--error ER_NO_SUCH_TABLE_IN_ENGINE +SELECT * FROM t2; + +--error ER_TABLE_CORRUPT +SELECT * FROM t2 where id = 1; + +--error ER_TABLE_CORRUPT +SELECT * FROM t2 where b = 1; + +--error ER_TABLE_CORRUPT +INSERT INTO t2 VALUES ('tmp',3,3); + +--error ER_TABLE_CORRUPT +DELETE FROM t2 where b = 3; + +--error ER_TABLE_CORRUPT +DELETE FROM t2 where id = 3; + +--error ER_TABLE_CORRUPT +UPDATE t2 set b = b +1; + +OPTIMIZE TABLE t2; + +--error ER_TABLE_CORRUPT +ALTER TABLE t2 ADD COLUMN d INT; + +ANALYZE TABLE t2; + +--error ER_TABLE_CORRUPT +TRUNCATE TABLE t2; + +DROP TABLE t2; +--enable_warnings + +--echo +--echo # Start server with keys2.txt +-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt +-- source include/restart_mysqld.inc diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change2.combinations b/mysql-test/suite/encryption/t/innodb-bad-key-change2.combinations new file mode 100644 index 00000000..72938059 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change2.combinations @@ -0,0 +1,5 @@ +[strict_crc32] +--innodb-checksum-algorithm=strict_crc32 + +[strict_full_crc32] +--innodb-checksum-algorithm=strict_full_crc32 diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change2.opt b/mysql-test/suite/encryption/t/innodb-bad-key-change2.opt new file mode 100644 index 00000000..d14f3bcb --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change2.opt @@ -0,0 +1 @@ +--skip-innodb-fast-shutdown diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change2.test b/mysql-test/suite/encryption/t/innodb-bad-key-change2.test new file mode 100644 index 00000000..21a9ddb2 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change2.test @@ -0,0 +1,103 @@ +--source include/have_innodb.inc +# embedded does not support restart +-- source include/not_embedded.inc +-- source filekeys_plugin_exists.inc +# +# MDEV-8750: Server crashes in page_cur_is_after_last on altering table using a wrong encryption key +# MDEV-8769: Server crash at file btr0btr.ic line 122 when defragmenting encrypted table using incorrect keys +# MDEV-8768: Server crash at file btr0btr.ic line 122 when checking encrypted table using incorrect keys +# MDEV-8727: Server/InnoDB hangs on shutdown after trying to read an encrypted table with a wrong key +# +call mtr.add_suppression("InnoDB: Table `test`\\.`t1` (has an unreadable root page|does not exist.*is trying to rename)"); +call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t1(new)?\\.ibd' cannot be decrypted; key_version=1"); +call mtr.add_suppression("InnoDB: Recovery failed to read page"); +# 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("InnoDB: Tablespace for table \`test\`.\`t1\` is set as discarded\\."); +call mtr.add_suppression("Table .*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: 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 --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt +--source include/restart_mysqld.inc + +SET GLOBAL innodb_file_per_table = ON; + +CREATE TABLE t1 (pk INT PRIMARY KEY, f VARCHAR(8)) ENGINE=InnoDB +ENCRYPTED=YES ENCRYPTION_KEY_ID=4; +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); + +--let $restart_parameters=--plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys3.txt +--source include/restart_mysqld.inc + +--error ER_NO_SUCH_TABLE_IN_ENGINE +SELECT * FROM t1; +--replace_regex /key_id [1-9][0-9]*/\1 / +SHOW WARNINGS; +--error ER_TABLE_CORRUPT +ALTER TABLE t1 ENGINE=InnoDB; +--replace_regex /key_id [1-9][0-9]*/\1 / +SHOW WARNINGS; +OPTIMIZE TABLE t1; +--replace_regex /key_id [1-9][0-9]*/\1 / +SHOW WARNINGS; + +CHECK TABLE t1; +--replace_regex /key_id [1-9][0-9]*/\1 / +SHOW WARNINGS; + +--let $restart_parameters=--plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt +--source include/restart_mysqld.inc + +let MYSQLD_DATADIR =`SELECT @@datadir`; + +FLUSH TABLES t1 FOR EXPORT; +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_backup_tablespaces("test", "t1"); +EOF +UNLOCK TABLES; + +--let $restart_parameters=--plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys3.txt +--source include/restart_mysqld.inc + +--error ER_NO_SUCH_TABLE_IN_ENGINE +ALTER TABLE t1 DISCARD TABLESPACE; +# Drop table will succeed. +DROP TABLE t1; + +CREATE TABLE t1 (pk INT PRIMARY KEY, f VARCHAR(8)) ENGINE=InnoDB +ENCRYPTED=YES ENCRYPTION_KEY_ID=4; +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 + +--let $restart_parameters=--plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt +--source include/restart_mysqld.inc + +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; +SHOW CREATE TABLE t1; + +--let $restart_parameters= --innodb-encrypt-tables --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys3.txt +--source include/restart_mysqld.inc + +--error ER_ERROR_ON_RENAME +RENAME TABLE t1 TO t1new; +--error ER_TABLE_CORRUPT +ALTER TABLE t1 RENAME TO t1new; +# Drop should succeed even with incorrect keys +DROP TABLE t1; diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change3.combinations b/mysql-test/suite/encryption/t/innodb-bad-key-change3.combinations new file mode 100644 index 00000000..72938059 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change3.combinations @@ -0,0 +1,5 @@ +[strict_crc32] +--innodb-checksum-algorithm=strict_crc32 + +[strict_full_crc32] +--innodb-checksum-algorithm=strict_full_crc32 diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change3.test b/mysql-test/suite/encryption/t/innodb-bad-key-change3.test new file mode 100644 index 00000000..9c2918f3 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change3.test @@ -0,0 +1,100 @@ +--source include/have_innodb.inc +# embedded does not support restart +-- source include/not_embedded.inc +-- source include/not_valgrind.inc +# Avoid CrashReporter popup on Mac +-- source include/not_crashrep.inc +-- source filekeys_plugin_exists.inc +# +# MDEV-8772: Assertion failure in file ha_innodb.cc line 20027 when importing page compressed and encrypted tablespace using incorrect keys +# + +call mtr.add_suppression("InnoDB: Tablespace for table .* is set as discarded."); +call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* because the .ibd file is missing. Please refer to .* for how to resolve the issue."); + +--let $MYSQLD_TMPDIR = `SELECT @@tmpdir` +--let $MYSQLD_DATADIR = `SELECT @@datadir` +--let SEARCH_RANGE = 10000000 +--let t1_IBD = $MYSQLD_DATADIR/test/t1.ibd +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server +--source include/wait_until_disconnected.inc + +--write_file $MYSQLTEST_VARDIR/keys1.txt +1;770A8A65DA156D24EE2A093277530142 +4;770A8A65DA156D24EE2A093277530143 +EOF + +--exec echo "restart:--innodb-encrypt-tables --innodb-stats-persistent --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/keys1.txt" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc + +set global innodb_compression_algorithm = 1; + +CREATE TABLE t1 (pk INT PRIMARY KEY, f VARCHAR(255)) ENGINE=InnoDB PAGE_COMPRESSED=1 ENCRYPTED=YES ENCRYPTION_KEY_ID=4; +SHOW WARNINGS; +SHOW CREATE TABLE t1; +INSERT INTO t1 VALUES (1,'foobar'),(2,'barfoo'); +let MYSQLD_DATADIR =`SELECT @@datadir`; +FLUSH TABLE t1 FOR EXPORT; +--echo # List before copying files +--list_files $MYSQLD_DATADIR/test +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_backup_tablespaces("test", "t1"); +EOF +UNLOCK TABLES; + +ALTER TABLE t1 DISCARD TABLESPACE; + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server +--source include/wait_until_disconnected.inc + +--write_file $MYSQLTEST_VARDIR/keys2.txt +1;770A8A65DA156D24EE2A093277530142 +4;770A8A65DA156D24EE2A093277530144 +EOF + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1"); +ib_restore_tablespaces("test", "t1"); +EOF + +--exec echo "restart:--innodb-encrypt-tables --innodb-stats-persistent --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/keys2.txt" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc +--source include/restart_mysqld.inc + +--error ER_GET_ERRMSG +ALTER TABLE t1 IMPORT TABLESPACE; +SHOW CREATE TABLE t1; +--error ER_TABLESPACE_DISCARDED +SELECT * FROM t1; +--sleep 5 +--echo # Tablespaces should be still encrypted +-- let SEARCH_FILE=$t1_IBD +--let SEARCH_PATTERN=foobar +--echo # t1 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t1_IBD +-- source include/search_pattern_in_file.inc + +--exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--shutdown_server +--source include/wait_until_disconnected.inc +--remove_file $MYSQLTEST_VARDIR/keys1.txt +--write_file $MYSQLTEST_VARDIR/keys1.txt +1;770A8A65DA156D24EE2A093277530142 +4;770A8A65DA156D24EE2A093277530143 +EOF + +--exec echo "restart:--innodb-encrypt-tables --innodb-stats-persistent --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQLTEST_VARDIR/keys1.txt" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect +--enable_reconnect +--source include/wait_until_connected_again.inc +DROP TABLE t1; + +# reset system + +--remove_file $MYSQLTEST_VARDIR/keys1.txt +--remove_file $MYSQLTEST_VARDIR/keys2.txt diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change4.combinations b/mysql-test/suite/encryption/t/innodb-bad-key-change4.combinations new file mode 100644 index 00000000..72938059 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change4.combinations @@ -0,0 +1,5 @@ +[strict_crc32] +--innodb-checksum-algorithm=strict_crc32 + +[strict_full_crc32] +--innodb-checksum-algorithm=strict_full_crc32 diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change4.opt b/mysql-test/suite/encryption/t/innodb-bad-key-change4.opt new file mode 100644 index 00000000..ce4c31a5 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change4.opt @@ -0,0 +1,5 @@ +--loose-innodb-buffer-pool-stats +--loose-innodb-buffer-page +--loose-innodb-buffer-page-lru +--innodb-defragment=1 +--skip-innodb-fast-shutdown diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change4.test b/mysql-test/suite/encryption/t/innodb-bad-key-change4.test new file mode 100644 index 00000000..c37eb365 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change4.test @@ -0,0 +1,44 @@ +--source include/have_innodb.inc +# embedded does not support restart +-- source include/not_embedded.inc +-- source filekeys_plugin_exists.inc +# +# MDEV-8769: Server crash at file btr0btr.ic line 122 when defragmenting encrypted table using incorrect keys +# MDEV-8768: Server crash at file btr0btr.ic line 122 when checking encrypted table using incorrect keys +# + +call mtr.add_suppression("InnoDB: Table `test`\\.`t1` (has an unreadable root page)"); +call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t1\\.ibd' cannot be decrypted; key_version=1"); +call mtr.add_suppression("InnoDB: Recovery failed to read page"); +# 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("Table .*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 --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt +--source include/restart_mysqld.inc + +SET GLOBAL innodb_file_per_table = ON; + +CREATE TABLE t1 (pk INT PRIMARY KEY, f VARCHAR(8)) ENGINE=InnoDB +ENCRYPTED=YES ENCRYPTION_KEY_ID=4; +INSERT INTO t1 VALUES (1,'foo'),(2,'bar'); + +--let $restart_parameters=--plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys3.txt +--source include/restart_mysqld.inc + +--replace_regex /key_id [1-9][0-9]*/\1 / +OPTIMIZE TABLE t1; +--replace_regex /key_id [1-9][0-9]*/\1 / +SHOW WARNINGS; + +--replace_regex /key_id [1-9][0-9]*/\1 / +CHECK TABLE t1; +--replace_regex /key_id [1-9][0-9]*/\1 / +SHOW WARNINGS; + +--let $restart_parameters=--plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt +--source include/restart_mysqld.inc + +DROP TABLE t1; diff --git a/mysql-test/suite/encryption/t/innodb-checksum-algorithm.test b/mysql-test/suite/encryption/t/innodb-checksum-algorithm.test new file mode 100644 index 00000000..157fb25b --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-checksum-algorithm.test @@ -0,0 +1,83 @@ +-- source include/innodb_checksum_algorithm.inc +-- source include/innodb_page_size.inc +-- source include/have_file_key_management_plugin.inc + +SET @saved_file_per_table = @@global.innodb_file_per_table; +SET @saved_encrypt_tables = @@global.innodb_encrypt_tables; +SET @saved_encryption_threads = @@global.innodb_encryption_threads; +SET @saved_encryption_key_id = @@global.innodb_default_encryption_key_id; + +SET GLOBAL innodb_file_per_table = ON; +SET GLOBAL innodb_encrypt_tables = ON; +SET GLOBAL innodb_encryption_threads = 4; + +SET GLOBAL innodb_default_encryption_key_id=4; + +let MYSQLD_DATADIR =`SELECT @@datadir`; + +# ROW_FORMAT=COMPRESSED is unavailable with innodb_page_size=32k or 64k +let $row_format_compressed= `select case when @@global.innodb_page_size>16384 +then 'ROW_FORMAT=DYNAMIC' else 'ROW_FORMAT=COMPRESSED' end`; + +eval create table tce(a serial, b blob, index(b(10))) engine=innodb +$row_format_compressed encrypted=yes; +eval create table tc(a serial, b blob, index(b(10))) engine=innodb +$row_format_compressed encrypted=no; +eval create table te(a serial, b blob, index(b(10))) engine=innodb +encrypted=yes; +eval create table t(a serial, b blob, index(b(10))) engine=innodb +encrypted=no; +eval create table tpe(a serial, b blob, index(b(10))) engine=innodb +page_compressed=yes encrypted=yes; +eval create table tp(a serial, b blob, index(b(10))) engine=innodb +page_compressed=yes encrypted=no; + +begin; +eval insert into tce(b) values (repeat('secret',20)); +eval insert into tc(b) values (repeat('secret',20)); +eval insert into te(b) values (repeat('secret',20)); +eval insert into t(b) values (repeat('secret',20)); +eval insert into tpe(b) values (repeat('secret',20)); +eval insert into tp(b) values (repeat('secret',20)); +commit; + +eval FLUSH TABLES tce, tc, te, t, tpe, tp FOR EXPORT; +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_backup_tablespaces("test", ("tce", "tc", "te", "t", "tpe", "tp")); +EOF +--list_files $MYSQLD_DATADIR/test +UNLOCK TABLES; + +ALTER TABLE tce DISCARD TABLESPACE; +ALTER TABLE tc DISCARD TABLESPACE; +ALTER TABLE te DISCARD TABLESPACE; +ALTER TABLE t DISCARD TABLESPACE; +ALTER TABLE tpe DISCARD TABLESPACE; +ALTER TABLE tp DISCARD TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_restore_tablespaces("test", ("tce", "tc", "te", "t", "tpe", "tp")); +EOF + +ALTER TABLE tce IMPORT TABLESPACE; +update tce set b=substr(b,1); +ALTER TABLE tc IMPORT TABLESPACE; +update tc set b=substr(b,1); +ALTER TABLE te IMPORT TABLESPACE; +update te set b=substr(b,1); +ALTER TABLE t IMPORT TABLESPACE; +update t set b=substr(b,1); +ALTER TABLE tpe IMPORT TABLESPACE; +update tpe set b=substr(b,1); +ALTER TABLE tp IMPORT TABLESPACE; +update tp set b=substr(b,1); + +CHECK TABLE tce, tc, te, t, tpe, tp; +DROP TABLE tce, tc, te, t, tpe, tp; + +SET GLOBAL innodb_file_per_table = @saved_file_per_table; +SET GLOBAL innodb_encrypt_tables = @saved_encrypt_tables; +SET GLOBAL innodb_encryption_threads = @saved_encryption_threads; +SET GLOBAL innodb_default_encryption_key_id = @saved_encryption_key_id; diff --git a/mysql-test/suite/encryption/t/innodb-compressed-blob.opt b/mysql-test/suite/encryption/t/innodb-compressed-blob.opt new file mode 100644 index 00000000..f44dcb1e --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-compressed-blob.opt @@ -0,0 +1,5 @@ +--max-allowed-packet=64K +--innodb-tablespaces-encryption +--innodb-encrypt-tables=on +--innodb-encryption-threads=4 +--skip-innodb-fast-shutdown diff --git a/mysql-test/suite/encryption/t/innodb-compressed-blob.test b/mysql-test/suite/encryption/t/innodb-compressed-blob.test new file mode 100644 index 00000000..12d061a8 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-compressed-blob.test @@ -0,0 +1,41 @@ +-- source include/innodb_page_size_small.inc +-- source include/have_file_key_management_plugin.inc + +# embedded does not support restart +-- source include/not_embedded.inc + +call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted; key_version=1"); +call mtr.add_suppression("InnoDB: Recovery failed to read page"); +call mtr.add_suppression("InnoDB: Unable to decompress ..test.t[1-3]\\.ibd\\[page id: space=[1-9][0-9]*, page number=[0-9]+\\]"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` is corrupted"); + +--echo # Restart mysqld --file-key-management-filename=keys2.txt +-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt +-- source include/restart_mysqld.inc + +SET GLOBAL innodb_file_per_table = ON; + +set GLOBAL innodb_default_encryption_key_id=4; +create table t1(a int not null primary key, b blob, index(b(10))) engine=innodb row_format=compressed; +create table t2(a int not null primary key, b blob, index(b(10))) engine=innodb row_format=compressed encrypted=yes; +create table t3(a int not null primary key, b blob, index(b(10))) engine=innodb row_format=compressed encrypted=no; + +insert into t1 values (1, repeat('secret',6000)); +insert into t2 values (1, repeat('secret',6000)); +insert into t3 values (1, repeat('secret',6000)); + +--echo # Restart mysqld --file-key-management-filename=keys3.txt +-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys3.txt +-- source include/restart_mysqld.inc + +--error ER_NO_SUCH_TABLE_IN_ENGINE +select count(*) from t1 FORCE INDEX (b) where b like 'secret%'; +--error ER_NO_SUCH_TABLE_IN_ENGINE +select count(*) from t2 FORCE INDEX (b) where b like 'secret%'; +select count(*) from t3 FORCE INDEX (b) where b like 'secret%'; + +--echo # Restart mysqld --file-key-management-filename=keys2.txt +-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt +-- source include/restart_mysqld.inc + +drop table t1,t2,t3; diff --git a/mysql-test/suite/encryption/t/innodb-discard-import-change.combinations b/mysql-test/suite/encryption/t/innodb-discard-import-change.combinations new file mode 100644 index 00000000..72938059 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-discard-import-change.combinations @@ -0,0 +1,5 @@ +[strict_crc32] +--innodb-checksum-algorithm=strict_crc32 + +[strict_full_crc32] +--innodb-checksum-algorithm=strict_full_crc32 diff --git a/mysql-test/suite/encryption/t/innodb-discard-import-change.test b/mysql-test/suite/encryption/t/innodb-discard-import-change.test new file mode 100644 index 00000000..2cb6865e --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-discard-import-change.test @@ -0,0 +1,118 @@ +-- 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"); + +let $innodb_compression_algo = `SELECT @@innodb_compression_algorithm`; + +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; + +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_query_log +EVAL SET GLOBAL innodb_compression_algorithm = $innodb_compression_algo; +--enable_query_log diff --git a/mysql-test/suite/encryption/t/innodb-discard-import.combinations b/mysql-test/suite/encryption/t/innodb-discard-import.combinations new file mode 100644 index 00000000..72938059 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-discard-import.combinations @@ -0,0 +1,5 @@ +[strict_crc32] +--innodb-checksum-algorithm=strict_crc32 + +[strict_full_crc32] +--innodb-checksum-algorithm=strict_full_crc32 diff --git a/mysql-test/suite/encryption/t/innodb-discard-import.test b/mysql-test/suite/encryption/t/innodb-discard-import.test new file mode 100644 index 00000000..62dafec4 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-discard-import.test @@ -0,0 +1,121 @@ +-- source include/have_innodb.inc +-- source include/innodb_page_size_small.inc +-- source include/have_file_key_management_plugin.inc + +# +# MDEV-8770: Incorrect error message when importing page compressed tablespace +# + +call mtr.add_suppression("InnoDB: Tablespace for table .* is set as discarded."); +call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* because the .ibd file is missing. Please refer to .* for how to resolve the issue."); + +let $innodb_compression_algo = `SELECT @@innodb_compression_algorithm`; +SET GLOBAL innodb_compression_algorithm = 1; + +--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 + +create table t1(c1 bigint not null, b char(200)) engine=innodb encrypted=yes encryption_key_id=4; +show warnings; +create table t2(c1 bigint not null, b char(200)) engine=innodb page_compressed=1 encrypted=yes encryption_key_id=4; +show warnings; +let $kbs= `select floor(@@global.innodb_page_size/1024)`; +--replace_regex / key_block_size=\d+//i +eval create table t3(c1 bigint not null, b char(200)) engine=innodb row_format=compressed encrypted=yes encryption_key_id=4 key_block_size=$kbs; +show warnings; +create table t4(c1 bigint not null, b char(200)) engine=innodb page_compressed=1; +show warnings; + +delimiter //; +create procedure innodb_insert_proc (repeat_count int) +begin + declare current_num int; + set current_num = 0; + while current_num < repeat_count do + insert into t1 values(current_num, repeat('foobar',30)); + insert into t2 values(current_num, repeat('barfoo',30)); + insert into t3 values(current_num, repeat('tmpres',30)); + insert into t4 values(current_num, repeat('mysql',30)); + set current_num = current_num + 1; + end while; +end// +delimiter ;// +commit; + +set autocommit=0; +call innodb_insert_proc(2000); +commit; +set autocommit=1; + +select count(*) from t1; +select count(*) from t2; +select count(*) from t3; +select count(*) from t4; + +let MYSQLD_DATADIR =`SELECT @@datadir`; +FLUSH TABLE t1,t2,t3,t4 FOR EXPORT; +--echo # List before copying files +--list_files $MYSQLD_DATADIR/test +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_backup_tablespaces("test", "t1","t2","t3","t4"); +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; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1","t2","t3","t4"); +ib_restore_tablespaces("test", "t1","t2","t3","t4"); +EOF + +ALTER TABLE t1 IMPORT TABLESPACE; +SHOW CREATE TABLE t1; +SELECT COUNT(*) FROM t1; +ALTER TABLE t2 IMPORT TABLESPACE; +SHOW CREATE TABLE t2; +SELECT COUNT(*) FROM t2; +ALTER TABLE t3 IMPORT TABLESPACE; +--replace_regex / key_block_size=\d+//i +SHOW CREATE TABLE t3; +SELECT COUNT(*) FROM t3; +ALTER TABLE t4 IMPORT TABLESPACE; +SHOW CREATE TABLE t4; +SELECT COUNT(*) FROM t4; + +--echo # tables should be still either encrypted and/or compressed +--let SEARCH_PATTERN=foobar +--echo # t1 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t1_IBD +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=barfoo +--echo # t2 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t2_IBD +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=tmpres +--echo # t3 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t3_IBD +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=mysql +--echo # t4 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t4_IBD +-- source include/search_pattern_in_file.inc + +DROP PROCEDURE innodb_insert_proc; +DROP TABLE t1,t2,t3,t4; + +# reset system +--disable_query_log +eval SET GLOBAL innodb_compression_algorithm = $innodb_compression_algo; +--enable_query_log diff --git a/mysql-test/suite/encryption/t/innodb-encr-threads.test b/mysql-test/suite/encryption/t/innodb-encr-threads.test new file mode 100644 index 00000000..1a90a318 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-encr-threads.test @@ -0,0 +1,14 @@ +--source include/have_innodb.inc +--source include/have_file_key_management_plugin.inc + +# +# MDEV-8159 InnoDB: Failing assertion: key_state->key_id +# +create table t1 (i int) engine=innodb; +set global innodb_encryption_threads = 1; +set global innodb_encryption_rotate_key_age = 2; +insert t1 values (1); +drop table t1; +set global innodb_encryption_threads = 0; +set global innodb_encryption_rotate_key_age = 1; + diff --git a/mysql-test/suite/encryption/t/innodb-encryption-alter.test b/mysql-test/suite/encryption/t/innodb-encryption-alter.test new file mode 100644 index 00000000..6e5d449b --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-encryption-alter.test @@ -0,0 +1,133 @@ +-- source include/have_innodb.inc +-- source include/have_debug.inc +-- source include/have_debug_sync.inc +-- source include/have_file_key_management_plugin.inc + +# +# MDEV-8817: Failing assertion: new_state->key_version != ENCRYPTION_KEY_VERSION_INVALID +# + +SET GLOBAL innodb_encrypt_tables = ON; +SET GLOBAL innodb_encryption_threads = 4; + +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=NO ENCRYPTION_KEY_ID=4; +DROP TABLE t1; +set @save_global = @@GLOBAL.innodb_default_encryption_key_id; +set innodb_default_encryption_key_id = 99; +set global innodb_default_encryption_key_id = 99; +set global innodb_default_encryption_key_id = @save_global; +--error 1005 +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB; +SHOW WARNINGS; +--error 1005 +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=YES; +SHOW WARNINGS; +set innodb_default_encryption_key_id = 4; +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=YES; +SHOW CREATE TABLE t1; +DROP TABLE t1; +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB; +SHOW CREATE TABLE t1; +CREATE TABLE t2 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=NO ENCRYPTION_KEY_ID=1; +--error ER_ILLEGAL_HA_CREATE_OPTION +ALTER TABLE t1 ENCRYPTION_KEY_ID=99; +SHOW WARNINGS; +set innodb_default_encryption_key_id = 1; + + +--disable_warnings +--disable_query_log +let $i = 400; +while ($i) +{ +INSERT INTO t1 values(NULL, substring(MD5(RAND()), -128)); +dec $i; +} +commit; +INSERT INTO t2 select * from t1; + +--disable_abort_on_error + +--connect (con1,localhost,root,,test) +--connect (con2,localhost,root,,test) + +let $i = 50; +while ($i) +{ +connection con1; +send ALTER TABLE t1 ENCRYPTED=NO ENCRYPTION_KEY_ID=1; +connection con2; +send ALTER TABLE t1 ENCRYPTED=YES ENCRYPTION_KEY_ID=4; +connection default; +send ALTER TABLE t2 ENCRYPTED=NO ENCRYPTION_KEY_ID=1; +connection con1; +--reap; +ALTER TABLE t1 ENCRYPTED=NO ENCRYPTION_KEY_ID=1; +connection con2; +--reap +ALTER TABLE t1 ENCRYPTED=YES ENCRYPTION_KEY_ID=4; +connection default; +--reap +ALTER TABLE t2 ENCRYPTED=YES ENCRYPTION_KEY_ID=1; +ALTER TABLE t1 ENCRYPTED=NO ENCRYPTION_KEY_ID=1; +dec $i; +} + +connection default; +--disconnect con1 +--disconnect con2 + +--enable_abort_on_error +--enable_warnings +--enable_query_log + +drop table t1,t2; + +# +# MDEV-17230: encryption_key_id from alter is ignored by encryption threads +# +--enable_warnings +SET GLOBAL innodb_encrypt_tables=OFF; +CREATE TABLE t1 (a int not null primary key) engine=innodb; +ALTER TABLE t1 ENCRYPTION_KEY_ID=4; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t2 (a int not null primary key) engine=innodb; +ALTER TABLE t2 ENCRYPTION_KEY_ID=4, ALGORITHM=COPY; +SHOW WARNINGS; +SHOW CREATE TABLE t2; + +CREATE TABLE t3 (a int not null primary key) engine=innodb ENCRYPTION_KEY_ID=4; +DROP TABLE t3; + +SET GLOBAL innodb_encrypt_tables='FORCE'; +--error ER_CANT_CREATE_TABLE +CREATE TABLE t1 (a int primary key) engine=innodb encrypted=no; +SHOW WARNINGS; + +FLUSH TABLES; + +create table t1(f1 int not null, f2 int not null)engine=innodb encrypted=yes; +insert into t1 values(1, 2), (2, 3), (4, 5), (5, 6), (7, 8); +insert into t1 select * from t1; +BEGIN; +INSERT INTO t2 VALUES (1); + +connect con1, localhost, root; +SET DEBUG_SYNC = 'row_log_table_apply2_before SIGNAL done WAIT_FOR ever'; +send alter table t1 force; + +connection default; +SET DEBUG_SYNC = 'now WAIT_FOR done'; +SET GLOBAL innodb_flush_log_at_trx_commit=1; +COMMIT; + +let $restart_parameters = --innodb_encryption_threads=2; +let $restart_noprint = 2; +--let $shutdown_timeout= 0 +--source include/restart_mysqld.inc +disconnect con1; + +select * from t1; +drop table t1,t2; diff --git a/mysql-test/suite/encryption/t/innodb-encryption-disable.opt b/mysql-test/suite/encryption/t/innodb-encryption-disable.opt new file mode 100644 index 00000000..d14f3bcb --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-encryption-disable.opt @@ -0,0 +1 @@ +--skip-innodb-fast-shutdown diff --git a/mysql-test/suite/encryption/t/innodb-encryption-disable.test b/mysql-test/suite/encryption/t/innodb-encryption-disable.test new file mode 100644 index 00000000..939ad2b5 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-encryption-disable.test @@ -0,0 +1,55 @@ +-- source include/have_innodb.inc +# embedded does not support restart +-- source include/not_embedded.inc +-- source filekeys_plugin_exists.inc + +# +# MDEV-9559: Server without encryption configs crashes if selecting from an implicitly encrypted table +# + +call mtr.add_suppression("InnoDB: Table `test`\\.`t[15]` (has an unreadable root page|is corrupted)"); +call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[15]\\.ibd' cannot be decrypted\\."); +call mtr.add_suppression("InnoDB: Recovery failed to read page"); +call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t[15].ibd looks corrupted; key_version=1"); +call mtr.add_suppression("InnoDB: Table `test`\\.`t[15]` is corrupted"); + +# Suppression for builds where file_key_management plugin is linked statically +call mtr.add_suppression("Couldn't load plugins from 'file_key_management"); + +--let $restart_parameters=--innodb-encrypt-tables=ON --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt +--source include/restart_mysqld.inc + +create table t5 ( + `intcol1` int(32) DEFAULT NULL, + `intcol2` int(32) DEFAULT NULL, + `charcol1` varchar(128) DEFAULT NULL, + `charcol2` varchar(128) DEFAULT NULL, + `charcol3` varchar(128) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + +insert into t5 values (1,2,'maria','db','encryption'); + +CREATE TABLE `t1` ( + `intcol1` int(32) DEFAULT NULL, + `intcol2` int(32) DEFAULT NULL, + `charcol1` varchar(128) DEFAULT NULL, + `charcol2` varchar(128) DEFAULT NULL, + `charcol3` varchar(128) DEFAULT NULL +) ENGINE=InnoDB; + +insert into t1 values (1,2,'maria','db','encryption'); +alter table t1 encrypted='yes' `encryption_key_id`=1; + +--let $restart_parameters=--innodb-encrypt-tables=OFF +--source include/restart_mysqld.inc + +--error ER_NO_SUCH_TABLE_IN_ENGINE +select * from t1; +--error ER_NO_SUCH_TABLE_IN_ENGINE +select * from t5; + +--let $restart_parameters=--innodb-encrypt-tables=ON --plugin-load-add=file_key_management --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt +--source include/restart_mysqld.inc + +drop table t1; +drop table t5; diff --git a/mysql-test/suite/encryption/t/innodb-first-page-read.opt b/mysql-test/suite/encryption/t/innodb-first-page-read.opt new file mode 100644 index 00000000..38d69691 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-first-page-read.opt @@ -0,0 +1,5 @@ +--innodb-encrypt-tables=ON +--innodb-encrypt-log=ON +--innodb-encryption-rotate-key-age=15 +--innodb-encryption-threads=4 +--innodb-tablespaces-encryption diff --git a/mysql-test/suite/encryption/t/innodb-force-corrupt.opt b/mysql-test/suite/encryption/t/innodb-force-corrupt.opt new file mode 100644 index 00000000..d14f3bcb --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-force-corrupt.opt @@ -0,0 +1 @@ +--skip-innodb-fast-shutdown diff --git a/mysql-test/suite/encryption/t/innodb-force-corrupt.test b/mysql-test/suite/encryption/t/innodb-force-corrupt.test new file mode 100644 index 00000000..51771f1e --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-force-corrupt.test @@ -0,0 +1,87 @@ +# +# MDEV-11759: Encryption code in MariaDB 10.1/10.2 causes compatibility problems +# + +-- source include/have_innodb.inc +-- source include/have_file_key_management_plugin.inc +# Don't test under embedded +-- source include/not_embedded.inc + +call mtr.add_suppression("InnoDB: Table `test`\\.`t[13]` (has an unreadable root page|is corrupted)"); +call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=\\d+, page number=[36]\\] in file .*test.t[123]\\.ibd looks corrupted; key_version="); +call mtr.add_suppression("\\[ERROR\\] InnoDB: We detected index corruption in an InnoDB type table"); +call mtr.add_suppression("\\[ERROR\\] (mysqld|mariadbd).*: Index for table 't2' is corrupt; try to repair it"); + +SET GLOBAL innodb_file_per_table = ON; +set global innodb_compression_algorithm = 1; + +--echo # Create and populate tables to be corrupted +CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT,c char(200)) ENGINE=InnoDB encrypted=yes; +CREATE TABLE t2 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT,c char(200)) ENGINE=InnoDB row_format=compressed encrypted=yes; +CREATE TABLE t3 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT, c char(200)) ENGINE=InnoDB page_compressed=yes encrypted=yes; + +BEGIN; +INSERT INTO t1 (b,c) VALUES ('corrupt me','secret'); +--disable_query_log +--let $i = 100 +while ($i) +{ + INSERT INTO t1 (b,c) VALUES (REPEAT('abcabcabc', 100),'secretsecret'); + dec $i; +} +--enable_query_log + +INSERT INTO t1 (b,c) VALUES ('corrupt me','moresecretmoresecret'); +INSERT INTO t2 select * from t1; +INSERT INTO t3 select * from t1; +COMMIT; + +let INNODB_PAGE_SIZE=`select @@innodb_page_size`; +let MYSQLD_DATADIR=`select @@datadir`; + +--source include/shutdown_mysqld.inc + +--echo # Backup tables before corrupting +--copy_file $MYSQLD_DATADIR/test/t1.ibd $MYSQLD_DATADIR/test/t1.ibd.backup +--copy_file $MYSQLD_DATADIR/test/t2.ibd $MYSQLD_DATADIR/test/t2.ibd.backup +--copy_file $MYSQLD_DATADIR/test/t3.ibd $MYSQLD_DATADIR/test/t3.ibd.backup + +--echo # Corrupt tables + +perl; +open(FILE, "+<", "$ENV{MYSQLD_DATADIR}/test/t1.ibd") or die "open"; +binmode FILE; +seek(FILE, $ENV{'INNODB_PAGE_SIZE'} * 3 + 26, SEEK_SET) or die "seek"; +print FILE pack("H*", "c001cafedeadb017"); +close FILE or die "close"; +open(FILE, "+<", "$ENV{MYSQLD_DATADIR}/test/t2.ibd") or die "open"; +binmode FILE; +seek(FILE, $ENV{'INNODB_PAGE_SIZE'} * 3 + 26, SEEK_SET) or die "seek"; +print FILE pack("H*", "c001cafedeadb017"); +close FILE or die "close"; +open(FILE, "+<", "$ENV{MYSQLD_DATADIR}/test/t3.ibd") or die "open"; +binmode FILE; +seek(FILE, $ENV{'INNODB_PAGE_SIZE'} * 3 + 26, SEEK_SET) or die "seek"; +print FILE pack("H*", "c001cafedeadb017"); +close FILE or die "close"; +EOF + +--source include/start_mysqld.inc + +--error ER_NO_SUCH_TABLE_IN_ENGINE +SELECT * FROM t1; +--error ER_GET_ERRMSG,ER_NOT_KEYFILE +SELECT * FROM t2; +--error ER_NO_SUCH_TABLE_IN_ENGINE +SELECT * FROM t3; + +--source include/shutdown_mysqld.inc + +--echo # Restore the original tables +--move_file $MYSQLD_DATADIR/test/t1.ibd.backup $MYSQLD_DATADIR/test/t1.ibd +--move_file $MYSQLD_DATADIR/test/t2.ibd.backup $MYSQLD_DATADIR/test/t2.ibd +--move_file $MYSQLD_DATADIR/test/t3.ibd.backup $MYSQLD_DATADIR/test/t3.ibd + +--source include/start_mysqld.inc + +DROP TABLE t1,t2,t3; diff --git a/mysql-test/suite/encryption/t/innodb-key-rotation-disable.opt b/mysql-test/suite/encryption/t/innodb-key-rotation-disable.opt new file mode 100644 index 00000000..03a0028d --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-key-rotation-disable.opt @@ -0,0 +1,5 @@ +--innodb-encrypt-tables +--innodb-encrypt-log +--innodb-encryption-rotate-key-age=0 +--innodb-encryption-threads=4 +--innodb-tablespaces-encryption diff --git a/mysql-test/suite/encryption/t/innodb-key-rotation-disable.test b/mysql-test/suite/encryption/t/innodb-key-rotation-disable.test new file mode 100644 index 00000000..d360d5f8 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-key-rotation-disable.test @@ -0,0 +1,77 @@ +-- source include/have_innodb.inc +-- source include/have_file_key_management_plugin.inc +# not embedded because of restarts +-- source include/not_embedded.inc + +let $encryption = `SELECT @@innodb_encrypt_tables`; +SET GLOBAL innodb_file_per_table = ON; +# zlib +set global innodb_compression_algorithm = 1; + +create database enctests; +use enctests; +create table t1(a int not null primary key, b char(200)) engine=innodb; +create table t2(a int not null primary key, b char(200)) engine=innodb row_format=compressed; +create table t3(a int not null primary key, b char(200)) engine=innodb page_compressed=yes; +create table t4(a int not null primary key, b char(200)) engine=innodb encrypted=yes; +create table t5(a int not null primary key, b char(200)) engine=innodb encrypted=yes row_format=compressed; +create table t6(a int not null primary key, b char(200)) engine=innodb encrypted=yes page_compressed=yes; +create table t7(a int not null primary key, b char(200)) engine=innodb encrypted=no; +create table t8(a int not null primary key, b char(200)) engine=innodb encrypted=no row_format=compressed; +create table t9(a int not null primary key, b char(200)) engine=innodb encrypted=no page_compressed=yes; + +insert into t1 values (1, 'secredmessage'); +insert into t2 values (1, 'secredmessage'); +insert into t3 values (1, 'secredmessagecompressedaaaaaaaaabbbbbbbbbbbbbbccccccccccccccc'); +insert into t4 values (1, 'secredmessage'); +insert into t5 values (1, 'secredmessage'); +insert into t6 values (1, 'secredmessagecompressedaaaaaaaaabbbbbbbbbbbbbbccccccccccccccc'); +insert into t7 values (1, 'publicmessage'); +insert into t8 values (1, 'publicmessage'); +insert into t9 values (1, 'pugliccompressedaaaaaaaaabbbbbbbbbbbbbbccccccccccccccc'); + +--echo # should list tables t1-t6 +--sorted_result +SELECT NAME,ENCRYPTION_SCHEME,CURRENT_KEY_ID FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'enctests%'; +--echo # should list tables t7-t9 +--sorted_result +SELECT NAME,ENCRYPTION_SCHEME,CURRENT_KEY_ID FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 and NAME LIKE 'enctests%'; + +--let $MYSQLD_DATADIR=`select @@datadir` + +-- source include/shutdown_mysqld.inc + +--let SEARCH_RANGE = 10000000 +--let SEARCH_PATTERN=secred +--echo # t1 default on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/enctests/t1.ibd +-- source include/search_pattern_in_file.inc +--echo # t2 default on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/enctests/t2.ibd +-- source include/search_pattern_in_file.inc +--echo # t3 default on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/enctests/t3.ibd +-- source include/search_pattern_in_file.inc +--echo # t4 on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/enctests/t4.ibd +-- source include/search_pattern_in_file.inc +--echo # t5 on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/enctests/t5.ibd +-- source include/search_pattern_in_file.inc +--echo # t6 on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/enctests/t6.ibd +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=public +--echo # t7 off expecting FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/enctests/t7.ibd +-- source include/search_pattern_in_file.inc +--echo # t8 row compressed expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/enctests/t8.ibd +-- source include/search_pattern_in_file.inc +--echo # t9 page compressed expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/enctests/t9.ibd +-- source include/search_pattern_in_file.inc + +-- source include/start_mysqld.inc + +drop database enctests; diff --git a/mysql-test/suite/encryption/t/innodb-missing-key.opt b/mysql-test/suite/encryption/t/innodb-missing-key.opt new file mode 100644 index 00000000..6a8ee144 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-missing-key.opt @@ -0,0 +1,5 @@ +--innodb-encrypt-tables +--innodb-encryption-rotate-key-age=15 +--innodb-encryption-threads=4 +--innodb-tablespaces-encryption +--skip-innodb-fast-shutdown diff --git a/mysql-test/suite/encryption/t/innodb-missing-key.test b/mysql-test/suite/encryption/t/innodb-missing-key.test new file mode 100644 index 00000000..53fc820a --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-missing-key.test @@ -0,0 +1,65 @@ +--source include/have_innodb.inc +-- source include/have_file_key_management_plugin.inc +# embedded does not support restart +-- source include/not_embedded.inc + +# +# MDEV-11004: Unable to start (Segfault or os error 2) when encryption key missing +# + +call mtr.add_suppression("InnoDB: Table `test`\\.`t1` has an unreadable root page"); +call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[123]\\.ibd' cannot be decrypted\\."); +call mtr.add_suppression("InnoDB: Recovery failed to read page"); +call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file .*test.t[12].ibd looks corrupted; key_version=1"); +call mtr.add_suppression("Table .*t1.* is corrupted"); + +--echo # Start server with keys2.txt +-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt +-- source include/restart_mysqld.inc + +CREATE TABLE t1(a int not null primary key auto_increment, b varchar(128)) engine=innodb ENCRYPTED=YES ENCRYPTION_KEY_ID=19; +CREATE TABLE t2(a int not null primary key auto_increment, b varchar(128)) engine=innodb ENCRYPTED=YES ENCRYPTION_KEY_ID=1; +CREATE TABLE t3(a int not null primary key auto_increment, b varchar(128)) engine=innodb ENCRYPTED=NO; +INSERT INTO t1(b) VALUES ('thisissecredmessage'); +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 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; + +--echo +--echo # Restart server with keys3.txt +-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys3.txt +-- source include/restart_mysqld.inc + +set global innodb_encryption_rotate_key_age = 1; +use test; +CREATE TABLE t4(a int not null primary key auto_increment, b varchar(128)) engine=innodb ENCRYPTED=YES ENCRYPTION_KEY_ID=1; +SELECT SLEEP(5); +SELECT COUNT(1) FROM t3; +SELECT COUNT(1) FROM t2; +--error ER_NO_SUCH_TABLE_IN_ENGINE +SELECT COUNT(1) FROM t2,t1 where t2.a = t1.a; +--error ER_TABLE_CORRUPT +SELECT COUNT(1) FROM t1 where b = 'ab'; +--error ER_TABLE_CORRUPT +SELECT COUNT(1) FROM t1; + +--echo +--echo # Start server with keys2.txt +-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt +-- source include/restart_mysqld.inc + +SELECT COUNT(1) FROM t1; +SELECT COUNT(1) FROM t2; +SELECT COUNT(1) FROM t3; + +DROP TABLE t1, t2, t3; diff --git a/mysql-test/suite/encryption/t/innodb-page_encryption-32k.opt b/mysql-test/suite/encryption/t/innodb-page_encryption-32k.opt new file mode 100644 index 00000000..a9021f6d --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-page_encryption-32k.opt @@ -0,0 +1,2 @@ +--default_storage_engine=InnoDB +--innodb-buffer-pool-size=24M diff --git a/mysql-test/suite/encryption/t/innodb-page_encryption-32k.test b/mysql-test/suite/encryption/t/innodb-page_encryption-32k.test new file mode 100644 index 00000000..03c9c93f --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-page_encryption-32k.test @@ -0,0 +1,82 @@ +--source include/no_valgrind_without_big.inc +--source include/not_embedded.inc +# Tests for setting innodb-page-size=32k; +--source include/have_innodb.inc +--source include/have_innodb_32k.inc +--source include/have_file_key_management_plugin.inc + +create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb; +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=1; +--error ER_CANT_CREATE_TABLE +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=3; +show warnings; +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=33; +create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant encrypted=yes encryption_key_id=4; + +show create table innodb_compact; +show create table innodb_dynamic; +show create table innodb_redundant; + +delimiter //; +create procedure innodb_insert_proc (repeat_count int) +begin + declare current_num int; + set current_num = 0; + while current_num < repeat_count do + insert into innodb_normal values(current_num, substring(MD5(RAND()), -150)); + set current_num = current_num + 1; + end while; +end// +delimiter ;// +commit; + +set autocommit=0; +call innodb_insert_proc(5000); +commit; +set autocommit=1; + +insert into innodb_compact select * from innodb_normal; +insert into innodb_dynamic select * from innodb_normal; +insert into innodb_redundant select * from innodb_normal; + +update innodb_compact set c1 = c1 + 1; +update innodb_dynamic set c1 = c1 + 1; +update innodb_redundant set c1 = c1 + 1; +select count(*) from innodb_compact where c1 < 1500000; +select count(*) from innodb_dynamic where c1 < 1500000; +select count(*) from innodb_redundant where c1 < 1500000; + +--source include/restart_mysqld.inc + +update innodb_compact set c1 = c1 + 1; +update innodb_dynamic set c1 = c1 + 1; +update innodb_redundant set c1 = c1 + 1; +select count(*) from innodb_compact where c1 < 1500000; +select count(*) from innodb_dynamic where c1 < 1500000; +select count(*) from innodb_redundant where c1 < 1500000; + +alter table innodb_compact engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_compact; +alter table innodb_dynamic engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_dynamic; +alter table innodb_redundant engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_redundant; + +--source include/restart_mysqld.inc + +show create table innodb_compact; +show create table innodb_dynamic; +show create table innodb_redundant; + +update innodb_compact set c1 = c1 + 1; +update innodb_dynamic set c1 = c1 + 1; +update innodb_redundant set c1 = c1 + 1; +select count(*) from innodb_compact where c1 < 1500000; +select count(*) from innodb_dynamic where c1 < 1500000; +select count(*) from innodb_redundant where c1 < 1500000; + +drop procedure innodb_insert_proc; +drop table innodb_normal; +drop table innodb_compact; +drop table innodb_dynamic; +drop table innodb_redundant; diff --git a/mysql-test/suite/encryption/t/innodb-page_encryption.test b/mysql-test/suite/encryption/t/innodb-page_encryption.test new file mode 100644 index 00000000..d756f07a --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-page_encryption.test @@ -0,0 +1,152 @@ +-- source include/have_innodb.inc +-- source include/have_file_key_management_plugin.inc + +# The test can take very long time with valgrind +--source include/not_valgrind.inc + +create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb; +show warnings; +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=1; +show warnings; +create table innodb_compressed(c1 bigint not null, b char(200)) engine=innodb row_format=compressed encrypted=yes encryption_key_id=2; +show warnings; +--error ER_CANT_CREATE_TABLE +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=3; +show warnings; +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=33; +show warnings; +create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant encrypted=yes encryption_key_id=4; +show warnings; + +set innodb_default_encryption_key_id = 5; +create table innodb_defkey(c1 bigint not null, b char(200)) engine=innodb encrypted=yes; +show create table innodb_defkey; + +show create table innodb_compact; +show create table innodb_compressed; +show create table innodb_dynamic; +show create table innodb_redundant; + +delimiter //; +create procedure innodb_insert_proc (repeat_count int) +begin + declare current_num int; + set current_num = 0; + while current_num < repeat_count do + insert into innodb_normal values(current_num, substring(MD5(RAND()), -64)); + set current_num = current_num + 1; + end while; +end// +delimiter ;// +commit; + +set autocommit=0; +call innodb_insert_proc(2000); +commit; +set autocommit=1; + +insert into innodb_compact select * from innodb_normal; +insert into innodb_compressed select * from innodb_normal; +insert into innodb_dynamic select * from innodb_normal; +insert into innodb_redundant select * from innodb_normal; +insert into innodb_defkey select * from innodb_normal; + +update innodb_normal set c1 = c1 +1; +update innodb_compact set c1 = c1 + 1; +update innodb_compressed set c1 = c1 + 1; +update innodb_dynamic set c1 = c1 + 1; +update innodb_redundant set c1 = c1 + 1; +update innodb_defkey set c1 = c1 + 1; + +select count(*) from innodb_compact where c1 < 1500000; +select count(*) from innodb_compressed where c1 < 1500000; +select count(*) from innodb_dynamic where c1 < 1500000; +select count(*) from innodb_redundant where c1 < 1500000; +select count(*) from innodb_defkey where c1 < 1500000; +select count(*) from innodb_compact t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +select count(*) from innodb_dynamic t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +select count(*) from innodb_compressed t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +select count(*) from innodb_redundant t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +select count(*) from innodb_defkey t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; + +# Note there that these variables are updated only when real I/O is done, thus they are not reliable +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; + +--source include/restart_mysqld.inc + +update innodb_normal set c1 = c1 +1; +update innodb_compact set c1 = c1 + 1; +update innodb_compressed set c1 = c1 + 1; +update innodb_dynamic set c1 = c1 + 1; +update innodb_redundant set c1 = c1 + 1; +update innodb_defkey set c1 = c1 + 1; +select count(*) from innodb_compact where c1 < 1500000; +select count(*) from innodb_compressed where c1 < 1500000; +select count(*) from innodb_dynamic where c1 < 1500000; +select count(*) from innodb_redundant where c1 < 1500000; +select count(*) from innodb_defkey where c1 < 1500000; +select count(*) from innodb_compact t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +select count(*) from innodb_dynamic t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +select count(*) from innodb_compressed t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +select count(*) from innodb_redundant t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +select count(*) from innodb_defkey t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; + +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; + +alter table innodb_compact engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_compact; +alter table innodb_compressed engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_compressed; +alter table innodb_dynamic engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_dynamic; +alter table innodb_redundant engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_redundant; + +--source include/restart_mysqld.inc + +show create table innodb_compact; +show create table innodb_compressed; +show create table innodb_dynamic; +show create table innodb_redundant; +show create table innodb_defkey; + +update innodb_normal set c1 = c1 +1; +update innodb_compact set c1 = c1 + 1; +update innodb_compressed set c1 = c1 + 1; +update innodb_dynamic set c1 = c1 + 1; +update innodb_redundant set c1 = c1 + 1; +select count(*) from innodb_compact where c1 < 1500000; +select count(*) from innodb_compressed where c1 < 1500000; +select count(*) from innodb_dynamic where c1 < 1500000; +select count(*) from innodb_redundant where c1 < 1500000; +select count(*) from innodb_compact t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +select count(*) from innodb_dynamic t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +select count(*) from innodb_compressed t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +select count(*) from innodb_redundant t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; + +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; + +drop procedure innodb_insert_proc; +drop table innodb_normal; +drop table innodb_compact; +drop table innodb_compressed; +drop table innodb_dynamic; +drop table innodb_redundant; +drop table innodb_defkey; diff --git a/mysql-test/suite/encryption/t/innodb-page_encryption_compression.test b/mysql-test/suite/encryption/t/innodb-page_encryption_compression.test new file mode 100644 index 00000000..5fe6f686 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-page_encryption_compression.test @@ -0,0 +1,73 @@ +-- source include/have_innodb.inc +-- source include/not_embedded.inc +-- source include/have_file_key_management_plugin.inc + +let $innodb_compression_algorithm_orig=`SELECT @@innodb_compression_algorithm`; + +# zlib +set global innodb_compression_algorithm = 1; + +create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb page_compressed=1; +show warnings; +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=1 page_compressed=1; +show warnings; +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=2 page_compressed=1; +show warnings; + +show create table innodb_normal; +show create table innodb_compact; +show create table innodb_dynamic; + +delimiter //; +create procedure innodb_insert_proc (repeat_count int) +begin + declare current_num int; + set current_num = 0; + while current_num < repeat_count do + insert into innodb_normal values(current_num, substring(MD5(RAND()), -128)); + set current_num = current_num + 1; + end while; +end// +delimiter ;// +commit; + +begin; +call innodb_insert_proc(2000); +insert into innodb_compact select * from innodb_normal; +insert into innodb_dynamic select * from innodb_normal; +commit; + +FLUSH TABLES innodb_compact FOR EXPORT; UNLOCK TABLES; +FLUSH TABLES innodb_dynamic FOR EXPORT; UNLOCK TABLES; +select variable_value > 0 from information_schema.global_status +where variable_name = 'INNODB_NUM_PAGES_PAGE_COMPRESSED'; + +--let $restart_parameters=--innodb-encrypt-tables=OFF +--source include/restart_mysqld.inc + +# zlib +set global innodb_compression_algorithm = 1; + +alter table innodb_normal engine=innodb page_compressed=DEFAULT; +show create table innodb_normal; +alter table innodb_compact engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT page_compressed=DEFAULT; +show create table innodb_compact; +alter table innodb_dynamic engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT page_compressed=DEFAULT; +show create table innodb_dynamic; + +FLUSH TABLES innodb_normal FOR EXPORT; UNLOCK TABLES; +FLUSH TABLES innodb_compact FOR EXPORT; UNLOCK TABLES; +FLUSH TABLES innodb_dynamic FOR EXPORT; UNLOCK TABLES; + +select variable_value > 0 from information_schema.global_status +where variable_name = 'INNODB_NUM_PAGES_PAGE_DECOMPRESSED'; + +drop procedure innodb_insert_proc; +drop table innodb_normal; +drop table innodb_compact; +drop table innodb_dynamic; + +# reset system +--disable_query_log +EVAL SET GLOBAL innodb_compression_algorithm = $innodb_compression_algorithm_orig; +--enable_query_log diff --git a/mysql-test/suite/encryption/t/innodb-page_encryption_log_encryption.opt b/mysql-test/suite/encryption/t/innodb-page_encryption_log_encryption.opt new file mode 100644 index 00000000..d09b26a3 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-page_encryption_log_encryption.opt @@ -0,0 +1,3 @@ +--innodb-encrypt-log=ON +--innodb-encrypt-tables=ON + diff --git a/mysql-test/suite/encryption/t/innodb-page_encryption_log_encryption.test b/mysql-test/suite/encryption/t/innodb-page_encryption_log_encryption.test new file mode 100644 index 00000000..a736c729 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-page_encryption_log_encryption.test @@ -0,0 +1,82 @@ +-- source include/have_innodb.inc +-- source include/not_embedded.inc +-- source include/have_file_key_management_plugin.inc + +create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb; +show warnings; +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=1; +show warnings; +create table innodb_compressed(c1 bigint not null, b char(200)) engine=innodb row_format=compressed encrypted=yes encryption_key_id=2; +show warnings; +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=33; +show warnings; +create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant encrypted=yes encryption_key_id=4; +show warnings; + +show create table innodb_compact; +show create table innodb_compressed; +show create table innodb_dynamic; +show create table innodb_redundant; + +FLUSH TABLES innodb_normal FOR EXPORT; UNLOCK TABLES; +FLUSH TABLES innodb_compact FOR EXPORT; UNLOCK TABLES; +FLUSH TABLES innodb_compressed FOR EXPORT; UNLOCK TABLES; +FLUSH TABLES innodb_dynamic FOR EXPORT; UNLOCK TABLES; +FLUSH TABLES innodb_redundant FOR EXPORT; UNLOCK TABLES; + +select variable_value > 0 from information_schema.global_status +where variable_name = 'INNODB_NUM_PAGES_ENCRYPTED'; + +--source include/restart_mysqld.inc + +BEGIN; +INSERT INTO innodb_normal SET c1 = 1; +INSERT INTO innodb_compact SET c1 = 1; +INSERT INTO innodb_compressed SET c1 = 1; +INSERT INTO innodb_dynamic SET c1 = 1; +INSERT INTO innodb_redundant SET c1 = 1; +COMMIT; + +FLUSH TABLES innodb_normal FOR EXPORT; UNLOCK TABLES; +FLUSH TABLES innodb_compact FOR EXPORT; UNLOCK TABLES; +FLUSH TABLES innodb_compressed FOR EXPORT; UNLOCK TABLES; +FLUSH TABLES innodb_dynamic FOR EXPORT; UNLOCK TABLES; +FLUSH TABLES innodb_redundant FOR EXPORT; UNLOCK TABLES; + +select variable_name from information_schema.global_status +where variable_value > 0 and variable_name +IN ('INNODB_NUM_PAGES_ENCRYPTED','INNODB_NUM_PAGES_DECRYPTED'); + +SET GLOBAL innodb_encrypt_tables=OFF; +alter table innodb_compact engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_compact; +alter table innodb_compressed engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_compressed; +alter table innodb_dynamic engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_dynamic; +alter table innodb_redundant engine=innodb encrypted=DEFAULT encryption_key_id=DEFAULT; +show create table innodb_redundant; + +FLUSH TABLES innodb_normal FOR EXPORT; UNLOCK TABLES; +FLUSH TABLES innodb_compact FOR EXPORT; UNLOCK TABLES; +FLUSH TABLES innodb_compressed FOR EXPORT; UNLOCK TABLES; +FLUSH TABLES innodb_dynamic FOR EXPORT; UNLOCK TABLES; +FLUSH TABLES innodb_redundant FOR EXPORT; UNLOCK TABLES; + +drop table innodb_normal; +drop table innodb_compact; +drop table innodb_compressed; +drop table innodb_dynamic; +drop table innodb_redundant; +# +# MDEV-8143: InnoDB: Database page corruption on disk or a failed file read +# +CREATE TABLE t1 (pk INT PRIMARY KEY) ENGINE=InnoDB ENCRYPTION_KEY_ID=2 ENCRYPTED=YES; +INSERT INTO t1 VALUES (1),(2); + +--echo # Restarting server... +--source include/restart_mysqld.inc + +SELECT * FROM t1; + +DROP TABLE t1; diff --git a/mysql-test/suite/encryption/t/innodb-read-only.opt b/mysql-test/suite/encryption/t/innodb-read-only.opt new file mode 100644 index 00000000..acedb1a1 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-read-only.opt @@ -0,0 +1,3 @@ +--innodb-encrypt-tables=1 +--innodb-encryption-threads=4 +--innodb-tablespaces-encryption diff --git a/mysql-test/suite/encryption/t/innodb-read-only.test b/mysql-test/suite/encryption/t/innodb-read-only.test new file mode 100644 index 00000000..10ec8746 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-read-only.test @@ -0,0 +1,34 @@ +--source suite/encryption/include/have_file_key_management_plugin.inc +--source include/have_innodb.inc +--source include/not_embedded.inc + +--echo # Wait max 10 min for key encryption threads to encrypt all spaces +let $cnt=600; +while ($cnt) +{ + let $success=`SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0`; + if ($success) + { + let $cnt=0; + } + if (!$success) + { + real_sleep 1; + dec $cnt; + } +} +if (!$success) +{ + SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION; + SHOW STATUS LIKE 'innodb_encryption%'; + -- die Timeout waiting for encryption threads +} +--echo # Success! + +# +# MDEV-11835: InnoDB: Failing assertion: free_slot != NULL on +# restarting server with encryption and read-only +# +--let $restart_parameters= --innodb-read-only=1 --innodb-encrypt-tables=1 +--source include/restart_mysqld.inc +--echo # All done diff --git a/mysql-test/suite/encryption/t/innodb-redo-badkey.combinations b/mysql-test/suite/encryption/t/innodb-redo-badkey.combinations new file mode 100644 index 00000000..72938059 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-redo-badkey.combinations @@ -0,0 +1,5 @@ +[strict_crc32] +--innodb-checksum-algorithm=strict_crc32 + +[strict_full_crc32] +--innodb-checksum-algorithm=strict_full_crc32 diff --git a/mysql-test/suite/encryption/t/innodb-redo-badkey.opt b/mysql-test/suite/encryption/t/innodb-redo-badkey.opt new file mode 100644 index 00000000..0efdc8a7 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-redo-badkey.opt @@ -0,0 +1,6 @@ +--innodb-change-buffering=all +--innodb-encrypt-tables=on +--innodb-tablespaces-encryption +--innodb-encryption-threads=2 +--innodb-default-encryption-key-id=4 +--skip-innodb-fast-shutdown diff --git a/mysql-test/suite/encryption/t/innodb-redo-badkey.test b/mysql-test/suite/encryption/t/innodb-redo-badkey.test new file mode 100644 index 00000000..393ca4ad --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-redo-badkey.test @@ -0,0 +1,98 @@ +-- source include/have_innodb.inc +-- source include/have_file_key_management_plugin.inc +# embedded does not support restart +-- source include/not_embedded.inc +# MDEV-20839 innodb-redo-badkey sporadically fails on buildbot with page dump +# We only require a debug build to avoid getting page dumps, making use of +# MDEV-19766: Disable page dump output in debug builds +-- source include/have_debug.inc + +call mtr.add_suppression("Plugin 'file_key_management'"); +call mtr.add_suppression("Plugin 'InnoDB' init function returned error."); +call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\] in file '.*test.t[1-4]\\.ibd' cannot be decrypted; key_version=1"); +call mtr.add_suppression("InnoDB: File '.*test/t[1234]\\.ibd' is corrupted"); +call mtr.add_suppression("InnoDB: Recovery failed to read page"); +call mtr.add_suppression("InnoDB: Unable to decompress .*.test.t[12]\\.ibd\\[page id: space=[1-9][0-9]*, page number=[0-9]+\\]"); +call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed read of file '.*test.t[12]\\.ibd'"); +call mtr.add_suppression("InnoDB: Failed to read page .* from file '.*'"); +call mtr.add_suppression("InnoDB: OPT_PAGE_CHECKSUM mismatch"); +call mtr.add_suppression("InnoDB: Set innodb_force_recovery=1 to ignore corruption"); +call mtr.add_suppression("InnoDB: (Unable to apply log to|Discarding log for) corrupted page "); +call mtr.add_suppression("InnoDB: Plugin initialization aborted"); +call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed"); +# for innodb_checksum_algorithm=full_crc32 only +call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot decrypt \\[page id: space="); + +-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt +-- source include/restart_mysqld.inc + +--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 +--source include/wait_condition.inc + +SET GLOBAL innodb_file_per_table = ON; + +create table t1(a int not null primary key auto_increment, c char(250), b blob, index(b(10))) engine=innodb row_format=compressed encrypted=yes encryption_key_id=4; +create table t2(a int not null primary key auto_increment, c char(250), b blob, index(b(10))) engine=innodb row_format=compressed; +create table t3(a int not null primary key auto_increment, c char(250), b blob, index(b(10))) engine=innodb encrypted=yes encryption_key_id=4; +create table t4(a int not null primary key auto_increment, c char(250), b blob, index(b(10))) engine=innodb; + +begin; +--disable_query_log +--let $i = 20 +begin; +while ($i) +{ + insert into t1(c,b) values (repeat('secret1',20), repeat('secret2',6000)); + dec $i; +} +--enable_query_log + +insert into t2 select * from t1; +insert into t3 select * from t1; +insert into t4 select * from t1; +commit; + +--source ../../suite/innodb/include/no_checkpoint_start.inc + +# +# We test redo log page read at recv_read_page using +# incorrect keys from std_data/keys.txt. If checkpoint +# happens we will skip this test. If no checkpoint +# happens, InnoDB refuses to start as used +# encryption key is incorrect. +# +SET GLOBAL innodb_flush_log_at_trx_commit=1; +begin; +update t1 set c = repeat('secret3', 20); +update t2 set c = repeat('secret4', 20); +update t3 set c = repeat('secret4', 20); +update t4 set c = repeat('secret4', 20); +insert into t1 (c,b) values (repeat('secret5',20), repeat('secret6',6000)); +insert into t2 (c,b) values (repeat('secret7',20), repeat('secret8',6000)); +insert into t3 (c,b) values (repeat('secret9',20), repeat('secre10',6000)); +insert into t4 (c,b) values (repeat('secre11',20), repeat('secre12',6000)); +COMMIT; +let $cleanup= drop table t1,t2,t3,t4; +--let CLEANUP_IF_CHECKPOINT= $cleanup; +--source ../../suite/innodb/include/no_checkpoint_end.inc + +--error 1 +-- source include/start_mysqld.inc +--source include/kill_mysqld.inc + +# +# Now test with innodb-force-recovery=1 i.e. ignore corrupt pages +# + +-- let $restart_parameters=--innodb-force-recovery=1 +--error 1 +-- source include/start_mysqld.inc + +--source include/kill_mysqld.inc + +-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt +-- source include/start_mysqld.inc + +drop table t1, t2,t3,t4; diff --git a/mysql-test/suite/encryption/t/innodb-redo-nokeys.opt b/mysql-test/suite/encryption/t/innodb-redo-nokeys.opt new file mode 100644 index 00000000..6190ad24 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-redo-nokeys.opt @@ -0,0 +1,2 @@ +--innodb-change-buffering=none +--innodb-default-encryption-key-id=20 diff --git a/mysql-test/suite/encryption/t/innodb-redo-nokeys.test b/mysql-test/suite/encryption/t/innodb-redo-nokeys.test new file mode 100644 index 00000000..52c12761 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-redo-nokeys.test @@ -0,0 +1,90 @@ +-- source include/have_innodb.inc +-- source include/have_file_key_management_plugin.inc +# embedded does not support restart +-- source include/not_embedded.inc + +call mtr.add_suppression("mariadbd.*: File "); +call mtr.add_suppression("Plugin 'file_key_management' "); +call mtr.add_suppression("InnoDB: Recovery cannot access file"); +call mtr.add_suppression("InnoDB: Plugin initialization aborted"); +call mtr.add_suppression("Plugin 'InnoDB' init function returned error\\."); +call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed."); +call mtr.add_suppression("InnoDB: (Unable to apply log to|Discarding log for) corrupted page "); +call mtr.add_suppression("InnoDB: Cannot apply log to \\[page id: space=[1-9][0-9]*, page number=0\\] of corrupted file '.*test.t[1-5]\\.ibd'"); +call mtr.add_suppression("InnoDB: Failed to read page .* from file '.*'"); +call mtr.add_suppression("InnoDB: OPT_PAGE_CHECKSUM mismatch"); +call mtr.add_suppression("InnoDB: Missing FILE_CHECKPOINT"); +call mtr.add_suppression("InnoDB: Log scan aborted at LSN"); +call mtr.add_suppression("InnoDB: Set innodb_force_recovery=1 to ignore corruption"); +call mtr.add_suppression("InnoDB: Encryption key is not found for"); + +-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt +-- source include/restart_mysqld.inc + +SET GLOBAL innodb_file_per_table = ON; + +create table t1(a int not null primary key auto_increment, c char(200), b blob, index(b(10))) engine=innodb row_format=compressed encrypted=yes encryption_key_id=20; +create table t2(a int not null primary key auto_increment, c char(200), b blob, index(b(10))) engine=innodb row_format=compressed encrypted=yes; +create table t3(a int not null primary key auto_increment, c char(200), b blob, index(b(10))) engine=innodb encrypted=yes encryption_key_id=20; +create table t4(a int not null primary key auto_increment, c char(200), b blob, index(b(10))) engine=innodb encrypted=yes; + +begin; +--disable_query_log +--let $i = 20 +begin; +while ($i) +{ + insert into t1(c,b) values (repeat('secret1',20), repeat('secret2',6000)); + dec $i; +} +--enable_query_log + +insert into t2 select * from t1; +insert into t3 select * from t1; +insert into t4 select * from t1; +commit; + +--source ../../suite/innodb/include/no_checkpoint_start.inc +# +# We test redo log page read at recv_read_page using +# keys that are not in std_data/keys.txt. If checkpoint +# happens we will skip this test. If no checkpoint +# happens, InnoDB refuses to start as used +# encryption key is not found. +# +CREATE TABLE t5 (a VARCHAR(8)) ENGINE=InnoDB ENCRYPTED=YES; +SET GLOBAL innodb_flush_log_at_trx_commit=1; +begin; +update t1 set c = repeat('secret3', 20); +update t2 set c = repeat('secret4', 20); +update t3 set c = repeat('secret4', 20); +update t4 set c = repeat('secret4', 20); +insert into t1 (c,b) values (repeat('secret5',20), repeat('secret6',6000)); +insert into t2 (c,b) values (repeat('secret7',20), repeat('secret8',6000)); +insert into t3 (c,b) values (repeat('secret9',20), repeat('secre10',6000)); +insert into t4 (c,b) values (repeat('secre11',20), repeat('secre12',6000)); +INSERT INTO t5 VALUES ('foo'),('bar'); +COMMIT; + +let $cleanup= drop table t1,t2,t3,t4,t5; +--let CLEANUP_IF_CHECKPOINT= $cleanup; +--source ../../suite/innodb/include/no_checkpoint_end.inc + +-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys-not-found.txt +-- source include/start_mysqld.inc +SELECT * FROM INFORMATION_SCHEMA.ENGINES +WHERE engine = 'innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); + +let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err; +let SEARCH_PATTERN = \[ERROR\] InnoDB: Encryption key is not found for .*test.t1.ibd; +--source include/search_pattern_in_file.inc + +# +# In above server does start but InnoDB refuses to start +# thus we need to restart server with correct key file +# +-- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt +-- source include/restart_mysqld.inc + +drop table t1,t2,t3,t4,t5; diff --git a/mysql-test/suite/encryption/t/innodb-remove-encryption.test b/mysql-test/suite/encryption/t/innodb-remove-encryption.test new file mode 100644 index 00000000..8ff5fd63 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-remove-encryption.test @@ -0,0 +1,63 @@ +--source include/have_innodb.inc +# Test uses restart +--source include/not_embedded.inc +--source filekeys_plugin.inc +--source include/innodb_undo_tablespaces.inc + +# +# MDEV-15566: System tablespace does not easily key rotate to unencrypted +# + +set global innodb_file_per_table=OFF; + +call mtr.add_suppression("(mysqld|mariadbd).*: file-key-management-filename is not set"); +call mtr.add_suppression("Plugin 'file_key_management' init function returned error."); +call mtr.add_suppression("Plugin 'file_key_management' registration as a ENCRYPTION failed."); +flush tables; + +create table t1(a int not null primary key, b char(200)) engine=innodb; + +--echo +--echo # Restart server with encryption +-- let $restart_parameters=--plugin-load-add=file_key_management --loose-file-key-management --loose-file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys.txt --file-key-management-encryption-algorithm=aes_cbc --innodb-encrypt-tables=ON --innodb-encryption-threads=4 --innodb-tablespaces-encryption --innodb-encryption-rotate-key-age=15 +-- source include/restart_mysqld.inc + +--echo # Wait until encryption threads have encrypted all tablespaces + +--let $tables_count= `select count(*) + @@global.innodb_undo_tablespaces from information_schema.tables where engine = 'InnoDB'` +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) = $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND ROTATING_OR_FLUSHING = 0; +--source include/wait_condition.inc + +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + +--echo # Success! + +SELECT * from t1; + +--echo # Now turn off encryption and wait for threads to decrypt all tablespaces +SET GLOBAL innodb_encrypt_tables = off; + +--let $wait_condition=SELECT COUNT(*) = $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND ROTATING_OR_FLUSHING = 0; +--source include/wait_condition.inc + +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + +--echo # Success! + +--echo +--echo # Restart server with no encryption setup, there should be no crashes +--let $restart_parameters=--skip-file-key-management --innodb-encrypt-tables=OFF --innodb-encryption-threads=0 --innodb-tablespaces-encryption +-- source include/restart_mysqld.inc + +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + +SELECT * from t1; +DROP TABLE t1; + diff --git a/mysql-test/suite/encryption/t/innodb-spatial-index.opt b/mysql-test/suite/encryption/t/innodb-spatial-index.opt new file mode 100644 index 00000000..d1f1bb9c --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-spatial-index.opt @@ -0,0 +1,4 @@ +--innodb-encrypt-tables +--innodb-encryption-rotate-key-age=15 +--innodb-encryption-threads=4 +--innodb-tablespaces-encryption diff --git a/mysql-test/suite/encryption/t/innodb-spatial-index.test b/mysql-test/suite/encryption/t/innodb-spatial-index.test new file mode 100644 index 00000000..2caffb14 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-spatial-index.test @@ -0,0 +1,94 @@ +--source include/have_innodb.inc +--source include/have_file_key_management_plugin.inc +--source include/innodb_checksum_algorithm.inc + +# +# MDEV-11974: MariaDB 10.2 encryption does not support spatial indexes +# + +# +# +# +let $checksum_algorithm = `SELECT @@innodb_checksum_algorithm`; +let $error_code = ER_CANT_CREATE_TABLE, ER_ILLEGAL_HA_CREATE_OPTION; +if ($checksum_algorithm == "full_crc32") +{ + let $error_code = 0; +} +if ($checksum_algorithm == "strict_full_crc32") +{ + let $error_code = 0; +} + +--error $error_code +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, +c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB +ENCRYPTED=YES; + +if (!$error_code) { +INSERT INTO t1(c, coordinate) values('mysql', ST_GeomFromText('POINT(903994614 180726515)')); +--source include/restart_mysqld.inc +INSERT INTO t1(c, coordinate) values('mariadb', ST_GeomFromText('POINT(903994614 180726515)')); +DROP TABLE t1; +} + +# +# (2) Alter table +# +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, +c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB; +--error $error_code +ALTER TABLE t1 ENCRYPTED=YES; +DROP TABLE t1; + +# +# Index creation +# +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, +c VARCHAR(256), coordinate POINT NOT NULL) +PAGE_COMPRESSED=YES, ENCRYPTED=YES ENGINE=INNODB; +# FIXME: MDEV-13851 Encrypted table refuses some form of ALGORITHM=COPY, +# but allows rebuild by FORCE +--error $error_code +ALTER TABLE t1 ADD SPATIAL INDEX b1(coordinate), ALGORITHM=COPY; +--error $error_code +ALTER TABLE t1 ADD SPATIAL INDEX b2(coordinate), FORCE, ALGORITHM=INPLACE; +--error $error_code +ALTER TABLE t1 ADD SPATIAL INDEX(coordinate); +--error $error_code +CREATE SPATIAL INDEX b3 on t1(coordinate); +DROP TABLE t1; + +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, +c VARCHAR(256), coordinate POINT NOT NULL) ENCRYPTED=DEFAULT ENGINE=INNODB; +CREATE SPATIAL INDEX b on t1(coordinate); +INSERT INTO t1 values(1, 'secret', ST_GeomFromText('POINT(903994614 180726515)')); +ALTER TABLE t1 DROP INDEX b; +INSERT INTO t1 values(2, 'secret', ST_GeomFromText('POINT(903994614 180726515)')); +ALTER TABLE t1 ADD SPATIAL INDEX b(coordinate); +INSERT INTO t1 values(3, 'secret', ST_GeomFromText('POINT(903994614 180726515)')); +DROP TABLE t1; +# +# (3) Default encryption should still work +# + +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, +c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB; +CREATE TABLE t2 (pk INT PRIMARY KEY AUTO_INCREMENT, +c VARCHAR(256), coordinate POINT NOT NULL, SPATIAL index(coordinate)) ENGINE=INNODB PAGE_COMPRESSED=YES; + +INSERT INTO t1 values(1, 'secret', ST_GeomFromText('POINT(903994614 180726515)')); +INSERT INTO t2 values(1, 'secret', ST_GeomFromText('POINT(903994614 180726515)')); + +--let $wait_timeout=600 +--let $wait_condition=SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +--source include/wait_condition.inc + +--echo # Success! + +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION > 0; +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; + +DROP TABLE t1, t2; diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_freed.opt b/mysql-test/suite/encryption/t/innodb_encrypt_freed.opt new file mode 100644 index 00000000..221e3836 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encrypt_freed.opt @@ -0,0 +1,4 @@ +--innodb-encrypt-tables +--innodb-encrypt-log +--innodb-encryption-threads=1 +--innodb-tablespaces-encryption diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_freed.test b/mysql-test/suite/encryption/t/innodb_encrypt_freed.test new file mode 100644 index 00000000..7ba0b5a2 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encrypt_freed.test @@ -0,0 +1,118 @@ +--source include/have_innodb.inc +--source include/have_example_key_management_plugin.inc +--source include/have_debug.inc +--source include/not_embedded.inc +--source include/innodb_undo_tablespaces.inc + +SHOW VARIABLES LIKE 'innodb_encrypt%'; + +SET GLOBAL innodb_encrypt_tables = ON; + +CREATE TABLE t1(f1 BIGINT PRIMARY KEY, f2 int not null, + f3 int not null, index(f1), index idx_1(f2), + index(f2, f3)) ENGINE=InnoDB; +--let $tables_count= `select count(*) + 1 + @@global.innodb_undo_tablespaces from information_schema.tables where engine = 'InnoDB'` + +--echo # Wait max 10 min for key encryption threads to encrypt all spaces +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + +CREATE TABLE t2 (f1 int not null)engine=innodb; +let $restart_parameters="--debug=d,ib_log_checkpoint_avoid"; +--source include/restart_mysqld.inc + +# Stop the purge +connect(con1,localhost,root,,,); +begin; +insert into t2 values(1); + +connection default; + +--let $tables_count= `select count(*) + 1 + @@global.innodb_undo_tablespaces from information_schema.tables where engine = 'InnoDB'` +set global innodb_encrypt_tables = OFF; + +--echo # Wait max 10 min for key encryption threads to decrypt all spaces +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 +--source include/wait_condition.inc +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; + +# Free the index `idx_1` +alter table t1 drop index idx_1; + +set global innodb_encrypt_tables = ON; + +--echo # Wait max 10 min for key encryption threads to encrypt all spaces +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + +disconnect con1; +let $shutdown_timeout=0; +--source include/restart_mysqld.inc + +drop table t1, t2; + +# +# +CREATE TABLE t1(f1 BIGINT PRIMARY KEY, f2 int not null, + f3 int not null, index(f1), index idx_1(f2), + index(f2, f3)) ENGINE=InnoDB; +--let $tables_count= `select count(*) + 1 + @@global.innodb_undo_tablespaces from information_schema.tables where engine = 'InnoDB'` + +--echo # Wait max 10 min for key encryption threads to encrypt all spaces +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + +CREATE TABLE t2 (f1 int not null)engine=innodb; +--source include/restart_mysqld.inc + +# Stop the purge +connect(con1,localhost,root,,,); +begin; +insert into t2 values(1); + +connection default; + +--let $tables_count= `select count(*) + 1 + @@global.innodb_undo_tablespaces from information_schema.tables where engine = 'InnoDB'` +set global innodb_encrypt_tables = OFF; + +--echo # Wait max 10 min for key encryption threads to decrypt all spaces +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +--source include/wait_condition.inc +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; + +# Free the index `idx_1` +alter table t1 drop index idx_1; + +disconnect con1; +--source include/restart_mysqld.inc + +# Stop the purge +connect(con1,localhost,root,,,); +begin; +insert into t2 values(1); + +connection default; +set global innodb_encrypt_tables = ON; + +--echo # Wait max 10 min for key encryption threads to encrypt all spaces +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + +disconnect con1; +drop table t2, t1; diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.opt b/mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.opt new file mode 100644 index 00000000..6fa06402 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.opt @@ -0,0 +1,2 @@ +--innodb-tablespaces-encryption +--innodb_encrypt_tables=ON diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.test b/mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.test new file mode 100644 index 00000000..c96d33aa --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.test @@ -0,0 +1,89 @@ +-- source include/have_innodb.inc +-- source include/not_embedded.inc +-- source include/have_example_key_management_plugin.inc +-- source include/innodb_undo_tablespaces.inc + +CREATE TABLE t1 (f1 INT, f2 VARCHAR(256))engine=innodb; +INSERT INTO t1 VALUES(1, 'MariaDB'), (2, 'Robot'), (3, 'Science'); +INSERT INTO t1 SELECT * FROM t1; + +CREATE TABLE t2(f1 INT, f2 VARCHAR(256))engine=innodb; +INSERT INTO t2 SELECT * FROM t1; + +CREATE TABLE t3(f1 INT, f2 VARCHAR(256))engine=innodb encrypted=yes; +INSERT INTO t3 SELECT * FROM t1; + +--echo # Restart the server with encryption + +let $restart_noprint=2; +let $restart_parameters= --innodb_encryption_threads=5 --innodb_encryption_rotate_key_age=16384; +--source include/restart_mysqld.inc + +--echo # Wait until encryption threads have encrypted all tablespaces + +--let $tables_count= `select count(*) + 1 + @@global.innodb_undo_tablespaces from information_schema.tables where engine = 'InnoDB'` +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc + +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + +--echo # Restart the server with innodb_encryption_rotate_key_age= 0 + +let $restart_parameters= --innodb_encryption_threads=1 --innodb_encryption_rotate_key_age=0; + +--source include/restart_mysqld.inc + +create table t4 (f1 int not null)engine=innodb encrypted=NO; + +--echo # Wait until encryption threads have encrypted all tablespaces + +--let $tables_count= `select count(*) + @@global.innodb_undo_tablespaces from information_schema.tables where engine = 'InnoDB'` +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc + +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; + +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + +--echo # Disable encryption when innodb_encryption_rotate_key_age is 0 +set global innodb_encrypt_tables = OFF; + +--echo # Wait until encryption threads to decrypt all unencrypted tablespaces + +--let $tables_count= `select count(*) + @@global.innodb_undo_tablespaces from information_schema.tables where engine = 'InnoDB'` +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND ROTATING_OR_FLUSHING = 0; +--source include/wait_condition.inc + +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +--echo # Display only encrypted create tables (t3) +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + +--echo # Enable encryption when innodb_encryption_rotate_key_age is 0 +set global innodb_encrypt_tables = ON; + +--echo # Wait until encryption threads to encrypt all unencrypted tablespaces + +--let $tables_count= `select count(*) + @@global.innodb_undo_tablespaces from information_schema.tables where engine = 'InnoDB'` +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc + +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +--echo # Display only unencrypted create tables (t4) +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + +--let $restart_parameters= +-- source include/restart_mysqld.inc + +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +DROP TABLE t4, t3, t2, t1; diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_log.opt b/mysql-test/suite/encryption/t/innodb_encrypt_log.opt new file mode 100644 index 00000000..24046fe7 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encrypt_log.opt @@ -0,0 +1,6 @@ +--innodb-encrypt-log=ON +--innodb-encrypt-tables=FORCE +--plugin-load-add=$FILE_KEY_MANAGEMENT_SO +--loose-file-key-management +--loose-file-key-management-filename=$MYSQL_TEST_DIR/std_data/logkey.txt +--file-key-management-encryption-algorithm=aes_cbc diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_log.test b/mysql-test/suite/encryption/t/innodb_encrypt_log.test new file mode 100644 index 00000000..5448a606 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encrypt_log.test @@ -0,0 +1,88 @@ +-- source include/have_innodb.inc +-- source include/not_embedded.inc +-- source filekeys_plugin.inc + +--echo # +--echo # MDEV-9011: Redo log encryption does not work +--echo # + +--echo # +--echo # MDEV-9422 Encrypted redo log checksum errors +--echo # on restart after killing busy server instance +--echo # + +--let $MYSQLD_DATADIR=`select @@datadir` + +CREATE TABLE t0 ( + pk bigint auto_increment, + col_int int, + col_int_key int, + col_char char(12), + col_char_key char(12), + primary key (pk), + key (col_int_key), + key (col_char_key) +) ENGINE=InnoDB ENCRYPTED=YES ENCRYPTION_KEY_ID=1; +CREATE TEMPORARY TABLE t LIKE t0; + +INSERT INTO t VALUES +(NULL,1,1,'private','secret'),(NULL,2,2,'sacred','success'), +(NULL,3,3,'story','secure'),(NULL,4,4,'security','sacrament'); + +# Force a redo log flush at the next commit. +SET GLOBAL innodb_flush_log_at_trx_commit=1; +INSERT INTO t0 + SELECT NULL, t1.col_int, t1.col_int_key, t1.col_char, t1.col_char_key + FROM t t1, t t2, t t3, t t4, t t5; + +--source include/kill_mysqld.inc + +--let SEARCH_RANGE = 10000000 +--let SEARCH_PATTERN=private|secret|sacr(ed|ament)|success|story|secur(e|ity) + +--echo # ibdata1 expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/ibdata1 +-- source include/search_pattern_in_file.inc +--echo # t0.ibd expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/test/t0.ibd +-- source include/search_pattern_in_file.inc +--echo # ib_logfile0 expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/ib_logfile0 +-- source include/search_pattern_in_file.inc + +--echo # Restart without redo log encryption +-- let $restart_parameters=--skip-innodb-encrypt-log +-- source include/start_mysqld.inc + +SELECT COUNT(*) FROM t0; +CHECK TABLE t0; +# Force a redo log flush at the next commit. +SET GLOBAL innodb_flush_log_at_trx_commit=1; +# If we tested with UPDATE, we would get clear-text redo log for +# encrypted undo log written with the old secret values. +INSERT INTO t0 VALUES(NULL, 5, 5, 'public', 'gossip'); + +--source include/kill_mysqld.inc + +--echo # ib_logfile0 expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/ib_logfile0 +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=(public|gossip).* +--echo # ib_logfile0 expecting FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/ib_logfile0 +-- source include/search_pattern_in_file.inc + +--let SEARCH_PATTERN=private|secret|sacr(ed|ament)|success|story|secur(e|ity)|public|gossip +--echo # ibdata1 expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/ibdata1 +-- source include/search_pattern_in_file.inc +--echo # t0.ibd expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/test/t0.ibd +-- source include/search_pattern_in_file.inc + +--let $restart_parameters= +--source include/start_mysqld.inc + +SELECT COUNT(*) FROM t0; +CHECK TABLE t0; +DROP TABLE t0; diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_log_corruption.opt b/mysql-test/suite/encryption/t/innodb_encrypt_log_corruption.opt new file mode 100644 index 00000000..ae20d676 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encrypt_log_corruption.opt @@ -0,0 +1,6 @@ +--innodb-encrypt-log=ON +--plugin-load-add=$FILE_KEY_MANAGEMENT_SO +--loose-file-key-management +--loose-file-key-management-filename=$MYSQL_TEST_DIR/std_data/logkey.txt +--file-key-management-encryption-algorithm=aes_cbc +--innodb-log-file-size=5242880 diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_log_corruption.test b/mysql-test/suite/encryption/t/innodb_encrypt_log_corruption.test new file mode 100644 index 00000000..f1642e83 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encrypt_log_corruption.test @@ -0,0 +1,15 @@ +--let $no_cleanup=1 +--source ../../innodb/t/log_corruption.test + +SELECT COUNT(*) `1` FROM INFORMATION_SCHEMA.ENGINES WHERE engine='innodb' +AND support IN ('YES', 'DEFAULT', 'ENABLED'); +--source include/shutdown_mysqld.inc +--let SEARCH_PATTERN= InnoDB: Encrypting redo log +--source include/search_pattern_in_file.inc + +--let $restart_parameters= +--source include/start_mysqld.inc + +--list_files $bugdir +--remove_files_wildcard $bugdir +--rmdir $bugdir diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.combinations b/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.combinations new file mode 100644 index 00000000..72938059 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.combinations @@ -0,0 +1,5 @@ +[strict_crc32] +--innodb-checksum-algorithm=strict_crc32 + +[strict_full_crc32] +--innodb-checksum-algorithm=strict_full_crc32 diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.opt b/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.opt new file mode 100644 index 00000000..70797302 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.opt @@ -0,0 +1,2 @@ +--innodb_buffer_pool_size=5M +--innodb_encrypt_temporary_tables=1 diff --git a/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.test b/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.test new file mode 100644 index 00000000..d99a55b9 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encrypt_temporary_tables.test @@ -0,0 +1,24 @@ +--source include/have_sequence.inc +--source include/have_innodb.inc +--source include/have_file_key_management_plugin.inc + +SELECT variable_value into @old_encrypted FROM information_schema.global_status +WHERE variable_name = 'innodb_encryption_n_temp_blocks_encrypted'; + +SELECT variable_value into @old_decrypted FROM information_schema.global_status +WHERE variable_name = 'innodb_encryption_n_temp_blocks_decrypted'; + +CREATE TEMPORARY TABLE t1(f1 CHAR(200), f2 CHAR(200)) ENGINE=InnoDB; +INSERT INTO t1 (f1,f2) SELECT '', '' FROM seq_1_to_8192; + +CREATE TEMPORARY TABLE t2(f1 CHAR(100), f2 CHAR(200), f3 CHAR(200))ENGINE=InnoDB; +INSERT INTO t2 (f1,f2,f3) SELECT '', '', '' FROM seq_1_to_8192; + +SELECT COUNT(*) FROM t1; +SELECT COUNT(*) FROM t2; + +SELECT variable_value > @old_encrypted FROM information_schema.global_status +WHERE variable_name = 'innodb_encryption_n_temp_blocks_encrypted'; + +SELECT variable_value > @old_decrypted FROM information_schema.global_status +WHERE variable_name = 'innodb_encryption_n_temp_blocks_decrypted'; diff --git a/mysql-test/suite/encryption/t/innodb_encryption-page-compression.opt b/mysql-test/suite/encryption/t/innodb_encryption-page-compression.opt new file mode 100644 index 00000000..0b7319dc --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encryption-page-compression.opt @@ -0,0 +1,7 @@ +--aria-encrypt-tables=ON +--encrypt-tmp-disk-tables=ON +--innodb-encrypt-tables=ON +--innodb-encrypt-log=ON +--innodb-encryption-rotate-key-age=15 +--innodb-encryption-threads=4 +--innodb-tablespaces-encryption diff --git a/mysql-test/suite/encryption/t/innodb_encryption-page-compression.test b/mysql-test/suite/encryption/t/innodb_encryption-page-compression.test new file mode 100644 index 00000000..57c87212 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encryption-page-compression.test @@ -0,0 +1,146 @@ +-- source include/have_innodb.inc +-- source include/have_example_key_management_plugin.inc +-- source include/not_embedded.inc +# This test is too slow for valgrind and causes innnodb semaphores to time out +-- source include/not_valgrind.inc + +let $innodb_encrypt_tables_orig = `SELECT @@innodb_encrypt_tables`; +let $innodb_encryption_threads_orig = `SELECT @@innodb_encryption_threads`; + +SET GLOBAL innodb_encryption_threads = 4; + +# zlib +set global innodb_compression_algorithm = 1; + +create table innodb_normal (c1 int, b char(20)) engine=innodb; +show warnings; +create table innodb_page_compressed1 (c1 int, b char(20)) engine=innodb page_compressed=1 page_compression_level=1; +show warnings; +show create table innodb_page_compressed1; +create table innodb_page_compressed2 (c1 int, b char(20)) engine=innodb page_compressed=1 page_compression_level=2; +show warnings; +show create table innodb_page_compressed2; +create table innodb_page_compressed3 (c1 int, b char(20)) engine=innodb page_compressed=1 page_compression_level=3; +show warnings; +show create table innodb_page_compressed3; +create table innodb_page_compressed4 (c1 int, b char(20)) engine=innodb page_compressed=1 page_compression_level=4; +show warnings; +show create table innodb_page_compressed4; +create table innodb_page_compressed5 (c1 int, b char(20)) engine=innodb page_compressed=1 page_compression_level=5; +show warnings; +show create table innodb_page_compressed5; +create table innodb_page_compressed6 (c1 int, b char(20)) engine=innodb page_compressed=1 page_compression_level=6; +show warnings; +show create table innodb_page_compressed6; +create table innodb_page_compressed7 (c1 int, b char(20)) engine=innodb page_compressed=1 page_compression_level=7; +show warnings; +show create table innodb_page_compressed7; +create table innodb_page_compressed8 (c1 int, b char(20)) engine=innodb page_compressed=1 page_compression_level=8; +show warnings; +show create table innodb_page_compressed8; +create table innodb_page_compressed9 (c1 int, b char(20)) engine=innodb page_compressed=1 page_compression_level=9; +show warnings; +show create table innodb_page_compressed9; +delimiter //; +create procedure innodb_insert_proc (repeat_count int) +begin + declare current_num int; + set current_num = 0; + while current_num < repeat_count do + insert into innodb_normal values(current_num,'testing..'); + set current_num = current_num + 1; + end while; +end// +delimiter ;// +commit; + +begin; +call innodb_insert_proc(2000); +insert into innodb_page_compressed1 select * from innodb_normal; +insert into innodb_page_compressed2 select * from innodb_normal; +insert into innodb_page_compressed3 select * from innodb_normal; +insert into innodb_page_compressed4 select * from innodb_normal; +insert into innodb_page_compressed5 select * from innodb_normal; +insert into innodb_page_compressed6 select * from innodb_normal; +insert into innodb_page_compressed7 select * from innodb_normal; +insert into innodb_page_compressed8 select * from innodb_normal; +insert into innodb_page_compressed9 select * from innodb_normal; +commit; + +select count(*) from innodb_page_compressed1 where c1 < 500000; +select count(*) from innodb_page_compressed2 where c1 < 500000; +select count(*) from innodb_page_compressed3 where c1 < 500000; +select count(*) from innodb_page_compressed4 where c1 < 500000; +select count(*) from innodb_page_compressed5 where c1 < 500000; +select count(*) from innodb_page_compressed6 where c1 < 500000; +select count(*) from innodb_page_compressed7 where c1 < 500000; +select count(*) from innodb_page_compressed8 where c1 < 500000; +select count(*) from innodb_page_compressed9 where c1 < 500000; + +flush tables innodb_page_compressed1, innodb_page_compressed2, +innodb_page_compressed3, innodb_page_compressed4, +innodb_page_compressed5, innodb_page_compressed6, +innodb_page_compressed7, innodb_page_compressed8, +innodb_page_compressed9 for export; + +unlock tables; + +--echo # Wait until dirty pages are compressed and encrypted +let $wait_condition= select variable_value > 0 from information_schema.global_status where variable_name = 'INNODB_NUM_PAGES_PAGE_COMPRESSED'; +--source include/wait_condition.inc +let $wait_condition= select variable_value > 0 from information_schema.global_status where variable_name = 'INNODB_NUM_PAGES_ENCRYPTED'; +--source include/wait_condition.inc + +SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_compressed'; + +--source include/restart_mysqld.inc + +SET GLOBAL innodb_encryption_threads = 4; +SET GLOBAL innodb_encrypt_tables = off; + +update innodb_page_compressed1 set c1 = c1 + 1; +update innodb_page_compressed2 set c1 = c1 + 1; +update innodb_page_compressed3 set c1 = c1 + 1; +update innodb_page_compressed4 set c1 = c1 + 1; +update innodb_page_compressed5 set c1 = c1 + 1; +update innodb_page_compressed6 set c1 = c1 + 1; +update innodb_page_compressed7 set c1 = c1 + 1; +update innodb_page_compressed8 set c1 = c1 + 1; +update innodb_page_compressed9 set c1 = c1 + 1; + +flush tables innodb_page_compressed1, innodb_page_compressed2, +innodb_page_compressed3, innodb_page_compressed4, +innodb_page_compressed5, innodb_page_compressed6, +innodb_page_compressed7, innodb_page_compressed8, +innodb_page_compressed9 for export; + +unlock tables; + +--echo # Wait until dirty pages are compressed and encrypted 2 +let $wait_condition= select variable_value > 0 from information_schema.global_status where variable_name = 'INNODB_NUM_PAGES_PAGE_COMPRESSED'; +--source include/wait_condition.inc +let $wait_condition= select variable_value > 0 from information_schema.global_status where variable_name = 'INNODB_NUM_PAGES_DECRYPTED'; +--source include/wait_condition.inc + +SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; +SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_compressed'; +SELECT variable_value > 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_decompressed'; + +drop procedure innodb_insert_proc; +drop table innodb_normal; +drop table innodb_page_compressed1; +drop table innodb_page_compressed2; +drop table innodb_page_compressed3; +drop table innodb_page_compressed4; +drop table innodb_page_compressed5; +drop table innodb_page_compressed6; +drop table innodb_page_compressed7; +drop table innodb_page_compressed8; +drop table innodb_page_compressed9; + +# reset system +--disable_query_log +EVAL SET GLOBAL innodb_encrypt_tables = $innodb_encrypt_tables_orig; +EVAL SET GLOBAL innodb_encryption_threads = $innodb_encryption_threads_orig; +--enable_query_log diff --git a/mysql-test/suite/encryption/t/innodb_encryption.opt b/mysql-test/suite/encryption/t/innodb_encryption.opt new file mode 100644 index 00000000..0f3634ac --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encryption.opt @@ -0,0 +1,8 @@ +--aria-encrypt-tables +--encrypt-tmp-disk-tables +--innodb-encrypt-tables +--innodb-encrypt-log +--innodb-encryption-rotate-key-age=15 +--innodb-encryption-threads=4 +--innodb-tablespaces-encryption + diff --git a/mysql-test/suite/encryption/t/innodb_encryption.test b/mysql-test/suite/encryption/t/innodb_encryption.test new file mode 100644 index 00000000..2b0b2b8d --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encryption.test @@ -0,0 +1,98 @@ +# +# +# +-- source include/have_innodb.inc +-- source include/have_example_key_management_plugin.inc +-- source include/innodb_undo_tablespaces.inc + +# embedded does not support restart +-- source include/not_embedded.inc + +SET @start_global_value = @@global.innodb_encryption_threads; + +SHOW VARIABLES LIKE 'innodb_encrypt%'; + +SET GLOBAL innodb_encrypt_tables = ON; + +--let $tables_count= `select count(*) + @@global.innodb_undo_tablespaces + 1 from information_schema.tables where engine = 'InnoDB'` + +--echo # Wait max 10 min for key encryption threads to encrypt all spaces +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc + +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; + +--echo # Success! + +--echo # Now turn off encryption and wait for threads to decrypt everything +SET GLOBAL innodb_encrypt_tables = off; + +--echo # Wait max 10 min for key encryption threads to decrypt all spaces +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc + +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; + +--echo # Success! + +--echo # Shutdown innodb_encryption_threads +SET GLOBAL innodb_encryption_threads=0; + +--echo # Turn on encryption +--echo # since threads are off tables should remain unencrypted +SET GLOBAL innodb_encrypt_tables = on; + +--echo # Wait 15s to check that nothing gets encrypted +--let $wait_timeout= 15 +--let $wait_condition=SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc + +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; + +--echo # Success! + +--echo # Startup innodb_encryption_threads +SET GLOBAL innodb_encryption_threads=@start_global_value; + +--echo # Wait max 10 min for key encryption threads to encrypt all spaces +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc + +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; + +--echo # Success! +--echo # Restart mysqld --innodb_encrypt_tables=0 --innodb_encryption_threads=0 +-- let $restart_parameters=--innodb_encrypt_tables=0 --innodb_encryption_threads=0 +-- source include/restart_mysqld.inc + +SHOW VARIABLES LIKE 'innodb_encrypt%'; + +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; +--sorted_result +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 +AND NAME NOT LIKE 'innodb_undo%' AND NAME NOT LIKE 'mysql/innodb_%_stats' AND NAME NOT LIKE 'mysql/transaction_registry'; diff --git a/mysql-test/suite/encryption/t/innodb_encryption_discard_import.opt b/mysql-test/suite/encryption/t/innodb_encryption_discard_import.opt new file mode 100644 index 00000000..9fe990f7 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encryption_discard_import.opt @@ -0,0 +1,7 @@ +--innodb-encrypt-tables=ON +--innodb-encrypt-log=ON +--innodb-encryption-rotate-key-age=15 +--innodb-encryption-threads=4 +--innodb-tablespaces-encryption +--innodb-max-dirty-pages-pct_lwm=0 +--innodb-max-dirty-pages-pct=0.001 diff --git a/mysql-test/suite/encryption/t/innodb_encryption_discard_import.test b/mysql-test/suite/encryption/t/innodb_encryption_discard_import.test new file mode 100644 index 00000000..22755571 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encryption_discard_import.test @@ -0,0 +1,154 @@ +-- 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 SEARCH_RANGE = 10000000 +--let $id = `SELECT RAND()` +--let t1_IBD = $MYSQLD_DATADIR/test/t1.ibd +--let t2_IBD = $MYSQLD_DATADIR/test/t2.ibd +--let t3_IBD = $MYSQLD_DATADIR/test/t3.ibd + +CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB encrypted=yes; +CREATE TABLE t2 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB; +CREATE TABLE t3 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB row_format=compressed encrypted=yes; + +delimiter //; +create procedure innodb_insert_proc (repeat_count int) +begin + declare current_num int; + set current_num = 0; + while current_num < repeat_count do + insert into t1 values (current_num,repeat('foobar',42)); + insert into t2 values (current_num,repeat('temp', 42)); + insert into t3 values (current_num,repeat('barfoo',42)); + set current_num = current_num + 1; + end while; +end// +delimiter ;// +commit; + +set autocommit=0; +call innodb_insert_proc(10000); +commit; +set autocommit=1; + +--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 + +# shutdown so that grep is safe +--source include/shutdown_mysqld.inc + +--echo # tablespaces should be now encrypted +--let SEARCH_PATTERN=foobar +--echo # t1 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t1_IBD +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=temp +--echo # t2 ... on expecting NOT FOUND +-- let SEARCH_FILE=$t2_IBD +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=barfoo +--echo # t3 ... on expecting NOT FOUND +-- let SEARCH_FILE=$t3_IBD +-- source include/search_pattern_in_file.inc + +--source include/start_mysqld.inc +let MYSQLD_DATADIR =`SELECT @@datadir`; + +--list_files $MYSQLD_DATADIR/test +FLUSH TABLES t1, t2, t3 FOR EXPORT; +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_backup_tablespaces("test", "t1","t2","t3"); +EOF +--list_files $MYSQLD_DATADIR/test +UNLOCK TABLES; + +ALTER TABLE t1 DISCARD TABLESPACE; +ALTER TABLE t2 DISCARD TABLESPACE; +ALTER TABLE t3 DISCARD TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "t1","t2","t3"); +ib_restore_tablespaces("test", "t1","t2","t3"); +EOF + +ALTER TABLE t1 IMPORT TABLESPACE; +SELECT COUNT(1) FROM t1; +ALTER TABLE t2 IMPORT TABLESPACE; +SELECT COUNT(1) FROM t2; +ALTER TABLE t3 IMPORT TABLESPACE; +SELECT COUNT(1) FROM t3; + +# shutdown so that grep is safe +--source include/shutdown_mysqld.inc + +--echo # tablespaces should remain encrypted after import +--let SEARCH_PATTERN=foobar +--echo # t1 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t1_IBD +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=temp +--echo # t2 ... on expecting NOT FOUND +-- let SEARCH_FILE=$t2_IBD +-- source include/search_pattern_in_file.inc +--echo # t3 ... on expecting NOT FOUND +--let SEARCH_PATTERN=barfoo +-- let SEARCH_FILE=$t3_IBD +-- source include/search_pattern_in_file.inc + +--source include/start_mysqld.inc + +ALTER TABLE t1 ENGINE InnoDB; +SHOW CREATE TABLE t1; +ALTER TABLE t2 ENGINE InnoDB; +SHOW CREATE TABLE t2; +ALTER TABLE t3 ENGINE InnoDB; +SHOW CREATE TABLE t3; + +--echo # Restarting server +-- source include/restart_mysqld.inc +--echo # Done restarting server + +--echo # Verify that tables are still usable +SELECT COUNT(1) FROM t1; +SELECT COUNT(1) FROM t2; +SELECT COUNT(1) FROM t3; + +# shutdown so that grep is safe +--source include/shutdown_mysqld.inc + +--echo # Tablespaces should be encrypted after restart +--let SEARCH_PATTERN=foobar +--echo # t1 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t1_IBD +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=temp +--echo # t2 ... on expecting NOT FOUND +-- let SEARCH_FILE=$t2_IBD +-- source include/search_pattern_in_file.inc +--echo # t3 ... on expecting NOT FOUND +--let SEARCH_PATTERN=barfoo +-- let SEARCH_FILE=$t3_IBD +-- source include/search_pattern_in_file.inc + +--source include/start_mysqld.inc + +--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 + +--echo # Success! +--echo # Restart mysqld --innodb_encrypt_tables=0 --innodb_encryption_threads=0 +-- let $restart_parameters=--innodb_encrypt_tables=0 --innodb_encryption_threads=0 +-- source include/restart_mysqld.inc + +DROP PROCEDURE innodb_insert_proc; +DROP TABLE t1, t2, t3; diff --git a/mysql-test/suite/encryption/t/innodb_encryption_filekeys.opt b/mysql-test/suite/encryption/t/innodb_encryption_filekeys.opt new file mode 100644 index 00000000..7d3f2da7 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encryption_filekeys.opt @@ -0,0 +1 @@ +--innodb-tablespaces-encryption diff --git a/mysql-test/suite/encryption/t/innodb_encryption_filekeys.test b/mysql-test/suite/encryption/t/innodb_encryption_filekeys.test new file mode 100644 index 00000000..03447bbc --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encryption_filekeys.test @@ -0,0 +1,133 @@ +-- source include/have_innodb.inc +-- source include/have_file_key_management_plugin.inc + +--disable_query_log +let $encrypt_tables = `SELECT @@innodb_encrypt_tables`; +let $threads = `SELECT @@innodb_encryption_threads`; +let $key_id = `SELECT @@innodb_default_encryption_key_id`; +--enable_query_log + +SET GLOBAL innodb_encrypt_tables = OFF; +SET GLOBAL innodb_encryption_threads = 4; + +CREATE TABLE t1 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB; +SHOW CREATE TABLE t1; +CREATE TABLE t2 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=YES; +CREATE TABLE t3 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=NO; +CREATE TABLE t4 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=YES ENCRYPTION_KEY_ID=4; + +--disable_warnings +--disable_query_log +begin; +let $i = 10; +while ($i) +{ +INSERT INTO t1 values(NULL, substring(MD5(RAND()), -128)); +dec $i; +} + +INSERT INTO t2 select * from t1; +INSERT INTO t3 select * from t1; +INSERT INTO t4 select * from t1; +commit; +--enable_warnings +--enable_query_log + +SET GLOBAL innodb_encrypt_tables = on; + +--echo # Wait max 10 min for key encryption threads to encrypt required all spaces +let $cnt=600; +while ($cnt) +{ + let $success=`SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0`; + if ($success) + { + let $cnt=0; + } + if (!$success) + { + real_sleep 1; + dec $cnt; + } +} +if (!$success) +{ + SELECT NAME,ENCRYPTION_SCHEME,MIN_KEY_VERSION, ROTATING_OR_FLUSHING FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION; + SHOW STATUS LIKE 'innodb_encryption%'; + -- die Timeout waiting for encryption threads +} +--echo # Success! + +SELECT COUNT(1) FROM t1; +SELECT COUNT(1) FROM t2; +SELECT COUNT(1) FROM t3; +SELECT COUNT(1) FROM t4; + +SET GLOBAL innodb_encrypt_tables = off; + +--echo # Wait max 10 min for key encryption threads to decrypt all required spaces +let $cnt=600; +while ($cnt) +{ + let $success=`SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0`; + if ($success) + { + let $cnt=0; + } + if (!$success) + { + real_sleep 1; + dec $cnt; + } +} +if (!$success) +{ + SELECT NAME,ENCRYPTION_SCHEME,MIN_KEY_VERSION, ROTATING_OR_FLUSHING FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION; + SHOW STATUS LIKE 'innodb_encryption%'; + -- die Timeout waiting for encryption threads +} +--echo # Success! + +SET GLOBAL innodb_encrypt_tables = ON; +set GLOBAL innodb_default_encryption_key_id=4; +CREATE TABLE t5 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB; +SHOW CREATE TABLE t5; +INSERT INTO t5 select * from t1; + +--echo # Wait max 10 min for key encryption threads to encrypt required all spaces +let $cnt=600; +while ($cnt) +{ + let $success=`SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0`; + if ($success) + { + let $cnt=0; + } + if (!$success) + { + real_sleep 1; + dec $cnt; + } +} +if (!$success) +{ + SELECT NAME,ENCRYPTION_SCHEME,MIN_KEY_VERSION, ROTATING_OR_FLUSHING FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION; + SHOW STATUS LIKE 'innodb_encryption%'; + -- die Timeout waiting for encryption threads +} +--echo # Success! + +SELECT COUNT(1) FROM t1; +SELECT COUNT(1) FROM t2; +SELECT COUNT(1) FROM t3; +SELECT COUNT(1) FROM t4; +SELECT COUNT(1) FROM t5; + +drop table t1,t2,t3,t4, t5; + +# reset system +--disable_query_log +EVAL SET GLOBAL innodb_encrypt_tables = $encrypt_tables; +EVAL SET GLOBAL innodb_encryption_threads = $threads; +EVAL set GLOBAL innodb_default_encryption_key_id = $key_id; +--enable_query_log diff --git a/mysql-test/suite/encryption/t/innodb_encryption_is.opt b/mysql-test/suite/encryption/t/innodb_encryption_is.opt new file mode 100644 index 00000000..26c70684 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encryption_is.opt @@ -0,0 +1 @@ +--loose-innodb-tablespaces-encryption diff --git a/mysql-test/suite/encryption/t/innodb_encryption_is.test b/mysql-test/suite/encryption/t/innodb_encryption_is.test new file mode 100644 index 00000000..9e15cebb --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encryption_is.test @@ -0,0 +1,18 @@ +-- source include/have_innodb.inc +-- source include/have_file_key_management_plugin.inc + +CREATE TABLE t1 (c VARCHAR(8)) ENGINE=InnoDB ENCRYPTED=YES ENCRYPTION_KEY_ID=1; +CREATE TABLE t2 (c VARCHAR(8)) ENGINE=InnoDB ENCRYPTED=YES ENCRYPTION_KEY_ID=2; +INSERT INTO t1 VALUES ('foobar'); +INSERT INTO t2 VALUES ('foobar'); + +# +# MDEV-9640: Add used key_id to INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION +# +--sorted_result +SELECT NAME, ENCRYPTION_SCHEME, MIN_KEY_VERSION, CURRENT_KEY_VERSION, +CURRENT_KEY_ID +FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION +WHERE NAME LIKE '%t1' OR NAME LIKE '%t2'; + +DROP TABLE t1, t2; diff --git a/mysql-test/suite/encryption/t/innodb_encryption_row_compressed.opt b/mysql-test/suite/encryption/t/innodb_encryption_row_compressed.opt new file mode 100644 index 00000000..7ebf81a0 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encryption_row_compressed.opt @@ -0,0 +1,4 @@ +--innodb-encrypt-tables=ON +--innodb-encryption-rotate-key-age=15 +--innodb-encryption-threads=4 +--innodb-tablespaces-encryption diff --git a/mysql-test/suite/encryption/t/innodb_encryption_row_compressed.test b/mysql-test/suite/encryption/t/innodb_encryption_row_compressed.test new file mode 100644 index 00000000..d6319164 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encryption_row_compressed.test @@ -0,0 +1,108 @@ +-- source include/have_innodb.inc +-- source include/have_file_key_management_plugin.inc +-- source include/not_embedded.inc + +create table innodb_compressed1(c1 bigint not null primary key, d int, a varchar(20), b char(200)) engine=innodb row_format=compressed encrypted=yes; +create table innodb_compressed2(c1 bigint not null primary key, d int, a varchar(20), b char(200)) engine=innodb row_format=compressed key_block_size=1 encrypted=yes; +create table innodb_compressed3(c1 bigint not null primary key, d int, a varchar(20), b char(200)) engine=innodb row_format=compressed key_block_size=2 encrypted=yes; +create table innodb_compressed4(c1 bigint not null primary key, d int, a varchar(20), b char(200)) engine=innodb row_format=compressed key_block_size=4 encrypted=yes; + +insert into innodb_compressed1 values (1, 20, 'private', 'evenmoreprivate'); +insert into innodb_compressed1 values (2, 20, 'private', 'evenmoreprivate'); +insert into innodb_compressed1 values (3, 30, 'private', 'evenmoreprivate'); +insert into innodb_compressed1 values (4, 30, 'private', 'evenmoreprivate'); +insert into innodb_compressed1 values (5, 30, 'private', 'evenmoreprivate'); +insert into innodb_compressed1 values (6, 30, 'private', 'evenmoreprivate'); +insert into innodb_compressed1 values (7, 30, 'private', 'evenmoreprivate'); +insert into innodb_compressed1 values (8, 20, 'private', 'evenmoreprivate'); +insert into innodb_compressed1 values (9, 20, 'private', 'evenmoreprivate'); +insert into innodb_compressed1 values (10, 20, 'private', 'evenmoreprivate'); + +insert into innodb_compressed2 select * from innodb_compressed1; +insert into innodb_compressed3 select * from innodb_compressed1; +insert into innodb_compressed4 select * from innodb_compressed1; + +--source include/restart_mysqld.inc + +--let $MYSQLD_DATADIR=`select @@datadir` +--let t1_IBD = $MYSQLD_DATADIR/test/innodb_compressed1.ibd +--let t2_IBD = $MYSQLD_DATADIR/test/innodb_compressed2.ibd +--let t3_IBD = $MYSQLD_DATADIR/test/innodb_compressed3.ibd +--let t4_IBD = $MYSQLD_DATADIR/test/innodb_compressed4.ibd +--let SEARCH_RANGE = 10000000 +--let SEARCH_PATTERN=private +--echo # t1 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t1_IBD +-- source include/search_pattern_in_file.inc +--echo # t2 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t2_IBD +-- source include/search_pattern_in_file.inc +--echo # t3 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t3_IBD +-- source include/search_pattern_in_file.inc +--echo # t4 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t4_IBD +-- source include/search_pattern_in_file.inc + +select * from innodb_compressed1 where d = 20; +select * from innodb_compressed1 where d = 30; +select * from innodb_compressed2 where d = 20; +select * from innodb_compressed2 where d = 30; +select * from innodb_compressed3 where d = 20; +select * from innodb_compressed3 where d = 30; +select * from innodb_compressed4 where d = 20; +select * from innodb_compressed4 where d = 30; + +update innodb_compressed1 set d = d + 10 where d = 30; +update innodb_compressed2 set d = d + 10 where d = 30; +update innodb_compressed3 set d = d + 10 where d = 30; +update innodb_compressed4 set d = d + 10 where d = 30; + +insert into innodb_compressed1 values (20, 60, 'newprivate', 'newevenmoreprivate'); +insert into innodb_compressed2 values (20, 60, 'newprivate', 'newevenmoreprivate'); +insert into innodb_compressed3 values (20, 60, 'newprivate', 'newevenmoreprivate'); +insert into innodb_compressed4 values (20, 60, 'newprivate', 'newevenmoreprivate'); + +--let SEARCH_PATTERN=private +--echo # t1 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t1_IBD +-- source include/search_pattern_in_file.inc +--echo # t2 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t2_IBD +-- source include/search_pattern_in_file.inc +--echo # t3 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t3_IBD +-- source include/search_pattern_in_file.inc +--echo # t4 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t4_IBD +-- source include/search_pattern_in_file.inc + +--source include/restart_mysqld.inc + +select * from innodb_compressed1 where d = 40; +select * from innodb_compressed1 where d = 60; +select * from innodb_compressed2 where d = 40; +select * from innodb_compressed2 where d = 60; +select * from innodb_compressed3 where d = 40; +select * from innodb_compressed3 where d = 60; +select * from innodb_compressed4 where d = 40; +select * from innodb_compressed4 where d = 60; + +--let SEARCH_PATTERN=private +--echo # t1 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t1_IBD +-- source include/search_pattern_in_file.inc +--echo # t2 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t2_IBD +-- source include/search_pattern_in_file.inc +--echo # t3 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t3_IBD +-- source include/search_pattern_in_file.inc +--echo # t4 yes on expecting NOT FOUND +-- let SEARCH_FILE=$t4_IBD +-- source include/search_pattern_in_file.inc + +drop table innodb_compressed1; +drop table innodb_compressed2; +drop table innodb_compressed3; +drop table innodb_compressed4; diff --git a/mysql-test/suite/encryption/t/innodb_encryption_tables.opt b/mysql-test/suite/encryption/t/innodb_encryption_tables.opt new file mode 100644 index 00000000..0b7319dc --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encryption_tables.opt @@ -0,0 +1,7 @@ +--aria-encrypt-tables=ON +--encrypt-tmp-disk-tables=ON +--innodb-encrypt-tables=ON +--innodb-encrypt-log=ON +--innodb-encryption-rotate-key-age=15 +--innodb-encryption-threads=4 +--innodb-tablespaces-encryption diff --git a/mysql-test/suite/encryption/t/innodb_encryption_tables.test b/mysql-test/suite/encryption/t/innodb_encryption_tables.test new file mode 100644 index 00000000..d03bc890 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_encryption_tables.test @@ -0,0 +1,99 @@ +-- source include/have_innodb.inc +-- source include/have_example_key_management_plugin.inc +-- source include/not_embedded.inc +# We can't run this test under valgrind as it 'takes forever' +-- source include/not_valgrind.inc + +create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb; +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact; +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic; +create table innodb_compressed(c1 bigint not null, b char(200)) engine=innodb row_format=compressed; +create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant; + +show warnings; + +show create table innodb_normal; +show create table innodb_compact; +show create table innodb_dynamic; +show create table innodb_compressed; +show create table innodb_redundant; + +delimiter //; +create procedure innodb_insert_proc (repeat_count int) +begin + declare current_num int; + set current_num = 0; + while current_num < repeat_count do + insert into innodb_normal values(current_num, substring(MD5(RAND()), -64)); + set current_num = current_num + 1; + end while; +end// +delimiter ;// +commit; + +set autocommit=0; +call innodb_insert_proc(2000); +commit; +set autocommit=1; + +insert into innodb_compact select * from innodb_normal; +insert into innodb_dynamic select * from innodb_normal; +insert into innodb_compressed select * from innodb_normal; +insert into innodb_redundant select * from innodb_normal; + +update innodb_normal set c1 = c1 + 1; +update innodb_compact set c1 = c1 + 1; +update innodb_dynamic set c1 = c1 + 1; +update innodb_compressed set c1 = c1 + 1; +update innodb_redundant set c1 = c1 + 1; +select count(*) from innodb_normal; +select count(*) from innodb_compact where c1 < 1500000; +select count(*) from innodb_dynamic where c1 < 1500000; +select count(*) from innodb_compressed where c1 < 1500000; +select count(*) from innodb_redundant where c1 < 1500000; +select count(*) from innodb_compact t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +select count(*) from innodb_dynamic t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +select count(*) from innodb_compressed t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +select count(*) from innodb_redundant t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; + +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_compressed'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_decompressed'; + +--source include/restart_mysqld.inc + +update innodb_normal set c1 = c1 + 1; +update innodb_compact set c1 = c1 + 1; +update innodb_dynamic set c1 = c1 + 1; +update innodb_compressed set c1 = c1 + 1; +update innodb_redundant set c1 = c1 + 1; +select count(*) from innodb_normal; +select count(*) from innodb_compact where c1 < 1500000; +select count(*) from innodb_dynamic where c1 < 1500000; +select count(*) from innodb_compressed where c1 < 1500000; +select count(*) from innodb_redundant where c1 < 1500000; +select count(*) from innodb_compact t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +select count(*) from innodb_dynamic t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +select count(*) from innodb_compressed t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; +select count(*) from innodb_redundant t1, innodb_normal t2 where +t1.c1 = t2.c1 and t1.b = t2.b; + +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_compressed'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_page_decompressed'; + +drop procedure innodb_insert_proc; +drop table innodb_normal; +drop table innodb_compact; +drop table innodb_dynamic; +drop table innodb_compressed; +drop table innodb_redundant; diff --git a/mysql-test/suite/encryption/t/innodb_first_page.opt b/mysql-test/suite/encryption/t/innodb_first_page.opt new file mode 100644 index 00000000..1a9099a6 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_first_page.opt @@ -0,0 +1,2 @@ +--innodb-encrypt-tables +--innodb-encrypt-log diff --git a/mysql-test/suite/encryption/t/innodb_first_page.test b/mysql-test/suite/encryption/t/innodb_first_page.test new file mode 100644 index 00000000..db4d8eb3 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_first_page.test @@ -0,0 +1,22 @@ +# +# MDEV-8021 "InnoDB: Tablespace id 4 encrypted but encryption service not available. Can't continue opening tablespace" on server restart when there are encrypted tables +# + +--source include/have_innodb.inc +--source include/have_file_key_management_plugin.inc +--source include/innodb_undo_tablespaces.inc + +let $datadir=`select @@datadir`; +--source include/shutdown_mysqld.inc + +--remove_file $datadir/ib_logfile0 +--remove_file $datadir/ibdata1 +--remove_files_wildcard $datadir undo* + +--source include/start_mysqld.inc + +create table t1 (a int); + +--source include/restart_mysqld.inc + +drop table t1; diff --git a/mysql-test/suite/encryption/t/innodb_import.combinations b/mysql-test/suite/encryption/t/innodb_import.combinations new file mode 100644 index 00000000..75458949 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_import.combinations @@ -0,0 +1,7 @@ +[page_compressed] +innodb-compression-default=1 +[encryption] +innodb-encrypt-tables=1 +[page_compressed_encryption] +innodb-compression-default=1 +innodb-encrypt-tables=1 diff --git a/mysql-test/suite/encryption/t/innodb_import.opt b/mysql-test/suite/encryption/t/innodb_import.opt new file mode 100644 index 00000000..c44c611e --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_import.opt @@ -0,0 +1 @@ +--innodb-checksum-algorithm=crc32 diff --git a/mysql-test/suite/encryption/t/innodb_import.test b/mysql-test/suite/encryption/t/innodb_import.test new file mode 100644 index 00000000..2e5470c5 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_import.test @@ -0,0 +1,23 @@ +--source include/have_innodb.inc +--source include/have_example_key_management_plugin.inc +--source include/innodb_checksum_algorithm.inc +--echo # +--echo # MDEV-26131 SEGV in ha_innobase::discard_or_import_tablespace +--echo # +let $MYSQLD_DATADIR = `SELECT @@datadir`; +CREATE TABLE t1(f1 int,f2 text)ENGINE=InnoDB; +INSERT INTO t1 VALUES(1, "InnoDB"); +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 ADD KEY idx (f2(13)); +ALTER TABLE t2 DISCARD TABLESPACE; +FLUSH TABLES t1 FOR EXPORT; +--copy_file $MYSQLD_DATADIR/test/t1.ibd $MYSQLD_DATADIR/test/t2.ibd +UNLOCK TABLES; +--error ER_INTERNAL_ERROR +ALTER TABLE t2 IMPORT TABLESPACE; + +ALTER TABLE t2 DROP KEY idx; +--replace_regex /opening '.*\/test\//opening '.\/test\// +ALTER TABLE t2 IMPORT TABLESPACE; +SELECT * FROM t2; +DROP TABLE t1, t2; diff --git a/mysql-test/suite/encryption/t/innodb_onlinealter_encryption.opt b/mysql-test/suite/encryption/t/innodb_onlinealter_encryption.opt new file mode 100644 index 00000000..38d69691 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_onlinealter_encryption.opt @@ -0,0 +1,5 @@ +--innodb-encrypt-tables=ON +--innodb-encrypt-log=ON +--innodb-encryption-rotate-key-age=15 +--innodb-encryption-threads=4 +--innodb-tablespaces-encryption diff --git a/mysql-test/suite/encryption/t/innodb_onlinealter_encryption.test b/mysql-test/suite/encryption/t/innodb_onlinealter_encryption.test new file mode 100644 index 00000000..9f61bf11 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_onlinealter_encryption.test @@ -0,0 +1,135 @@ +-- source include/have_innodb.inc +-- source include/have_file_key_management_plugin.inc +# test uses restart +-- source include/not_embedded.inc + +CREATE TABLE t1 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB encrypted=yes; +CREATE TABLE t2 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB; +CREATE TABLE t3 (id INT, a VARCHAR(255)) ENGINE=InnoDB encrypted=yes; +CREATE TABLE t4 (id INT, a VARCHAR(255)) engine=InnoDB; +CREATE TABLE t5 (id INT NOT NULL PRIMARY KEY, a TEXT(500), b VARCHAR(255), FULLTEXT(b)) ENGINE=InnoDB encrypted=yes; +CREATE TABLE t6 (id INT, a TEXT(500), b VARCHAR(255), FULLTEXT(b)) ENGINE=InnoDB; +CREATE TABLE t7 (id INT NOT NULL PRIMARY KEY, a VARCHAR(255)) ENGINE=InnoDB row_format=compressed encrypted=yes; + +delimiter //; +create procedure innodb_insert_proc (repeat_count int) +begin + declare current_num int; + set current_num = 0; + while current_num < repeat_count do + insert into t1 values (current_num,repeat('foobar',12)); + insert into t2 values (current_num,repeat('tempsecret', 12)); + insert into t3 values (current_num,repeat('barfoo',42)); + insert into t4 values (current_num,repeat('repeat',42)); + insert into t5 values (current_num,substring('A BC DEF GHIJ KLM NOPQRS TUV WXYZ 012 3456789', rand()*36+1, 100), repeat('author new',22)); + insert into t6 values (current_num,substring('A BC DEF GHIJ KLM NOPQRS TUV WXYZ 012 3456789', rand()*36+1, 100), repeat('mangled old',22)); + insert into t7 values (current_num,repeat('mysql',42)); + set current_num = current_num + 1; + end while; +end// +delimiter ;// +commit; + +set autocommit=0; +call innodb_insert_proc(1500); +commit; +set autocommit=1; + +--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 +--source include/wait_condition.inc +--let $MYSQLD_DATADIR=`select @@datadir` + +--source include/shutdown_mysqld.inc + +--let SEARCH_RANGE = 10000000 +--let SEARCH_PATTERN=foobar +--echo # t1 yes on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/test/t1.ibd +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=tempsecret +--echo # t2 ... on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/test/t2.ibd +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=barfoo +--echo # t3 ... on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/test/t3.ibd +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=repeat +--echo # t4 ... on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/test/t4.ibd +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=author +--echo # t5 ... on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/test/t5.ibd +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=mangled +--echo # t6 ... on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/test/t6.ibd +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=mysql +--echo # t7 ... on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/test/t7.ibd +-- source include/search_pattern_in_file.inc + +-- source include/start_mysqld.inc + +SET GLOBAL innodb_file_per_table = ON; + +ALTER TABLE t1 ADD COLUMN b int default 2; +ALTER TABLE t2 ADD COLUMN b int default 2; +ALTER TABLE t7 ADD COLUMN b int default 2; +ALTER TABLE t1 ADD KEY a(a), ADD KEY b(b); +ALTER TABLE t2 ADD KEY a(a), ADD KEY b(b); +ALTER TABLE t3 ADD COLUMN c int default 5; +ALTER TABLE t4 ADD COLUMN c int default 5; +ALTER TABLE t3 ADD KEY (a), ADD KEY c(c); +ALTER TABLE t4 ADD KEY (a), ADD KEY c(c); +ALTER TABLE t5 ADD FULLTEXT(a); +ALTER TABLE t6 ADD FULLTEXT(a); +ALTER TABLE t7 ADD KEY a(a), ADD key b(b); + +SHOW CREATE TABLE t1; +SHOW CREATE TABLE t2; +SHOW CREATE TABLE t3; +SHOW CREATE TABLE t4; +SHOW CREATE TABLE t5; +SHOW CREATE TABLE t6; +SHOW CREATE TABLE t7; + +--source include/shutdown_mysqld.inc + +--let SEARCH_PATTERN=foobar +--echo # t1 yes on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/test/t1.ibd +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=tempsecret +--echo # t2 ... on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/test/t2.ibd +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=barfoo +--echo # t3 ... on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/test/t3.ibd +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=repeat +--echo # t4 ... on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/test/t4.ibd +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=author +--echo # t5 ... on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/test/t5.ibd +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=mangled +--echo # t6 ... on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/test/t6.ibd +-- source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=mysql +--echo # t7 ... on expecting NOT FOUND +-- let SEARCH_FILE=$MYSQLD_DATADIR/test/t7.ibd +-- source include/search_pattern_in_file.inc + +-- source include/start_mysqld.inc + +DROP PROCEDURE innodb_insert_proc; +DROP TABLE t1, t2, t3, t4, t5, t6, t7; diff --git a/mysql-test/suite/encryption/t/innodb_page_encryption_key_change.test b/mysql-test/suite/encryption/t/innodb_page_encryption_key_change.test new file mode 100644 index 00000000..acba1f60 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb_page_encryption_key_change.test @@ -0,0 +1,77 @@ +-- source include/have_innodb.inc +-- source include/have_file_key_management_plugin.inc +# embedded does not support restart +-- source include/not_embedded.inc + +-- let $restart_parameters=--loose-file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt +-- source include/restart_mysqld.inc + +create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb; +show warnings; +create table innodb_compact(c1 bigint not null, b char(200)) engine=innodb row_format=compact encrypted=yes encryption_key_id=2; +show warnings; +create table innodb_compressed(c1 bigint not null, b char(200)) engine=innodb row_format=compressed encrypted=yes encryption_key_id=3; +show warnings; +create table innodb_dynamic(c1 bigint not null, b char(200)) engine=innodb row_format=dynamic encrypted=yes encryption_key_id=4; +show warnings; +create table innodb_redundant(c1 bigint not null, b char(200)) engine=innodb row_format=redundant encrypted=yes encryption_key_id=5; +show warnings; + +insert into innodb_normal values (1,'test1'),(2,'foo'),(3,'bar'),(4,'mariadb'); +insert into innodb_compact select * from innodb_normal; +insert into innodb_compressed select * from innodb_normal; +insert into innodb_dynamic select * from innodb_normal; +insert into innodb_redundant select * from innodb_normal; + +# Note there that these variables are updated only when real I/O is done, thus they are not reliable +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; + +alter table innodb_compact engine=innodb encryption_key_id = 6; +alter table innodb_compressed engine=innodb encryption_key_id = 6; +alter table innodb_dynamic engine=innodb encryption_key_id = 6; +alter table innodb_redundant engine=innodb encryption_key_id = 6; + +select * from innodb_normal; +select * from innodb_compact; +select * from innodb_compressed; +select * from innodb_dynamic; +select * from innodb_redundant; + +# Note there that these variables are updated only when real I/O is done, thus they are not reliable +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; + +-- let $restart_parameters=--loose-file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys3.txt +-- source include/restart_mysqld.inc + +select * from innodb_normal; +select * from innodb_compact; +select * from innodb_compressed; +select * from innodb_dynamic; +select * from innodb_redundant; + +# Note there that these variables are updated only when real I/O is done, thus they are not reliable +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; + +alter table innodb_compact engine=innodb encryption_key_id = 2; +alter table innodb_compressed engine=innodb encryption_key_id = 3; +alter table innodb_dynamic engine=innodb encryption_key_id = 4; +alter table innodb_redundant engine=innodb encryption_key_id = 5; + +select * from innodb_normal; +select * from innodb_compact; +select * from innodb_compressed; +select * from innodb_dynamic; +select * from innodb_redundant; + +# Note there that these variables are updated only when real I/O is done, thus they are not reliable +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_encrypted'; +SELECT variable_value >= 0 FROM information_schema.global_status WHERE variable_name = 'innodb_num_pages_decrypted'; + +drop table innodb_normal; +drop table innodb_compact; +drop table innodb_compressed; +drop table innodb_dynamic; +drop table innodb_redundant; diff --git a/mysql-test/suite/encryption/t/instant_alter_import.test b/mysql-test/suite/encryption/t/instant_alter_import.test new file mode 100644 index 00000000..3a00c546 --- /dev/null +++ b/mysql-test/suite/encryption/t/instant_alter_import.test @@ -0,0 +1,52 @@ +--source include/have_innodb.inc +--source include/have_sequence.inc +--source include/have_file_key_management_plugin.inc + +SET GLOBAL innodb_encrypt_tables = ON; +SET GLOBAL innodb_encryption_threads = 4; + + +--let $MYSQLD_DATADIR= `SELECT @@datadir` + +CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT, i2 INT, i1 INT) + ENGINE=INNODB ENCRYPTED=YES ENCRYPTION_KEY_ID=4; + +INSERT INTO t1 (i2) SELECT 4 FROM seq_1_to_1024; +ALTER TABLE t1 DROP COLUMN i2, ALGORITHM=INSTANT; + +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 DISCARD TABLESPACE; + +FLUSH TABLE t1 FOR EXPORT; + +--copy_file $MYSQLD_DATADIR/test/t1.ibd $MYSQLD_DATADIR/test/t2.ibd +--copy_file $MYSQLD_DATADIR/test/t1.cfg $MYSQLD_DATADIR/test/t2.cfg + +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; + +DROP TABLE t2, t1; + + +CREATE TABLE t1 (id INT PRIMARY KEY AUTO_INCREMENT, i2 INT, i1 INT) + ENGINE=INNODB ENCRYPTED=YES ENCRYPTION_KEY_ID=4 PAGE_COMPRESSED=1; + +INSERT INTO t1 (i2) SELECT 4 FROM seq_1_to_1024; +ALTER TABLE t1 DROP COLUMN i2, ALGORITHM=INSTANT; + +CREATE TABLE t2 LIKE t1; +ALTER TABLE t2 DISCARD TABLESPACE; + +FLUSH TABLE t1 FOR EXPORT; + +--copy_file $MYSQLD_DATADIR/test/t1.ibd $MYSQLD_DATADIR/test/t2.ibd +--copy_file $MYSQLD_DATADIR/test/t1.cfg $MYSQLD_DATADIR/test/t2.cfg + +UNLOCK TABLES; +ALTER TABLE t2 IMPORT TABLESPACE; + +DROP TABLE t2, t1; + + +SET GLOBAL innodb_encrypt_tables = OFF; +SET GLOBAL innodb_encryption_threads = 0; diff --git a/mysql-test/suite/encryption/t/key_version_rotation.opt b/mysql-test/suite/encryption/t/key_version_rotation.opt new file mode 100644 index 00000000..d7933f0f --- /dev/null +++ b/mysql-test/suite/encryption/t/key_version_rotation.opt @@ -0,0 +1,2 @@ +--innodb-tablespaces-encryption +--plugin-load-add=$DEBUG_KEY_MANAGEMENT_SO diff --git a/mysql-test/suite/encryption/t/key_version_rotation.test b/mysql-test/suite/encryption/t/key_version_rotation.test new file mode 100644 index 00000000..d36d4725 --- /dev/null +++ b/mysql-test/suite/encryption/t/key_version_rotation.test @@ -0,0 +1,41 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_sequence.inc + +create table t1(f1 int not null)engine=innodb; +create table t2(f1 int not null)engine=innodb; +insert into t1 select * from seq_1_to_100; +insert into t2 select * from seq_1_to_100; + +let $restart_parameters=--innodb_encrypt_tables=0 --innodb_encryption_threads=1 --innodb_encryption_rotate_key_age=9; +--source include/restart_mysqld.inc + +--echo # Enable encryption + +set global innodb_encrypt_tables=ON; +--let $tables_count= `select count(*) from information_schema.tables where engine = 'InnoDB'` +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc +--echo # Create a new table and it is added to rotation list +create table t3(f1 int not null)engine=innodb; +insert into t3 select * from seq_1_to_100; + +--echo # Increase the version and it should set rotation +--echo # variable for the encryption plugin + +set global debug_key_management_version=10; +select @@debug_key_management_version; +--let $tables_count= `select count(*) from information_schema.tables where engine = 'InnoDB'` +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc + +--echo # Decrease the key version and Disable the encryption +set global debug_key_management_version=1; +set global innodb_encrypt_tables=off; + +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) >= $tables_count FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +--source include/wait_condition.inc +DROP TABLE t1, t2, t3; diff --git a/mysql-test/suite/encryption/t/second_plugin-12863.test b/mysql-test/suite/encryption/t/second_plugin-12863.test new file mode 100644 index 00000000..c04fccf9 --- /dev/null +++ b/mysql-test/suite/encryption/t/second_plugin-12863.test @@ -0,0 +1,16 @@ +# +# MDEV-12863 No table can be created after second encryption plugin attempted to load +# +--source include/have_innodb.inc +--source include/have_file_key_management_plugin.inc + +call mtr.add_suppression('debug.key.management'); + +--error 1123 +install soname 'debug_key_management'; + +create table t1 (a varchar(255)) engine=innodb encrypted=yes; +create table t2 (a varchar(255)) engine=innodb; +create table t3 (a varchar(255)) engine=innodb encrypted=no; + +drop table t1, t2, t3; diff --git a/mysql-test/suite/encryption/t/tempfiles.combinations b/mysql-test/suite/encryption/t/tempfiles.combinations new file mode 100644 index 00000000..7010d2c1 --- /dev/null +++ b/mysql-test/suite/encryption/t/tempfiles.combinations @@ -0,0 +1,5 @@ +[none] +binlog-checksum=NONE + +[crc32] +binlog-checksum=CRC32 diff --git a/mysql-test/suite/encryption/t/tempfiles.opt b/mysql-test/suite/encryption/t/tempfiles.opt new file mode 100644 index 00000000..2b90f474 --- /dev/null +++ b/mysql-test/suite/encryption/t/tempfiles.opt @@ -0,0 +1 @@ +--encrypt-tmp-files diff --git a/mysql-test/suite/encryption/t/tempfiles.test b/mysql-test/suite/encryption/t/tempfiles.test new file mode 100644 index 00000000..74d03f5a --- /dev/null +++ b/mysql-test/suite/encryption/t/tempfiles.test @@ -0,0 +1,85 @@ +# +# Various test cases for IO_CACHE tempfiles (file==-1) encryption +# +source include/have_file_key_management_plugin.inc; +source include/have_sequence.inc; + +# Row binlog format to fill binlog cache faster +source include/have_binlog_format_row.inc; + +source include/have_innodb.inc; + +select @@encrypt_tmp_files; + +# +# MyISAM messing around with IO_CACHE::file +# +CREATE TABLE t1(a INT); +INSERT INTO t1 VALUES(1),(2); +DELETE FROM t1 WHERE a=1; +OPTIMIZE TABLE t1; +CHECK TABLE t1; +DROP TABLE t1; + +# +# filesort, my_b_pread, seeks in READ_CACHE +# +create table t1 (v varchar(10), c char(10), t text, key(v), key(c), key(t(10))); +insert into t1 (v) select concat(char(ascii('a')+s2.seq),repeat(' ',s1.seq)) + from seq_0_to_9 as s1, seq_0_to_26 as s2; +update t1 set c=v, t=v; +select sql_big_result t,count(t) from t1 group by t limit 10; +drop table t1; + +reset master; +set @save_binlog_cache_size=@@global.binlog_cache_size; +set global binlog_cache_size=8192; + +connect con1, localhost, root; + +# +# Test the last half-filled block: +# first write 3 blocks, then reinit the file and write one full and one +# partial block. reading the second time must stop in the middle of the +# second block, and NOT read till EOF. +# +create table t1 (a text) engine=innodb; +start transaction; +insert t1 select repeat(seq, 1000) from seq_1_to_15; +commit; +start transaction; +insert t1 select repeat(seq, 1000) from seq_1_to_8; +commit; + +disconnect con1; +connect con2, localhost, root; + +# +# Test reinit_io_cache(WRITE_CACHE) with non-zero seek_offset: +# Start a transaction, write until the cache goes to disk, +# create a savepoint, write more blocks to disk, rollback to savepoint. +# +create table t2 (a text) engine=innodb; +start transaction; +insert t2 select repeat(seq, 1000) from seq_1_to_15; +savepoint foo; +insert t2 select repeat(seq, 1000) from seq_16_to_30; +rollback to savepoint foo; +insert t2 select repeat(seq, 1000) from seq_31_to_40; +commit; + +disconnect con2; +connection default; + +flush binary logs; + +drop table t1, t2; + +set @@global.binlog_cache_size=@save_binlog_cache_size; + +let $MYSQLD_DATADIR= `select @@datadir`; +exec $MYSQL_BINLOG $MYSQLD_DATADIR/master-bin.000001 | $MYSQL; + +select left(a, 10) from t1; +select left(a, 10) from t2; +drop table t1, t2; diff --git a/mysql-test/suite/encryption/t/tempfiles_encrypted.opt b/mysql-test/suite/encryption/t/tempfiles_encrypted.opt new file mode 100644 index 00000000..81877a8d --- /dev/null +++ b/mysql-test/suite/encryption/t/tempfiles_encrypted.opt @@ -0,0 +1 @@ +--encrypt-tmp_files=ON diff --git a/mysql-test/suite/encryption/t/tempfiles_encrypted.test b/mysql-test/suite/encryption/t/tempfiles_encrypted.test new file mode 100644 index 00000000..7628442f --- /dev/null +++ b/mysql-test/suite/encryption/t/tempfiles_encrypted.test @@ -0,0 +1,47 @@ +--echo # +--echo # Tests when the temporary files are encrypted +--echo # + +source include/have_file_key_management_plugin.inc; +source include/have_sequence.inc; +source include/have_innodb.inc; + +select @@encrypt_tmp_files; + +--source main/win.test + +--echo # +--echo # MDEV-23867: select crash in compute_window_func +--echo # + +set @save_sort_buffer_size=@@sort_buffer_size; + +set sort_buffer_size= 2000; +CREATE TABLE t1( a INT, b INT, c INT); +INSERT INTO t1 select seq, seq, seq from seq_1_to_5000; +CREATE TABLE t2( a INT, b INT, c INT); +INSERT INTO t2 SELECT a, b, ROW_NUMBER() OVER (PARTITION BY b) FROM t1; +SELECT COUNT(*), MAX(c) FROM t2; +CREATE TABLE t3( a INT, b INT, c INT); +INSERT INTO t3 SELECT a, b, SUM(a) OVER () FROM t1; +SELECT COUNT(*), MAX(c) FROM t3; +set @@sort_buffer_size=@save_sort_buffer_size; +DROP TABLE t1,t2,t3; + +--echo # end of 10.2 test + +--echo # +--echo # MDEV-22556: Incorrect result for window function when using encrypt-tmp-files=ON +--echo # + +set @save_sort_buffer_size=@@sort_buffer_size; +set sort_buffer_size= 2000; +create table t1( a DECIMAL(12,0) DEFAULT NULL, b VARCHAR(20) DEFAULT NULL, c DECIMAL(12,0) DEFAULT NULL)engine=INNODB; +insert into t1 select seq, seq, seq from seq_1_to_5000; +select count(*) from (select a, b, c, ROW_NUMBER() OVER (PARTITION BY a) FROM t1)q; + +set @@sort_buffer_size=@save_sort_buffer_size; + +drop table t1; + +--echo # End of 10.4 tests |