1
0
mirror of https://github.com/MariaDB/server.git synced 2025-06-16 11:21:15 +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:
Jan Lindström
2015-05-17 14:14:16 +03:00
parent 476dfb1603
commit 20c23048c1
17 changed files with 993 additions and 249 deletions

View 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

View 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;

View File

@ -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;

View 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

View 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;

View File

@ -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

View File

@ -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;

View File

@ -4225,6 +4225,7 @@ buf_page_io_complete(
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
const ibool uncompressed = (buf_page_get_state(bpage) const ibool uncompressed = (buf_page_get_state(bpage)
== BUF_BLOCK_FILE_PAGE); == BUF_BLOCK_FILE_PAGE);
fil_space_t* space = NULL;
ut_a(buf_page_in_file(bpage)); ut_a(buf_page_in_file(bpage));
@ -4323,12 +4324,18 @@ buf_page_io_complete(
goto page_not_corrupt; goto page_not_corrupt;
;); ;);
corrupt: corrupt:
fil_system_enter();
space = fil_space_get_by_id(bpage->space);
fil_system_exit();
fprintf(stderr, fprintf(stderr,
"InnoDB: Database page corruption on disk" "InnoDB: Database page corruption on disk"
" or a failed\n" " 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" "InnoDB: You may have to recover"
" from a backup.\n", " from a backup.\n",
bpage->space,
space ? space->name : "NULL",
(ulong) bpage->offset); (ulong) bpage->offset);
buf_page_print(frame, buf_page_get_zip_size(bpage), buf_page_print(frame, buf_page_get_zip_size(bpage),
BUF_PAGE_PRINT_NO_CRASH); BUF_PAGE_PRINT_NO_CRASH);

View File

