summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-02-28 23:11:15 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2019-02-28 23:20:31 +0200
commite39d6e0c53bccaf0c6b2a0341f8deb420f5e79be (patch)
treea9b1664661e3164f80b8f1d2737751684b7c2aef
parent622e9e8a7a5e9babe1dd41e7499c20f396b6ebdf (diff)
downloadmariadb-git-e39d6e0c53bccaf0c6b2a0341f8deb420f5e79be.tar.gz
MDEV-18601 Can't create table with ENCRYPTED=DEFAULT when innodb_default_encryption_key_id!=1
The problem with the InnoDB table attribute encryption_key_id is that it is not being persisted anywhere in InnoDB except if the table attribute encryption is specified and is something else than encryption=default. MDEV-17320 made it a hard error if encryption_key_id is specified to be anything else than 1 in that case. Ideally, we would always persist encryption_key_id in InnoDB. But, then we would have to be prepared for the case that when encryption is being enabled for a table whose encryption_key_id attribute refers to a non-existing key. In MariaDB Server 10.1, our best option remains to not store anything inside InnoDB. But, instead of returning the error that MDEV-17320 introduced, we should merely issue a warning that the specified encryption_key_id is going to be ignored if encryption=default. To improve the situation a little more, we will issue a warning if SET [GLOBAL|SESSION] innodb_default_encryption_key_id is being set to something that does not refer to an available encryption key. Starting with MariaDB Server 10.2, thanks to MDEV-5800, we could open the table definition from InnoDB side when the encryption is being enabled, and actually fix the root cause of what was reported in MDEV-17320.
-rw-r--r--mysql-test/suite/encryption/r/innodb-checksum-algorithm,32k.rdiff18
-rw-r--r--mysql-test/suite/encryption/r/innodb-checksum-algorithm,64k.rdiff18
-rw-r--r--mysql-test/suite/encryption/r/innodb-checksum-algorithm.result18
-rw-r--r--mysql-test/suite/encryption/r/innodb-compressed-blob.result2
-rw-r--r--mysql-test/suite/encryption/r/innodb-encryption-alter.result35
-rw-r--r--mysql-test/suite/encryption/t/innodb-encryption-alter.test14
-rw-r--r--storage/innobase/handler/ha_innodb.cc120
-rw-r--r--storage/xtradb/handler/ha_innodb.cc119
8 files changed, 182 insertions, 162 deletions
diff --git a/mysql-test/suite/encryption/r/innodb-checksum-algorithm,32k.rdiff b/mysql-test/suite/encryption/r/innodb-checksum-algorithm,32k.rdiff
index cd66df7440b..d963cde132a 100644
--- a/mysql-test/suite/encryption/r/innodb-checksum-algorithm,32k.rdiff
+++ b/mysql-test/suite/encryption/r/innodb-checksum-algorithm,32k.rdiff
@@ -1,5 +1,5 @@
--- suite/encryption/r/innodb-checksum-algorithm.result
-+++ suite/encryption/r/innodb-checksum-algorithm,32k.reject
++++ suite/encryption/r/innodb-checksum-algorithm.result
@@ -13,9 +13,9 @@
SET GLOBAL innodb_default_encryption_key_id=4;
SET GLOBAL innodb_checksum_algorithm=crc32;
@@ -9,10 +9,10 @@
create table tc_crc32(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_crc32(a serial, b blob, index(b(10))) engine=innodb
- encrypted=yes;
- create table t_crc32(a serial, b blob, index(b(10))) engine=innodb
-@@ -222,9 +222,9 @@
+@@ -153,9 +153,9 @@
t_crc32, tpe_crc32, tp_crc32;
SET GLOBAL innodb_checksum_algorithm=innodb;
create table tce_innodb(a serial, b blob, index(b(10))) engine=innodb
@@ -21,10 +21,10 @@
create table tc_innodb(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_innodb(a serial, b blob, index(b(10))) engine=innodb
- encrypted=yes;
- create table t_innodb(a serial, b blob, index(b(10))) engine=innodb
-@@ -431,9 +431,9 @@
+@@ -293,9 +293,9 @@
t_innodb, tpe_innodb, tp_innodb;
SET GLOBAL innodb_checksum_algorithm=none;
create table tce_none(a serial, b blob, index(b(10))) engine=innodb
@@ -33,6 +33,6 @@
create table tc_none(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_none(a serial, b blob, index(b(10))) engine=innodb
- encrypted=yes;
- create table t_none(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
index 523074297da..d963cde132a 100644
--- a/mysql-test/suite/encryption/r/innodb-checksum-algorithm,64k.rdiff
+++ b/mysql-test/suite/encryption/r/innodb-checksum-algorithm,64k.rdiff
@@ -1,5 +1,5 @@
--- suite/encryption/r/innodb-checksum-algorithm.result
-+++ suite/encryption/r/innodb-checksum-algorithm,64k.reject
++++ suite/encryption/r/innodb-checksum-algorithm.result
@@ -13,9 +13,9 @@
SET GLOBAL innodb_default_encryption_key_id=4;
SET GLOBAL innodb_checksum_algorithm=crc32;
@@ -9,10 +9,10 @@
create table tc_crc32(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_crc32(a serial, b blob, index(b(10))) engine=innodb
- encrypted=yes;
- create table t_crc32(a serial, b blob, index(b(10))) engine=innodb
-@@ -222,9 +222,9 @@
+@@ -153,9 +153,9 @@
t_crc32, tpe_crc32, tp_crc32;
SET GLOBAL innodb_checksum_algorithm=innodb;
create table tce_innodb(a serial, b blob, index(b(10))) engine=innodb
@@ -21,10 +21,10 @@
create table tc_innodb(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_innodb(a serial, b blob, index(b(10))) engine=innodb
- encrypted=yes;
- create table t_innodb(a serial, b blob, index(b(10))) engine=innodb
-@@ -431,9 +431,9 @@
+@@ -293,9 +293,9 @@
t_innodb, tpe_innodb, tp_innodb;
SET GLOBAL innodb_checksum_algorithm=none;
create table tce_none(a serial, b blob, index(b(10))) engine=innodb
@@ -33,6 +33,6 @@
create table tc_none(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_none(a serial, b blob, index(b(10))) engine=innodb
- encrypted=yes;
- create table t_none(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
index 7fdea4b67b5..6fa2e7c594f 100644
--- a/mysql-test/suite/encryption/r/innodb-checksum-algorithm.result
+++ b/mysql-test/suite/encryption/r/innodb-checksum-algorithm.result
@@ -16,14 +16,20 @@ create table tce_crc32(a serial, b blob, index(b(10))) engine=innodb
ROW_FORMAT=COMPRESSED encrypted=yes;
create table tc_crc32(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_crc32(a serial, b blob, index(b(10))) engine=innodb
encrypted=yes;
create table t_crc32(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_crc32(a serial, b blob, index(b(10))) engine=innodb
page_compressed=yes encrypted=yes;
create table tp_crc32(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_crc32(b) values (repeat('secret',20));
insert into tc_crc32(b) values (repeat('secret',20));
@@ -150,14 +156,20 @@ create table tce_innodb(a serial, b blob, index(b(10))) engine=innodb
ROW_FORMAT=COMPRESSED encrypted=yes;
create table tc_innodb(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_innodb(a serial, b blob, index(b(10))) engine=innodb
encrypted=yes;
create table t_innodb(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_innodb(a serial, b blob, index(b(10))) engine=innodb
page_compressed=yes encrypted=yes;
create table tp_innodb(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_innodb(b) values (repeat('secret',20));
insert into tc_innodb(b) values (repeat('secret',20));
@@ -284,14 +296,20 @@ create table tce_none(a serial, b blob, index(b(10))) engine=innodb
ROW_FORMAT=COMPRESSED encrypted=yes;
create table tc_none(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_none(a serial, b blob, index(b(10))) engine=innodb
encrypted=yes;
create table t_none(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_none(a serial, b blob, index(b(10))) engine=innodb
page_compressed=yes encrypted=yes;
create table tp_none(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_none(b) values (repeat('secret',20));
insert into tc_none(b) values (repeat('secret',20));
diff --git a/mysql-test/suite/encryption/r/innodb-compressed-blob.result b/mysql-test/suite/encryption/r/innodb-compressed-blob.result
index ce73b80820f..4187877be49 100644
--- a/mysql-test/suite/encryption/r/innodb-compressed-blob.result
+++ b/mysql-test/suite/encryption/r/innodb-compressed-blob.result
@@ -7,6 +7,8 @@ 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));
diff --git a/mysql-test/suite/encryption/r/innodb-encryption-alter.result b/mysql-test/suite/encryption/r/innodb-encryption-alter.result
index 5245d1da7d0..b2f33b2b24d 100644
--- a/mysql-test/suite/encryption/r/innodb-encryption-alter.result
+++ b/mysql-test/suite/encryption/r/innodb-encryption-alter.result
@@ -4,9 +4,16 @@ 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: Ignored ENCRYPTION_KEY_ID 4 when encryption is disabled
+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;
@@ -40,8 +47,6 @@ t1 CREATE TABLE `t1` (
PRIMARY KEY (`pk`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 `ENCRYPTION_KEY_ID`=4
CREATE TABLE t2 (pk INT PRIMARY KEY AUTO_INCREMENT, c VARCHAR(256)) ENGINE=INNODB ENCRYPTED=NO ENCRYPTION_KEY_ID=1;
-Warnings:
-Warning 140 InnoDB: Ignored ENCRYPTION_KEY_ID 1 when encryption is disabled
ALTER TABLE t1 ENCRYPTION_KEY_ID=99;
ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTION_KEY_ID'
SHOW WARNINGS;
@@ -53,37 +58,29 @@ 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;
-ERROR HY000: Table storage engine 'InnoDB' does not support the create option 'ENCRYPTION_KEY_ID'
-SHOW WARNINGS;
-Level Code Message
-Warning 140 InnoDB: innodb_encrypt_tables=OFF only allows ENCRYPTION_KEY_ID=1
-Error 1478 Table storage engine 'InnoDB' does not support the create option 'ENCRYPTION_KEY_ID'
SHOW CREATE TABLE t1;
Table Create Table
t1 CREATE TABLE `t1` (
`a` int(11) NOT NULL,
PRIMARY KEY (`a`)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 `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;
-ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options")
-SHOW WARNINGS;
-Level Code Message
-Warning 140 InnoDB: innodb_encrypt_tables=OFF only allows ENCRYPTION_KEY_ID=1
-Error 1005 Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options")
-Warning 1030 Got error 140 "Wrong create options" from storage engine InnoDB
SHOW CREATE TABLE t2;
Table Create Table
t2 CREATE TABLE `t2` (
`a` int(11) NOT NULL,
PRIMARY KEY (`a`)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1
+) ENGINE=InnoDB DEFAULT CHARSET=latin1 `ENCRYPTION_KEY_ID`=4
DROP TABLE t2;
CREATE TABLE t3 (a int not null primary key) engine=innodb ENCRYPTION_KEY_ID=4;
-ERROR HY000: Can't create table `test`.`t3` (errno: 140 "Wrong create options")
+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: innodb_encrypt_tables=OFF only allows ENCRYPTION_KEY_ID=1
-Error 1005 Can't create table `test`.`t3` (errno: 140 "Wrong create options")
+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
diff --git a/mysql-test/suite/encryption/t/innodb-encryption-alter.test b/mysql-test/suite/encryption/t/innodb-encryption-alter.test
index 9465226dd96..711beeef1e1 100644
--- a/mysql-test/suite/encryption/t/innodb-encryption-alter.test
+++ b/mysql-test/suite/encryption/t/innodb-encryption-alter.test
@@ -19,7 +19,10 @@ 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;
@@ -90,25 +93,26 @@ 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;
---error ER_ILLEGAL_HA_CREATE_OPTION
ALTER TABLE t1 ENCRYPTION_KEY_ID=4;
-SHOW WARNINGS;
SHOW CREATE TABLE t1;
DROP TABLE t1;
CREATE TABLE t2 (a int not null primary key) engine=innodb;
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
---error ER_CANT_CREATE_TABLE
ALTER TABLE t2 ENCRYPTION_KEY_ID=4, ALGORITHM=COPY;
--replace_regex /#sql-[0-9a-f_]*`/#sql-temporary`/
-SHOW WARNINGS;
SHOW CREATE TABLE t2;
DROP TABLE t2;
---error ER_CANT_CREATE_TABLE
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;
# reset system
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 80ff2e02e13..c670839b5cd 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -4,7 +4,7 @@ Copyright (c) 2000, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2018, MariaDB Corporation.
+Copyright (c) 2013, 2019, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -686,9 +686,25 @@ static int mysql_tmpfile_path(const char *path, const char *prefix)
static void innodb_remember_check_sysvar_funcs();
mysql_var_check_func check_sysvar_enum;
+/** Update callback for SET [SESSION] innodb_default_encryption_key_id */
+static void
+innodb_default_encryption_key_id_update(THD* thd, st_mysql_sys_var* var,
+ void* var_ptr, const void *save)
+{
+ uint key_id = *static_cast<const uint*>(save);
+ if (key_id != FIL_DEFAULT_ENCRYPTION_KEY
+ && !encryption_key_id_exists(key_id)) {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_WRONG_ARGUMENTS,
+ "innodb_default_encryption_key=%u"
+ " is not available", key_id);
+ }
+ *static_cast<uint*>(var_ptr) = key_id;
+}
+
static MYSQL_THDVAR_UINT(default_encryption_key_id, PLUGIN_VAR_RQCMDARG,
"Default encryption key id used for table encryption.",
- NULL, NULL,
+ NULL, innodb_default_encryption_key_id_update,
FIL_DEFAULT_ENCRYPTION_KEY, 1, UINT_MAX32, 0);
/**
@@ -10862,8 +10878,7 @@ create_table_def(
const char* remote_path, /*!< in: Remote path or zero length-string */
ulint flags, /*!< in: table flags */
ulint flags2, /*!< in: table flags2 */
- fil_encryption_t mode, /*!< in: encryption mode */
- ulint key_id) /*!< in: encryption key_id */
+ const ha_table_option_struct*options)
{
THD* thd = trx->mysql_thd;
dict_table_t* table;
@@ -11053,7 +11068,9 @@ err_col:
fts_add_doc_id_column(table, heap);
}
- err = row_create_table_for_mysql(table, trx, false, mode, key_id);
+ err = row_create_table_for_mysql(table, trx, false,
+ fil_encryption_t(options->encryption),
+ options->encryption_key_id);
mem_heap_free(heap);
@@ -11887,21 +11904,47 @@ ha_innobase::check_table_options(
enum row_type row_format = table->s->row_type;
ha_table_option_struct *options= table->s->option_struct;
atomic_writes_t awrites = (atomic_writes_t)options->atomic_writes;
- fil_encryption_t encrypt = (fil_encryption_t)options->encryption;
- if (encrypt != FIL_ENCRYPTION_DEFAULT && !use_tablespace) {
+ switch (options->encryption) {
+ case FIL_ENCRYPTION_OFF:
+ if (options->encryption_key_id != FIL_DEFAULT_ENCRYPTION_KEY) {
+ push_warning(
+ thd, Sql_condition::WARN_LEVEL_WARN,
+ HA_WRONG_CREATE_OPTION,
+ "InnoDB: ENCRYPTED=NO implies"
+ " ENCRYPTION_KEY_ID=1");
+ compile_time_assert(FIL_DEFAULT_ENCRYPTION_KEY == 1);
+ }
+ if (srv_encrypt_tables != 2) {
+ break;
+ }
push_warning(
thd, Sql_condition::WARN_LEVEL_WARN,
HA_WRONG_CREATE_OPTION,
- "InnoDB: ENCRYPTED requires innodb_file_per_table");
+ "InnoDB: ENCRYPTED=NO cannot be used with"
+ " innodb_encrypt_tables=FORCE");
return "ENCRYPTED";
- }
+ case FIL_ENCRYPTION_DEFAULT:
+ if (!srv_encrypt_tables) {
+ break;
+ }
+ /* fall through */
+ case FIL_ENCRYPTION_ON:
+ if (!encryption_key_id_exists(options->encryption_key_id)) {
+ push_warning_printf(
+ thd, Sql_condition::WARN_LEVEL_WARN,
+ HA_WRONG_CREATE_OPTION,
+ "InnoDB: ENCRYPTION_KEY_ID %u not available",
+ options->encryption_key_id);
+ return "ENCRYPTION_KEY_ID";
+ }
+ }
- if (encrypt == FIL_ENCRYPTION_OFF && srv_encrypt_tables == 2) {
- push_warning(
- thd, Sql_condition::WARN_LEVEL_WARN,
- HA_WRONG_CREATE_OPTION,
- "InnoDB: ENCRYPTED=OFF cannot be used when innodb_encrypt_tables=FORCE");
+ if (!use_tablespace && options->encryption != FIL_ENCRYPTION_DEFAULT) {
+ push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
+ HA_WRONG_CREATE_OPTION,
+ "InnoDB: ENCRYPTED requires"
+ " innodb_file_per_table");
return "ENCRYPTED";
}
@@ -11977,46 +12020,6 @@ ha_innobase::check_table_options(
}
}
- /* If encryption is set up make sure that used key_id is found */
- if (encrypt == FIL_ENCRYPTION_ON ||
- (encrypt == FIL_ENCRYPTION_DEFAULT && srv_encrypt_tables)) {
- if (!encryption_key_id_exists((unsigned int)options->encryption_key_id)) {
- push_warning_printf(
- thd, Sql_condition::WARN_LEVEL_WARN,
- HA_WRONG_CREATE_OPTION,
- "InnoDB: ENCRYPTION_KEY_ID %u not available",
- (uint)options->encryption_key_id
- );
- return "ENCRYPTION_KEY_ID";
- }
- }
-
- /* Ignore nondefault key_id if encryption is set off */
- if (encrypt == FIL_ENCRYPTION_OFF &&
- options->encryption_key_id != THDVAR(thd, default_encryption_key_id)) {
- push_warning_printf(
- thd, Sql_condition::WARN_LEVEL_WARN,
- HA_WRONG_CREATE_OPTION,
- "InnoDB: Ignored ENCRYPTION_KEY_ID %u when encryption is disabled",
- (uint)options->encryption_key_id
- );
- options->encryption_key_id = FIL_DEFAULT_ENCRYPTION_KEY;
- }
-
- /* If default encryption is used and encryption is disabled, you may
- not use nondefault encryption_key_id as it is not stored anywhere. */
- if (encrypt == FIL_ENCRYPTION_DEFAULT
- && !srv_encrypt_tables
- && options->encryption_key_id != FIL_DEFAULT_ENCRYPTION_KEY) {
- compile_time_assert(FIL_DEFAULT_ENCRYPTION_KEY == 1);
- push_warning_printf(
- thd, Sql_condition::WARN_LEVEL_WARN,
- HA_WRONG_CREATE_OPTION,
- "InnoDB: innodb_encrypt_tables=OFF only allows ENCRYPTION_KEY_ID=1"
- );
- return "ENCRYPTION_KEY_ID";
- }
-
/* Check atomic writes requirements */
if (awrites == ATOMIC_WRITES_ON ||
(awrites == ATOMIC_WRITES_DEFAULT && srv_use_atomic_writes)) {
@@ -12074,10 +12077,6 @@ ha_innobase::create(
const char* stmt;
size_t stmt_len;
- /* Cache table options */
- ha_table_option_struct *options= form->s->option_struct;
- fil_encryption_t encrypt = (fil_encryption_t)options->encryption;
- uint key_id = (uint)options->encryption_key_id;
DBUG_ENTER("ha_innobase::create");
@@ -12100,7 +12099,7 @@ ha_innobase::create(
/* Validate create options if innodb_strict_mode is set. */
if (create_options_are_invalid(
- thd, form, create_info, use_tablespace)) {
+ thd, form, create_info, use_tablespace)) {
DBUG_RETURN(HA_WRONG_CREATE_OPTION);
}
@@ -12170,7 +12169,8 @@ ha_innobase::create(
row_mysql_lock_data_dictionary(trx);
error = create_table_def(trx, form, norm_name, temp_path,
- remote_path, flags, flags2, encrypt, key_id);
+ remote_path, flags, flags2,
+ form->s->option_struct);
if (error) {
goto cleanup;
}
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 4ed9f644b45..d943a87ab78 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -5,7 +5,7 @@ Copyright (c) 2013, 2018, MariaDB Corporation.
Copyright (c) 2008, 2009 Google Inc.
Copyright (c) 2009, Percona Inc.
Copyright (c) 2012, Facebook Inc.
-Copyright (c) 2013, 2018, MariaDB Corporation.
+Copyright (c) 2013, 2019, MariaDB Corporation.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -687,9 +687,25 @@ ib_cb_t innodb_api_cb[] = {
static void innodb_remember_check_sysvar_funcs();
mysql_var_check_func check_sysvar_enum;
+/** Update callback for SET [SESSION] innodb_default_encryption_key_id */
+static void
+innodb_default_encryption_key_id_update(THD* thd, st_mysql_sys_var* var,
+ void* var_ptr, const void *save)
+{
+ uint key_id = *static_cast<const uint*>(save);
+ if (key_id != FIL_DEFAULT_ENCRYPTION_KEY
+ && !encryption_key_id_exists(key_id)) {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ ER_WRONG_ARGUMENTS,
+ "innodb_default_encryption_key=%u"
+ " is not available", key_id);
+ }
+ *static_cast<uint*>(var_ptr) = key_id;
+}
+
static MYSQL_THDVAR_UINT(default_encryption_key_id, PLUGIN_VAR_RQCMDARG,
"Default encryption key id used for table encryption.",
- NULL, NULL,
+ NULL, innodb_default_encryption_key_id_update,
FIL_DEFAULT_ENCRYPTION_KEY, 1, UINT_MAX32, 0);
/**
@@ -11430,8 +11446,7 @@ create_table_def(
const char* remote_path, /*!< in: Remote path or zero length-string */
ulint flags, /*!< in: table flags */
ulint flags2, /*!< in: table flags2 */
- fil_encryption_t mode, /*!< in: encryption mode */
- ulint key_id) /*!< in: encryption key_id */
+ const ha_table_option_struct*options)
{
THD* thd = trx->mysql_thd;
dict_table_t* table;
@@ -11622,7 +11637,9 @@ err_col:
fts_add_doc_id_column(table, heap);
}
- err = row_create_table_for_mysql(table, trx, false, mode, key_id);
+ err = row_create_table_for_mysql(table, trx, false,
+ fil_encryption_t(options->encryption),
+ options->encryption_key_id);
mem_heap_free(heap);
@@ -12453,21 +12470,47 @@ ha_innobase::check_table_options(
enum row_type row_format = table->s->row_type;
ha_table_option_struct *options= table->s->option_struct;
atomic_writes_t awrites = (atomic_writes_t)options->atomic_writes;
- fil_encryption_t encrypt = (fil_encryption_t)options->encryption;
- if (encrypt != FIL_ENCRYPTION_DEFAULT && !use_tablespace) {
+ switch (options->encryption) {
+ case FIL_ENCRYPTION_OFF:
+ if (options->encryption_key_id != FIL_DEFAULT_ENCRYPTION_KEY) {
+ push_warning(
+ thd, Sql_condition::WARN_LEVEL_WARN,
+ HA_WRONG_CREATE_OPTION,
+ "InnoDB: ENCRYPTED=NO implies"
+ " ENCRYPTION_KEY_ID=1");
+ compile_time_assert(FIL_DEFAULT_ENCRYPTION_KEY == 1);
+ }
+ if (srv_encrypt_tables != 2) {
+ break;
+ }
push_warning(
thd, Sql_condition::WARN_LEVEL_WARN,
HA_WRONG_CREATE_OPTION,
- "InnoDB: ENCRYPTED requires innodb_file_per_table");
+ "InnoDB: ENCRYPTED=NO cannot be used with"
+ " innodb_encrypt_tables=FORCE");
return "ENCRYPTED";
+ case FIL_ENCRYPTION_DEFAULT:
+ if (!srv_encrypt_tables) {
+ break;
+ }
+ /* fall through */
+ case FIL_ENCRYPTION_ON:
+ if (!encryption_key_id_exists(options->encryption_key_id)) {
+ push_warning_printf(
+ thd, Sql_condition::WARN_LEVEL_WARN,
+ HA_WRONG_CREATE_OPTION,
+ "InnoDB: ENCRYPTION_KEY_ID %u not available",
+ options->encryption_key_id);
+ return "ENCRYPTION_KEY_ID";
+ }
}
- if (encrypt == FIL_ENCRYPTION_OFF && srv_encrypt_tables == 2) {
- push_warning(
- thd, Sql_condition::WARN_LEVEL_WARN,
- HA_WRONG_CREATE_OPTION,
- "InnoDB: ENCRYPTED=OFF cannot be used when innodb_encrypt_tables=FORCE");
+ if (!use_tablespace && options->encryption != FIL_ENCRYPTION_DEFAULT) {
+ push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
+ HA_WRONG_CREATE_OPTION,
+ "InnoDB: ENCRYPTED requires"
+ " innodb_file_per_table");
return "ENCRYPTED";
}
@@ -12543,47 +12586,6 @@ ha_innobase::check_table_options(
}
}
- /* If encryption is set up make sure that used key_id is found */
- if (encrypt == FIL_ENCRYPTION_ON ||
- (encrypt == FIL_ENCRYPTION_DEFAULT && srv_encrypt_tables)) {
- if (!encryption_key_id_exists((unsigned int)options->encryption_key_id)) {
- push_warning_printf(
- thd, Sql_condition::WARN_LEVEL_WARN,
- HA_WRONG_CREATE_OPTION,
- "InnoDB: ENCRYPTION_KEY_ID %u not available",
- (uint)options->encryption_key_id
- );
- return "ENCRYPTION_KEY_ID";
-
- }
- }
-
- /* Ignore nondefault key_id if encryption is set off */
- if (encrypt == FIL_ENCRYPTION_OFF &&
- options->encryption_key_id != THDVAR(thd, default_encryption_key_id)) {
- push_warning_printf(
- thd, Sql_condition::WARN_LEVEL_WARN,
- HA_WRONG_CREATE_OPTION,
- "InnoDB: Ignored ENCRYPTION_KEY_ID %u when encryption is disabled",
- (uint)options->encryption_key_id
- );
- options->encryption_key_id = FIL_DEFAULT_ENCRYPTION_KEY;
- }
-
- /* If default encryption is used and encryption is disabled, you may
- not use nondefault encryption_key_id as it is not stored anywhere. */
- if (encrypt == FIL_ENCRYPTION_DEFAULT
- && !srv_encrypt_tables
- && options->encryption_key_id != FIL_DEFAULT_ENCRYPTION_KEY) {
- compile_time_assert(FIL_DEFAULT_ENCRYPTION_KEY == 1);
- push_warning_printf(
- thd, Sql_condition::WARN_LEVEL_WARN,
- HA_WRONG_CREATE_OPTION,
- "InnoDB: innodb_encrypt_tables=OFF only allows ENCRYPTION_KEY_ID=1"
- );
- return "ENCRYPTION_KEY_ID";
- }
-
/* Check atomic writes requirements */
if (awrites == ATOMIC_WRITES_ON ||
(awrites == ATOMIC_WRITES_DEFAULT && srv_use_atomic_writes)) {
@@ -12641,10 +12643,6 @@ ha_innobase::create(
const char* stmt;
size_t stmt_len;
- /* Cache table options */
- ha_table_option_struct *options= form->s->option_struct;
- fil_encryption_t encrypt = (fil_encryption_t)options->encryption;
- uint key_id = (uint)options->encryption_key_id;
DBUG_ENTER("ha_innobase::create");
@@ -12667,7 +12665,7 @@ ha_innobase::create(
/* Validate create options if innodb_strict_mode is set. */
if (create_options_are_invalid(
- thd, form, create_info, use_tablespace)) {
+ thd, form, create_info, use_tablespace)) {
DBUG_RETURN(HA_WRONG_CREATE_OPTION);
}
@@ -12743,7 +12741,8 @@ ha_innobase::create(
row_mysql_lock_data_dictionary(trx);
error = create_table_def(trx, form, norm_name, temp_path,
- remote_path, flags, flags2, encrypt, key_id);
+ remote_path, flags, flags2,
+ form->s->option_struct);
if (error) {
goto cleanup;
}