mirror of
https://github.com/MariaDB/server.git
synced 2025-06-15 00:02:46 +03:00
MDEV-8164: Server crashes in pfs_mutex_enter_func after fil_crypt_is_closing or alike
Analysis: Problem was that tablespaces not encrypted might not have crypt_data stored on disk. Fixed by always creating crypt_data to memory cache of the tablespace. MDEV-8138: strange results from encrypt-and-grep test Analysis: crypt_data->type is not updated correctly on memory cache. This caused problem with state tranfer on encrypted => unencrypted => encrypted. Fixed by updating memory cache of crypt_data->type correctly based on current srv_encrypt_tables value to either CRYPT_SCHEME_1 or CRYPT_SCHEME_UNENCRYPTED.
This commit is contained in:
14
mysql-test/suite/encryption/disabled.def
Normal file
14
mysql-test/suite/encryption/disabled.def
Normal file
@ -0,0 +1,14 @@
|
||||
##############################################################################
|
||||
#
|
||||
# List the test cases that are to be disabled temporarily.
|
||||
#
|
||||
# Separate the test case name and the comment with ':'.
|
||||
#
|
||||
# <testcasename> : BUG#<xxxx> <date disabled> <disabler> <comment>
|
||||
#
|
||||
# Do not use any TAB characters for whitespace.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
innodb_scrub : MDEV-8139
|
||||
innodb_scrub_compressed : MDEV-8139
|
42
mysql-test/suite/encryption/r/encrypt_and_grep.result
Normal file
42
mysql-test/suite/encryption/r/encrypt_and_grep.result
Normal file
@ -0,0 +1,42 @@
|
||||
SET GLOBAL innodb_file_per_table = ON;
|
||||
create table t1 (a varchar(255)) engine=innodb encrypted=yes;
|
||||
create table t2 (a varchar(255)) engine=innodb;
|
||||
create table t3 (a varchar(255)) engine=innodb encrypted=no;
|
||||
insert t1 values (repeat('foobar', 42));
|
||||
insert t2 values (repeat('temp', 42));
|
||||
insert t3 values (repeat('dummy', 42));
|
||||
# Wait max 10 min for key encryption threads to encrypt all spaces
|
||||
# t1 yes on expecting NOT FOUND
|
||||
NOT FOUND /foobar/ in t1.ibd
|
||||
# t2 ... on expecting NOT FOUND
|
||||
NOT FOUND /temp/ in t2.ibd
|
||||
# t3 no on expecting FOUND
|
||||
FOUND /dummy/ in t3.ibd
|
||||
# ibdata1 expecting NOT FOUND
|
||||
NOT FOUND /foobar/ in ibdata1
|
||||
# Now turn off encryption and wait for threads to decrypt everything
|
||||
SET GLOBAL innodb_encryption_threads = 4;
|
||||
SET GLOBAL innodb_encrypt_tables = off;
|
||||
# Wait max 10 min for key encryption threads to decrypt all spaces
|
||||
# t1 yes on expecting NOT FOUND
|
||||
NOT FOUND /foobar/ in t1.ibd
|
||||
# t2 ... on expecting FOUND
|
||||
FOUND /temp/ in t2.ibd
|
||||
# t3 no on expecting FOUND
|
||||
FOUND /dummy/ in t3.ibd
|
||||
# ibdata1 expecting NOT FOUND
|
||||
NOT FOUND /foobar/ in ibdata1
|
||||
# Now turn on encryption and wait for threads to encrypt all spaces
|
||||
SET GLOBAL innodb_encryption_threads = 4;
|
||||
SET GLOBAL innodb_encrypt_tables = on;
|
||||
# Wait max 10 min for key encryption threads to encrypt all spaces
|
||||
# t1 yes on expecting NOT FOUND
|
||||
NOT FOUND /foobar/ in t1.ibd
|
||||
# t2 ... on expecting NOT FOUND
|
||||
NOT FOUND /temp/ in t2.ibd
|
||||
# t3 no on expecting FOUND
|
||||
FOUND /dummy/ in t3.ibd
|
||||
# ibdata1 expecting NOT FOUND
|
||||
NOT FOUND /foobar/ in ibdata1
|
||||
# TODO: add shutdown + grep tests
|
||||
drop table t1, t2, t3;
|
@ -0,0 +1,325 @@
|
||||
SET default_storage_engine = InnoDB;
|
||||
CREATE TABLE t1 (pk INT PRIMARY KEY, c VARCHAR(256));
|
||||
CREATE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
drop table t1,t2;
|
||||
SET GLOBAL innodb_encryption_threads = 0;
|
8
mysql-test/suite/encryption/t/encrypt_and_grep.opt
Normal file
8
mysql-test/suite/encryption/t/encrypt_and_grep.opt
Normal file
@ -0,0 +1,8 @@
|
||||
--innodb-encrypt-tables=ON
|
||||
--innodb-encrypt-log=ON
|
||||
--innodb-encryption-rotate-key-age=15
|
||||
--innodb-encryption-threads=4
|
||||
--innodb-tablespaces-encryption
|
||||
--innodb-max-dirty-pages-pct=0.001
|
||||
|
||||
|
104
mysql-test/suite/encryption/t/encrypt_and_grep.test
Normal file
104
mysql-test/suite/encryption/t/encrypt_and_grep.test
Normal file
@ -0,0 +1,104 @@
|
||||
-- source include/have_innodb.inc
|
||||
-- source include/have_example_key_management_plugin.inc
|
||||
|
||||
# embedded does not support restart
|
||||
-- source include/not_embedded.inc
|
||||
|
||||
#
|
||||
# MDEV-8138: strange results from encrypt-and-grep test
|
||||
#
|
||||
--let $MYSQLD_DATADIR=`select @@datadir`
|
||||
--let ib1_IBD = $MYSQLD_DATADIR/ibdata1
|
||||
--let t1_IBD = $MYSQLD_DATADIR/test/t1.ibd
|
||||
--let t2_IBD = $MYSQLD_DATADIR/test/t2.ibd
|
||||
--let t3_IBD = $MYSQLD_DATADIR/test/t3.ibd
|
||||
--let SEARCH_RANGE = 10000000
|
||||
--let SEARCH_PATTERN=foobar
|
||||
|
||||
SET GLOBAL innodb_file_per_table = ON;
|
||||
|
||||
create table t1 (a varchar(255)) engine=innodb encrypted=yes;
|
||||
create table t2 (a varchar(255)) engine=innodb;
|
||||
create table t3 (a varchar(255)) engine=innodb encrypted=no;
|
||||
|
||||
insert t1 values (repeat('foobar', 42));
|
||||
insert t2 values (repeat('temp', 42));
|
||||
insert t3 values (repeat('dummy', 42));
|
||||
|
||||
--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
|
||||
|
||||
--let SEARCH_PATTERN=foobar
|
||||
--echo # t1 yes on expecting NOT FOUND
|
||||
-- let SEARCH_FILE=$t1_IBD
|
||||
-- source include/search_pattern_in_file.inc
|
||||
--let SEARCH_PATTERN=temp
|
||||
--echo # t2 ... on expecting NOT FOUND
|
||||
-- let SEARCH_FILE=$t2_IBD
|
||||
-- source include/search_pattern_in_file.inc
|
||||
--let SEARCH_PATTERN=dummy
|
||||
--echo # t3 no on expecting FOUND
|
||||
-- let SEARCH_FILE=$t3_IBD
|
||||
-- source include/search_pattern_in_file.inc
|
||||
--let SEARCH_PATTERN=foobar
|
||||
--echo # ibdata1 expecting NOT FOUND
|
||||
-- let SEARCH_FILE=$ib1_IBD
|
||||
-- source include/search_pattern_in_file.inc
|
||||
|
||||
--echo # Now turn off encryption and wait for threads to decrypt everything
|
||||
SET GLOBAL innodb_encryption_threads = 4;
|
||||
SET GLOBAL innodb_encrypt_tables = off;
|
||||
|
||||
--echo # Wait max 10 min for key encryption threads to decrypt all spaces
|
||||
--let $wait_timeout= 600
|
||||
--let $wait_condition=SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION <> 0;
|
||||
--source include/wait_condition.inc
|
||||
|
||||
--let SEARCH_PATTERN=foobar
|
||||
--echo # t1 yes on expecting NOT FOUND
|
||||
-- let SEARCH_FILE=$t1_IBD
|
||||
-- source include/search_pattern_in_file.inc
|
||||
--let SEARCH_PATTERN=temp
|
||||
--echo # t2 ... on expecting FOUND
|
||||
-- let SEARCH_FILE=$t2_IBD
|
||||
-- source include/search_pattern_in_file.inc
|
||||
--let SEARCH_PATTERN=dummy
|
||||
--echo # t3 no on expecting FOUND
|
||||
-- let SEARCH_FILE=$t3_IBD
|
||||
-- source include/search_pattern_in_file.inc
|
||||
--let SEARCH_PATTERN=foobar
|
||||
--echo # ibdata1 expecting NOT FOUND
|
||||
-- let SEARCH_FILE=$ib1_IBD
|
||||
-- source include/search_pattern_in_file.inc
|
||||
|
||||
--echo # Now turn on encryption and wait for threads to encrypt all spaces
|
||||
SET GLOBAL innodb_encryption_threads = 4;
|
||||
SET GLOBAL innodb_encrypt_tables = on;
|
||||
|
||||
--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
|
||||
|
||||
--let SEARCH_PATTERN=foobar
|
||||
--echo # t1 yes on expecting NOT FOUND
|
||||
-- let SEARCH_FILE=$t1_IBD
|
||||
-- source include/search_pattern_in_file.inc
|
||||
--let SEARCH_PATTERN=temp
|
||||
--echo # t2 ... on expecting NOT FOUND
|
||||
-- let SEARCH_FILE=$t2_IBD
|
||||
-- source include/search_pattern_in_file.inc
|
||||
--let SEARCH_PATTERN=dummy
|
||||
--echo # t3 no on expecting FOUND
|
||||
-- let SEARCH_FILE=$t3_IBD
|
||||
-- source include/search_pattern_in_file.inc
|
||||
--let SEARCH_PATTERN=foobar
|
||||
--echo # ibdata1 expecting NOT FOUND
|
||||
-- let SEARCH_FILE=$ib1_IBD
|
||||
-- source include/search_pattern_in_file.inc
|
||||
|
||||
--echo # TODO: add shutdown + grep tests
|
||||
|
||||
drop table t1, t2, t3;
|
@ -0,0 +1,3 @@
|
||||
--plugin-load-add=$FILE_KEY_MANAGEMENT_SO
|
||||
--file-key-management-filekey=FILE:$MTR_SUITE_DIR/t/filekeys-data.key
|
||||
--file-key-management-filename=$MTR_SUITE_DIR/t/filekeys-data.enc
|
@ -0,0 +1,25 @@
|
||||
--source include/have_innodb.inc
|
||||
|
||||
#
|
||||
# MDEV-8164: Server crashes in pfs_mutex_enter_func after fil_crypt_is_closing or alike
|
||||
#
|
||||
SET default_storage_engine = InnoDB;
|
||||
|
||||
CREATE TABLE t1 (pk INT PRIMARY KEY, c VARCHAR(256));
|
||||
CREATE TABLE t2 AS SELECT * FROM t1;
|
||||
|
||||
let $i = 40;
|
||||
while ($i)
|
||||
{
|
||||
SET GLOBAL innodb_encrypt_tables = ON;
|
||||
SET GLOBAL innodb_encryption_threads = 1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
SET GLOBAL innodb_encryption_rotation_iops = 100;
|
||||
SET GLOBAL innodb_encrypt_tables = OFF;
|
||||
CREATE OR REPLACE TABLE t2 AS SELECT * FROM t1;
|
||||
CREATE OR REPLACE TABLE t1 AS SELECT * FROM t2;
|
||||
dec $i;
|
||||
}
|
||||
drop table t1,t2;
|
||||
SET GLOBAL innodb_encryption_threads = 0;
|
@ -4225,6 +4225,7 @@ buf_page_io_complete(
|
||||
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
|
||||
const ibool uncompressed = (buf_page_get_state(bpage)
|
||||
== BUF_BLOCK_FILE_PAGE);
|
||||
fil_space_t* space = NULL;
|
||||
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
|
||||
@ -4323,12 +4324,18 @@ buf_page_io_complete(
|
||||
goto page_not_corrupt;
|
||||
;);
|
||||
corrupt:
|
||||
fil_system_enter();
|
||||
space = fil_space_get_by_id(bpage->space);
|
||||
fil_system_exit();
|
||||
|
||||
fprintf(stderr,
|
||||
"InnoDB: Database page corruption on disk"
|
||||
" or a failed\n"
|
||||
"InnoDB: file read of page %lu.\n"
|
||||
"InnoDB: space %lu file %s read of page %lu.\n"
|
||||
"InnoDB: You may have to recover"
|
||||
" from a backup.\n",
|
||||
bpage->space,
|
||||
space ? space->name : "NULL",
|
||||
(ulong) bpage->offset);
|
||||
buf_page_print(frame, buf_page_get_zip_size(bpage),
|
||||
BUF_PAGE_PRINT_NO_CRASH);
|
||||
|
@ -43,6 +43,8 @@ Modified Jan Lindström jan.lindstrom@mariadb.com
|
||||
/** Mutex for keys */
|
||||
UNIV_INTERN ib_mutex_t fil_crypt_key_mutex;
|
||||
|
||||
static bool fil_crypt_threads_inited = false;
|
||||
|
||||
#ifdef UNIV_PFS_MUTEX
|
||||
UNIV_INTERN mysql_pfs_key_t fil_crypt_key_mutex_key;
|
||||
#endif
|
||||
@ -107,6 +109,8 @@ UNIV_INTERN mysql_pfs_key_t fil_crypt_data_mutex_key;
|
||||
static bool
|
||||
fil_crypt_needs_rotation(
|
||||
/*=====================*/
|
||||
fil_encryption_t encrypt_mode, /*!< in: Encryption
|
||||
mode */
|
||||
uint key_version, /*!< in: Key version */
|
||||
uint latest_key_version, /*!< in: Latest key version */
|
||||
uint rotate_key_age); /*!< in: When to rotate */
|
||||
@ -154,13 +158,14 @@ Get the latest(key-version), waking the encrypt thread, if needed */
|
||||
static inline
|
||||
uint
|
||||
fil_crypt_get_latest_key_version(
|
||||
/*=====================*/
|
||||
/*=============================*/
|
||||
fil_space_crypt_t* crypt_data) /*!< in: crypt data */
|
||||
{
|
||||
uint rc = encryption_key_get_latest_version(crypt_data->key_id);
|
||||
|
||||
if (fil_crypt_needs_rotation(crypt_data->min_key_version,
|
||||
rc, srv_fil_crypt_rotate_key_age)) {
|
||||
if (fil_crypt_needs_rotation(crypt_data->encryption,
|
||||
crypt_data->min_key_version,
|
||||
rc, srv_fil_crypt_rotate_key_age)) {
|
||||
os_event_set(fil_crypt_threads_event);
|
||||
}
|
||||
|
||||
@ -169,7 +174,12 @@ fil_crypt_get_latest_key_version(
|
||||
|
||||
/******************************************************************
|
||||
Mutex helper for crypt_data->scheme */
|
||||
static void crypt_data_scheme_locker(st_encryption_scheme *scheme, int exit)
|
||||
static
|
||||
void
|
||||
crypt_data_scheme_locker(
|
||||
/*=====================*/
|
||||
st_encryption_scheme* scheme,
|
||||
int exit)
|
||||
{
|
||||
fil_space_crypt_t* crypt_data =
|
||||
static_cast<fil_space_crypt_t*>(scheme);
|
||||
@ -220,7 +230,7 @@ Merge fil_space_crypt_t object */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_merge_crypt_data(
|
||||
/*====================*/
|
||||
/*=======================*/
|
||||
fil_space_crypt_t* dst,/*!< out: Crypt data */
|
||||
const fil_space_crypt_t* src)/*!< in: Crypt data */
|
||||
{
|
||||
@ -236,6 +246,7 @@ fil_space_merge_crypt_data(
|
||||
/* no support for changing iv (yet?) */
|
||||
ut_a(memcmp(src->iv, dst->iv, sizeof(src->iv)) == 0);
|
||||
|
||||
dst->encryption = src->encryption;
|
||||
dst->type = src->type;
|
||||
dst->min_key_version = src->min_key_version;
|
||||
dst->keyserver_requests += src->keyserver_requests;
|
||||
@ -255,8 +266,13 @@ fil_space_read_crypt_data(
|
||||
ulint offset) /*!< in: offset */
|
||||
{
|
||||
if (memcmp(page + offset, EMPTY_PATTERN, MAGIC_SZ) == 0) {
|
||||
/* crypt is not stored */
|
||||
return NULL;
|
||||
/* crypt is not stored but create memory cache for
|
||||
not system tablespace */
|
||||
if (space != 0) {
|
||||
return fil_space_create_crypt_data(FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (memcmp(page + offset, CRYPT_MAGIC, MAGIC_SZ) != 0) {
|
||||
@ -272,7 +288,12 @@ fil_space_read_crypt_data(
|
||||
page[offset + 3],
|
||||
page[offset + 4],
|
||||
page[offset + 5]);
|
||||
return NULL;
|
||||
/* Create memory cache for not system tablespace */
|
||||
if (space != 0) {
|
||||
return fil_space_create_crypt_data(FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ulint type = mach_read_from_1(page + offset + MAGIC_SZ + 0);
|
||||
@ -542,11 +563,12 @@ Check if page shall be encrypted before write
|
||||
UNIV_INTERN
|
||||
bool
|
||||
fil_space_check_encryption_write(
|
||||
/*==============================*/
|
||||
ulint space) /*!< in: tablespace id */
|
||||
/*=============================*/
|
||||
ulint space) /*!< in: tablespace id */
|
||||
{
|
||||
if (!srv_encrypt_tables)
|
||||
if (!srv_encrypt_tables) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space);
|
||||
|
||||
@ -599,6 +621,8 @@ fil_space_encrypt(
|
||||
return;
|
||||
}
|
||||
|
||||
ut_ad(crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF);
|
||||
|
||||
key_version = fil_crypt_get_latest_key_version(crypt_data);
|
||||
|
||||
if (key_version == ENCRYPTION_KEY_VERSION_INVALID) {
|
||||
@ -742,6 +766,8 @@ fil_space_decrypt(
|
||||
return false; /* page not decrypted */
|
||||
}
|
||||
|
||||
ut_ad(crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF);
|
||||
|
||||
/* read space & offset & lsn */
|
||||
ulint space = mach_read_from_4(
|
||||
src_frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
|
||||
@ -937,12 +963,15 @@ Check if a key needs rotation given a key_state
|
||||
static bool
|
||||
fil_crypt_needs_rotation(
|
||||
/*=====================*/
|
||||
fil_encryption_t encrypt_mode, /*!< in: Encryption
|
||||
mode */
|
||||
uint key_version, /*!< in: Key version */
|
||||
uint latest_key_version, /*!< in: Latest key version */
|
||||
uint rotate_key_age) /*!< in: When to rotate */
|
||||
{
|
||||
if (key_version == ENCRYPTION_KEY_VERSION_INVALID)
|
||||
if (key_version == ENCRYPTION_KEY_VERSION_INVALID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (key_version == 0 && latest_key_version != 0) {
|
||||
/* this is rotation unencrypted => encrypted
|
||||
@ -951,8 +980,11 @@ fil_crypt_needs_rotation(
|
||||
}
|
||||
|
||||
if (latest_key_version == 0 && key_version != 0) {
|
||||
/* this is rotation encrypted => unencrypted */
|
||||
return true;
|
||||
if (encrypt_mode == FIL_SPACE_ENCRYPTION_DEFAULT) {
|
||||
/* this is rotation encrypted => unencrypted */
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* this is rotation encrypted => encrypted,
|
||||
@ -973,11 +1005,15 @@ fil_crypt_is_closing(
|
||||
/*=================*/
|
||||
ulint space) /*!< in: FIL space id */
|
||||
{
|
||||
bool closing;
|
||||
bool closing=true;
|
||||
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
closing = crypt_data->closing;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
|
||||
if (crypt_data) {
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
closing = crypt_data->closing;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
}
|
||||
|
||||
return closing;
|
||||
}
|
||||
|
||||
@ -1189,6 +1225,7 @@ Check if space needs rotation given a key_state
|
||||
static
|
||||
bool
|
||||
fil_crypt_space_needs_rotation(
|
||||
/*===========================*/
|
||||
rotate_thread_t* state, /*!< in: Key rotation state */
|
||||
key_state_t* key_state, /*!< in: Key state */
|
||||
bool* recheck) /*!< out: needs recheck ? */
|
||||
@ -1228,11 +1265,6 @@ fil_crypt_space_needs_rotation(
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
|
||||
do {
|
||||
if (crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) {
|
||||
/* This space is unencrypted by user request */
|
||||
break;
|
||||
}
|
||||
|
||||
/* prevent threads from starting to rotate space */
|
||||
if (crypt_data->rotate_state.starting) {
|
||||
/* recheck this space later */
|
||||
@ -1255,6 +1287,7 @@ fil_crypt_space_needs_rotation(
|
||||
}
|
||||
|
||||
bool need_key_rotation = fil_crypt_needs_rotation(
|
||||
crypt_data->encryption,
|
||||
crypt_data->min_key_version,
|
||||
key_state->key_version, key_state->rotate_key_age);
|
||||
|
||||
@ -1351,7 +1384,7 @@ used when inside a space */
|
||||
static
|
||||
void
|
||||
fil_crypt_realloc_iops(
|
||||
/*========================*/
|
||||
/*===================*/
|
||||
rotate_thread_t *state) /*!< in: Key rotation status */
|
||||
{
|
||||
ut_a(state->allocated_iops > 0);
|
||||
@ -1444,7 +1477,7 @@ Return allocated iops to global */
|
||||
static
|
||||
void
|
||||
fil_crypt_return_iops(
|
||||
/*========================*/
|
||||
/*==================*/
|
||||
rotate_thread_t *state) /*!< in: Key rotation status */
|
||||
{
|
||||
if (state->allocated_iops > 0) {
|
||||
@ -1526,11 +1559,17 @@ fil_crypt_start_rotate_space(
|
||||
ulint space = state->space;
|
||||
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
|
||||
|
||||
ut_ad(crypt_data);
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
ut_ad(key_state->key_id == crypt_data->key_id);
|
||||
|
||||
if (crypt_data->rotate_state.active_threads == 0) {
|
||||
/* only first thread needs to init */
|
||||
if (crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) {
|
||||
crypt_data->type = CRYPT_SCHEME_UNENCRYPTED;
|
||||
} else {
|
||||
crypt_data->type = CRYPT_SCHEME_1;
|
||||
}
|
||||
crypt_data->rotate_state.next_offset = 1; // skip page 0
|
||||
/* no need to rotate beyond current max
|
||||
* if space extends, it will be encrypted with newer version */
|
||||
@ -1568,28 +1607,33 @@ fil_crypt_find_page_to_rotate(
|
||||
ulint space = state->space;
|
||||
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
|
||||
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
ut_ad(key_state->key_id == crypt_data->key_id);
|
||||
/* Space might already be dropped */
|
||||
if (crypt_data) {
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
ut_ad(key_state->key_id == crypt_data->key_id);
|
||||
|
||||
if (crypt_data->closing == false &&
|
||||
crypt_data->rotate_state.next_offset <
|
||||
crypt_data->rotate_state.max_offset) {
|
||||
if (crypt_data->closing == false &&
|
||||
crypt_data->rotate_state.next_offset <
|
||||
crypt_data->rotate_state.max_offset) {
|
||||
|
||||
state->offset = crypt_data->rotate_state.next_offset;
|
||||
ulint remaining = crypt_data->rotate_state.max_offset -
|
||||
crypt_data->rotate_state.next_offset;
|
||||
state->offset = crypt_data->rotate_state.next_offset;
|
||||
ulint remaining = crypt_data->rotate_state.max_offset -
|
||||
crypt_data->rotate_state.next_offset;
|
||||
|
||||
if (batch <= remaining)
|
||||
state->batch = batch;
|
||||
else
|
||||
state->batch = remaining;
|
||||
if (batch <= remaining) {
|
||||
state->batch = batch;
|
||||
} else {
|
||||
state->batch = remaining;
|
||||
}
|
||||
|
||||
crypt_data->rotate_state.next_offset += batch;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
crypt_data->rotate_state.next_offset += batch;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1636,6 +1680,7 @@ Get a page and compute sleep time
|
||||
static
|
||||
buf_block_t*
|
||||
fil_crypt_get_page_throttle_func(
|
||||
/*=============================*/
|
||||
rotate_thread_t* state, /*!< in/out: Key rotation state */
|
||||
ulint space, /*!< in: FIL space id */
|
||||
uint zip_size, /*!< in: compressed size if
|
||||
@ -1752,7 +1797,7 @@ Rotate one page */
|
||||
static
|
||||
void
|
||||
fil_crypt_rotate_page(
|
||||
/*===================*/
|
||||
/*==================*/
|
||||
const key_state_t* key_state, /*!< in: Key state */
|
||||
rotate_thread_t* state) /*!< in: Key rotation state */
|
||||
{
|
||||
@ -1791,8 +1836,10 @@ fil_crypt_rotate_page(
|
||||
if (kv == 0 &&
|
||||
fil_crypt_is_page_uninitialized(frame, zip_size)) {
|
||||
;
|
||||
} else if (fil_crypt_needs_rotation(kv, key_state->key_version,
|
||||
key_state->rotate_key_age)) {
|
||||
} else if (fil_crypt_needs_rotation(
|
||||
crypt_data->encryption,
|
||||
kv, key_state->key_version,
|
||||
key_state->rotate_key_age)) {
|
||||
|
||||
/* page can be "fresh" i.e never written in case
|
||||
* kv == 0 or it should have a key version at least
|
||||
@ -1812,11 +1859,13 @@ fil_crypt_rotate_page(
|
||||
/* statistics */
|
||||
state->crypt_stat.pages_modified++;
|
||||
} else {
|
||||
ut_a(kv >= crypt_data->min_key_version ||
|
||||
(kv == 0 && key_state->key_version == 0));
|
||||
if (crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF) {
|
||||
ut_a(kv >= crypt_data->min_key_version ||
|
||||
(kv == 0 && key_state->key_version == 0));
|
||||
|
||||
if (kv < state->min_key_version_found) {
|
||||
state->min_key_version_found = kv;
|
||||
if (kv < state->min_key_version_found) {
|
||||
state->min_key_version_found = kv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1878,6 +1927,7 @@ fil_crypt_rotate_page(
|
||||
/* if we just detected that scrubbing was turned off
|
||||
* update global state to reflect this */
|
||||
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
|
||||
ut_ad(crypt_data);
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
crypt_data->rotate_state.scrubbing.is_active = false;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
@ -2006,68 +2056,73 @@ fil_crypt_complete_rotate_space(
|
||||
{
|
||||
ulint space = state->space;
|
||||
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
|
||||
/**
|
||||
* Update crypt data state with state from thread
|
||||
*/
|
||||
if (state->min_key_version_found <
|
||||
crypt_data->rotate_state.min_key_version_found) {
|
||||
crypt_data->rotate_state.min_key_version_found =
|
||||
state->min_key_version_found;
|
||||
}
|
||||
/* Space might already be dropped */
|
||||
if (crypt_data) {
|
||||
ut_ad(crypt_data);
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
|
||||
if (state->end_lsn > crypt_data->rotate_state.end_lsn) {
|
||||
crypt_data->rotate_state.end_lsn = state->end_lsn;
|
||||
}
|
||||
/**
|
||||
* Update crypt data state with state from thread
|
||||
*/
|
||||
if (state->min_key_version_found <
|
||||
crypt_data->rotate_state.min_key_version_found) {
|
||||
crypt_data->rotate_state.min_key_version_found =
|
||||
state->min_key_version_found;
|
||||
}
|
||||
|
||||
ut_a(crypt_data->rotate_state.active_threads > 0);
|
||||
crypt_data->rotate_state.active_threads--;
|
||||
bool last = crypt_data->rotate_state.active_threads == 0;
|
||||
if (state->end_lsn > crypt_data->rotate_state.end_lsn) {
|
||||
crypt_data->rotate_state.end_lsn = state->end_lsn;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if space is fully done
|
||||
* this as when threads shutdown, it could be that we "complete"
|
||||
* iterating before we have scanned the full space.
|
||||
*/
|
||||
bool done = crypt_data->rotate_state.next_offset >=
|
||||
crypt_data->rotate_state.max_offset;
|
||||
ut_a(crypt_data->rotate_state.active_threads > 0);
|
||||
crypt_data->rotate_state.active_threads--;
|
||||
bool last = crypt_data->rotate_state.active_threads == 0;
|
||||
|
||||
/**
|
||||
* we should flush space if we're last thread AND
|
||||
* the iteration is done
|
||||
*/
|
||||
bool should_flush = last && done;
|
||||
/**
|
||||
* check if space is fully done
|
||||
* this as when threads shutdown, it could be that we "complete"
|
||||
* iterating before we have scanned the full space.
|
||||
*/
|
||||
bool done = crypt_data->rotate_state.next_offset >=
|
||||
crypt_data->rotate_state.max_offset;
|
||||
|
||||
if (should_flush) {
|
||||
/* we're the last active thread */
|
||||
crypt_data->rotate_state.flushing = true;
|
||||
crypt_data->min_key_version =
|
||||
crypt_data->rotate_state.min_key_version_found;
|
||||
}
|
||||
/**
|
||||
* we should flush space if we're last thread AND
|
||||
* the iteration is done
|
||||
*/
|
||||
bool should_flush = last && done;
|
||||
|
||||
/* inform scrubbing */
|
||||
crypt_data->rotate_state.scrubbing.is_active = false;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
|
||||
/* all threads must call btr_scrub_complete_space wo/ mutex held */
|
||||
if (btr_scrub_complete_space(&state->scrub_data) == true) {
|
||||
if (should_flush) {
|
||||
/* only last thread updates last_scrub_completed */
|
||||
/* we're the last active thread */
|
||||
crypt_data->rotate_state.flushing = true;
|
||||
crypt_data->min_key_version =
|
||||
crypt_data->rotate_state.min_key_version_found;
|
||||
}
|
||||
|
||||
/* inform scrubbing */
|
||||
crypt_data->rotate_state.scrubbing.is_active = false;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
|
||||
/* all threads must call btr_scrub_complete_space wo/ mutex held */
|
||||
if (btr_scrub_complete_space(&state->scrub_data) == true) {
|
||||
if (should_flush) {
|
||||
/* only last thread updates last_scrub_completed */
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
crypt_data->rotate_state.scrubbing.
|
||||
last_scrub_completed = time(0);
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
if (should_flush) {
|
||||
fil_crypt_flush_space(state, space);
|
||||
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
crypt_data->rotate_state.scrubbing.
|
||||
last_scrub_completed = time(0);
|
||||
crypt_data->rotate_state.flushing = false;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
if (should_flush) {
|
||||
fil_crypt_flush_space(state, space);
|
||||
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
crypt_data->rotate_state.flushing = false;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
@ -2194,8 +2249,8 @@ fil_crypt_set_thread_cnt(
|
||||
os_thread_id_t rotation_thread_id;
|
||||
os_thread_create(fil_crypt_thread, NULL, &rotation_thread_id);
|
||||
ib_logf(IB_LOG_LEVEL_INFO,
|
||||
"Creating #%d thread id %lu total threads %du\n",
|
||||
i, os_thread_pf(rotation_thread_id), new_cnt);
|
||||
"Creating #%d thread id %lu total threads %u\n",
|
||||
i+1, os_thread_pf(rotation_thread_id), new_cnt);
|
||||
}
|
||||
} else if (new_cnt < srv_n_fil_crypt_threads) {
|
||||
srv_n_fil_crypt_threads = new_cnt;
|
||||
@ -2232,6 +2287,18 @@ fil_crypt_set_rotation_iops(
|
||||
os_event_set(fil_crypt_threads_event);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
Adjust encrypt tables */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_crypt_set_encrypt_tables(
|
||||
/*=========================*/
|
||||
uint val) /*!< in: New srv_encrypt_tables setting */
|
||||
{
|
||||
srv_encrypt_tables = val;
|
||||
os_event_set(fil_crypt_threads_event);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
Init threads for key rotation */
|
||||
UNIV_INTERN
|
||||
@ -2243,6 +2310,7 @@ fil_crypt_threads_init()
|
||||
fil_crypt_threads_event = os_event_create();
|
||||
mutex_create(fil_crypt_threads_mutex_key,
|
||||
&fil_crypt_threads_mutex, SYNC_NO_ORDER_CHECK);
|
||||
fil_crypt_threads_inited = true;
|
||||
|
||||
uint cnt = srv_n_fil_crypt_threads;
|
||||
srv_n_fil_crypt_threads = 0;
|
||||
@ -2279,7 +2347,7 @@ fil_space_crypt_mark_space_closing(
|
||||
/*===============================*/
|
||||
ulint space) /*!< in: Space id */
|
||||
{
|
||||
if (!srv_encrypt_tables) {
|
||||
if (!fil_crypt_threads_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -6857,7 +6857,7 @@ Get crypt data for a tablespace */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_set_crypt_data(
|
||||
/*==================*/
|
||||
/*=====================*/
|
||||
ulint id, /*!< in: space id */
|
||||
fil_space_crypt_t* crypt_data) /*!< in: crypt data */
|
||||
{
|
||||
@ -6872,19 +6872,26 @@ fil_space_set_crypt_data(
|
||||
|
||||
if (space != NULL) {
|
||||
if (space->crypt_data != NULL) {
|
||||
/* Here we need to release fil_system mutex to
|
||||
avoid mutex deadlock assertion. Here we would
|
||||
taje mutexes in order fil_system, crypt_data and
|
||||
in fil_crypt_start_encrypting_space we would
|
||||
take them in order crypt_data, fil_system
|
||||
at fil_space_get_flags -> fil_space_get_space */
|
||||
mutex_exit(&fil_system->mutex);
|
||||
fil_space_merge_crypt_data(space->crypt_data,
|
||||
crypt_data);
|
||||
free_crypt_data = crypt_data;
|
||||
} else {
|
||||
space->crypt_data = crypt_data;
|
||||
mutex_exit(&fil_system->mutex);
|
||||
}
|
||||
} else {
|
||||
/* there is a small risk that tablespace has been deleted */
|
||||
free_crypt_data = crypt_data;
|
||||
mutex_exit(&fil_system->mutex);
|
||||
}
|
||||
|
||||
mutex_exit(&fil_system->mutex);
|
||||
|
||||
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
|
||||
|
@ -17821,6 +17821,7 @@ which control InnoDB "status monitor" output to the error log.
|
||||
static
|
||||
void
|
||||
innodb_status_output_update(
|
||||
/*========================*/
|
||||
THD* thd __attribute__((unused)),
|
||||
struct st_mysql_sys_var* var __attribute__((unused)),
|
||||
void* var_ptr __attribute__((unused)),
|
||||
@ -17836,7 +17837,7 @@ Update the system variable innodb_encryption_threads */
|
||||
static
|
||||
void
|
||||
innodb_encryption_threads_update(
|
||||
/*=========================*/
|
||||
/*=============================*/
|
||||
THD* thd, /*!< in: thread handle */
|
||||
struct st_mysql_sys_var* var, /*!< in: pointer to
|
||||
system variable */
|
||||
@ -17853,7 +17854,7 @@ Update the system variable innodb_encryption_rotate_key_age */
|
||||
static
|
||||
void
|
||||
innodb_encryption_rotate_key_age_update(
|
||||
/*=========================*/
|
||||
/*====================================*/
|
||||
THD* thd, /*!< in: thread handle */
|
||||
struct st_mysql_sys_var* var, /*!< in: pointer to
|
||||
system variable */
|
||||
@ -17870,7 +17871,7 @@ Update the system variable innodb_encryption_rotation_iops */
|
||||
static
|
||||
void
|
||||
innodb_encryption_rotation_iops_update(
|
||||
/*=========================*/
|
||||
/*===================================*/
|
||||
THD* thd, /*!< in: thread handle */
|
||||
struct st_mysql_sys_var* var, /*!< in: pointer to
|
||||
system variable */
|
||||
@ -17882,6 +17883,23 @@ innodb_encryption_rotation_iops_update(
|
||||
fil_crypt_set_rotation_iops(*static_cast<const uint*>(save));
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
Update the system variable innodb_encrypt_tables*/
|
||||
static
|
||||
void
|
||||
innodb_encrypt_tables_update(
|
||||
/*=========================*/
|
||||
THD* thd, /*!< in: thread handle */
|
||||
struct st_mysql_sys_var* var, /*!< in: pointer to
|
||||
system variable */
|
||||
void* var_ptr,/*!< out: where the
|
||||
formal string goes */
|
||||
const void* save) /*!< in: immediate result
|
||||
from check function */
|
||||
{
|
||||
fil_crypt_set_encrypt_tables(*static_cast<const uint*>(save));
|
||||
}
|
||||
|
||||
static SHOW_VAR innodb_status_variables_export[]= {
|
||||
{"Innodb", (char*) &show_innodb_vars, SHOW_FUNC},
|
||||
{NullS, NullS, SHOW_LONG}
|
||||
@ -19183,7 +19201,9 @@ 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",
|
||||
innodb_encrypt_tables_validate, NULL, 0,
|
||||
NULL,
|
||||
innodb_encrypt_tables_update,
|
||||
0,
|
||||
&srv_encrypt_tables_typelib);
|
||||
|
||||
static MYSQL_SYSVAR_UINT(encryption_threads, srv_n_fil_crypt_threads,
|
||||
|
@ -128,7 +128,7 @@ Get crypt data for a space*/
|
||||
UNIV_INTERN
|
||||
fil_space_crypt_t *
|
||||
fil_space_get_crypt_data(
|
||||
/*======================*/
|
||||
/*=====================*/
|
||||
ulint space); /*!< in: tablespace id */
|
||||
|
||||
/*********************************************************************
|
||||
@ -136,15 +136,16 @@ Set crypt data for a space*/
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_set_crypt_data(
|
||||
/*======================*/
|
||||
/*=====================*/
|
||||
ulint space, /*!< in: tablespace id */
|
||||
fil_space_crypt_t* crypt_data); /*!< in: crypt data to set */
|
||||
|
||||
/*********************************************************************
|
||||
Merge crypt data */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_merge_crypt_data(
|
||||
/*======================*/
|
||||
/*=======================*/
|
||||
fil_space_crypt_t* dst_crypt_data, /*!< in: crypt_data */
|
||||
const fil_space_crypt_t* src_crypt_data); /*!< in: crypt data */
|
||||
|
||||
@ -175,7 +176,7 @@ Clear crypt data from page 0 (used for import tablespace) */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_clear_crypt_data(
|
||||
/*======================*/
|
||||
/*=======================*/
|
||||
byte* page, /*!< in: buffer page */
|
||||
ulint offset); /*!< in: offset where crypt data is stored */
|
||||
|
||||
@ -194,7 +195,7 @@ Check if extra buffer shall be allocated for decrypting after read */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
fil_space_check_encryption_read(
|
||||
/*==============================*/
|
||||
/*============================*/
|
||||
ulint space); /*!< in: tablespace id */
|
||||
|
||||
/*********************************************************************
|
||||
@ -202,7 +203,7 @@ Check if page shall be encrypted before write */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
fil_space_check_encryption_write(
|
||||
/*==============================*/
|
||||
/*=============================*/
|
||||
ulint space); /*!< in: tablespace id */
|
||||
|
||||
/*********************************************************************
|
||||
@ -210,7 +211,7 @@ Encrypt buffer page */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_encrypt(
|
||||
/*===============*/
|
||||
/*==============*/
|
||||
ulint space, /*!< in: tablespace id */
|
||||
ulint offset, /*!< in: page no */
|
||||
lsn_t lsn, /*!< in: page lsn */
|
||||
@ -223,7 +224,7 @@ Decrypt buffer page */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_decrypt(
|
||||
/*===============*/
|
||||
/*==============*/
|
||||
ulint space, /*!< in: tablespace id */
|
||||
const byte* src_frame,/*!< in: page frame */
|
||||
ulint page_size, /*!< in: size of data to encrypt */
|
||||
@ -236,7 +237,7 @@ Decrypt buffer page
|
||||
UNIV_INTERN
|
||||
bool
|
||||
fil_space_decrypt(
|
||||
/*===============*/
|
||||
/*==============*/
|
||||
fil_space_crypt_t* crypt_data, /*!< in: crypt data */
|
||||
const byte* src_frame,/*!< in: page frame */
|
||||
ulint page_size, /*!< in: page size */
|
||||
@ -250,7 +251,7 @@ as it modifies srv_checksum_algorithm (temporarily)
|
||||
UNIV_INTERN
|
||||
bool
|
||||
fil_space_verify_crypt_checksum(
|
||||
/*===============*/
|
||||
/*============================*/
|
||||
const byte* src_frame,/*!< in: page frame */
|
||||
ulint zip_size); /*!< in: size of data to encrypt */
|
||||
|
||||
@ -285,7 +286,7 @@ Set rotate key age */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_crypt_set_rotate_key_age(
|
||||
/*=====================*/
|
||||
/*=========================*/
|
||||
uint rotate_age); /*!< in: requested rotate age */
|
||||
|
||||
/*********************************************************************
|
||||
@ -293,7 +294,7 @@ Set rotation threads iops */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_crypt_set_rotation_iops(
|
||||
/*=====================*/
|
||||
/*========================*/
|
||||
uint iops); /*!< in: requested iops */
|
||||
|
||||
/*********************************************************************
|
||||
@ -301,7 +302,7 @@ Mark a space as closing */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_crypt_mark_space_closing(
|
||||
/*===============*/
|
||||
/*===============================*/
|
||||
ulint space); /*!< in: tablespace id */
|
||||
|
||||
/*********************************************************************
|
||||
@ -309,7 +310,7 @@ Wait for crypt threads to stop accessing space */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_crypt_close_tablespace(
|
||||
/*===============*/
|
||||
/*=============================*/
|
||||
ulint space); /*!< in: tablespace id */
|
||||
|
||||
/** Struct for retreiving info about encryption */
|
||||
@ -331,7 +332,7 @@ Get crypt status for a space
|
||||
UNIV_INTERN
|
||||
int
|
||||
fil_space_crypt_get_status(
|
||||
/*==================*/
|
||||
/*=======================*/
|
||||
ulint id, /*!< in: space id */
|
||||
struct fil_space_crypt_status_t * status); /*!< out: status */
|
||||
|
||||
@ -370,10 +371,19 @@ Get scrub status for a space
|
||||
UNIV_INTERN
|
||||
int
|
||||
fil_space_get_scrub_status(
|
||||
/*==================*/
|
||||
/*=======================*/
|
||||
ulint id, /*!< in: space id */
|
||||
struct fil_space_scrub_status_t * status); /*!< out: status */
|
||||
|
||||
/*********************************************************************
|
||||
Adjust encrypt tables */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_crypt_set_encrypt_tables(
|
||||
/*=========================*/
|
||||
uint val); /*!< in: New srv_encrypt_tables setting */
|
||||
|
||||
|
||||
#ifndef UNIV_NONINL
|
||||
#include "fil0crypt.ic"
|
||||
#endif
|
||||
|
@ -4302,6 +4302,7 @@ buf_page_io_complete(
|
||||
const ibool uncompressed = (buf_page_get_state(bpage)
|
||||
== BUF_BLOCK_FILE_PAGE);
|
||||
bool have_LRU_mutex = false;
|
||||
fil_space_t* space = NULL;
|
||||
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
|
||||
@ -4403,13 +4404,20 @@ buf_page_io_complete(
|
||||
goto page_not_corrupt;
|
||||
;);
|
||||
corrupt:
|
||||
|
||||
fil_system_enter();
|
||||
space = fil_space_get_by_id(bpage->space);
|
||||
fil_system_exit();
|
||||
fprintf(stderr,
|
||||
"InnoDB: Database page corruption on disk"
|
||||
" or a failed\n"
|
||||
"InnoDB: file read of page %lu.\n"
|
||||
"InnoDB: space %lu file %s read of page %lu.\n"
|
||||
"InnoDB: You may have to recover"
|
||||
" from a backup.\n",
|
||||
bpage->space,
|
||||
space ? space->name : "NULL",
|
||||
(ulong) bpage->offset);
|
||||
|
||||
buf_page_print(frame, buf_page_get_zip_size(bpage),
|
||||
BUF_PAGE_PRINT_NO_CRASH);
|
||||
fprintf(stderr,
|
||||
|
@ -43,6 +43,8 @@ Modified Jan Lindström jan.lindstrom@mariadb.com
|
||||
/** Mutex for keys */
|
||||
UNIV_INTERN ib_mutex_t fil_crypt_key_mutex;
|
||||
|
||||
static bool fil_crypt_threads_inited = false;
|
||||
|
||||
#ifdef UNIV_PFS_MUTEX
|
||||
UNIV_INTERN mysql_pfs_key_t fil_crypt_key_mutex_key;
|
||||
#endif
|
||||
@ -107,6 +109,8 @@ UNIV_INTERN mysql_pfs_key_t fil_crypt_data_mutex_key;
|
||||
static bool
|
||||
fil_crypt_needs_rotation(
|
||||
/*=====================*/
|
||||
fil_encryption_t encrypt_mode, /*!< in: Encryption
|
||||
mode */
|
||||
uint key_version, /*!< in: Key version */
|
||||
uint latest_key_version, /*!< in: Latest key version */
|
||||
uint rotate_key_age); /*!< in: When to rotate */
|
||||
@ -154,13 +158,14 @@ Get the latest(key-version), waking the encrypt thread, if needed */
|
||||
static inline
|
||||
uint
|
||||
fil_crypt_get_latest_key_version(
|
||||
/*=====================*/
|
||||
/*=============================*/
|
||||
fil_space_crypt_t* crypt_data) /*!< in: crypt data */
|
||||
{
|
||||
uint rc = encryption_key_get_latest_version(crypt_data->key_id);
|
||||
|
||||
if (fil_crypt_needs_rotation(crypt_data->min_key_version,
|
||||
rc, srv_fil_crypt_rotate_key_age)) {
|
||||
if (fil_crypt_needs_rotation(crypt_data->encryption,
|
||||
crypt_data->min_key_version,
|
||||
rc, srv_fil_crypt_rotate_key_age)) {
|
||||
os_event_set(fil_crypt_threads_event);
|
||||
}
|
||||
|
||||
@ -169,7 +174,12 @@ fil_crypt_get_latest_key_version(
|
||||
|
||||
/******************************************************************
|
||||
Mutex helper for crypt_data->scheme */
|
||||
static void crypt_data_scheme_locker(st_encryption_scheme *scheme, int exit)
|
||||
static
|
||||
void
|
||||
crypt_data_scheme_locker(
|
||||
/*=====================*/
|
||||
st_encryption_scheme* scheme,
|
||||
int exit)
|
||||
{
|
||||
fil_space_crypt_t* crypt_data =
|
||||
static_cast<fil_space_crypt_t*>(scheme);
|
||||
@ -220,7 +230,7 @@ Merge fil_space_crypt_t object */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_merge_crypt_data(
|
||||
/*====================*/
|
||||
/*=======================*/
|
||||
fil_space_crypt_t* dst,/*!< out: Crypt data */
|
||||
const fil_space_crypt_t* src)/*!< in: Crypt data */
|
||||
{
|
||||
@ -236,6 +246,7 @@ fil_space_merge_crypt_data(
|
||||
/* no support for changing iv (yet?) */
|
||||
ut_a(memcmp(src->iv, dst->iv, sizeof(src->iv)) == 0);
|
||||
|
||||
dst->encryption = src->encryption;
|
||||
dst->type = src->type;
|
||||
dst->min_key_version = src->min_key_version;
|
||||
dst->keyserver_requests += src->keyserver_requests;
|
||||
@ -255,8 +266,13 @@ fil_space_read_crypt_data(
|
||||
ulint offset) /*!< in: offset */
|
||||
{
|
||||
if (memcmp(page + offset, EMPTY_PATTERN, MAGIC_SZ) == 0) {
|
||||
/* crypt is not stored */
|
||||
return NULL;
|
||||
/* crypt is not stored but create memory cache for
|
||||
not system tablespace */
|
||||
if (space != 0) {
|
||||
return fil_space_create_crypt_data(FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (memcmp(page + offset, CRYPT_MAGIC, MAGIC_SZ) != 0) {
|
||||
@ -272,7 +288,12 @@ fil_space_read_crypt_data(
|
||||
page[offset + 3],
|
||||
page[offset + 4],
|
||||
page[offset + 5]);
|
||||
return NULL;
|
||||
/* Create memory cache for not system tablespace */
|
||||
if (space != 0) {
|
||||
return fil_space_create_crypt_data(FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY);
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ulint type = mach_read_from_1(page + offset + MAGIC_SZ + 0);
|
||||
@ -542,11 +563,12 @@ Check if page shall be encrypted before write
|
||||
UNIV_INTERN
|
||||
bool
|
||||
fil_space_check_encryption_write(
|
||||
/*==============================*/
|
||||
ulint space) /*!< in: tablespace id */
|
||||
/*=============================*/
|
||||
ulint space) /*!< in: tablespace id */
|
||||
{
|
||||
if (!srv_encrypt_tables)
|
||||
if (!srv_encrypt_tables) {
|
||||
return false;
|
||||
}
|
||||
|
||||
fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space);
|
||||
|
||||
@ -599,6 +621,8 @@ fil_space_encrypt(
|
||||
return;
|
||||
}
|
||||
|
||||
ut_ad(crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF);
|
||||
|
||||
key_version = fil_crypt_get_latest_key_version(crypt_data);
|
||||
|
||||
if (key_version == ENCRYPTION_KEY_VERSION_INVALID) {
|
||||
@ -742,6 +766,8 @@ fil_space_decrypt(
|
||||
return false; /* page not decrypted */
|
||||
}
|
||||
|
||||
ut_ad(crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF);
|
||||
|
||||
/* read space & offset & lsn */
|
||||
ulint space = mach_read_from_4(
|
||||
src_frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
|
||||
@ -794,7 +820,7 @@ fil_space_decrypt(
|
||||
FIL_PAGE_DATA_END);
|
||||
|
||||
// clear key-version & crypt-checksum from dst
|
||||
memset(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8);
|
||||
memset(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, 0, 8);
|
||||
}
|
||||
|
||||
srv_stats.pages_decrypted.inc();
|
||||
@ -937,12 +963,15 @@ Check if a key needs rotation given a key_state
|
||||
static bool
|
||||
fil_crypt_needs_rotation(
|
||||
/*=====================*/
|
||||
fil_encryption_t encrypt_mode, /*!< in: Encryption
|
||||
mode */
|
||||
uint key_version, /*!< in: Key version */
|
||||
uint latest_key_version, /*!< in: Latest key version */
|
||||
uint rotate_key_age) /*!< in: When to rotate */
|
||||
{
|
||||
if (key_version == ENCRYPTION_KEY_VERSION_INVALID)
|
||||
if (key_version == ENCRYPTION_KEY_VERSION_INVALID) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (key_version == 0 && latest_key_version != 0) {
|
||||
/* this is rotation unencrypted => encrypted
|
||||
@ -951,8 +980,11 @@ fil_crypt_needs_rotation(
|
||||
}
|
||||
|
||||
if (latest_key_version == 0 && key_version != 0) {
|
||||
/* this is rotation encrypted => unencrypted */
|
||||
return true;
|
||||
if (encrypt_mode == FIL_SPACE_ENCRYPTION_DEFAULT) {
|
||||
/* this is rotation encrypted => unencrypted */
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/* this is rotation encrypted => encrypted,
|
||||
@ -973,11 +1005,15 @@ fil_crypt_is_closing(
|
||||
/*=================*/
|
||||
ulint space) /*!< in: FIL space id */
|
||||
{
|
||||
bool closing;
|
||||
bool closing=true;
|
||||
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
closing = crypt_data->closing;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
|
||||
if (crypt_data) {
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
closing = crypt_data->closing;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
}
|
||||
|
||||
return closing;
|
||||
}
|
||||
|
||||
@ -1189,6 +1225,7 @@ Check if space needs rotation given a key_state
|
||||
static
|
||||
bool
|
||||
fil_crypt_space_needs_rotation(
|
||||
/*===========================*/
|
||||
rotate_thread_t* state, /*!< in: Key rotation state */
|
||||
key_state_t* key_state, /*!< in: Key state */
|
||||
bool* recheck) /*!< out: needs recheck ? */
|
||||
@ -1228,11 +1265,6 @@ fil_crypt_space_needs_rotation(
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
|
||||
do {
|
||||
if (crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) {
|
||||
/* This space is unencrypted by user request */
|
||||
break;
|
||||
}
|
||||
|
||||
/* prevent threads from starting to rotate space */
|
||||
if (crypt_data->rotate_state.starting) {
|
||||
/* recheck this space later */
|
||||
@ -1255,6 +1287,7 @@ fil_crypt_space_needs_rotation(
|
||||
}
|
||||
|
||||
bool need_key_rotation = fil_crypt_needs_rotation(
|
||||
crypt_data->encryption,
|
||||
crypt_data->min_key_version,
|
||||
key_state->key_version, key_state->rotate_key_age);
|
||||
|
||||
@ -1351,7 +1384,7 @@ used when inside a space */
|
||||
static
|
||||
void
|
||||
fil_crypt_realloc_iops(
|
||||
/*========================*/
|
||||
/*===================*/
|
||||
rotate_thread_t *state) /*!< in: Key rotation status */
|
||||
{
|
||||
ut_a(state->allocated_iops > 0);
|
||||
@ -1444,7 +1477,7 @@ Return allocated iops to global */
|
||||
static
|
||||
void
|
||||
fil_crypt_return_iops(
|
||||
/*========================*/
|
||||
/*==================*/
|
||||
rotate_thread_t *state) /*!< in: Key rotation status */
|
||||
{
|
||||
if (state->allocated_iops > 0) {
|
||||
@ -1526,11 +1559,17 @@ fil_crypt_start_rotate_space(
|
||||
ulint space = state->space;
|
||||
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
|
||||
|
||||
ut_ad(crypt_data);
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
ut_ad(key_state->key_id == crypt_data->key_id);
|
||||
|
||||
if (crypt_data->rotate_state.active_threads == 0) {
|
||||
/* only first thread needs to init */
|
||||
if (crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) {
|
||||
crypt_data->type = CRYPT_SCHEME_UNENCRYPTED;
|
||||
} else {
|
||||
crypt_data->type = CRYPT_SCHEME_1;
|
||||
}
|
||||
crypt_data->rotate_state.next_offset = 1; // skip page 0
|
||||
/* no need to rotate beyond current max
|
||||
* if space extends, it will be encrypted with newer version */
|
||||
@ -1568,28 +1607,33 @@ fil_crypt_find_page_to_rotate(
|
||||
ulint space = state->space;
|
||||
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
|
||||
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
ut_ad(key_state->key_id == crypt_data->key_id);
|
||||
/* Space might already be dropped */
|
||||
if (crypt_data) {
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
ut_ad(key_state->key_id == crypt_data->key_id);
|
||||
|
||||
if (crypt_data->closing == false &&
|
||||
crypt_data->rotate_state.next_offset <
|
||||
crypt_data->rotate_state.max_offset) {
|
||||
if (crypt_data->closing == false &&
|
||||
crypt_data->rotate_state.next_offset <
|
||||
crypt_data->rotate_state.max_offset) {
|
||||
|
||||
state->offset = crypt_data->rotate_state.next_offset;
|
||||
ulint remaining = crypt_data->rotate_state.max_offset -
|
||||
crypt_data->rotate_state.next_offset;
|
||||
state->offset = crypt_data->rotate_state.next_offset;
|
||||
ulint remaining = crypt_data->rotate_state.max_offset -
|
||||
crypt_data->rotate_state.next_offset;
|
||||
|
||||
if (batch <= remaining)
|
||||
state->batch = batch;
|
||||
else
|
||||
state->batch = remaining;
|
||||
if (batch <= remaining) {
|
||||
state->batch = batch;
|
||||
} else {
|
||||
state->batch = remaining;
|
||||
}
|
||||
|
||||
crypt_data->rotate_state.next_offset += batch;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
crypt_data->rotate_state.next_offset += batch;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
return true;
|
||||
}
|
||||
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1636,6 +1680,7 @@ Get a page and compute sleep time
|
||||
static
|
||||
buf_block_t*
|
||||
fil_crypt_get_page_throttle_func(
|
||||
/*=============================*/
|
||||
rotate_thread_t* state, /*!< in/out: Key rotation state */
|
||||
ulint space, /*!< in: FIL space id */
|
||||
uint zip_size, /*!< in: compressed size if
|
||||
@ -1752,7 +1797,7 @@ Rotate one page */
|
||||
static
|
||||
void
|
||||
fil_crypt_rotate_page(
|
||||
/*===================*/
|
||||
/*==================*/
|
||||
const key_state_t* key_state, /*!< in: Key state */
|
||||
rotate_thread_t* state) /*!< in: Key rotation state */
|
||||
{
|
||||
@ -1791,8 +1836,10 @@ fil_crypt_rotate_page(
|
||||
if (kv == 0 &&
|
||||
fil_crypt_is_page_uninitialized(frame, zip_size)) {
|
||||
;
|
||||
} else if (fil_crypt_needs_rotation(kv, key_state->key_version,
|
||||
key_state->rotate_key_age)) {
|
||||
} else if (fil_crypt_needs_rotation(
|
||||
crypt_data->encryption,
|
||||
kv, key_state->key_version,
|
||||
key_state->rotate_key_age)) {
|
||||
|
||||
/* page can be "fresh" i.e never written in case
|
||||
* kv == 0 or it should have a key version at least
|
||||
@ -1812,11 +1859,13 @@ fil_crypt_rotate_page(
|
||||
/* statistics */
|
||||
state->crypt_stat.pages_modified++;
|
||||
} else {
|
||||
ut_a(kv >= crypt_data->min_key_version ||
|
||||
(kv == 0 && key_state->key_version == 0));
|
||||
if (crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF) {
|
||||
ut_a(kv >= crypt_data->min_key_version ||
|
||||
(kv == 0 && key_state->key_version == 0));
|
||||
|
||||
if (kv < state->min_key_version_found) {
|
||||
state->min_key_version_found = kv;
|
||||
if (kv < state->min_key_version_found) {
|
||||
state->min_key_version_found = kv;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1878,6 +1927,7 @@ fil_crypt_rotate_page(
|
||||
/* if we just detected that scrubbing was turned off
|
||||
* update global state to reflect this */
|
||||
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
|
||||
ut_ad(crypt_data);
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
crypt_data->rotate_state.scrubbing.is_active = false;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
@ -2006,68 +2056,73 @@ fil_crypt_complete_rotate_space(
|
||||
{
|
||||
ulint space = state->space;
|
||||
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
|
||||
/**
|
||||
* Update crypt data state with state from thread
|
||||
*/
|
||||
if (state->min_key_version_found <
|
||||
crypt_data->rotate_state.min_key_version_found) {
|
||||
crypt_data->rotate_state.min_key_version_found =
|
||||
state->min_key_version_found;
|
||||
}
|
||||
/* Space might already be dropped */
|
||||
if (crypt_data) {
|
||||
ut_ad(crypt_data);
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
|
||||
if (state->end_lsn > crypt_data->rotate_state.end_lsn) {
|
||||
crypt_data->rotate_state.end_lsn = state->end_lsn;
|
||||
}
|
||||
/**
|
||||
* Update crypt data state with state from thread
|
||||
*/
|
||||
if (state->min_key_version_found <
|
||||
crypt_data->rotate_state.min_key_version_found) {
|
||||
crypt_data->rotate_state.min_key_version_found =
|
||||
state->min_key_version_found;
|
||||
}
|
||||
|
||||
ut_a(crypt_data->rotate_state.active_threads > 0);
|
||||
crypt_data->rotate_state.active_threads--;
|
||||
bool last = crypt_data->rotate_state.active_threads == 0;
|
||||
if (state->end_lsn > crypt_data->rotate_state.end_lsn) {
|
||||
crypt_data->rotate_state.end_lsn = state->end_lsn;
|
||||
}
|
||||
|
||||
/**
|
||||
* check if space is fully done
|
||||
* this as when threads shutdown, it could be that we "complete"
|
||||
* iterating before we have scanned the full space.
|
||||
*/
|
||||
bool done = crypt_data->rotate_state.next_offset >=
|
||||
crypt_data->rotate_state.max_offset;
|
||||
ut_a(crypt_data->rotate_state.active_threads > 0);
|
||||
crypt_data->rotate_state.active_threads--;
|
||||
bool last = crypt_data->rotate_state.active_threads == 0;
|
||||
|
||||
/**
|
||||
* we should flush space if we're last thread AND
|
||||
* the iteration is done
|
||||
*/
|
||||
bool should_flush = last && done;
|
||||
/**
|
||||
* check if space is fully done
|
||||
* this as when threads shutdown, it could be that we "complete"
|
||||
* iterating before we have scanned the full space.
|
||||
*/
|
||||
bool done = crypt_data->rotate_state.next_offset >=
|
||||
crypt_data->rotate_state.max_offset;
|
||||
|
||||
if (should_flush) {
|
||||
/* we're the last active thread */
|
||||
crypt_data->rotate_state.flushing = true;
|
||||
crypt_data->min_key_version =
|
||||
crypt_data->rotate_state.min_key_version_found;
|
||||
}
|
||||
/**
|
||||
* we should flush space if we're last thread AND
|
||||
* the iteration is done
|
||||
*/
|
||||
bool should_flush = last && done;
|
||||
|
||||
/* inform scrubbing */
|
||||
crypt_data->rotate_state.scrubbing.is_active = false;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
|
||||
/* all threads must call btr_scrub_complete_space wo/ mutex held */
|
||||
if (btr_scrub_complete_space(&state->scrub_data) == true) {
|
||||
if (should_flush) {
|
||||
/* only last thread updates last_scrub_completed */
|
||||
/* we're the last active thread */
|
||||
crypt_data->rotate_state.flushing = true;
|
||||
crypt_data->min_key_version =
|
||||
crypt_data->rotate_state.min_key_version_found;
|
||||
}
|
||||
|
||||
/* inform scrubbing */
|
||||
crypt_data->rotate_state.scrubbing.is_active = false;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
|
||||
/* all threads must call btr_scrub_complete_space wo/ mutex held */
|
||||
if (btr_scrub_complete_space(&state->scrub_data) == true) {
|
||||
if (should_flush) {
|
||||
/* only last thread updates last_scrub_completed */
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
crypt_data->rotate_state.scrubbing.
|
||||
last_scrub_completed = time(0);
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
if (should_flush) {
|
||||
fil_crypt_flush_space(state, space);
|
||||
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
crypt_data->rotate_state.scrubbing.
|
||||
last_scrub_completed = time(0);
|
||||
crypt_data->rotate_state.flushing = false;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
if (should_flush) {
|
||||
fil_crypt_flush_space(state, space);
|
||||
|
||||
mutex_enter(&crypt_data->mutex);
|
||||
crypt_data->rotate_state.flushing = false;
|
||||
mutex_exit(&crypt_data->mutex);
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
@ -2194,8 +2249,8 @@ fil_crypt_set_thread_cnt(
|
||||
os_thread_id_t rotation_thread_id;
|
||||
os_thread_create(fil_crypt_thread, NULL, &rotation_thread_id);
|
||||
ib_logf(IB_LOG_LEVEL_INFO,
|
||||
"Creating #%d thread id %lu total threads %du\n",
|
||||
i, os_thread_pf(rotation_thread_id), new_cnt);
|
||||
"Creating #%d thread id %lu total threads %u\n",
|
||||
i+1, os_thread_pf(rotation_thread_id), new_cnt);
|
||||
}
|
||||
} else if (new_cnt < srv_n_fil_crypt_threads) {
|
||||
srv_n_fil_crypt_threads = new_cnt;
|
||||
@ -2232,6 +2287,18 @@ fil_crypt_set_rotation_iops(
|
||||
os_event_set(fil_crypt_threads_event);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
Adjust encrypt tables */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_crypt_set_encrypt_tables(
|
||||
/*=========================*/
|
||||
uint val) /*!< in: New srv_encrypt_tables setting */
|
||||
{
|
||||
srv_encrypt_tables = val;
|
||||
os_event_set(fil_crypt_threads_event);
|
||||
}
|
||||
|
||||
/*********************************************************************
|
||||
Init threads for key rotation */
|
||||
UNIV_INTERN
|
||||
@ -2279,7 +2346,7 @@ fil_space_crypt_mark_space_closing(
|
||||
/*===============================*/
|
||||
ulint space) /*!< in: Space id */
|
||||
{
|
||||
if (!srv_encrypt_tables) {
|
||||
if (!fil_crypt_threads_inited) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -6999,19 +6999,26 @@ fil_space_set_crypt_data(
|
||||
|
||||
if (space != NULL) {
|
||||
if (space->crypt_data != NULL) {
|
||||
/* Here we need to release fil_system mutex to
|
||||
avoid mutex deadlock assertion. Here we would
|
||||
take mutexes in order fil_system, crypt_data and
|
||||
in fil_crypt_start_encrypting_space we would
|
||||
take them in order crypt_data, fil_system
|
||||
at fil_space_get_flags -> fil_space_get_space */
|
||||
mutex_exit(&fil_system->mutex);
|
||||
fil_space_merge_crypt_data(space->crypt_data,
|
||||
crypt_data);
|
||||
free_crypt_data = crypt_data;
|
||||
} else {
|
||||
space->crypt_data = crypt_data;
|
||||
mutex_exit(&fil_system->mutex);
|
||||
}
|
||||
} else {
|
||||
/* there is a small risk that tablespace has been deleted */
|
||||
free_crypt_data = crypt_data;
|
||||
mutex_exit(&fil_system->mutex);
|
||||
}
|
||||
|
||||
mutex_exit(&fil_system->mutex);
|
||||
|
||||
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
|
||||
|
@ -3604,7 +3604,7 @@ innobase_init(
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#ifndef HAVE_LZ4
|
||||
if (innodb_compression_algorithm == PAGE_LZ4_ALGORITHM) {
|
||||
sql_print_error("InnoDB: innodb_compression_algorithm = %lu unsupported.\n"
|
||||
@ -18746,6 +18746,7 @@ which control InnoDB "status monitor" output to the error log.
|
||||
static
|
||||
void
|
||||
innodb_status_output_update(
|
||||
/*========================*/
|
||||
THD* thd __attribute__((unused)),
|
||||
struct st_mysql_sys_var* var __attribute__((unused)),
|
||||
void* var_ptr __attribute__((unused)),
|
||||
@ -18761,7 +18762,7 @@ Update the system variable innodb_encryption_threads */
|
||||
static
|
||||
void
|
||||
innodb_encryption_threads_update(
|
||||
/*=========================*/
|
||||
/*=============================*/
|
||||
THD* thd, /*!< in: thread handle */
|
||||
struct st_mysql_sys_var* var, /*!< in: pointer to
|
||||
system variable */
|
||||
@ -18778,7 +18779,7 @@ Update the system variable innodb_encryption_rotate_key_age */
|
||||
static
|
||||
void
|
||||
innodb_encryption_rotate_key_age_update(
|
||||
/*=========================*/
|
||||
/*====================================*/
|
||||
THD* thd, /*!< in: thread handle */
|
||||
struct st_mysql_sys_var* var, /*!< in: pointer to
|
||||
system variable */
|
||||
@ -18795,7 +18796,7 @@ Update the system variable innodb_encryption_rotation_iops */
|
||||
static
|
||||
void
|
||||
innodb_encryption_rotation_iops_update(
|
||||
/*=========================*/
|
||||
/*===================================*/
|
||||
THD* thd, /*!< in: thread handle */
|
||||
struct st_mysql_sys_var* var, /*!< in: pointer to
|
||||
system variable */
|
||||
@ -18807,6 +18808,23 @@ innodb_encryption_rotation_iops_update(
|
||||
fil_crypt_set_rotation_iops(*static_cast<const uint*>(save));
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
Update the system variable innodb_encrypt_tables*/
|
||||
static
|
||||
void
|
||||
innodb_encrypt_tables_update(
|
||||
/*=========================*/
|
||||
THD* thd, /*!< in: thread handle */
|
||||
struct st_mysql_sys_var* var, /*!< in: pointer to
|
||||
system variable */
|
||||
void* var_ptr,/*!< out: where the
|
||||
formal string goes */
|
||||
const void* save) /*!< in: immediate result
|
||||
from check function */
|
||||
{
|
||||
fil_crypt_set_encrypt_tables(*static_cast<const uint*>(save));
|
||||
}
|
||||
|
||||
static SHOW_VAR innodb_status_variables_export[]= {
|
||||
{"Innodb", (char*) &show_innodb_vars, SHOW_FUNC},
|
||||
{NullS, NullS, SHOW_LONG}
|
||||
@ -20365,7 +20383,9 @@ 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",
|
||||
innodb_encrypt_tables_validate, NULL, 0,
|
||||
NULL,
|
||||
innodb_encrypt_tables_update,
|
||||
0,
|
||||
&srv_encrypt_tables_typelib);
|
||||
|
||||
static MYSQL_SYSVAR_UINT(encryption_threads, srv_n_fil_crypt_threads,
|
||||
|
@ -128,7 +128,7 @@ Get crypt data for a space*/
|
||||
UNIV_INTERN
|
||||
fil_space_crypt_t *
|
||||
fil_space_get_crypt_data(
|
||||
/*======================*/
|
||||
/*=====================*/
|
||||
ulint space); /*!< in: tablespace id */
|
||||
|
||||
/*********************************************************************
|
||||
@ -136,15 +136,16 @@ Set crypt data for a space*/
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_set_crypt_data(
|
||||
/*======================*/
|
||||
/*=====================*/
|
||||
ulint space, /*!< in: tablespace id */
|
||||
fil_space_crypt_t* crypt_data); /*!< in: crypt data to set */
|
||||
|
||||
/*********************************************************************
|
||||
Merge crypt data */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_merge_crypt_data(
|
||||
/*======================*/
|
||||
/*=======================*/
|
||||
fil_space_crypt_t* dst_crypt_data, /*!< in: crypt_data */
|
||||
const fil_space_crypt_t* src_crypt_data); /*!< in: crypt data */
|
||||
|
||||
@ -175,7 +176,7 @@ Clear crypt data from page 0 (used for import tablespace) */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_clear_crypt_data(
|
||||
/*======================*/
|
||||
/*=======================*/
|
||||
byte* page, /*!< in: buffer page */
|
||||
ulint offset); /*!< in: offset where crypt data is stored */
|
||||
|
||||
@ -194,7 +195,7 @@ Check if extra buffer shall be allocated for decrypting after read */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
fil_space_check_encryption_read(
|
||||
/*==============================*/
|
||||
/*============================*/
|
||||
ulint space); /*!< in: tablespace id */
|
||||
|
||||
/*********************************************************************
|
||||
@ -202,7 +203,7 @@ Check if page shall be encrypted before write */
|
||||
UNIV_INTERN
|
||||
bool
|
||||
fil_space_check_encryption_write(
|
||||
/*==============================*/
|
||||
/*=============================*/
|
||||
ulint space); /*!< in: tablespace id */
|
||||
|
||||
/*********************************************************************
|
||||
@ -210,7 +211,7 @@ Encrypt buffer page */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_encrypt(
|
||||
/*===============*/
|
||||
/*==============*/
|
||||
ulint space, /*!< in: tablespace id */
|
||||
ulint offset, /*!< in: page no */
|
||||
lsn_t lsn, /*!< in: page lsn */
|
||||
@ -223,7 +224,7 @@ Decrypt buffer page */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_decrypt(
|
||||
/*===============*/
|
||||
/*==============*/
|
||||
ulint space, /*!< in: tablespace id */
|
||||
const byte* src_frame,/*!< in: page frame */
|
||||
ulint page_size, /*!< in: size of data to encrypt */
|
||||
@ -236,7 +237,7 @@ Decrypt buffer page
|
||||
UNIV_INTERN
|
||||
bool
|
||||
fil_space_decrypt(
|
||||
/*===============*/
|
||||
/*==============*/
|
||||
fil_space_crypt_t* crypt_data, /*!< in: crypt data */
|
||||
const byte* src_frame,/*!< in: page frame */
|
||||
ulint page_size, /*!< in: page size */
|
||||
@ -250,7 +251,7 @@ as it modifies srv_checksum_algorithm (temporarily)
|
||||
UNIV_INTERN
|
||||
bool
|
||||
fil_space_verify_crypt_checksum(
|
||||
/*===============*/
|
||||
/*============================*/
|
||||
const byte* src_frame,/*!< in: page frame */
|
||||
ulint zip_size); /*!< in: size of data to encrypt */
|
||||
|
||||
@ -285,7 +286,7 @@ Set rotate key age */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_crypt_set_rotate_key_age(
|
||||
/*=====================*/
|
||||
/*=========================*/
|
||||
uint rotate_age); /*!< in: requested rotate age */
|
||||
|
||||
/*********************************************************************
|
||||
@ -293,7 +294,7 @@ Set rotation threads iops */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_crypt_set_rotation_iops(
|
||||
/*=====================*/
|
||||
/*========================*/
|
||||
uint iops); /*!< in: requested iops */
|
||||
|
||||
/*********************************************************************
|
||||
@ -301,7 +302,7 @@ Mark a space as closing */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_crypt_mark_space_closing(
|
||||
/*===============*/
|
||||
/*===============================*/
|
||||
ulint space); /*!< in: tablespace id */
|
||||
|
||||
/*********************************************************************
|
||||
@ -309,7 +310,7 @@ Wait for crypt threads to stop accessing space */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_space_crypt_close_tablespace(
|
||||
/*===============*/
|
||||
/*=============================*/
|
||||
ulint space); /*!< in: tablespace id */
|
||||
|
||||
/** Struct for retreiving info about encryption */
|
||||
@ -331,7 +332,7 @@ Get crypt status for a space
|
||||
UNIV_INTERN
|
||||
int
|
||||
fil_space_crypt_get_status(
|
||||
/*==================*/
|
||||
/*=======================*/
|
||||
ulint id, /*!< in: space id */
|
||||
struct fil_space_crypt_status_t * status); /*!< out: status */
|
||||
|
||||
@ -370,10 +371,18 @@ Get scrub status for a space
|
||||
UNIV_INTERN
|
||||
int
|
||||
fil_space_get_scrub_status(
|
||||
/*==================*/
|
||||
/*=======================*/
|
||||
ulint id, /*!< in: space id */
|
||||
struct fil_space_scrub_status_t * status); /*!< out: status */
|
||||
|
||||
/*********************************************************************
|
||||
Adjust encrypt tables */
|
||||
UNIV_INTERN
|
||||
void
|
||||
fil_crypt_set_encrypt_tables(
|
||||
/*=========================*/
|
||||
uint val); /*!< in: New srv_encrypt_tables setting */
|
||||
|
||||
#ifndef UNIV_NONINL
|
||||
#include "fil0crypt.ic"
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user