diff options
author | Jan Lindström <jan.lindstrom@mariadb.com> | 2017-08-25 11:08:45 +0300 |
---|---|---|
committer | Jan Lindström <jan.lindstrom@mariadb.com> | 2017-08-25 11:08:45 +0300 |
commit | 7049b864bd8eaa0de2b832868ed0735f201c97c0 (patch) | |
tree | 2799f973a84ffe4c75dbb5de0e36019c6155e848 | |
parent | 97f9d3c08056f8b532118c0fb1b988df18db4f63 (diff) | |
download | mariadb-git-bb-10.1-MDEV-13557.tar.gz |
MDEV-13557: Startup failure, unable to decrypt ibdata1bb-10.1-MDEV-13557
Problem was that we created encryption metadata (crypt_data) for
system tablespace even when no encryption was enabled and too early.
System tablespace can be encrypted only using key rotation.
Test innodb-key-rotation-disable, innodb_encryption, innodb_lotoftables
require adjustment because INFORMATION_SCHEMA INNODB_TABLESPACES_ENCRYPTION
contain row only if tablespace really has encryption metadata.
fil_crypt_set_thread_cnt: Send message to background encryption threads
if they exits when they are ready. This is required to find tablespaces
requiring key rotation if no other changes happen.
fsp_header_init: Write encryption metadata to page 0 only if tablespace is
encrypted or encryption is disabled by table option.
i_s_dict_fill_tablespaces_encryption : Skip tablespaces that do not
contain encryption metadata. This is required to avoid too early
wait condition trigger in encrypted -> unencrypted state transfer.
open_or_create_data_files: Do not create encryption metadata
by default to system tablespace.
-rw-r--r-- | mysql-test/suite/encryption/r/innodb-key-rotation-disable.result | 3 | ||||
-rw-r--r-- | mysql-test/suite/encryption/r/innodb_encryption.result | 61 | ||||
-rw-r--r-- | mysql-test/suite/encryption/r/innodb_lotoftables.result | 14 | ||||
-rw-r--r-- | mysql-test/suite/encryption/t/innodb_encryption.test | 163 | ||||
-rw-r--r-- | mysql-test/suite/encryption/t/innodb_lotoftables.test | 6 | ||||
-rw-r--r-- | storage/innobase/fil/fil0crypt.cc | 13 | ||||
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 2 | ||||
-rw-r--r-- | storage/innobase/fsp/fsp0fsp.cc | 6 | ||||
-rw-r--r-- | storage/innobase/handler/i_s.cc | 7 | ||||
-rw-r--r-- | storage/innobase/srv/srv0start.cc | 5 | ||||
-rw-r--r-- | storage/xtradb/fil/fil0crypt.cc | 13 | ||||
-rw-r--r-- | storage/xtradb/fil/fil0fil.cc | 2 | ||||
-rw-r--r-- | storage/xtradb/fsp/fsp0fsp.cc | 6 | ||||
-rw-r--r-- | storage/xtradb/handler/i_s.cc | 7 | ||||
-rw-r--r-- | storage/xtradb/srv/srv0start.cc | 5 |
15 files changed, 123 insertions, 190 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 89677490d92..6c09e015a1e 100644 --- a/mysql-test/suite/encryption/r/innodb-key-rotation-disable.result +++ b/mysql-test/suite/encryption/r/innodb-key-rotation-disable.result @@ -2,9 +2,6 @@ SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_ NAME SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; NAME -mysql/innodb_table_stats -mysql/innodb_index_stats -./ibdata1 create database enctests; use enctests; create table t1(a int not null primary key, b char(200)) engine=innodb; diff --git a/mysql-test/suite/encryption/r/innodb_encryption.result b/mysql-test/suite/encryption/r/innodb_encryption.result index 26c77499d25..73e4af2b243 100644 --- a/mysql-test/suite/encryption/r/innodb_encryption.result +++ b/mysql-test/suite/encryption/r/innodb_encryption.result @@ -6,25 +6,25 @@ innodb_encrypt_tables ON innodb_encryption_rotate_key_age 15 innodb_encryption_rotation_iops 100 innodb_encryption_threads 4 -DESCRIBE INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION; -Field Type Null Key Default Extra -SPACE int(11) unsigned NO 0 -NAME varchar(655) YES NULL -ENCRYPTION_SCHEME int(11) unsigned NO 0 -KEYSERVER_REQUESTS int(11) unsigned NO 0 -MIN_KEY_VERSION int(11) unsigned NO 0 -CURRENT_KEY_VERSION int(11) unsigned NO 0 -KEY_ROTATION_PAGE_NUMBER bigint(21) unsigned YES NULL -KEY_ROTATION_MAX_PAGE_NUMBER bigint(21) unsigned YES NULL -CURRENT_KEY_ID int(11) unsigned NO 0 -ROTATING_OR_FLUSHING int(1) unsigned NO 0 -# Wait max 5 min for key encryption threads to encrypt one space -# Success! -# Wait max 10 min for key encryption threads to encrypt all space +# Wait max 10 min for key encryption threads to encrypt all spaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +NAME +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +NAME +mysql/innodb_table_stats +mysql/innodb_index_stats +./ibdata1 # Success! # Now turn off encryption and wait for threads to decrypt everything SET GLOBAL innodb_encrypt_tables = off; -# Wait max 10 min for key encryption threads to decrypt all space +# Wait max 10 min for key encryption threads to encrypt all spaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +NAME +mysql/innodb_table_stats +mysql/innodb_index_stats +./ibdata1 +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +NAME # Success! # Shutdown innodb_encryption_threads SET GLOBAL innodb_encryption_threads=0; @@ -32,16 +32,24 @@ SET GLOBAL innodb_encryption_threads=0; # since threads are off tables should remain unencrypted SET GLOBAL innodb_encrypt_tables = on; # Wait 15s to check that nothing gets encrypted +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +NAME +mysql/innodb_table_stats +mysql/innodb_index_stats +./ibdata1 +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +NAME # Success! # Startup innodb_encryption_threads SET GLOBAL innodb_encryption_threads=@start_global_value; -# Wait 1 min to check that it start encrypting again -# Success! -# -# Check that restart with encryption turned off works -# even if spaces are encrypted -# -# First wait max 10 min for key encryption threads to encrypt all spaces +# Wait max 10 min for key encryption threads to encrypt all spaces +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +NAME +mysql/innodb_table_stats +mysql/innodb_index_stats +./ibdata1 +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +NAME # Success! # Restart mysqld --innodb_encrypt_tables=0 --innodb_encryption_threads=0 SHOW VARIABLES LIKE 'innodb_encrypt%'; @@ -51,9 +59,8 @@ innodb_encrypt_tables OFF innodb_encryption_rotate_key_age 15 innodb_encryption_rotation_iops 100 innodb_encryption_threads 0 -SELECT COUNT(*) > 0 as should_be_1 +SELECT COUNT(*) > 0 as should_be_0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; -should_be_1 -1 -# Restart mysqld again...with default options +should_be_0 +0 diff --git a/mysql-test/suite/encryption/r/innodb_lotoftables.result b/mysql-test/suite/encryption/r/innodb_lotoftables.result index 86ab60e7836..2f130177472 100644 --- a/mysql-test/suite/encryption/r/innodb_lotoftables.result +++ b/mysql-test/suite/encryption/r/innodb_lotoftables.result @@ -19,10 +19,10 @@ commit work; show status like 'innodb_pages0_read%'; Variable_name Value Innodb_pages0_read 3 -# should be 100 +# should be 0 SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE NAME LIKE 'innodb_encrypted%'; COUNT(*) -100 +0 create database innodb_encrypted_2; use innodb_encrypted_2; show status like 'innodb_pages0_read%'; @@ -38,10 +38,10 @@ Innodb_pages0_read 3 SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%'; COUNT(*) 100 -# should be 100 +# should be 0 SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%'; COUNT(*) -100 +0 create database innodb_encrypted_3; use innodb_encrypted_3; show status like 'innodb_pages0_read%'; @@ -57,10 +57,10 @@ Innodb_pages0_read 3 SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%'; COUNT(*) 100 -# should be 200 +# should be 100 SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%'; COUNT(*) -200 +100 use test; show status like 'innodb_pages0_read%'; Variable_name Value @@ -70,7 +70,7 @@ COUNT(*) 100 SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%'; COUNT(*) -200 +100 SET GLOBAL innodb_encrypt_tables = on; SET GLOBAL innodb_encryption_threads=4; # Wait until all encrypted tables have been encrypted diff --git a/mysql-test/suite/encryption/t/innodb_encryption.test b/mysql-test/suite/encryption/t/innodb_encryption.test index 50aca2a7260..d62df66a958 100644 --- a/mysql-test/suite/encryption/t/innodb_encryption.test +++ b/mysql-test/suite/encryption/t/innodb_encryption.test @@ -11,78 +11,27 @@ SET @start_global_value = @@global.innodb_encryption_threads; SHOW VARIABLES LIKE 'innodb_encrypt%'; -DESCRIBE INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION; - ---echo # Wait max 5 min for key encryption threads to encrypt one space -let $cnt=300; -while ($cnt) -{ - let $success=`SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION > 0`; - if ($success) - { - let $cnt=0; - } - if (!$success) - { - real_sleep 1; - dec $cnt; - } -} -if (!$success) -{ - SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION; - SHOW STATUS LIKE 'innodb_encryption%'; - -- die Timeout waiting for encryption threads -} ---echo # Success! +--echo # Wait max 10 min for key encryption threads to encrypt all spaces +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) = 3 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 # Wait max 10 min for key encryption threads to encrypt all space -let $cnt=600; -while ($cnt) -{ - let $success=`SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0`; - if ($success) - { - let $cnt=0; - } - if (!$success) - { - real_sleep 1; - dec $cnt; - } -} -if (!$success) -{ - SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION; - SHOW STATUS LIKE 'innodb_encryption%'; - -- die Timeout waiting for encryption threads -} --echo # Success! --echo # Now turn off encryption and wait for threads to decrypt everything SET GLOBAL innodb_encrypt_tables = off; ---echo # Wait max 10 min for key encryption threads to decrypt all space -let $cnt=600; -while ($cnt) -{ - let $success=`SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0`; - if ($success) - { - let $cnt=0; - } - if (!$success) - { - real_sleep 1; - dec $cnt; - } -} -if (!$success) -{ - SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION; - SHOW STATUS LIKE 'innodb_encryption%'; - -- die Timeout waiting for encryption threads -} +--echo # Wait max 10 min for key encryption threads to encrypt all spaces +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc + +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + --echo # Success! --echo # Shutdown innodb_encryption_threads @@ -93,84 +42,34 @@ SET GLOBAL innodb_encryption_threads=0; SET GLOBAL innodb_encrypt_tables = on; --echo # Wait 15s to check that nothing gets encrypted -let $cnt=15; -while ($cnt) -{ - let $success=`SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0`; - if ($success) - { - real_sleep 1; - dec $cnt; - } - if (!$success) - { - SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; - -- die Failure, tablespace getting encrypted even if innodb_encryption_threads=0 - } -} +--let $wait_timeout= 15 +--let $wait_condition=SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc + +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0; +SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; + --echo # Success! --echo # Startup innodb_encryption_threads SET GLOBAL innodb_encryption_threads=@start_global_value; ---echo # Wait 1 min to check that it start encrypting again -let $cnt=60; -while ($cnt) -{ - let $success=`SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 OR KEY_ROTATION_PAGE_NUMBER IS NOT NULL`; - if ($success) - { - let $cnt=0; - } - if (!$success) - { - real_sleep 1; - dec $cnt; - } -} -if (!$success) -{ - SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION; - SHOW STATUS LIKE 'innodb_encryption%'; - -- die Timeout waiting for encryption threads -} ---echo # Success! +--echo # Wait max 10 min for key encryption threads to encrypt all spaces +--let $wait_timeout= 600 +--let $wait_condition=SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; +--source include/wait_condition.inc + +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 # ---echo # Check that restart with encryption turned off works ---echo # even if spaces are encrypted ---echo # ---echo # First wait max 10 min for key encryption threads to encrypt all spaces -let $cnt=600; -while ($cnt) -{ - let $success=`SELECT COUNT(*) = 0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0`; - if ($success) - { - let $cnt=0; - } - if (!$success) - { - real_sleep 1; - dec $cnt; - } -} -if (!$success) -{ - SELECT * FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION; - SHOW STATUS LIKE 'innodb_encryption%'; - -- die Timeout waiting for encryption threads -} --echo # Success! --echo # Restart mysqld --innodb_encrypt_tables=0 --innodb_encryption_threads=0 -- let $restart_parameters=--innodb_encrypt_tables=0 --innodb_encryption_threads=0 -- source include/restart_mysqld.inc SHOW VARIABLES LIKE 'innodb_encrypt%'; -SELECT COUNT(*) > 0 as should_be_1 +SELECT COUNT(*) > 0 as should_be_0 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0; ---echo # Restart mysqld again...with default options --- let $restart_parameters= --- source include/restart_mysqld.inc + diff --git a/mysql-test/suite/encryption/t/innodb_lotoftables.test b/mysql-test/suite/encryption/t/innodb_lotoftables.test index 8bad356a9e0..ec0f00d9c0d 100644 --- a/mysql-test/suite/encryption/t/innodb_lotoftables.test +++ b/mysql-test/suite/encryption/t/innodb_lotoftables.test @@ -53,7 +53,7 @@ show status like 'innodb_pages0_read%'; # # Verify # ---echo # should be 100 +--echo # should be 0 SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE NAME LIKE 'innodb_encrypted%'; @@ -91,7 +91,7 @@ show status like 'innodb_pages0_read%'; # --echo # should be 100 SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%'; ---echo # should be 100 +--echo # should be 0 SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%'; # @@ -128,7 +128,7 @@ show status like 'innodb_pages0_read%'; # --echo # should be 100 SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0 AND NAME LIKE 'innodb_encrypted%'; ---echo # should be 200 +--echo # should be 100 SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%'; use test; diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 683974d8920..d974b9a8586 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -2298,7 +2298,7 @@ fil_crypt_set_thread_cnt( os_thread_create(fil_crypt_thread, NULL, &rotation_thread_id); ib_logf(IB_LOG_LEVEL_INFO, - "Creating #%d thread id %lu total threads %u.", + "Creating #%d encryption thread id %lu total threads %u.", i+1, os_thread_pf(rotation_thread_id), new_cnt); } } else if (new_cnt < srv_n_fil_crypt_threads) { @@ -2312,6 +2312,14 @@ fil_crypt_set_thread_cnt( os_event_reset(fil_crypt_event); os_event_wait_time(fil_crypt_event, 1000000); } + + /* Send a message to encryption threads that there could be + something to do. */ + if (srv_n_fil_crypt_threads) { + mutex_enter(&fil_crypt_threads_mutex); + os_event_set(fil_crypt_threads_event); + mutex_exit(&fil_crypt_threads_mutex); + } } /********************************************************************* @@ -2456,9 +2464,10 @@ fil_space_crypt_get_status( ut_ad(space->n_pending_ops > 0); fil_crypt_read_crypt_data(const_cast<fil_space_t*>(space)); - status->space = space->id; + status->space = ULINT_UNDEFINED; if (fil_space_crypt_t* crypt_data = space->crypt_data) { + status->space = space->id; mutex_enter(&crypt_data->mutex); status->scheme = crypt_data->type; status->keyserver_requests = crypt_data->keyserver_requests; diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 6abc7f0e1c2..23e7250f7c6 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -2214,7 +2214,7 @@ fil_write_flushed_lsn( /* If tablespace is not encrypted, stamp flush_lsn to first page of all system tablespace datafiles to avoid unnecessary error messages on possible downgrade. */ - if (space->crypt_data->min_key_version == 0) { + if (!space->crypt_data || space->crypt_data->min_key_version == 0) { fil_node_t* node; ulint sum_of_sizes = 0; diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index ab96befb700..187547ec435 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -725,7 +725,11 @@ fsp_header_init(ulint space_id, ulint size, mtr_t* mtr) fil_space_t* space = fil_space_acquire(space_id); ut_ad(space); - if (space->crypt_data) { + /* Write encryption metadata to page 0 if tablespace is + encrypted or encryption is disabled by table option. */ + if (space->crypt_data && + (space->crypt_data->should_encrypt() || + space->crypt_data->not_encrypted())) { space->crypt_data->write_page0(page, mtr); } diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index da790a32a11..0b413a510c2 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -8212,6 +8212,12 @@ i_s_dict_fill_tablespaces_encryption( fil_space_crypt_get_status(space, &status); + /* If tablespace id does not match, we did not find + encryption information for this tablespace. */ + if (space->id != status.space) { + goto skip; + } + OK(fields[TABLESPACES_ENCRYPTION_SPACE]->store(space->id)); OK(field_store_string(fields[TABLESPACES_ENCRYPTION_NAME], @@ -8246,6 +8252,7 @@ i_s_dict_fill_tablespaces_encryption( OK(schema_table_store_record(thd, table_to_fill)); +skip: DBUG_RETURN(0); } /*******************************************************************//** diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 0880f93c7fa..6fdf2bdf02e 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -1191,11 +1191,6 @@ check_first_page: ut_a(ret); if (i == 0) { - if (!crypt_data) { - crypt_data = fil_space_create_crypt_data(FIL_ENCRYPTION_DEFAULT, - FIL_DEFAULT_ENCRYPTION_KEY); - } - flags = FSP_FLAGS_PAGE_SSIZE(); fil_space_create(name, 0, flags, FIL_TABLESPACE, diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc index 683974d8920..d974b9a8586 100644 --- a/storage/xtradb/fil/fil0crypt.cc +++ b/storage/xtradb/fil/fil0crypt.cc @@ -2298,7 +2298,7 @@ fil_crypt_set_thread_cnt( os_thread_create(fil_crypt_thread, NULL, &rotation_thread_id); ib_logf(IB_LOG_LEVEL_INFO, - "Creating #%d thread id %lu total threads %u.", + "Creating #%d encryption thread id %lu total threads %u.", i+1, os_thread_pf(rotation_thread_id), new_cnt); } } else if (new_cnt < srv_n_fil_crypt_threads) { @@ -2312,6 +2312,14 @@ fil_crypt_set_thread_cnt( os_event_reset(fil_crypt_event); os_event_wait_time(fil_crypt_event, 1000000); } + + /* Send a message to encryption threads that there could be + something to do. */ + if (srv_n_fil_crypt_threads) { + mutex_enter(&fil_crypt_threads_mutex); + os_event_set(fil_crypt_threads_event); + mutex_exit(&fil_crypt_threads_mutex); + } } /********************************************************************* @@ -2456,9 +2464,10 @@ fil_space_crypt_get_status( ut_ad(space->n_pending_ops > 0); fil_crypt_read_crypt_data(const_cast<fil_space_t*>(space)); - status->space = space->id; + status->space = ULINT_UNDEFINED; if (fil_space_crypt_t* crypt_data = space->crypt_data) { + status->space = space->id; mutex_enter(&crypt_data->mutex); status->scheme = crypt_data->type; status->keyserver_requests = crypt_data->keyserver_requests; diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index dbf6501b183..8469cb1364d 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -2268,7 +2268,7 @@ fil_write_flushed_lsn( /* If tablespace is not encrypted, stamp flush_lsn to first page of all system tablespace datafiles to avoid unnecessary error messages on possible downgrade. */ - if (space->crypt_data->min_key_version == 0) { + if (!space->crypt_data || space->crypt_data->min_key_version == 0) { fil_node_t* node; ulint sum_of_sizes = 0; diff --git a/storage/xtradb/fsp/fsp0fsp.cc b/storage/xtradb/fsp/fsp0fsp.cc index b5491ac6550..13aa3b8b3f9 100644 --- a/storage/xtradb/fsp/fsp0fsp.cc +++ b/storage/xtradb/fsp/fsp0fsp.cc @@ -728,7 +728,11 @@ fsp_header_init(ulint space_id, ulint size, mtr_t* mtr) fil_space_t* space = fil_space_acquire(space_id); ut_ad(space); - if (space->crypt_data) { + /* Write encryption metadata to page 0 if tablespace is + encrypted or encryption is disabled by table option. */ + if (space->crypt_data && + (space->crypt_data->should_encrypt() || + space->crypt_data->not_encrypted())) { space->crypt_data->write_page0(page, mtr); } diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc index 9cef04c4244..4be4e93a19a 100644 --- a/storage/xtradb/handler/i_s.cc +++ b/storage/xtradb/handler/i_s.cc @@ -8524,6 +8524,12 @@ i_s_dict_fill_tablespaces_encryption( fil_space_crypt_get_status(space, &status); + /* If tablespace id does not match, we did not find + encryption information for this tablespace. */ + if (space->id != status.space) { + goto skip; + } + OK(fields[TABLESPACES_ENCRYPTION_SPACE]->store(space->id)); OK(field_store_string(fields[TABLESPACES_ENCRYPTION_NAME], @@ -8558,6 +8564,7 @@ i_s_dict_fill_tablespaces_encryption( OK(schema_table_store_record(thd, table_to_fill)); +skip: DBUG_RETURN(0); } /*******************************************************************//** diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc index aab0bc9282b..43fdb202a18 100644 --- a/storage/xtradb/srv/srv0start.cc +++ b/storage/xtradb/srv/srv0start.cc @@ -1228,11 +1228,6 @@ check_first_page: ut_a(ret); if (i == 0) { - if (!crypt_data) { - crypt_data = fil_space_create_crypt_data(FIL_ENCRYPTION_DEFAULT, - FIL_DEFAULT_ENCRYPTION_KEY); - } - flags = FSP_FLAGS_PAGE_SSIZE(); fil_space_create(name, 0, flags, FIL_TABLESPACE, |