summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThirunarayanan Balathandayuthapani <thiru@mariadb.com>2019-05-01 17:24:58 +0530
committerMarko Mäkelä <marko.makela@mariadb.com>2019-05-02 13:31:59 +0300
commitada1074bb10359342ee00e220fe9c172574265fb (patch)
treeaf53d4122769de2bc0c1436b453a7979e387411b
parent2370eeb028b269243633b18f7661dca999089a41 (diff)
downloadmariadb-git-ada1074bb10359342ee00e220fe9c172574265fb.tar.gz
MDEV-14398 innodb_encryption_rotate_key_age=0 causes innodb_encrypt_tables to be ignoredbb-10.2-MDEV-14398-alternative
The statement SET GLOBAL innodb_encryption_rotate_key_age=0; would have the unwanted side effect that ENCRYPTION=DEFAULT tablespaces would no longer be encrypted or decrypted according to the setting of innodb_encrypt_tables. We implement a trigger, so that whenever one of the following is executed: SET GLOBAL innodb_encrypt_tables=OFF; SET GLOBAL innodb_encrypt_tables=ON; SET GLOBAL innodb_encrypt_tables=FORCE; all wrong-state ENCRYPTION=DEFAULT tablespaces will be added to fil_system_t::rotation_list, so that the encryption will be added or removed. Note: This will *NOT* happen automatically after a server restart. Before reading the first page of a data file, InnoDB cannot know the encryption status of the data file. The statement SET GLOBAL innodb_encrypt_tables will have the side effect that all not-yet-read InnoDB data files will be accessed in order to determine the encryption status. innodb_encrypt_tables_validate(): Stop disallowing SET GLOBAL innodb_encrypt_tables when innodb_encryption_rotate_key_age=0. This reverts part of commit 50eb40a2a8aa3af6cc271f6028f4d6d74301d030 that addressed MDEV-11738 and MDEV-11581. fil_system_t::read_page0(): Trigger a call to fil_node_t::read_page0(). Refactored from fil_space_get_space(). fil_crypt_rotation_list_fill(): If innodb_encryption_rotate_key_age=0, initialize fil_system->rotation_list. This is invoked both on SET GLOBAL innodb_encrypt_tables and on SET GLOBAL innodb_encryption_rotate_key_age=0. fil_space_set_crypt_data(): Remove. fil_parse_write_crypt_data(): Simplify the logic. This is joint work with Marko Mäkelä.
-rw-r--r--mysql-test/suite/encryption/r/innodb-key-rotation-disable.result4
-rw-r--r--mysql-test/suite/encryption/r/innodb_encrypt_key_rotation_age.result75
-rw-r--r--mysql-test/suite/encryption/t/innodb-key-rotation-disable.test5
-rw-r--r--mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.opt2
-rw-r--r--mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.test82
-rw-r--r--storage/innobase/fil/fil0crypt.cc164
-rw-r--r--storage/innobase/fil/fil0fil.cc84
-rw-r--r--storage/innobase/handler/ha_innodb.cc10
-rw-r--r--storage/innobase/include/fil0fil.h6
9 files changed, 314 insertions, 118 deletions
diff --git a/mysql-test/suite/encryption/r/innodb-key-rotation-disable.result b/mysql-test/suite/encryption/r/innodb-key-rotation-disable.result
index 680db692c17..a662f5e6343 100644
--- a/mysql-test/suite/encryption/r/innodb-key-rotation-disable.result
+++ b/mysql-test/suite/encryption/r/innodb-key-rotation-disable.result
@@ -37,10 +37,6 @@ NAME ENCRYPTION_SCHEME CURRENT_KEY_ID
enctests/t7 0 1
enctests/t8 0 1
enctests/t9 0 1
-SET GLOBAL innodb_encrypt_tables=OFF;
-ERROR 42000: Variable 'innodb_encrypt_tables' can't be set to the value of 'OFF'
-SET GLOBAL innodb_encrypt_tables=ON;
-ERROR 42000: Variable 'innodb_encrypt_tables' can't be set to the value of 'ON'
# t1 default on expecting NOT FOUND
NOT FOUND /secred/ in t1.ibd
# t2 default on expecting NOT FOUND
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 00000000000..137ce01e14c
--- /dev/null
+++ b/mysql-test/suite/encryption/r/innodb_encrypt_key_rotation_age.result
@@ -0,0 +1,75 @@
+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
+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
+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
+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
+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
+test/t1
+test/t2
+test/t3
+DROP TABLE t4, t3, t2, t1;
diff --git a/mysql-test/suite/encryption/t/innodb-key-rotation-disable.test b/mysql-test/suite/encryption/t/innodb-key-rotation-disable.test
index 574e0c3becc..2e5d877f7c0 100644
--- a/mysql-test/suite/encryption/t/innodb-key-rotation-disable.test
+++ b/mysql-test/suite/encryption/t/innodb-key-rotation-disable.test
@@ -43,11 +43,6 @@ SELECT NAME,ENCRYPTION_SCHEME,CURRENT_KEY_ID FROM INFORMATION_SCHEMA.INNODB_TABL
--echo # 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%';
---error ER_WRONG_VALUE_FOR_VAR
-SET GLOBAL innodb_encrypt_tables=OFF;
---error ER_WRONG_VALUE_FOR_VAR
-SET GLOBAL innodb_encrypt_tables=ON;
-
--let $MYSQLD_DATADIR=`select @@datadir`
-- source include/shutdown_mysqld.inc
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 00000000000..6fa06402377
--- /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 00000000000..c3fafb0751b
--- /dev/null
+++ b/mysql-test/suite/encryption/t/innodb_encrypt_key_rotation_age.test
@@ -0,0 +1,82 @@
+-- source include/have_innodb.inc
+-- source include/not_embedded.inc
+-- source include/have_example_key_management_plugin.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_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 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;
+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(*) 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;
+
+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(*) 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;
+--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(*) 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)
+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;
+SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
+DROP TABLE t4, t3, t2, t1;
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index 32fd844ec17..5a53355a279 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
-Copyright (c) 2014, 2018, MariaDB Corporation. All Rights Reserved.
+Copyright (c) 2014, 2019, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -419,45 +419,6 @@ fil_space_crypt_t::write_page0(
}
/******************************************************************
-Set crypt data for a tablespace
-@param[in,out] space Tablespace
-@param[in,out] crypt_data Crypt data to be set
-@return crypt_data in tablespace */
-static
-fil_space_crypt_t*
-fil_space_set_crypt_data(
- fil_space_t* space,
- fil_space_crypt_t* crypt_data)
-{
- fil_space_crypt_t* free_crypt_data = NULL;
- fil_space_crypt_t* ret_crypt_data = NULL;
-
- /* Provided space is protected using fil_space_acquire()
- from concurrent operations. */
- if (space->crypt_data != NULL) {
- /* There is already crypt data present,
- merge new crypt_data */
- fil_space_merge_crypt_data(space->crypt_data,
- crypt_data);
- ret_crypt_data = space->crypt_data;
- free_crypt_data = crypt_data;
- } else {
- space->crypt_data = crypt_data;
- ret_crypt_data = space->crypt_data;
- }
-
- if (free_crypt_data != NULL) {
- /* there was already crypt data present and the new crypt
- * data provided as argument to this function has been merged
- * into that => free new crypt data
- */
- fil_space_destroy_crypt_data(&free_crypt_data);
- }
-
- return ret_crypt_data;
-}
-
-/******************************************************************
Parse a MLOG_FILE_WRITE_CRYPT_DATA log entry
@param[in] ptr Log entry start
@param[in] end_ptr Log entry end
@@ -515,26 +476,36 @@ fil_parse_write_crypt_data(
return NULL;
}
- fil_space_crypt_t* crypt_data = fil_space_create_crypt_data(encryption, key_id);
- /* Need to overwrite these as above will initialize fields. */
+ mutex_enter(&fil_system->mutex);
+
+ fil_space_t* space = fil_space_get_by_id(space_id);
+
+ if (!space) {
+ mutex_exit(&fil_system->mutex);
+ return ptr + len;
+ }
+
+ fil_space_crypt_t* crypt_data = fil_space_create_crypt_data(
+ encryption, key_id);
+
crypt_data->page0_offset = offset;
crypt_data->min_key_version = min_key_version;
- crypt_data->encryption = encryption;
crypt_data->type = type;
memcpy(crypt_data->iv, ptr, len);
ptr += len;
- /* update fil_space memory cache with crypt_data */
- if (fil_space_t* space = fil_space_acquire_silent(space_id)) {
- crypt_data = fil_space_set_crypt_data(space, crypt_data);
- fil_space_release(space);
- /* Check is used key found from encryption plugin */
- if (crypt_data->should_encrypt()
- && !crypt_data->is_key_found()) {
- *err = DB_DECRYPTION_FAILED;
- }
- } else {
+ if (space->crypt_data) {
+ fil_space_merge_crypt_data(space->crypt_data, crypt_data);
fil_space_destroy_crypt_data(&crypt_data);
+ crypt_data = space->crypt_data;
+ } else {
+ space->crypt_data = crypt_data;
+ }
+
+ mutex_exit(&fil_system->mutex);
+
+ if (crypt_data->should_encrypt() && !crypt_data->is_key_found()) {
+ *err = DB_DECRYPTION_FAILED;
}
return ptr;
@@ -919,11 +890,15 @@ fil_crypt_needs_rotation(
if (crypt_data->encryption == FIL_ENCRYPTION_DEFAULT
&& crypt_data->type == CRYPT_SCHEME_1
- && srv_encrypt_tables == 0 ) {
+ && !srv_encrypt_tables) {
/* This is rotation encrypted => unencrypted */
return true;
}
+ if (rotate_key_age == 0) {
+ return false;
+ }
+
/* this is rotation encrypted => encrypted,
* only reencrypt if key is sufficiently old */
if (key_version + rotate_key_age < latest_key_version) {
@@ -1006,7 +981,8 @@ fil_crypt_start_encrypting_space(
* crypt data in page 0 */
/* 1 - create crypt data */
- crypt_data = fil_space_create_crypt_data(FIL_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
+ crypt_data = fil_space_create_crypt_data(
+ FIL_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
if (crypt_data == NULL) {
mutex_exit(&fil_crypt_threads_mutex);
@@ -1019,9 +995,9 @@ fil_crypt_start_encrypting_space(
crypt_data->rotate_state.starting = true;
crypt_data->rotate_state.active_threads = 1;
- mutex_enter(&crypt_data->mutex);
- crypt_data = fil_space_set_crypt_data(space, crypt_data);
- mutex_exit(&crypt_data->mutex);
+ mutex_enter(&fil_system->mutex);
+ space->crypt_data = crypt_data;
+ mutex_exit(&fil_system->mutex);
fil_crypt_start_converting = true;
mutex_exit(&fil_crypt_threads_mutex);
@@ -2292,6 +2268,64 @@ fil_crypt_set_thread_cnt(
}
}
+/** Initialize the tablespace rotation_list
+if innodb_encryption_rotate_key_age=0. */
+static void fil_crypt_rotation_list_fill()
+{
+ ut_ad(mutex_own(&fil_system->mutex));
+
+ for (fil_space_t* space = UT_LIST_GET_FIRST(fil_system->space_list);
+ space != NULL;
+ space = UT_LIST_GET_NEXT(space_list, space)) {
+ if (space->purpose != FIL_TYPE_TABLESPACE
+ || space->is_in_rotation_list()
+ || space->is_stopping()
+ || UT_LIST_GET_LEN(space->chain) == 0) {
+ continue;
+ }
+
+ /* Ensure that crypt_data has been initialized. */
+ if (!space->size) {
+ /* Protect the tablespace while we may
+ release fil_system->mutex. */
+ space->n_pending_ops++;
+ fil_space_t* s= fil_system->read_page0(
+ space->id);
+ ut_ad(!s || s == space);
+ space->n_pending_ops--;
+ if (!space->size) {
+ /* Page 0 was not loaded.
+ Skip this tablespace. */
+ continue;
+ }
+ }
+
+ /* Skip ENCRYPTION!=DEFAULT tablespaces. */
+ if (space->crypt_data
+ && !space->crypt_data->is_default_encryption()) {
+ continue;
+ }
+
+ if (srv_encrypt_tables) {
+ /* Skip encrypted tablespaces if
+ innodb_encrypt_tables!=OFF */
+ if (space->crypt_data
+ && space->crypt_data->min_key_version) {
+ continue;
+ }
+ } else {
+ /* Skip unencrypted tablespaces if
+ innodb_encrypt_tables=OFF */
+ if (!space->crypt_data
+ || !space->crypt_data->min_key_version) {
+ continue;
+ }
+ }
+
+ UT_LIST_ADD_LAST(fil_system->rotation_list, space);
+ }
+}
+
/*********************************************************************
Adjust max key age
@param[in] val New max key age */
@@ -2300,7 +2334,12 @@ void
fil_crypt_set_rotate_key_age(
uint val)
{
+ mutex_enter(&fil_system->mutex);
srv_fil_crypt_rotate_key_age = val;
+ if (val == 0) {
+ fil_crypt_rotation_list_fill();
+ }
+ mutex_exit(&fil_system->mutex);
os_event_set(fil_crypt_threads_event);
}
@@ -2324,7 +2363,16 @@ void
fil_crypt_set_encrypt_tables(
uint val)
{
+ mutex_enter(&fil_system->mutex);
+
srv_encrypt_tables = val;
+
+ if (srv_fil_crypt_rotate_key_age == 0) {
+ fil_crypt_rotation_list_fill();
+ }
+
+ mutex_exit(&fil_system->mutex);
+
os_event_set(fil_crypt_threads_event);
}
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 2de94fe3e40..102d7e178b5 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -1525,6 +1525,47 @@ fil_assign_new_space_id(
return(success);
}
+/** Trigger a call to fil_node_t::read_page0()
+@param[in] id tablespace identifier
+@return tablespace
+@retval NULL if the tablespace does not exist or cannot be read */
+fil_space_t* fil_system_t::read_page0(ulint id)
+{
+ mutex_exit(&mutex);
+
+ ut_ad(id != 0);
+
+ /* It is possible that the tablespace is dropped while we are
+ not holding the mutex. */
+ fil_mutex_enter_and_prepare_for_io(id);
+
+ fil_space_t* space = fil_space_get_by_id(id);
+
+ if (space == NULL || UT_LIST_GET_LEN(space->chain) == 0) {
+ return(NULL);
+ }
+
+ /* The following code must change when InnoDB supports
+ multiple datafiles per tablespace. */
+ ut_a(1 == UT_LIST_GET_LEN(space->chain));
+
+ fil_node_t* node = UT_LIST_GET_FIRST(space->chain);
+
+ /* It must be a single-table tablespace and we have not opened
+ the file yet; the following calls will open it and update the
+ size fields */
+
+ if (!fil_node_prepare_for_io(node, fil_system, space)) {
+ /* The single-table tablespace can't be opened,
+ because the ibd file is missing. */
+ return(NULL);
+ }
+
+ fil_node_complete_io(node, IORequestRead);
+
+ return space;
+}
+
/*******************************************************************//**
Returns a pointer to the fil_space_t that is in the memory cache
associated with a space id. The caller must lock fil_system->mutex.
@@ -1535,12 +1576,7 @@ fil_space_get_space(
/*================*/
ulint id) /*!< in: space id */
{
- fil_space_t* space;
- fil_node_t* node;
-
- ut_ad(fil_system);
-
- space = fil_space_get_by_id(id);
+ fil_space_t* space = fil_space_get_by_id(id);
if (space == NULL || space->size != 0) {
return(space);
}
@@ -1551,41 +1587,7 @@ fil_space_get_space(
case FIL_TYPE_TEMPORARY:
case FIL_TYPE_TABLESPACE:
case FIL_TYPE_IMPORT:
- ut_a(id != 0);
-
- mutex_exit(&fil_system->mutex);
-
- /* It is possible that the space gets evicted at this point
- before the fil_mutex_enter_and_prepare_for_io() acquires
- the fil_system->mutex. Check for this after completing the
- call to fil_mutex_enter_and_prepare_for_io(). */
- fil_mutex_enter_and_prepare_for_io(id);
-
- /* We are still holding the fil_system->mutex. Check if
- the space is still in memory cache. */
- space = fil_space_get_by_id(id);
-
- if (space == NULL || UT_LIST_GET_LEN(space->chain) == 0) {
- return(NULL);
- }
-
- /* The following code must change when InnoDB supports
- multiple datafiles per tablespace. */
- ut_a(1 == UT_LIST_GET_LEN(space->chain));
-
- node = UT_LIST_GET_FIRST(space->chain);
-
- /* It must be a single-table tablespace and we have not opened
- the file yet; the following calls will open it and update the
- size fields */
-
- if (!fil_node_prepare_for_io(node, fil_system, space)) {
- /* The single-table tablespace can't be opened,
- because the ibd file is missing. */
- return(NULL);
- }
-
- fil_node_complete_io(node, IORequestRead);
+ space = fil_system->read_page0(id);
}
return(space);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 64559b1dae2..ecf85a81638 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -22404,16 +22404,6 @@ innodb_encrypt_tables_validate(
return 1;
}
- if (!srv_fil_crypt_rotate_key_age) {
- const char *msg = (encrypt_tables ? "enable" : "disable");
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
- HA_ERR_UNSUPPORTED,
- "InnoDB: cannot %s encryption, "
- "innodb_encryption_rotate_key_age=0"
- " i.e. key rotation disabled", msg);
- return 1;
- }
-
return 0;
}
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index 1a37dde4452..0ef5e7a3364 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -532,6 +532,12 @@ struct fil_system_t {
/* !< TRUE if fil_space_create()
has issued a warning about
potential space_id reuse */
+
+ /** Trigger a call to fil_node_t::read_page0()
+ @param[in] id tablespace identifier
+ @return tablespace
+ @retval NULL if the tablespace does not exist or cannot be read */
+ fil_space_t* read_page0(ulint id);
};
/** The tablespace memory cache. This variable is NULL before the module is