mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-13557: Startup failure, unable to decrypt ibdata1
Fixes also MDEV-13488: InnoDB writes CRYPT_INFO even though encryption is not enabled. 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. fil_crypt_find_space_to_rotate: Decrease the amount of time waiting when nothing happens to better enable key rotation on startup. 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.
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
SET GLOBAL innodb_file_format = `Barracuda`;
|
||||
SET GLOBAL innodb_file_per_table = ON;
|
||||
FLUSH STATUS;
|
||||
create database innodb_test;
|
||||
use innodb_test;
|
||||
create table innodb_normal(c1 bigint not null, b char(200)) engine=innodb;
|
||||
@@ -50,40 +51,48 @@ insert into innodb_datadir1 select * from innodb_normal;
|
||||
insert into innodb_datadir2 select * from innodb_normal;
|
||||
insert into innodb_datadir3 select * from innodb_normal;
|
||||
commit;
|
||||
FLUSH STATUS;
|
||||
# Restart server and see how many page 0's are read
|
||||
# result should be less than actual number of tables
|
||||
# i.e. < 23 + 3 = 26
|
||||
show status like 'innodb_pages0_read%';
|
||||
Variable_name Value
|
||||
Innodb_pages0_read 19
|
||||
# result should actual number of tables except remote tables could be read twice
|
||||
# i.e. < 23 + 3*2 = 29
|
||||
SELECT VARIABLE_VALUE <= 29 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'innodb_pages0_read';
|
||||
VARIABLE_VALUE <= 29
|
||||
1
|
||||
use innodb_test;
|
||||
show status like 'innodb_pages0_read%';
|
||||
Variable_name Value
|
||||
Innodb_pages0_read 19
|
||||
SELECT VARIABLE_VALUE <= 29 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'innodb_pages0_read';
|
||||
VARIABLE_VALUE <= 29
|
||||
1
|
||||
use test;
|
||||
show status like 'innodb_pages0_read%';
|
||||
Variable_name Value
|
||||
Innodb_pages0_read 19
|
||||
SELECT VARIABLE_VALUE <= 29 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'innodb_pages0_read';
|
||||
VARIABLE_VALUE <= 29
|
||||
1
|
||||
set global innodb_encrypt_tables=OFF;
|
||||
# wait until tables are decrypted
|
||||
show status like 'innodb_pages0_read%';
|
||||
Variable_name Value
|
||||
Innodb_pages0_read 29
|
||||
# result should be actual number of tables except remote tables could be read twice
|
||||
# i.e. < 23 + 3*2 = 29
|
||||
SELECT VARIABLE_VALUE <= 29 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'innodb_pages0_read';
|
||||
VARIABLE_VALUE <= 29
|
||||
1
|
||||
use innodb_test;
|
||||
show status like 'innodb_pages0_read%';
|
||||
Variable_name Value
|
||||
Innodb_pages0_read 29
|
||||
SELECT VARIABLE_VALUE <= 29 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'innodb_pages0_read';
|
||||
VARIABLE_VALUE <= 29
|
||||
1
|
||||
use test;
|
||||
SELECT VARIABLE_VALUE <= 29 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'innodb_pages0_read';
|
||||
VARIABLE_VALUE <= 29
|
||||
1
|
||||
FLUSH STATUS;
|
||||
# restart and see number read page 0
|
||||
show status like 'innodb_pages0_read%';
|
||||
Variable_name Value
|
||||
Innodb_pages0_read 19
|
||||
SELECT VARIABLE_VALUE <= 29 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'innodb_pages0_read';
|
||||
VARIABLE_VALUE <= 29
|
||||
1
|
||||
use innodb_test;
|
||||
show status like 'innodb_pages0_read%';
|
||||
Variable_name Value
|
||||
Innodb_pages0_read 19
|
||||
SELECT VARIABLE_VALUE <= 29 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'innodb_pages0_read';
|
||||
VARIABLE_VALUE <= 29
|
||||
1
|
||||
use test;
|
||||
SELECT VARIABLE_VALUE <= 29 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'innodb_pages0_read';
|
||||
VARIABLE_VALUE <= 29
|
||||
1
|
||||
drop database innodb_test;
|
||||
show status like 'innodb_pages0_read%';
|
||||
Variable_name Value
|
||||
Innodb_pages0_read 29
|
||||
FLUSH STATUS;
|
||||
|
@@ -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;
|
||||
|
@@ -8,25 +8,22 @@ 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
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
# 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
|
||||
./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
|
||||
./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;
|
||||
@@ -34,16 +31,20 @@ 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
|
||||
./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
|
||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
|
||||
NAME
|
||||
./ibdata1
|
||||
# Success!
|
||||
# Restart mysqld --innodb_encrypt_tables=0 --innodb_encryption_threads=0
|
||||
SHOW VARIABLES LIKE 'innodb_encrypt%';
|
||||
@@ -53,9 +54,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
|
||||
FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION
|
||||
WHERE MIN_KEY_VERSION <> 0;
|
||||
should_be_1
|
||||
1
|
||||
# Restart mysqld again...with default options
|
||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
|
||||
NAME
|
||||
./ibdata1
|
||||
SELECT NAME FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0;
|
||||
NAME
|
||||
|
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user