@ -43,6 +43,8 @@ Modified Jan Lindström jan.lindstrom@mariadb.com
/** Mutex for keys */ /** Mutex for keys */
UNIV_INTERN ib_mutex_t fil_crypt_key_mutex; UNIV_INTERN ib_mutex_t fil_crypt_key_mutex;
static bool fil_crypt_threads_inited = false;
#ifdef UNIV_PFS_MUTEX #ifdef UNIV_PFS_MUTEX
UNIV_INTERN mysql_pfs_key_t fil_crypt_key_mutex_key; UNIV_INTERN mysql_pfs_key_t fil_crypt_key_mutex_key;
#endif #endif
@ -107,6 +109,8 @@ UNIV_INTERN mysql_pfs_key_t fil_crypt_data_mutex_key;
static bool static bool
fil_crypt_needs_rotation( fil_crypt_needs_rotation(
/*=====================*/ /*=====================*/
fil_encryption_t encrypt_mode, /*!< in: Encryption
mode */
uint key_version, /*!< in: Key version */ uint key_version, /*!< in: Key version */
uint latest_key_version, /*!< in: Latest key version */ uint latest_key_version, /*!< in: Latest key version */
uint rotate_key_age); /*!< in: When to rotate */ 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 static inline
uint uint
fil_crypt_get_latest_key_version( fil_crypt_get_latest_key_version(
/*=====================*/ /*=============================*/
fil_space_crypt_t* crypt_data) /*!< in: crypt data */ fil_space_crypt_t* crypt_data) /*!< in: crypt data */
{ {
uint rc = encryption_key_get_latest_version(crypt_data->key_id); uint rc = encryption_key_get_latest_version(crypt_data->key_id);
if (fil_crypt_needs_rotation(crypt_data->min_key_version, if (fil_crypt_needs_rotation(crypt_data->encryption,
rc, srv_fil_crypt_rotate_key_age)) { crypt_data->min_key_version,
rc, srv_fil_crypt_rotate_key_age)) {
os_event_set(fil_crypt_threads_event); os_event_set(fil_crypt_threads_event);
} }
@ -169,7 +174,12 @@ fil_crypt_get_latest_key_version(
/****************************************************************** /******************************************************************
Mutex helper for crypt_data->scheme */ 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 = fil_space_crypt_t* crypt_data =
static_cast<fil_space_crypt_t*>(scheme); static_cast<fil_space_crypt_t*>(scheme);
@ -220,7 +230,7 @@ Merge fil_space_crypt_t object */
UNIV_INTERN UNIV_INTERN
void void
fil_space_merge_crypt_data( fil_space_merge_crypt_data(
/*====================*/ /*=======================*/
fil_space_crypt_t* dst,/*!< out: Crypt data */ fil_space_crypt_t* dst,/*!< out: Crypt data */
const fil_space_crypt_t* src)/*!< in: 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?) */ /* no support for changing iv (yet?) */
ut_a(memcmp(src->iv, dst->iv, sizeof(src->iv)) == 0); ut_a(memcmp(src->iv, dst->iv, sizeof(src->iv)) == 0);
dst->encryption = src->encryption;
dst->type = src->type; dst->type = src->type;
dst->min_key_version = src->min_key_version; dst->min_key_version = src->min_key_version;
dst->keyserver_requests += src->keyserver_requests; dst->keyserver_requests += src->keyserver_requests;
@ -255,8 +266,13 @@ fil_space_read_crypt_data(
ulint offset) /*!< in: offset */ ulint offset) /*!< in: offset */
{ {
if (memcmp(page + offset, EMPTY_PATTERN, MAGIC_SZ) == 0) { if (memcmp(page + offset, EMPTY_PATTERN, MAGIC_SZ) == 0) {
/* crypt is not stored */ /* crypt is not stored but create memory cache for
return NULL; 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) { if (memcmp(page + offset, CRYPT_MAGIC, MAGIC_SZ) != 0) {
@ -272,7 +288,12 @@ fil_space_read_crypt_data(
page[offset + 3], page[offset + 3],
page[offset + 4], page[offset + 4],
page[offset + 5]); 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); 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 UNIV_INTERN
bool bool
fil_space_check_encryption_write( 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; return false;
}
fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space); fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space);
@ -599,6 +621,8 @@ fil_space_encrypt(
return; return;
} }
ut_ad(crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF);
key_version = fil_crypt_get_latest_key_version(crypt_data); key_version = fil_crypt_get_latest_key_version(crypt_data);
if (key_version == ENCRYPTION_KEY_VERSION_INVALID) { if (key_version == ENCRYPTION_KEY_VERSION_INVALID) {
@ -742,6 +766,8 @@ fil_space_decrypt(
return false; /* page not decrypted */ return false; /* page not decrypted */
} }
ut_ad(crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF);
/* read space & offset & lsn */ /* read space & offset & lsn */
ulint space = mach_read_from_4( ulint space = mach_read_from_4(
src_frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); 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 static bool
fil_crypt_needs_rotation( fil_crypt_needs_rotation(
/*=====================*/ /*=====================*/
fil_encryption_t encrypt_mode, /*!< in: Encryption
mode */
uint key_version, /*!< in: Key version */ uint key_version, /*!< in: Key version */
uint latest_key_version, /*!< in: Latest key version */ uint latest_key_version, /*!< in: Latest key version */
uint rotate_key_age) /*!< in: When to rotate */ uint rotate_key_age) /*!< in: When to rotate */
{ {
if (key_version == ENCRYPTION_KEY_VERSION_INVALID) if (key_version == ENCRYPTION_KEY_VERSION_INVALID) {
return false; return false;
}
if (key_version == 0 && latest_key_version != 0) { if (key_version == 0 && latest_key_version != 0) {
/* this is rotation unencrypted => encrypted /* this is rotation unencrypted => encrypted
@ -951,8 +980,11 @@ fil_crypt_needs_rotation(
} }
if (latest_key_version == 0 && key_version != 0) { if (latest_key_version == 0 && key_version != 0) {
/* this is rotation encrypted => unencrypted */ if (encrypt_mode == FIL_SPACE_ENCRYPTION_DEFAULT) {
return true; /* this is rotation encrypted => unencrypted */
return true;
}
return false;
} }
/* this is rotation encrypted => encrypted, /* this is rotation encrypted => encrypted,
@ -973,11 +1005,15 @@ fil_crypt_is_closing(
/*=================*/ /*=================*/
ulint space) /*!< in: FIL space id */ ulint space) /*!< in: FIL space id */
{ {
bool closing; bool closing=true;
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
mutex_enter(&crypt_data->mutex);
closing = crypt_data->closing; if (crypt_data) {
mutex_exit(&crypt_data->mutex); mutex_enter(&crypt_data->mutex);
closing = crypt_data->closing;
mutex_exit(&crypt_data->mutex);
}
return closing; return closing;
} }
@ -1189,6 +1225,7 @@ Check if space needs rotation given a key_state
static static
bool bool
fil_crypt_space_needs_rotation( fil_crypt_space_needs_rotation(
/*===========================*/
rotate_thread_t* state, /*!< in: Key rotation state */ rotate_thread_t* state, /*!< in: Key rotation state */
key_state_t* key_state, /*!< in: Key state */ key_state_t* key_state, /*!< in: Key state */
bool* recheck) /*!< out: needs recheck ? */ bool* recheck) /*!< out: needs recheck ? */
@ -1228,11 +1265,6 @@ fil_crypt_space_needs_rotation(
mutex_enter(&crypt_data->mutex); mutex_enter(&crypt_data->mutex);
do { do {
if (crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) {
/* This space is unencrypted by user request */
break;
}
/* prevent threads from starting to rotate space */ /* prevent threads from starting to rotate space */
if (crypt_data->rotate_state.starting) { if (crypt_data->rotate_state.starting) {
/* recheck this space later */ /* recheck this space later */
@ -1255,6 +1287,7 @@ fil_crypt_space_needs_rotation(
} }
bool need_key_rotation = fil_crypt_needs_rotation( bool need_key_rotation = fil_crypt_needs_rotation(
crypt_data->encryption,
crypt_data->min_key_version, crypt_data->min_key_version,
key_state->key_version, key_state->rotate_key_age); key_state->key_version, key_state->rotate_key_age);
@ -1351,7 +1384,7 @@ used when inside a space */
static static
void void
fil_crypt_realloc_iops( fil_crypt_realloc_iops(
/*========================*/ /*===================*/
rotate_thread_t *state) /*!< in: Key rotation status */ rotate_thread_t *state) /*!< in: Key rotation status */
{ {
ut_a(state->allocated_iops > 0); ut_a(state->allocated_iops > 0);
@ -1444,7 +1477,7 @@ Return allocated iops to global */
static static
void void
fil_crypt_return_iops( fil_crypt_return_iops(
/*========================*/ /*==================*/
rotate_thread_t *state) /*!< in: Key rotation status */ rotate_thread_t *state) /*!< in: Key rotation status */
{ {
if (state->allocated_iops > 0) { if (state->allocated_iops > 0) {
@ -1526,11 +1559,17 @@ fil_crypt_start_rotate_space(
ulint space = state->space; ulint space = state->space;
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
ut_ad(crypt_data);
mutex_enter(&crypt_data->mutex); mutex_enter(&crypt_data->mutex);
ut_ad(key_state->key_id == crypt_data->key_id); ut_ad(key_state->key_id == crypt_data->key_id);
if (crypt_data->rotate_state.active_threads == 0) { if (crypt_data->rotate_state.active_threads == 0) {
/* only first thread needs to init */ /* 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 crypt_data->rotate_state.next_offset = 1; // skip page 0
/* no need to rotate beyond current max /* no need to rotate beyond current max
* if space extends, it will be encrypted with newer version */ * if space extends, it will be encrypted with newer version */
@ -1568,28 +1607,33 @@ fil_crypt_find_page_to_rotate(
ulint space = state->space; ulint space = state->space;
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
mutex_enter(&crypt_data->mutex); /* Space might already be dropped */
ut_ad(key_state->key_id == crypt_data->key_id); if (crypt_data) {
mutex_enter(&crypt_data->mutex);
ut_ad(key_state->key_id == crypt_data->key_id);
if (crypt_data->closing == false && if (crypt_data->closing == false &&
crypt_data->rotate_state.next_offset < crypt_data->rotate_state.next_offset <
crypt_data->rotate_state.max_offset) { crypt_data->rotate_state.max_offset) {
state->offset = crypt_data->rotate_state.next_offset; state->offset = crypt_data->rotate_state.next_offset;
ulint remaining = crypt_data->rotate_state.max_offset - ulint remaining = crypt_data->rotate_state.max_offset -
crypt_data->rotate_state.next_offset; crypt_data->rotate_state.next_offset;
if (batch <= remaining) if (batch <= remaining) {
state->batch = batch; state->batch = batch;
else } else {
state->batch = remaining; 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); mutex_exit(&crypt_data->mutex);
return true;
} }
mutex_exit(&crypt_data->mutex);
return false; return false;
} }
@ -1636,6 +1680,7 @@ Get a page and compute sleep time
static static
buf_block_t* buf_block_t*
fil_crypt_get_page_throttle_func( fil_crypt_get_page_throttle_func(
/*=============================*/
rotate_thread_t* state, /*!< in/out: Key rotation state */ rotate_thread_t* state, /*!< in/out: Key rotation state */
ulint space, /*!< in: FIL space id */ ulint space, /*!< in: FIL space id */
uint zip_size, /*!< in: compressed size if uint zip_size, /*!< in: compressed size if
@ -1752,7 +1797,7 @@ Rotate one page */
static static
void void
fil_crypt_rotate_page( fil_crypt_rotate_page(
/*===================*/ /*==================*/
const key_state_t* key_state, /*!< in: Key state */ const key_state_t* key_state, /*!< in: Key state */
rotate_thread_t* state) /*!< in: Key rotation state */ rotate_thread_t* state) /*!< in: Key rotation state */
{ {
@ -1791,8 +1836,10 @@ fil_crypt_rotate_page(
if (kv == 0 && if (kv == 0 &&
fil_crypt_is_page_uninitialized(frame, zip_size)) { fil_crypt_is_page_uninitialized(frame, zip_size)) {
; ;
} else if (fil_crypt_needs_rotation(kv, key_state->key_version, } else if (fil_crypt_needs_rotation(
key_state->rotate_key_age)) { crypt_data->encryption,
kv, key_state->key_version,
key_state->rotate_key_age)) {
/* page can be "fresh" i.e never written in case /* page can be "fresh" i.e never written in case
* kv == 0 or it should have a key version at least * kv == 0 or it should have a key version at least
@ -1812,11 +1859,13 @@ fil_crypt_rotate_page(
/* statistics */ /* statistics */
state->crypt_stat.pages_modified++; state->crypt_stat.pages_modified++;
} else { } else {
ut_a(kv >= crypt_data->min_key_version || if (crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF) {
(kv == 0 && key_state->key_version == 0)); ut_a(kv >= crypt_data->min_key_version ||
(kv == 0 && key_state->key_version == 0));
if (kv < state->min_key_version_found) { if (kv < state->min_key_version_found) {
state->min_key_version_found = kv; state->min_key_version_found = kv;
}
} }
} }
@ -1878,6 +1927,7 @@ fil_crypt_rotate_page(
/* if we just detected that scrubbing was turned off /* if we just detected that scrubbing was turned off
* update global state to reflect this */ * update global state to reflect this */
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
ut_ad(crypt_data);
mutex_enter(&crypt_data->mutex); mutex_enter(&crypt_data->mutex);
crypt_data->rotate_state.scrubbing.is_active = false; crypt_data->rotate_state.scrubbing.is_active = false;
mutex_exit(&crypt_data->mutex); mutex_exit(&crypt_data->mutex);
@ -2006,68 +2056,73 @@ fil_crypt_complete_rotate_space(
{ {
ulint space = state->space; ulint space = state->space;
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
mutex_enter(&crypt_data->mutex);
/** /* Space might already be dropped */
* Update crypt data state with state from thread if (crypt_data) {
*/ ut_ad(crypt_data);
if (state->min_key_version_found < mutex_enter(&crypt_data->mutex);
crypt_data->rotate_state.min_key_version_found) {
crypt_data->rotate_state.min_key_version_found =
state->min_key_version_found;
}
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); if (state->end_lsn > crypt_data->rotate_state.end_lsn) {
crypt_data->rotate_state.active_threads--; crypt_data->rotate_state.end_lsn = state->end_lsn;
bool last = crypt_data->rotate_state.active_threads == 0; }
/** ut_a(crypt_data->rotate_state.active_threads > 0);
* check if space is fully done crypt_data->rotate_state.active_threads--;
* this as when threads shutdown, it could be that we "complete" bool last = crypt_data->rotate_state.active_threads == 0;
* iterating before we have scanned the full space.
*/
bool done = crypt_data->rotate_state.next_offset >=
crypt_data->rotate_state.max_offset;
/** /**
* we should flush space if we're last thread AND * check if space is fully done
* the iteration is done * this as when threads shutdown, it could be that we "complete"
*/ * iterating before we have scanned the full space.
bool should_flush = last && done; */
bool done = crypt_data->rotate_state.next_offset >=
crypt_data->rotate_state.max_offset;
if (should_flush) { /**
/* we're the last active thread */ * we should flush space if we're last thread AND
crypt_data->rotate_state.flushing = true; * the iteration is done
crypt_data->min_key_version = */
crypt_data->rotate_state.min_key_version_found; 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) { 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); mutex_enter(&crypt_data->mutex);
crypt_data->rotate_state.scrubbing. crypt_data->rotate_state.flushing = false;
last_scrub_completed = time(0);
mutex_exit(&crypt_data->mutex); 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_id_t rotation_thread_id;
os_thread_create(fil_crypt_thread, NULL, &rotation_thread_id); os_thread_create(fil_crypt_thread, NULL, &rotation_thread_id);
ib_logf(IB_LOG_LEVEL_INFO, ib_logf(IB_LOG_LEVEL_INFO,
"Creating #%d thread id %lu total threads %du\n", "Creating #%d thread id %lu total threads %u\n",
i, os_thread_pf(rotation_thread_id), new_cnt); i+1, os_thread_pf(rotation_thread_id), new_cnt);
} }
} else if (new_cnt < srv_n_fil_crypt_threads) { } else if (new_cnt < srv_n_fil_crypt_threads) {
srv_n_fil_crypt_threads = new_cnt; srv_n_fil_crypt_threads = new_cnt;
@ -2232,6 +2287,18 @@ fil_crypt_set_rotation_iops(
os_event_set(fil_crypt_threads_event); 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 */ Init threads for key rotation */
UNIV_INTERN UNIV_INTERN
@ -2243,6 +2310,7 @@ fil_crypt_threads_init()
fil_crypt_threads_event = os_event_create(); fil_crypt_threads_event = os_event_create();
mutex_create(fil_crypt_threads_mutex_key, mutex_create(fil_crypt_threads_mutex_key,
&fil_crypt_threads_mutex, SYNC_NO_ORDER_CHECK); &fil_crypt_threads_mutex, SYNC_NO_ORDER_CHECK);
fil_crypt_threads_inited = true;
uint cnt = srv_n_fil_crypt_threads; uint cnt = srv_n_fil_crypt_threads;
srv_n_fil_crypt_threads = 0; srv_n_fil_crypt_threads = 0;
@ -2279,7 +2347,7 @@ fil_space_crypt_mark_space_closing(
/*===============================*/ /*===============================*/
ulint space) /*!< in: Space id */ ulint space) /*!< in: Space id */
{ {
if (!srv_encrypt_tables) { if (!fil_crypt_threads_inited) {
return; return;
} }

View File

@ -6857,7 +6857,7 @@ Get crypt data for a tablespace */
UNIV_INTERN UNIV_INTERN
void void
fil_space_set_crypt_data( fil_space_set_crypt_data(
/*==================*/ /*=====================*/
ulint id, /*!< in: space id */ ulint id, /*!< in: space id */
fil_space_crypt_t* crypt_data) /*!< in: crypt data */ fil_space_crypt_t* crypt_data) /*!< in: crypt data */
{ {
@ -6872,19 +6872,26 @@ fil_space_set_crypt_data(
if (space != NULL) { if (space != NULL) {
if (space->crypt_data != 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, fil_space_merge_crypt_data(space->crypt_data,
crypt_data); crypt_data);
free_crypt_data = crypt_data; free_crypt_data = crypt_data;
} else { } else {
space->crypt_data = crypt_data; space->crypt_data = crypt_data;
mutex_exit(&fil_system->mutex);
} }
} else { } else {
/* there is a small risk that tablespace has been deleted */ /* there is a small risk that tablespace has been deleted */
free_crypt_data = crypt_data; free_crypt_data = crypt_data;
mutex_exit(&fil_system->mutex);
} }
mutex_exit(&fil_system->mutex);
if (free_crypt_data != NULL) { if (free_crypt_data != NULL) {
/* there was already crypt data present and the new crypt /* there was already crypt data present and the new crypt
* data provided as argument to this function has been merged * data provided as argument to this function has been merged

View File

@ -17821,6 +17821,7 @@ which control InnoDB "status monitor" output to the error log.
static static
void void
innodb_status_output_update( innodb_status_output_update(
/*========================*/
THD* thd __attribute__((unused)), THD* thd __attribute__((unused)),
struct st_mysql_sys_var* var __attribute__((unused)), struct st_mysql_sys_var* var __attribute__((unused)),
void* var_ptr __attribute__((unused)), void* var_ptr __attribute__((unused)),
@ -17836,7 +17837,7 @@ Update the system variable innodb_encryption_threads */
static static
void void
innodb_encryption_threads_update( innodb_encryption_threads_update(
/*=========================*/ /*=============================*/
THD* thd, /*!< in: thread handle */ THD* thd, /*!< in: thread handle */
struct st_mysql_sys_var* var, /*!< in: pointer to struct st_mysql_sys_var* var, /*!< in: pointer to
system variable */ system variable */
@ -17853,7 +17854,7 @@ Update the system variable innodb_encryption_rotate_key_age */
static static
void void
innodb_encryption_rotate_key_age_update( innodb_encryption_rotate_key_age_update(
/*=========================*/ /*====================================*/
THD* thd, /*!< in: thread handle */ THD* thd, /*!< in: thread handle */
struct st_mysql_sys_var* var, /*!< in: pointer to struct st_mysql_sys_var* var, /*!< in: pointer to
system variable */ system variable */
@ -17870,7 +17871,7 @@ Update the system variable innodb_encryption_rotation_iops */
static static
void void
innodb_encryption_rotation_iops_update( innodb_encryption_rotation_iops_update(
/*=========================*/ /*===================================*/
THD* thd, /*!< in: thread handle */ THD* thd, /*!< in: thread handle */
struct st_mysql_sys_var* var, /*!< in: pointer to struct st_mysql_sys_var* var, /*!< in: pointer to
system variable */ system variable */
@ -17882,6 +17883,23 @@ innodb_encryption_rotation_iops_update(
fil_crypt_set_rotation_iops(*static_cast<const uint*>(save)); 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[]= { static SHOW_VAR innodb_status_variables_export[]= {
{"Innodb", (char*) &show_innodb_vars, SHOW_FUNC}, {"Innodb", (char*) &show_innodb_vars, SHOW_FUNC},
{NullS, NullS, SHOW_LONG} {NullS, NullS, SHOW_LONG}
@ -19183,7 +19201,9 @@ static MYSQL_SYSVAR_ENUM(encrypt_tables, srv_encrypt_tables,
PLUGIN_VAR_OPCMDARG, PLUGIN_VAR_OPCMDARG,
"Enable encryption for tables. " "Enable encryption for tables. "
"Don't forget to enable --innodb-encrypt-log too", "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); &srv_encrypt_tables_typelib);
static MYSQL_SYSVAR_UINT(encryption_threads, srv_n_fil_crypt_threads, static MYSQL_SYSVAR_UINT(encryption_threads, srv_n_fil_crypt_threads,

View File

@ -128,7 +128,7 @@ Get crypt data for a space*/
UNIV_INTERN UNIV_INTERN
fil_space_crypt_t * fil_space_crypt_t *
fil_space_get_crypt_data( fil_space_get_crypt_data(
/*======================*/ /*=====================*/
ulint space); /*!< in: tablespace id */ ulint space); /*!< in: tablespace id */
/********************************************************************* /*********************************************************************
@ -136,15 +136,16 @@ Set crypt data for a space*/
UNIV_INTERN UNIV_INTERN
void void
fil_space_set_crypt_data( fil_space_set_crypt_data(
/*======================*/ /*=====================*/
ulint space, /*!< in: tablespace id */ ulint space, /*!< in: tablespace id */
fil_space_crypt_t* crypt_data); /*!< in: crypt data to set */ fil_space_crypt_t* crypt_data); /*!< in: crypt data to set */
/********************************************************************* /*********************************************************************
Merge crypt data */ Merge crypt data */
UNIV_INTERN
void void
fil_space_merge_crypt_data( fil_space_merge_crypt_data(
/*======================*/ /*=======================*/
fil_space_crypt_t* dst_crypt_data, /*!< in: crypt_data */ fil_space_crypt_t* dst_crypt_data, /*!< in: crypt_data */
const fil_space_crypt_t* src_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 UNIV_INTERN
void void
fil_space_clear_crypt_data( fil_space_clear_crypt_data(
/*======================*/ /*=======================*/
byte* page, /*!< in: buffer page */ byte* page, /*!< in: buffer page */
ulint offset); /*!< in: offset where crypt data is stored */ 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 UNIV_INTERN
bool bool
fil_space_check_encryption_read( fil_space_check_encryption_read(
/*==============================*/ /*============================*/
ulint space); /*!< in: tablespace id */ ulint space); /*!< in: tablespace id */
/********************************************************************* /*********************************************************************
@ -202,7 +203,7 @@ Check if page shall be encrypted before write */
UNIV_INTERN UNIV_INTERN
bool bool
fil_space_check_encryption_write( fil_space_check_encryption_write(
/*==============================*/ /*=============================*/
ulint space); /*!< in: tablespace id */ ulint space); /*!< in: tablespace id */
/********************************************************************* /*********************************************************************
@ -210,7 +211,7 @@ Encrypt buffer page */
UNIV_INTERN UNIV_INTERN
void void
fil_space_encrypt( fil_space_encrypt(
/*===============*/ /*==============*/
ulint space, /*!< in: tablespace id */ ulint space, /*!< in: tablespace id */
ulint offset, /*!< in: page no */ ulint offset, /*!< in: page no */
lsn_t lsn, /*!< in: page lsn */ lsn_t lsn, /*!< in: page lsn */
@ -223,7 +224,7 @@ Decrypt buffer page */
UNIV_INTERN UNIV_INTERN
void void
fil_space_decrypt( fil_space_decrypt(
/*===============*/ /*==============*/
ulint space, /*!< in: tablespace id */ ulint space, /*!< in: tablespace id */
const byte* src_frame,/*!< in: page frame */ const byte* src_frame,/*!< in: page frame */
ulint page_size, /*!< in: size of data to encrypt */ ulint page_size, /*!< in: size of data to encrypt */
@ -236,7 +237,7 @@ Decrypt buffer page
UNIV_INTERN UNIV_INTERN
bool bool
fil_space_decrypt( fil_space_decrypt(
/*===============*/ /*==============*/
fil_space_crypt_t* crypt_data, /*!< in: crypt data */ fil_space_crypt_t* crypt_data, /*!< in: crypt data */
const byte* src_frame,/*!< in: page frame */ const byte* src_frame,/*!< in: page frame */
ulint page_size, /*!< in: page size */ ulint page_size, /*!< in: page size */
@ -250,7 +251,7 @@ as it modifies srv_checksum_algorithm (temporarily)
UNIV_INTERN UNIV_INTERN
bool bool
fil_space_verify_crypt_checksum( fil_space_verify_crypt_checksum(
/*===============*/ /*============================*/
const byte* src_frame,/*!< in: page frame */ const byte* src_frame,/*!< in: page frame */
ulint zip_size); /*!< in: size of data to encrypt */ ulint zip_size); /*!< in: size of data to encrypt */
@ -285,7 +286,7 @@ Set rotate key age */
UNIV_INTERN UNIV_INTERN
void void
fil_crypt_set_rotate_key_age( fil_crypt_set_rotate_key_age(
/*=====================*/ /*=========================*/
uint rotate_age); /*!< in: requested rotate age */ uint rotate_age); /*!< in: requested rotate age */
/********************************************************************* /*********************************************************************
@ -293,7 +294,7 @@ Set rotation threads iops */
UNIV_INTERN UNIV_INTERN
void void
fil_crypt_set_rotation_iops( fil_crypt_set_rotation_iops(
/*=====================*/ /*========================*/
uint iops); /*!< in: requested iops */ uint iops); /*!< in: requested iops */
/********************************************************************* /*********************************************************************
@ -301,7 +302,7 @@ Mark a space as closing */
UNIV_INTERN UNIV_INTERN
void void
fil_space_crypt_mark_space_closing( fil_space_crypt_mark_space_closing(
/*===============*/ /*===============================*/
ulint space); /*!< in: tablespace id */ ulint space); /*!< in: tablespace id */
/********************************************************************* /*********************************************************************
@ -309,7 +310,7 @@ Wait for crypt threads to stop accessing space */
UNIV_INTERN UNIV_INTERN
void void
fil_space_crypt_close_tablespace( fil_space_crypt_close_tablespace(
/*===============*/ /*=============================*/
ulint space); /*!< in: tablespace id */ ulint space); /*!< in: tablespace id */
/** Struct for retreiving info about encryption */ /** Struct for retreiving info about encryption */
@ -331,7 +332,7 @@ Get crypt status for a space
UNIV_INTERN UNIV_INTERN
int int
fil_space_crypt_get_status( fil_space_crypt_get_status(
/*==================*/ /*=======================*/
ulint id, /*!< in: space id */ ulint id, /*!< in: space id */
struct fil_space_crypt_status_t * status); /*!< out: status */ struct fil_space_crypt_status_t * status); /*!< out: status */
@ -370,10 +371,19 @@ Get scrub status for a space
UNIV_INTERN UNIV_INTERN
int int
fil_space_get_scrub_status( fil_space_get_scrub_status(
/*==================*/ /*=======================*/
ulint id, /*!< in: space id */ ulint id, /*!< in: space id */
struct fil_space_scrub_status_t * status); /*!< out: status */ 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 #ifndef UNIV_NONINL
#include "fil0crypt.ic" #include "fil0crypt.ic"
#endif #endif

View File

@ -4302,6 +4302,7 @@ buf_page_io_complete(
const ibool uncompressed = (buf_page_get_state(bpage) const ibool uncompressed = (buf_page_get_state(bpage)
== BUF_BLOCK_FILE_PAGE); == BUF_BLOCK_FILE_PAGE);
bool have_LRU_mutex = false; bool have_LRU_mutex = false;
fil_space_t* space = NULL;
ut_a(buf_page_in_file(bpage)); ut_a(buf_page_in_file(bpage));
@ -4403,13 +4404,20 @@ buf_page_io_complete(
goto page_not_corrupt; goto page_not_corrupt;
;); ;);
corrupt: corrupt:
fil_system_enter();
space = fil_space_get_by_id(bpage->space);
fil_system_exit();
fprintf(stderr, fprintf(stderr,
"InnoDB: Database page corruption on disk" "InnoDB: Database page corruption on disk"
" or a failed\n" " 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" "InnoDB: You may have to recover"
" from a backup.\n", " from a backup.\n",
bpage->space,
space ? space->name : "NULL",
(ulong) bpage->offset); (ulong) bpage->offset);
buf_page_print(frame, buf_page_get_zip_size(bpage), buf_page_print(frame, buf_page_get_zip_size(bpage),
BUF_PAGE_PRINT_NO_CRASH); BUF_PAGE_PRINT_NO_CRASH);
fprintf(stderr, fprintf(stderr,

View File

@ -43,6 +43,8 @@ Modified Jan Lindström jan.lindstrom@mariadb.com
/** Mutex for keys */ /** Mutex for keys */
UNIV_INTERN ib_mutex_t fil_crypt_key_mutex; UNIV_INTERN ib_mutex_t fil_crypt_key_mutex;
static bool fil_crypt_threads_inited = false;
#ifdef UNIV_PFS_MUTEX #ifdef UNIV_PFS_MUTEX
UNIV_INTERN mysql_pfs_key_t fil_crypt_key_mutex_key; UNIV_INTERN mysql_pfs_key_t fil_crypt_key_mutex_key;
#endif #endif
@ -107,6 +109,8 @@ UNIV_INTERN mysql_pfs_key_t fil_crypt_data_mutex_key;
static bool static bool
fil_crypt_needs_rotation( fil_crypt_needs_rotation(
/*=====================*/ /*=====================*/
fil_encryption_t encrypt_mode, /*!< in: Encryption
mode */
uint key_version, /*!< in: Key version */ uint key_version, /*!< in: Key version */
uint latest_key_version, /*!< in: Latest key version */ uint latest_key_version, /*!< in: Latest key version */
uint rotate_key_age); /*!< in: When to rotate */ 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 static inline
uint uint
fil_crypt_get_latest_key_version( fil_crypt_get_latest_key_version(
/*=====================*/ /*=============================*/
fil_space_crypt_t* crypt_data) /*!< in: crypt data */ fil_space_crypt_t* crypt_data) /*!< in: crypt data */
{ {
uint rc = encryption_key_get_latest_version(crypt_data->key_id); uint rc = encryption_key_get_latest_version(crypt_data->key_id);
if (fil_crypt_needs_rotation(crypt_data->min_key_version, if (fil_crypt_needs_rotation(crypt_data->encryption,
rc, srv_fil_crypt_rotate_key_age)) { crypt_data->min_key_version,
rc, srv_fil_crypt_rotate_key_age)) {
os_event_set(fil_crypt_threads_event); os_event_set(fil_crypt_threads_event);
} }
@ -169,7 +174,12 @@ fil_crypt_get_latest_key_version(
/****************************************************************** /******************************************************************
Mutex helper for crypt_data->scheme */ 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 = fil_space_crypt_t* crypt_data =
static_cast<fil_space_crypt_t*>(scheme); static_cast<fil_space_crypt_t*>(scheme);
@ -220,7 +230,7 @@ Merge fil_space_crypt_t object */
UNIV_INTERN UNIV_INTERN
void void
fil_space_merge_crypt_data( fil_space_merge_crypt_data(
/*====================*/ /*=======================*/
fil_space_crypt_t* dst,/*!< out: Crypt data */ fil_space_crypt_t* dst,/*!< out: Crypt data */
const fil_space_crypt_t* src)/*!< in: 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?) */ /* no support for changing iv (yet?) */
ut_a(memcmp(src->iv, dst->iv, sizeof(src->iv)) == 0); ut_a(memcmp(src->iv, dst->iv, sizeof(src->iv)) == 0);
dst->encryption = src->encryption;
dst->type = src->type; dst->type = src->type;
dst->min_key_version = src->min_key_version; dst->min_key_version = src->min_key_version;
dst->keyserver_requests += src->keyserver_requests; dst->keyserver_requests += src->keyserver_requests;
@ -255,8 +266,13 @@ fil_space_read_crypt_data(
ulint offset) /*!< in: offset */ ulint offset) /*!< in: offset */
{ {
if (memcmp(page + offset, EMPTY_PATTERN, MAGIC_SZ) == 0) { if (memcmp(page + offset, EMPTY_PATTERN, MAGIC_SZ) == 0) {
/* crypt is not stored */ /* crypt is not stored but create memory cache for
return NULL; 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) { if (memcmp(page + offset, CRYPT_MAGIC, MAGIC_SZ) != 0) {
@ -272,7 +288,12 @@ fil_space_read_crypt_data(
page[offset + 3], page[offset + 3],
page[offset + 4], page[offset + 4],
page[offset + 5]); 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); 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 UNIV_INTERN
bool bool
fil_space_check_encryption_write( 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; return false;
}
fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space); fil_space_crypt_t* crypt_data = fil_space_get_crypt_data(space);
@ -599,6 +621,8 @@ fil_space_encrypt(
return; return;
} }
ut_ad(crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF);
key_version = fil_crypt_get_latest_key_version(crypt_data); key_version = fil_crypt_get_latest_key_version(crypt_data);
if (key_version == ENCRYPTION_KEY_VERSION_INVALID) { if (key_version == ENCRYPTION_KEY_VERSION_INVALID) {
@ -742,6 +766,8 @@ fil_space_decrypt(
return false; /* page not decrypted */ return false; /* page not decrypted */
} }
ut_ad(crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF);
/* read space & offset & lsn */ /* read space & offset & lsn */
ulint space = mach_read_from_4( ulint space = mach_read_from_4(
src_frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); src_frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID);
@ -794,7 +820,7 @@ fil_space_decrypt(
FIL_PAGE_DATA_END); FIL_PAGE_DATA_END);
// clear key-version & crypt-checksum from dst // 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(); srv_stats.pages_decrypted.inc();
@ -937,12 +963,15 @@ Check if a key needs rotation given a key_state
static bool static bool
fil_crypt_needs_rotation( fil_crypt_needs_rotation(
/*=====================*/ /*=====================*/
fil_encryption_t encrypt_mode, /*!< in: Encryption
mode */
uint key_version, /*!< in: Key version */ uint key_version, /*!< in: Key version */
uint latest_key_version, /*!< in: Latest key version */ uint latest_key_version, /*!< in: Latest key version */
uint rotate_key_age) /*!< in: When to rotate */ uint rotate_key_age) /*!< in: When to rotate */
{ {
if (key_version == ENCRYPTION_KEY_VERSION_INVALID) if (key_version == ENCRYPTION_KEY_VERSION_INVALID) {
return false; return false;
}
if (key_version == 0 && latest_key_version != 0) { if (key_version == 0 && latest_key_version != 0) {
/* this is rotation unencrypted => encrypted /* this is rotation unencrypted => encrypted
@ -951,8 +980,11 @@ fil_crypt_needs_rotation(
} }
if (latest_key_version == 0 && key_version != 0) { if (latest_key_version == 0 && key_version != 0) {
/* this is rotation encrypted => unencrypted */ if (encrypt_mode == FIL_SPACE_ENCRYPTION_DEFAULT) {
return true; /* this is rotation encrypted => unencrypted */
return true;
}
return false;
} }
/* this is rotation encrypted => encrypted, /* this is rotation encrypted => encrypted,
@ -973,11 +1005,15 @@ fil_crypt_is_closing(
/*=================*/ /*=================*/
ulint space) /*!< in: FIL space id */ ulint space) /*!< in: FIL space id */
{ {
bool closing; bool closing=true;
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
mutex_enter(&crypt_data->mutex);
closing = crypt_data->closing; if (crypt_data) {
mutex_exit(&crypt_data->mutex); mutex_enter(&crypt_data->mutex);
closing = crypt_data->closing;
mutex_exit(&crypt_data->mutex);
}
return closing; return closing;
} }
@ -1189,6 +1225,7 @@ Check if space needs rotation given a key_state
static static
bool bool
fil_crypt_space_needs_rotation( fil_crypt_space_needs_rotation(
/*===========================*/
rotate_thread_t* state, /*!< in: Key rotation state */ rotate_thread_t* state, /*!< in: Key rotation state */
key_state_t* key_state, /*!< in: Key state */ key_state_t* key_state, /*!< in: Key state */
bool* recheck) /*!< out: needs recheck ? */ bool* recheck) /*!< out: needs recheck ? */
@ -1228,11 +1265,6 @@ fil_crypt_space_needs_rotation(
mutex_enter(&crypt_data->mutex); mutex_enter(&crypt_data->mutex);
do { do {
if (crypt_data->encryption == FIL_SPACE_ENCRYPTION_OFF) {
/* This space is unencrypted by user request */
break;
}
/* prevent threads from starting to rotate space */ /* prevent threads from starting to rotate space */
if (crypt_data->rotate_state.starting) { if (crypt_data->rotate_state.starting) {
/* recheck this space later */ /* recheck this space later */
@ -1255,6 +1287,7 @@ fil_crypt_space_needs_rotation(
} }
bool need_key_rotation = fil_crypt_needs_rotation( bool need_key_rotation = fil_crypt_needs_rotation(
crypt_data->encryption,
crypt_data->min_key_version, crypt_data->min_key_version,
key_state->key_version, key_state->rotate_key_age); key_state->key_version, key_state->rotate_key_age);
@ -1351,7 +1384,7 @@ used when inside a space */
static static
void void
fil_crypt_realloc_iops( fil_crypt_realloc_iops(
/*========================*/ /*===================*/
rotate_thread_t *state) /*!< in: Key rotation status */ rotate_thread_t *state) /*!< in: Key rotation status */
{ {
ut_a(state->allocated_iops > 0); ut_a(state->allocated_iops > 0);
@ -1444,7 +1477,7 @@ Return allocated iops to global */
static static
void void
fil_crypt_return_iops( fil_crypt_return_iops(
/*========================*/ /*==================*/
rotate_thread_t *state) /*!< in: Key rotation status */ rotate_thread_t *state) /*!< in: Key rotation status */
{ {
if (state->allocated_iops > 0) { if (state->allocated_iops > 0) {
@ -1526,11 +1559,17 @@ fil_crypt_start_rotate_space(
ulint space = state->space; ulint space = state->space;
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
ut_ad(crypt_data);
mutex_enter(&crypt_data->mutex); mutex_enter(&crypt_data->mutex);
ut_ad(key_state->key_id == crypt_data->key_id); ut_ad(key_state->key_id == crypt_data->key_id);
if (crypt_data->rotate_state.active_threads == 0) { if (crypt_data->rotate_state.active_threads == 0) {
/* only first thread needs to init */ /* 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 crypt_data->rotate_state.next_offset = 1; // skip page 0
/* no need to rotate beyond current max /* no need to rotate beyond current max
* if space extends, it will be encrypted with newer version */ * if space extends, it will be encrypted with newer version */
@ -1568,28 +1607,33 @@ fil_crypt_find_page_to_rotate(
ulint space = state->space; ulint space = state->space;
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
mutex_enter(&crypt_data->mutex); /* Space might already be dropped */
ut_ad(key_state->key_id == crypt_data->key_id); if (crypt_data) {
mutex_enter(&crypt_data->mutex);
ut_ad(key_state->key_id == crypt_data->key_id);
if (crypt_data->closing == false && if (crypt_data->closing == false &&
crypt_data->rotate_state.next_offset < crypt_data->rotate_state.next_offset <
crypt_data->rotate_state.max_offset) { crypt_data->rotate_state.max_offset) {
state->offset = crypt_data->rotate_state.next_offset; state->offset = crypt_data->rotate_state.next_offset;
ulint remaining = crypt_data->rotate_state.max_offset - ulint remaining = crypt_data->rotate_state.max_offset -
crypt_data->rotate_state.next_offset; crypt_data->rotate_state.next_offset;
if (batch <= remaining) if (batch <= remaining) {
state->batch = batch; state->batch = batch;
else } else {
state->batch = remaining; 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); mutex_exit(&crypt_data->mutex);
return true;
} }
mutex_exit(&crypt_data->mutex);
return false; return false;
} }
@ -1636,6 +1680,7 @@ Get a page and compute sleep time
static static
buf_block_t* buf_block_t*
fil_crypt_get_page_throttle_func( fil_crypt_get_page_throttle_func(
/*=============================*/
rotate_thread_t* state, /*!< in/out: Key rotation state */ rotate_thread_t* state, /*!< in/out: Key rotation state */
ulint space, /*!< in: FIL space id */ ulint space, /*!< in: FIL space id */
uint zip_size, /*!< in: compressed size if uint zip_size, /*!< in: compressed size if
@ -1752,7 +1797,7 @@ Rotate one page */
static static
void void
fil_crypt_rotate_page( fil_crypt_rotate_page(
/*===================*/ /*==================*/
const key_state_t* key_state, /*!< in: Key state */ const key_state_t* key_state, /*!< in: Key state */
rotate_thread_t* state) /*!< in: Key rotation state */ rotate_thread_t* state) /*!< in: Key rotation state */
{ {
@ -1791,8 +1836,10 @@ fil_crypt_rotate_page(
if (kv == 0 && if (kv == 0 &&
fil_crypt_is_page_uninitialized(frame, zip_size)) { fil_crypt_is_page_uninitialized(frame, zip_size)) {
; ;
} else if (fil_crypt_needs_rotation(kv, key_state->key_version, } else if (fil_crypt_needs_rotation(
key_state->rotate_key_age)) { crypt_data->encryption,
kv, key_state->key_version,
key_state->rotate_key_age)) {
/* page can be "fresh" i.e never written in case /* page can be "fresh" i.e never written in case
* kv == 0 or it should have a key version at least * kv == 0 or it should have a key version at least
@ -1812,11 +1859,13 @@ fil_crypt_rotate_page(
/* statistics */ /* statistics */
state->crypt_stat.pages_modified++; state->crypt_stat.pages_modified++;
} else { } else {
ut_a(kv >= crypt_data->min_key_version || if (crypt_data->encryption != FIL_SPACE_ENCRYPTION_OFF) {
(kv == 0 && key_state->key_version == 0)); ut_a(kv >= crypt_data->min_key_version ||
(kv == 0 && key_state->key_version == 0));
if (kv < state->min_key_version_found) { if (kv < state->min_key_version_found) {
state->min_key_version_found = kv; state->min_key_version_found = kv;
}
} }
} }
@ -1878,6 +1927,7 @@ fil_crypt_rotate_page(
/* if we just detected that scrubbing was turned off /* if we just detected that scrubbing was turned off
* update global state to reflect this */ * update global state to reflect this */
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
ut_ad(crypt_data);
mutex_enter(&crypt_data->mutex); mutex_enter(&crypt_data->mutex);
crypt_data->rotate_state.scrubbing.is_active = false; crypt_data->rotate_state.scrubbing.is_active = false;
mutex_exit(&crypt_data->mutex); mutex_exit(&crypt_data->mutex);
@ -2006,68 +2056,73 @@ fil_crypt_complete_rotate_space(
{ {
ulint space = state->space; ulint space = state->space;
fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space); fil_space_crypt_t *crypt_data = fil_space_get_crypt_data(space);
mutex_enter(&crypt_data->mutex);
/** /* Space might already be dropped */
* Update crypt data state with state from thread if (crypt_data) {
*/ ut_ad(crypt_data);
if (state->min_key_version_found < mutex_enter(&crypt_data->mutex);
crypt_data->rotate_state.min_key_version_found) {
crypt_data->rotate_state.min_key_version_found =
state->min_key_version_found;
}
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); if (state->end_lsn > crypt_data->rotate_state.end_lsn) {
crypt_data->rotate_state.active_threads--; crypt_data->rotate_state.end_lsn = state->end_lsn;
bool last = crypt_data->rotate_state.active_threads == 0; }
/** ut_a(crypt_data->rotate_state.active_threads > 0);
* check if space is fully done crypt_data->rotate_state.active_threads--;
* this as when threads shutdown, it could be that we "complete" bool last = crypt_data->rotate_state.active_threads == 0;
* iterating before we have scanned the full space.
*/
bool done = crypt_data->rotate_state.next_offset >=
crypt_data->rotate_state.max_offset;
/** /**
* we should flush space if we're last thread AND * check if space is fully done
* the iteration is done * this as when threads shutdown, it could be that we "complete"
*/ * iterating before we have scanned the full space.
bool should_flush = last && done; */
bool done = crypt_data->rotate_state.next_offset >=
crypt_data->rotate_state.max_offset;
if (should_flush) { /**
/* we're the last active thread */ * we should flush space if we're last thread AND
crypt_data->rotate_state.flushing = true; * the iteration is done
crypt_data->min_key_version = */
crypt_data->rotate_state.min_key_version_found; 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) { 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); mutex_enter(&crypt_data->mutex);
crypt_data->rotate_state.scrubbing. crypt_data->rotate_state.flushing = false;
last_scrub_completed = time(0);
mutex_exit(&crypt_data->mutex); 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_id_t rotation_thread_id;
os_thread_create(fil_crypt_thread, NULL, &rotation_thread_id); os_thread_create(fil_crypt_thread, NULL, &rotation_thread_id);
ib_logf(IB_LOG_LEVEL_INFO, ib_logf(IB_LOG_LEVEL_INFO,
"Creating #%d thread id %lu total threads %du\n", "Creating #%d thread id %lu total threads %u\n",
i, os_thread_pf(rotation_thread_id), new_cnt); i+1, os_thread_pf(rotation_thread_id), new_cnt);
} }
} else if (new_cnt < srv_n_fil_crypt_threads) { } else if (new_cnt < srv_n_fil_crypt_threads) {
srv_n_fil_crypt_threads = new_cnt; srv_n_fil_crypt_threads = new_cnt;
@ -2232,6 +2287,18 @@ fil_crypt_set_rotation_iops(
os_event_set(fil_crypt_threads_event); 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 */ Init threads for key rotation */
UNIV_INTERN UNIV_INTERN
@ -2279,7 +2346,7 @@ fil_space_crypt_mark_space_closing(
/*===============================*/ /*===============================*/
ulint space) /*!< in: Space id */ ulint space) /*!< in: Space id */
{ {
if (!srv_encrypt_tables) { if (!fil_crypt_threads_inited) {
return; return;
} }

View File

@ -6999,19 +6999,26 @@ fil_space_set_crypt_data(
if (space != NULL) { if (space != NULL) {
if (space->crypt_data != 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, fil_space_merge_crypt_data(space->crypt_data,
crypt_data); crypt_data);
free_crypt_data = crypt_data; free_crypt_data = crypt_data;
} else { } else {
space->crypt_data = crypt_data; space->crypt_data = crypt_data;
mutex_exit(&fil_system->mutex);
} }
} else { } else {
/* there is a small risk that tablespace has been deleted */ /* there is a small risk that tablespace has been deleted */
free_crypt_data = crypt_data; free_crypt_data = crypt_data;
mutex_exit(&fil_system->mutex);
} }
mutex_exit(&fil_system->mutex);
if (free_crypt_data != NULL) { if (free_crypt_data != NULL) {
/* there was already crypt data present and the new crypt /* there was already crypt data present and the new crypt
* data provided as argument to this function has been merged * data provided as argument to this function has been merged

View File

@ -18746,6 +18746,7 @@ which control InnoDB "status monitor" output to the error log.
static static
void void
innodb_status_output_update( innodb_status_output_update(
/*========================*/
THD* thd __attribute__((unused)), THD* thd __attribute__((unused)),
struct st_mysql_sys_var* var __attribute__((unused)), struct st_mysql_sys_var* var __attribute__((unused)),
void* var_ptr __attribute__((unused)), void* var_ptr __attribute__((unused)),
@ -18761,7 +18762,7 @@ Update the system variable innodb_encryption_threads */
static static
void void
innodb_encryption_threads_update( innodb_encryption_threads_update(
/*=========================*/ /*=============================*/
THD* thd, /*!< in: thread handle */ THD* thd, /*!< in: thread handle */
struct st_mysql_sys_var* var, /*!< in: pointer to struct st_mysql_sys_var* var, /*!< in: pointer to
system variable */ system variable */
@ -18778,7 +18779,7 @@ Update the system variable innodb_encryption_rotate_key_age */
static static
void void
innodb_encryption_rotate_key_age_update( innodb_encryption_rotate_key_age_update(
/*=========================*/ /*====================================*/
THD* thd, /*!< in: thread handle */ THD* thd, /*!< in: thread handle */
struct st_mysql_sys_var* var, /*!< in: pointer to struct st_mysql_sys_var* var, /*!< in: pointer to
system variable */ system variable */
@ -18795,7 +18796,7 @@ Update the system variable innodb_encryption_rotation_iops */
static static
void void
innodb_encryption_rotation_iops_update( innodb_encryption_rotation_iops_update(
/*=========================*/ /*===================================*/
THD* thd, /*!< in: thread handle */ THD* thd, /*!< in: thread handle */
struct st_mysql_sys_var* var, /*!< in: pointer to struct st_mysql_sys_var* var, /*!< in: pointer to
system variable */ system variable */
@ -18807,6 +18808,23 @@ innodb_encryption_rotation_iops_update(
fil_crypt_set_rotation_iops(*static_cast<const uint*>(save)); 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[]= { static SHOW_VAR innodb_status_variables_export[]= {
{"Innodb", (char*) &show_innodb_vars, SHOW_FUNC}, {"Innodb", (char*) &show_innodb_vars, SHOW_FUNC},
{NullS, NullS, SHOW_LONG} {NullS, NullS, SHOW_LONG}
@ -20365,7 +20383,9 @@ static MYSQL_SYSVAR_ENUM(encrypt_tables, srv_encrypt_tables,
PLUGIN_VAR_OPCMDARG, PLUGIN_VAR_OPCMDARG,
"Enable encryption for tables. " "Enable encryption for tables. "
"Don't forget to enable --innodb-encrypt-log too", "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); &srv_encrypt_tables_typelib);
static MYSQL_SYSVAR_UINT(encryption_threads, srv_n_fil_crypt_threads, static MYSQL_SYSVAR_UINT(encryption_threads, srv_n_fil_crypt_threads,

View File

@ -128,7 +128,7 @@ Get crypt data for a space*/
UNIV_INTERN UNIV_INTERN
fil_space_crypt_t * fil_space_crypt_t *
fil_space_get_crypt_data( fil_space_get_crypt_data(
/*======================*/ /*=====================*/
ulint space); /*!< in: tablespace id */ ulint space); /*!< in: tablespace id */
/********************************************************************* /*********************************************************************
@ -136,15 +136,16 @@ Set crypt data for a space*/
UNIV_INTERN UNIV_INTERN
void void
fil_space_set_crypt_data( fil_space_set_crypt_data(
/*======================*/ /*=====================*/
ulint space, /*!< in: tablespace id */ ulint space, /*!< in: tablespace id */
fil_space_crypt_t* crypt_data); /*!< in: crypt data to set */ fil_space_crypt_t* crypt_data); /*!< in: crypt data to set */
/********************************************************************* /*********************************************************************
Merge crypt data */ Merge crypt data */
UNIV_INTERN
void void
fil_space_merge_crypt_data( fil_space_merge_crypt_data(
/*======================*/ /*=======================*/
fil_space_crypt_t* dst_crypt_data, /*!< in: crypt_data */ fil_space_crypt_t* dst_crypt_data, /*!< in: crypt_data */
const fil_space_crypt_t* src_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 UNIV_INTERN
void void
fil_space_clear_crypt_data( fil_space_clear_crypt_data(
/*======================*/ /*=======================*/
byte* page, /*!< in: buffer page */ byte* page, /*!< in: buffer page */
ulint offset); /*!< in: offset where crypt data is stored */ 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 UNIV_INTERN
bool bool
fil_space_check_encryption_read( fil_space_check_encryption_read(
/*==============================*/ /*============================*/
ulint space); /*!< in: tablespace id */ ulint space); /*!< in: tablespace id */
/********************************************************************* /*********************************************************************
@ -202,7 +203,7 @@ Check if page shall be encrypted before write */
UNIV_INTERN UNIV_INTERN
bool bool
fil_space_check_encryption_write( fil_space_check_encryption_write(
/*==============================*/ /*=============================*/
ulint space); /*!< in: tablespace id */ ulint space); /*!< in: tablespace id */
/********************************************************************* /*********************************************************************
@ -210,7 +211,7 @@ Encrypt buffer page */
UNIV_INTERN UNIV_INTERN
void void
fil_space_encrypt( fil_space_encrypt(
/*===============*/ /*==============*/
ulint space, /*!< in: tablespace id */ ulint space, /*!< in: tablespace id */
ulint offset, /*!< in: page no */ ulint offset, /*!< in: page no */
lsn_t lsn, /*!< in: page lsn */ lsn_t lsn, /*!< in: page lsn */
@ -223,7 +224,7 @@ Decrypt buffer page */
UNIV_INTERN UNIV_INTERN
void void
fil_space_decrypt( fil_space_decrypt(
/*===============*/ /*==============*/
ulint space, /*!< in: tablespace id */ ulint space, /*!< in: tablespace id */
const byte* src_frame,/*!< in: page frame */ const byte* src_frame,/*!< in: page frame */
ulint page_size, /*!< in: size of data to encrypt */ ulint page_size, /*!< in: size of data to encrypt */
@ -236,7 +237,7 @@ Decrypt buffer page
UNIV_INTERN UNIV_INTERN
bool bool
fil_space_decrypt( fil_space_decrypt(
/*===============*/ /*==============*/
fil_space_crypt_t* crypt_data, /*!< in: crypt data */ fil_space_crypt_t* crypt_data, /*!< in: crypt data */
const byte* src_frame,/*!< in: page frame */ const byte* src_frame,/*!< in: page frame */
ulint page_size, /*!< in: page size */ ulint page_size, /*!< in: page size */
@ -250,7 +251,7 @@ as it modifies srv_checksum_algorithm (temporarily)
UNIV_INTERN UNIV_INTERN
bool bool
fil_space_verify_crypt_checksum( fil_space_verify_crypt_checksum(
/*===============*/ /*============================*/
const byte* src_frame,/*!< in: page frame */ const byte* src_frame,/*!< in: page frame */
ulint zip_size); /*!< in: size of data to encrypt */ ulint zip_size); /*!< in: size of data to encrypt */
@ -285,7 +286,7 @@ Set rotate key age */
UNIV_INTERN UNIV_INTERN
void void
fil_crypt_set_rotate_key_age( fil_crypt_set_rotate_key_age(
/*=====================*/ /*=========================*/
uint rotate_age); /*!< in: requested rotate age */ uint rotate_age); /*!< in: requested rotate age */
/********************************************************************* /*********************************************************************
@ -293,7 +294,7 @@ Set rotation threads iops */
UNIV_INTERN UNIV_INTERN
void void
fil_crypt_set_rotation_iops( fil_crypt_set_rotation_iops(
/*=====================*/ /*========================*/
uint iops); /*!< in: requested iops */ uint iops); /*!< in: requested iops */
/********************************************************************* /*********************************************************************
@ -301,7 +302,7 @@ Mark a space as closing */
UNIV_INTERN UNIV_INTERN
void void
fil_space_crypt_mark_space_closing( fil_space_crypt_mark_space_closing(
/*===============*/ /*===============================*/
ulint space); /*!< in: tablespace id */ ulint space); /*!< in: tablespace id */
/********************************************************************* /*********************************************************************
@ -309,7 +310,7 @@ Wait for crypt threads to stop accessing space */
UNIV_INTERN UNIV_INTERN
void void
fil_space_crypt_close_tablespace( fil_space_crypt_close_tablespace(
/*===============*/ /*=============================*/
ulint space); /*!< in: tablespace id */ ulint space); /*!< in: tablespace id */
/** Struct for retreiving info about encryption */ /** Struct for retreiving info about encryption */
@ -331,7 +332,7 @@ Get crypt status for a space
UNIV_INTERN UNIV_INTERN
int int
fil_space_crypt_get_status( fil_space_crypt_get_status(
/*==================*/ /*=======================*/
ulint id, /*!< in: space id */ ulint id, /*!< in: space id */
struct fil_space_crypt_status_t * status); /*!< out: status */ struct fil_space_crypt_status_t * status); /*!< out: status */
@ -370,10 +371,18 @@ Get scrub status for a space
UNIV_INTERN UNIV_INTERN
int int
fil_space_get_scrub_status( fil_space_get_scrub_status(
/*==================*/ /*=======================*/
ulint id, /*!< in: space id */ ulint id, /*!< in: space id */
struct fil_space_scrub_status_t * status); /*!< out: status */ 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 #ifndef UNIV_NONINL
#include "fil0crypt.ic" #include "fil0crypt.ic"
#endif #endif