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.
This commit is contained in:
Marko Mäkelä 2019-02-28 23:11:15 +02:00
parent 622e9e8a7a
commit e39d6e0c53
8 changed files with 182 additions and 162 deletions

View file

@ -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

View file

@ -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

View file

@ -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));

View file

@ -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));

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}