diff --git a/mysql-test/suite/innodb/r/innodb_encryption_force.result b/mysql-test/suite/innodb/r/innodb_encryption_force.result new file mode 100644 index 00000000000..8e129899275 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_encryption_force.result @@ -0,0 +1,47 @@ +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") +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 `encrypted`=yes +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=no +alter table t1 encrypted=no; +ERROR HY000: Can't create table `test`.`#sql-temporary` (errno: 140 "Wrong create options") +alter table t2 encrypted=yes; +alter table t3 encrypted=default; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=yes +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 `encrypted`=yes +show create table t3; +Table Create Table +t3 CREATE TABLE `t3` ( + `a` int(11) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +drop table t1; +drop table t2; +drop table t3; diff --git a/mysql-test/suite/innodb/t/innodb_encryption_force.opt b/mysql-test/suite/innodb/t/innodb_encryption_force.opt new file mode 100644 index 00000000000..c9e532878e1 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_encryption_force.opt @@ -0,0 +1,2 @@ +--innodb-encrypt-tables=FORCE +--innodb-encrypt-log=ON diff --git a/mysql-test/suite/innodb/t/innodb_encryption_force.test b/mysql-test/suite/innodb/t/innodb_encryption_force.test new file mode 100644 index 00000000000..71ca23ff3cc --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_encryption_force.test @@ -0,0 +1,31 @@ +-- source include/have_innodb.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; + +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; + +--replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ +--error ER_CANT_CREATE_TABLE +alter table t1 encrypted=no; +alter table t2 encrypted=yes; +alter table t3 encrypted=default; + +show create table t1; +show create table t2; +show create table t3; + +drop table t1; +drop table t2; +drop table t3; diff --git a/mysql-test/suite/sys_vars/r/innodb_encrypt_tables_basic.result b/mysql-test/suite/sys_vars/r/innodb_encrypt_tables_basic.result index 87212399f09..bcca96b8cd7 100644 --- a/mysql-test/suite/sys_vars/r/innodb_encrypt_tables_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_encrypt_tables_basic.result @@ -1,7 +1,7 @@ SET @start_global_value = @@global.innodb_encrypt_tables; select @@global.innodb_encrypt_tables; @@global.innodb_encrypt_tables -0 +OFF select @@session.innodb_encrypt_tables; ERROR HY000: Variable 'innodb_encrypt_tables' is a GLOBAL variable show global variables like 'innodb_encrypt_tables'; @@ -21,15 +21,15 @@ INNODB_ENCRYPT_TABLES OFF set global innodb_encrypt_tables=ON; select @@global.innodb_encrypt_tables; @@global.innodb_encrypt_tables -1 +ON set global innodb_encrypt_tables=OFF; select @@global.innodb_encrypt_tables; @@global.innodb_encrypt_tables -0 +OFF set global innodb_encrypt_tables=1; select @@global.innodb_encrypt_tables; @@global.innodb_encrypt_tables -1 +ON set session innodb_encrypt_tables=1; ERROR HY000: Variable 'innodb_encrypt_tables' is a GLOBAL variable and should be set with SET GLOBAL set global innodb_encrypt_tables=1.1; diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff b/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff index d44f2bb7842..a5b8fc1a205 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_innodb,xtradb.rdiff @@ -199,9 +199,9 @@ SESSION_VALUE NULL GLOBAL_VALUE 1 @@ -803,6 +957,20 @@ - ENUM_VALUE_LIST NULL + ENUM_VALUE_LIST OFF,ON,FORCE READ_ONLY NO - COMMAND_LINE_ARGUMENT REQUIRED + COMMAND_LINE_ARGUMENT OPTIONAL +VARIABLE_NAME INNODB_FAKE_CHANGES +SESSION_VALUE OFF +GLOBAL_VALUE OFF diff --git a/mysql-test/suite/sys_vars/r/sysvars_innodb.result b/mysql-test/suite/sys_vars/r/sysvars_innodb.result index a3506b342b7..15d0209e2dc 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_innodb.result +++ b/mysql-test/suite/sys_vars/r/sysvars_innodb.result @@ -782,7 +782,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE OFF VARIABLE_SCOPE GLOBAL VARIABLE_TYPE BOOLEAN -VARIABLE_COMMENT Enable redo log encryption/decryption. +VARIABLE_COMMENT Enable redo log encryption NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL @@ -795,14 +795,14 @@ GLOBAL_VALUE OFF GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE OFF VARIABLE_SCOPE GLOBAL -VARIABLE_TYPE BOOLEAN -VARIABLE_COMMENT Enable InnoDB on-disk data encryption +VARIABLE_TYPE ENUM +VARIABLE_COMMENT Enable encryption for tables. Don't forget to enable --innodb-encrypt-log too NUMERIC_MIN_VALUE NULL NUMERIC_MAX_VALUE NULL NUMERIC_BLOCK_SIZE NULL -ENUM_VALUE_LIST NULL +ENUM_VALUE_LIST OFF,ON,FORCE READ_ONLY NO -COMMAND_LINE_ARGUMENT REQUIRED +COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME INNODB_FAST_SHUTDOWN SESSION_VALUE NULL GLOBAL_VALUE 1 diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 68c5017c3b0..04dad889d65 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -48,7 +48,7 @@ UNIV_INTERN mysql_pfs_key_t fil_crypt_key_mutex_key; #endif /** Is encryption enabled/disabled */ -UNIV_INTERN my_bool srv_encrypt_tables = FALSE; +UNIV_INTERN ulong srv_encrypt_tables = 0; /** No of key rotation threads requested */ UNIV_INTERN uint srv_n_fil_crypt_threads = 0; @@ -257,7 +257,7 @@ fil_space_create_crypt_data(uint key_id) memset(crypt_data, 0, sz); - if (srv_encrypt_tables == FALSE) { + if (!srv_encrypt_tables) { crypt_data->type = CRYPT_SCHEME_UNENCRYPTED; crypt_data->min_key_version = 0; } else { @@ -596,7 +596,7 @@ fil_space_check_encryption_write( /*==============================*/ ulint space) /*!< in: tablespace id */ { - if (srv_encrypt_tables == FALSE) + if (!srv_encrypt_tables) return false; fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space); @@ -981,7 +981,7 @@ fil_crypt_get_key_state( /*====================*/ key_state_t *new_state) /*!< out: key state */ { - if (srv_encrypt_tables == TRUE) { + if (srv_encrypt_tables) { new_state->key_version = encryption_key_get_latest_version(FIL_DEFAULT_ENCRYPTION_KEY); new_state->rotate_key_age = srv_fil_crypt_rotate_key_age; @@ -2438,7 +2438,7 @@ fil_space_crypt_get_status( } mutex_exit(&crypt_data->mutex); - if (srv_encrypt_tables == TRUE) { + if (srv_encrypt_tables) { status->current_key_version = encryption_key_get_latest_version(crypt_data->key_id); } else { diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 36d5a2946dd..172696df3ba 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -1992,7 +1992,7 @@ fil_read_first_page( /* If file space is encrypted we need to have at least some encryption service available where to get keys */ if ((cdata && cdata->encryption == FIL_SPACE_ENCRYPTION_ON) || - ( srv_encrypt_tables && + (srv_encrypt_tables && cdata && cdata->encryption == FIL_SPACE_ENCRYPTION_DEFAULT)) { uint rc = encryption_key_get_latest_version(cdata->key_id); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 47609494ab8..eee3f9920a9 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -236,7 +236,6 @@ static char* internal_innobase_data_file_path = NULL; static char* innodb_version_str = (char*) INNODB_VERSION_STR; -extern my_bool srv_encrypt_tables; extern uint srv_n_fil_crypt_threads; extern uint srv_fil_crypt_rotate_key_age; extern uint srv_n_fil_crypt_iops; @@ -11298,6 +11297,14 @@ ha_innobase::check_table_options( return "ENCRYPTED"; } + if (encrypt == FIL_SPACE_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"); + return "ENCRYPTED"; + } + /* Check page compression requirements */ if (options->page_compressed) { @@ -19117,9 +19124,16 @@ static MYSQL_SYSVAR_ULONG(fatal_semaphore_wait_threshold, srv_fatal_semaphore_wa UINT_MAX32, /* Maximum setting */ 0); -static MYSQL_SYSVAR_BOOL(encrypt_tables, srv_encrypt_tables, 0, - "Enable InnoDB on-disk data encryption", - 0, 0, 0); +static const char* srv_encrypt_tables_names[] = { "OFF", "ON", "FORCE", 0 }; +static TYPELIB srv_encrypt_tables_typelib = { + array_elements(srv_encrypt_tables_names)-1, 0, srv_encrypt_tables_names, + NULL +}; +static MYSQL_SYSVAR_ENUM(encrypt_tables, srv_encrypt_tables, + PLUGIN_VAR_OPCMDARG, + "Enable encryption for tables. " + "Don't forget to enable --innodb-encrypt-log too", + NULL, NULL, 0, &srv_encrypt_tables_typelib); static MYSQL_SYSVAR_UINT(encryption_threads, srv_n_fil_crypt_threads, PLUGIN_VAR_RQCMDARG, @@ -19161,7 +19175,7 @@ static MYSQL_SYSVAR_ULONGLONG(scrub_log_speed, innodb_scrub_log_speed, static MYSQL_SYSVAR_BOOL(encrypt_log, srv_encrypt_log, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, - "Enable redo log encryption/decryption.", + "Enable redo log encryption", NULL, NULL, FALSE); static MYSQL_SYSVAR_BOOL(immediate_scrub_data_uncompressed, diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 7039349ad68..34f8432d19f 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -544,7 +544,7 @@ extern my_bool srv_print_all_deadlocks; extern my_bool srv_cmp_per_index_enabled; /* is encryption enabled */ -extern my_bool srv_encrypt_tables; +extern ulong srv_encrypt_tables; /** Status variables to be passed to MySQL */ extern struct export_var_t export_vars; diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc index aec9ceb4712..69f194578ae 100644 --- a/storage/xtradb/fil/fil0crypt.cc +++ b/storage/xtradb/fil/fil0crypt.cc @@ -48,7 +48,7 @@ UNIV_INTERN mysql_pfs_key_t fil_crypt_key_mutex_key; #endif /** Is encryption enabled/disabled */ -UNIV_INTERN my_bool srv_encrypt_tables = FALSE; +UNIV_INTERN ulong srv_encrypt_tables = 0; /** No of key rotation threads requested */ UNIV_INTERN uint srv_n_fil_crypt_threads = 0; @@ -257,7 +257,7 @@ fil_space_create_crypt_data(uint key_id) memset(crypt_data, 0, sz); - if (srv_encrypt_tables == FALSE) { + if (!srv_encrypt_tables) { crypt_data->type = CRYPT_SCHEME_UNENCRYPTED; crypt_data->min_key_version = 0; } else { @@ -596,7 +596,7 @@ fil_space_check_encryption_write( /*==============================*/ ulint space) /*!< in: tablespace id */ { - if (srv_encrypt_tables == FALSE) + if (!srv_encrypt_tables) return false; fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space); @@ -981,7 +981,7 @@ fil_crypt_get_key_state( /*====================*/ key_state_t *new_state) /*!< out: key state */ { - if (srv_encrypt_tables == TRUE) { + if (srv_encrypt_tables) { new_state->key_version = encryption_key_get_latest_version(FIL_DEFAULT_ENCRYPTION_KEY); new_state->rotate_key_age = srv_fil_crypt_rotate_key_age; @@ -2438,7 +2438,7 @@ fil_space_crypt_get_status( } mutex_exit(&crypt_data->mutex); - if (srv_encrypt_tables == TRUE) { + if (srv_encrypt_tables) { status->current_key_version = encryption_key_get_latest_version(crypt_data->key_id); } else { diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index bc0c92beaa0..5cb4c071eb0 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -2030,7 +2030,7 @@ fil_read_first_page( /* If file space is encrypted we need to have at least some encryption service available where to get keys */ if ((cdata && cdata->encryption == FIL_SPACE_ENCRYPTION_ON) || - ( srv_encrypt_tables && + (srv_encrypt_tables && cdata && cdata->encryption == FIL_SPACE_ENCRYPTION_DEFAULT)) { uint rc = encryption_key_get_latest_version(cdata->key_id); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index d5bbfe9fbd7..aeb3e4fb5c1 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -246,7 +246,6 @@ static char* internal_innobase_data_file_path = NULL; static char* innodb_version_str = (char*) INNODB_VERSION_STR; -extern my_bool srv_encrypt_tables; extern uint srv_n_fil_crypt_threads; extern uint srv_fil_crypt_rotate_key_age; extern uint srv_n_fil_crypt_iops; @@ -11804,6 +11803,14 @@ ha_innobase::check_table_options( return "ENCRYPTED"; } + if (encrypt == FIL_SPACE_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"); + return "ENCRYPTED"; + } + /* Check page compression requirements */ if (options->page_compressed) { @@ -20299,9 +20306,16 @@ static MYSQL_SYSVAR_ULONG(fatal_semaphore_wait_threshold, srv_fatal_semaphore_wa UINT_MAX32, /* Maximum setting */ 0); -static MYSQL_SYSVAR_BOOL(encrypt_tables, srv_encrypt_tables, 0, - "Enable InnoDB on-disk data encryption", - 0, 0, 0); +static const char* srv_encrypt_tables_names[] = { "OFF", "ON", "FORCE", 0 }; +static TYPELIB srv_encrypt_tables_typelib = { + array_elements(srv_encrypt_tables_names)-1, 0, srv_encrypt_tables_names, + NULL +}; +static MYSQL_SYSVAR_ENUM(encrypt_tables, srv_encrypt_tables, + PLUGIN_VAR_OPCMDARG, + "Enable encryption for tables. " + "Don't forget to enable --innodb-encrypt-log too", + NULL, NULL, 0, &srv_encrypt_tables_typelib); static MYSQL_SYSVAR_UINT(encryption_threads, srv_n_fil_crypt_threads, PLUGIN_VAR_RQCMDARG, @@ -20343,7 +20357,7 @@ static MYSQL_SYSVAR_ULONGLONG(scrub_log_speed, innodb_scrub_log_speed, static MYSQL_SYSVAR_BOOL(encrypt_log, srv_encrypt_log, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, - "Enable redo log encryption/decryption.", + "Enable redo log encryption", NULL, NULL, FALSE); static MYSQL_SYSVAR_BOOL(immediate_scrub_data_uncompressed, diff --git a/storage/xtradb/include/srv0srv.h b/storage/xtradb/include/srv0srv.h index 10d0cc961f7..b8a57098f40 100644 --- a/storage/xtradb/include/srv0srv.h +++ b/storage/xtradb/include/srv0srv.h @@ -683,7 +683,7 @@ extern my_bool srv_print_all_deadlocks; extern my_bool srv_cmp_per_index_enabled; /* is encryption enabled */ -extern my_bool srv_encrypt_tables; +extern ulong srv_encrypt_tables; /** Status variables to be passed to MySQL */ extern struct export_var_t export_vars;