Skip to content

Commit 1ce2f5d

Browse files
committed
WL#13775 - InnoDB: Encrypt DBLWR files
Currently, all the pages in the double write files are unencrypted. Even pages belonging to encrypted tablespaces, remain unencrypted in the double write files. The purpose of this worklog is to ensure that the pages in double write files belonging to encrypted tablespaces are also encrypted. Likewise, the pages in dblwr files that belong to unencrypted tablespace remain unencrypted. There is no separate encryption key for the double write files. The pages are encrypted making use of the respective tablespace encryption keys. The same encrypted page that will be written to the data file of a tablespace is also written to the double write file. The high level steps would be: * If transparent compression is enabled for a tablespace, do compression. * If encryption is enabled for a tablespace, do encryption using the tablespace key. * Flush the compressed+encrypted page to the dblwr file. * Flush the same compressed+encrypted page to the data file of tablespace. The double write files now contain different types of pages depending on the tablespaces. Some of them are unencrypted, some are encrypted with their respective tablespaces keys, and the remaining are compressed+encrypted with their respective tablespace keys. rb#24072 approved by Mayank Prasad <[email protected]> and Sunny Bains <[email protected]>
1 parent 0e38778 commit 1ce2f5d

File tree

78 files changed

+4601
-376
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

78 files changed

+4601
-376
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#
2+
# WL#13775: InnoDB: Encrypt DBLWR files
3+
#
4+
create table t1 (f1 int primary key, f2 blob) ENCRYPTION='Y';
5+
START TRANSACTION;
6+
INSERT INTO t1 VALUES(1, repeat('#',12));
7+
INSERT INTO t1 VALUES(2, repeat('+',12));
8+
INSERT INTO t1 VALUES(3, repeat('/',12));
9+
INSERT INTO t1 VALUES(4, repeat('-',12));
10+
INSERT INTO t1 VALUES(5, repeat('.',12));
11+
COMMIT WORK;
12+
# Ensure that dirty pages of table t1 is flushed.
13+
FLUSH TABLES t1 FOR EXPORT;
14+
UNLOCK TABLES;
15+
SET SESSION innodb_interpreter = 'init';
16+
SET SESSION innodb_interpreter = 'open_table test/t1';
17+
# Identify the space_id of the given table.
18+
SET SESSION innodb_interpreter = 'find_space_id test/t1';
19+
SELECT @@session.innodb_interpreter_output INTO @space_id;
20+
# Find the root page number of the given table.
21+
SET SESSION innodb_interpreter = 'find_root_page_no test/t1';
22+
SELECT @@session.innodb_interpreter_output INTO @page_no;
23+
# Find the on-disk page type of the given page.
24+
SET @cmd = CONCAT('find_ondisk_page_type ', @space_id, ' ', @page_no);
25+
SET SESSION innodb_interpreter = @cmd;
26+
SELECT @@session.innodb_interpreter_output INTO @page_type;
27+
SELECT @page_type;
28+
@page_type
29+
FIL_PAGE_ENCRYPTED
30+
set global innodb_interpreter = 'destroy';
31+
drop table t1;
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#
2+
# WL#13775 - InnoDB: Encrypt DBLWR files
3+
#
4+
#
5+
# Test Begin: Test if recovery works if first page of user
6+
# tablespace is corrupted. Valid copy of that page is there
7+
# in DBLWR file.
8+
#
9+
# Wait for purge to complete
10+
create table t1 (f1 int primary key, f2 blob) ENCRYPTION='Y';
11+
START TRANSACTION;
12+
INSERT INTO t1 VALUES(1, repeat('#',12));
13+
INSERT INTO t1 VALUES(2, repeat('+',12));
14+
INSERT INTO t1 VALUES(3, repeat('/',12));
15+
INSERT INTO t1 VALUES(4, repeat('-',12));
16+
INSERT INTO t1 VALUES(5, repeat('.',12));
17+
COMMIT WORK;
18+
SELECT space from INFORMATION_SCHEMA.INNODB_TABLESPACES
19+
WHERE name = 'test/t1' INTO @space_id;
20+
# Wait for purge to complete
21+
# Ensure that dirty pages of table t1 is flushed.
22+
FLUSH TABLES t1 FOR EXPORT;
23+
UNLOCK TABLES;
24+
SET GLOBAL innodb_master_thread_disabled_debug=1;
25+
SET GLOBAL innodb_checkpoint_disabled=1;
26+
BEGIN;
27+
INSERT INTO t1 VALUES (6, repeat('%', 12));
28+
# Kill the server
29+
# Corrupt the first page (page_no=0) of the user tablespace.
30+
# restart
31+
set global innodb_interpreter = 'init';
32+
set global innodb_interpreter = 'print_dblwr_has_encrypted_pages';
33+
set global innodb_interpreter = 'destroy';
34+
Pattern "Double write file has encrypted pages" found
35+
Pattern "\[Note\] .* Restoring page \[page id: space=\d+, page number=0\] of datafile .* from the doublewrite buffer. Writing .*" found
36+
CHECK TABLE t1;
37+
Table Op Msg_type Msg_text
38+
test.t1 check status OK
39+
SELECT f1, f2 FROM t1;
40+
f1 f2
41+
1 ############
42+
2 ++++++++++++
43+
3 ////////////
44+
4 ------------
45+
5 ............
46+
DROP TABLE t1;
47+
# Test End
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
create table t1 (f1 int primary key, f2 blob) ENCRYPTION='Y';
2+
START TRANSACTION;
3+
INSERT INTO t1 VALUES(1, repeat('#',12));
4+
INSERT INTO t1 VALUES(2, repeat('+',12));
5+
INSERT INTO t1 VALUES(3, repeat('/',12));
6+
INSERT INTO t1 VALUES(4, repeat('-',12));
7+
INSERT INTO t1 VALUES(5, repeat('.',12));
8+
COMMIT WORK;
9+
# Wait for purge to complete
10+
# Ensure that dirty pages of table t1 is flushed.
11+
FLUSH TABLES t1 FOR EXPORT;
12+
UNLOCK TABLES;
13+
SET GLOBAL innodb_master_thread_disabled_debug=1;
14+
SET GLOBAL innodb_checkpoint_disabled = 1;
15+
BEGIN;
16+
INSERT INTO t1 VALUES (6, repeat('%', 12));
17+
SET SESSION innodb_interpreter = 'init';
18+
SET SESSION innodb_interpreter = 'open_table test/t1';
19+
# Identify the space_id of the given table.
20+
SET SESSION innodb_interpreter = 'find_space_id test/t1';
21+
SELECT @@session.innodb_interpreter_output INTO @space_id;
22+
# Find the root page number of the given table.
23+
SET SESSION innodb_interpreter = 'find_root_page_no test/t1';
24+
SELECT @@session.innodb_interpreter_output INTO @page_no;
25+
# Find the on-disk page type of the given page.
26+
SET @cmd = CONCAT('find_ondisk_page_type ', @space_id, ' ', @page_no);
27+
SET SESSION innodb_interpreter = @cmd;
28+
SELECT @@session.innodb_interpreter_output INTO @page_type;
29+
SELECT @page_type;
30+
@page_type
31+
FIL_PAGE_ENCRYPTED
32+
SET SESSION innodb_interpreter = 'find_tablespace_file_name test/t1';
33+
SELECT @@session.innodb_interpreter_output INTO @space_file_name;
34+
SET SESSION innodb_interpreter = 'find_tablespace_physical_page_size test/t1';
35+
SELECT @@session.innodb_interpreter_output INTO @space_page_size;
36+
SET SESSION innodb_interpreter = 'destroy';
37+
# Kill the server
38+
# Corrupt the root page of table t1 in the user tablespace.
39+
# restart
40+
SET SESSION innodb_interpreter = 'init';
41+
SET SESSION innodb_interpreter = 'print_dblwr_has_encrypted_pages';
42+
SET SESSION innodb_interpreter = 'destroy';
43+
Pattern "Double write file has encrypted pages" found
44+
Pattern "\[Note\] \[MY-\d+\] \[InnoDB\] Recovered page \[page id: space=\d+, page number=\d+\] from the doublewrite buffer" found
45+
CHECK TABLE t1;
46+
Table Op Msg_type Msg_text
47+
test.t1 check status OK
48+
SELECT f1, f2 FROM t1;
49+
f1 f2
50+
1 ############
51+
2 ++++++++++++
52+
3 ////////////
53+
4 ------------
54+
5 ............
55+
DROP TABLE t1;
56+
# Test End
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
select @@binlog_encryption;
2+
@@binlog_encryption
3+
1
4+
select @@innodb_redo_log_encrypt;
5+
@@innodb_redo_log_encrypt
6+
1
7+
select @@innodb_undo_log_encrypt;
8+
@@innodb_undo_log_encrypt
9+
1
10+
create table t1 (f1 int, f2 blob) ENCRYPTION='Y';
11+
show create table t1;
12+
Table Create Table
13+
t1 CREATE TABLE `t1` (
14+
`f1` int DEFAULT NULL,
15+
`f2` blob
16+
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci ENCRYPTION='Y'
17+
START TRANSACTION;
18+
INSERT INTO t1 VALUES(1, repeat('#',12));
19+
INSERT INTO t1 VALUES(2, repeat('+',12));
20+
INSERT INTO t1 VALUES(3, repeat('/',12));
21+
INSERT INTO t1 VALUES(4, repeat('-',12));
22+
INSERT INTO t1 VALUES(5, repeat('.',12));
23+
COMMIT WORK;
24+
# Ensure that dirty pages of table t1 is flushed.
25+
FLUSH TABLES t1 FOR EXPORT;
26+
UNLOCK TABLES;
27+
# Kill and restart
28+
select 2;
29+
2
30+
2
31+
SET SESSION innodb_interpreter = 'init';
32+
SET SESSION innodb_interpreter = 'print_dblwr_has_encrypted_pages';
33+
SET SESSION innodb_interpreter = 'destroy';
34+
Pattern "Double write file has encrypted pages" found
35+
Pattern "\[Note\] \[MY-\d+\] \[InnoDB\] Recovered page \[page id: space=\d+, page number=\d+\] from the doublewrite buffer" not found
36+
DROP TABLE t1;
37+
# Test End
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
create table t1 (f1 int, f2 blob) ENCRYPTION='Y';
2+
START TRANSACTION;
3+
INSERT INTO t1 VALUES(1, repeat('#',12));
4+
INSERT INTO t1 VALUES(2, repeat('+',12));
5+
INSERT INTO t1 VALUES(3, repeat('/',12));
6+
INSERT INTO t1 VALUES(4, repeat('-',12));
7+
INSERT INTO t1 VALUES(5, repeat('.',12));
8+
COMMIT WORK;
9+
# Wait for purge to complete
10+
# Ensure that dirty pages of table t1 is flushed.
11+
FLUSH TABLES t1 FOR EXPORT;
12+
UNLOCK TABLES;
13+
SET GLOBAL innodb_master_thread_disabled_debug=1;
14+
SET GLOBAL innodb_checkpoint_disabled = 1;
15+
BEGIN;
16+
INSERT INTO t1 VALUES (6, repeat('%', 12));
17+
SET SESSION innodb_interpreter = 'init';
18+
SET SESSION innodb_interpreter = 'open_table test/t1';
19+
# Identify the space_id of the given table.
20+
SET SESSION innodb_interpreter = 'find_space_id test/t1';
21+
SELECT @@session.innodb_interpreter_output INTO @space_id;
22+
# Find the root page number of the given table.
23+
SET SESSION innodb_interpreter = 'find_root_page_no test/t1';
24+
SELECT @@session.innodb_interpreter_output INTO @page_no;
25+
# Find the on-disk page type of the given page.
26+
SET @cmd = CONCAT('find_ondisk_page_type ', @space_id, ' ', @page_no);
27+
SET SESSION innodb_interpreter = @cmd;
28+
SELECT @@session.innodb_interpreter_output INTO @page_type;
29+
SELECT @page_type;
30+
@page_type
31+
FIL_PAGE_ENCRYPTED
32+
SET SESSION innodb_interpreter = 'find_tablespace_file_name test/t1';
33+
SELECT @@session.innodb_interpreter_output INTO @space_file_name;
34+
SET SESSION innodb_interpreter = 'find_tablespace_physical_page_size test/t1';
35+
SELECT @@session.innodb_interpreter_output INTO @space_page_size;
36+
SET SESSION innodb_interpreter = 'destroy';
37+
# Kill the server
38+
# Corrupt the root page of table t1 in the user tablespace.
39+
# restart
40+
SET SESSION innodb_interpreter = 'init';
41+
SET SESSION innodb_interpreter = 'print_dblwr_has_encrypted_pages';
42+
SET SESSION innodb_interpreter = 'destroy';
43+
Pattern "Double write file has encrypted pages" found
44+
Pattern "\[Note\] \[MY-\d+\] \[InnoDB\] Recovered page \[page id: space=\d+, page number=\d+\] from the doublewrite buffer" found
45+
CHECK TABLE t1;
46+
Table Op Msg_type Msg_text
47+
test.t1 check status OK
48+
SELECT f1, f2 FROM t1;
49+
f1 f2
50+
1 ############
51+
2 ++++++++++++
52+
3 ////////////
53+
4 ------------
54+
5 ............
55+
ALTER TABLE t1 ROW_FORMAT=REDUNDANT;
56+
# Ensure that dirty pages of table t1 is flushed.
57+
FLUSH TABLES t1 FOR EXPORT;
58+
UNLOCK TABLES;
59+
SET GLOBAL innodb_master_thread_disabled_debug=1;
60+
SET GLOBAL innodb_checkpoint_disabled = 1;
61+
BEGIN;
62+
INSERT INTO t1 VALUES (6, repeat('%', 12));
63+
SET SESSION innodb_interpreter = 'init';
64+
SET SESSION innodb_interpreter = 'open_table test/t1';
65+
# Identify the space_id of the given table.
66+
SET SESSION innodb_interpreter = 'find_space_id test/t1';
67+
SELECT @@session.innodb_interpreter_output INTO @space_id;
68+
# Find the root page number of the given table.
69+
SET SESSION innodb_interpreter = 'find_root_page_no test/t1';
70+
SELECT @@session.innodb_interpreter_output INTO @page_no;
71+
# Find the on-disk page type of the given page.
72+
SET @cmd = CONCAT('find_ondisk_page_type ', @space_id, ' ', @page_no);
73+
SET SESSION innodb_interpreter = @cmd;
74+
SELECT @@session.innodb_interpreter_output INTO @page_type;
75+
SELECT @page_type;
76+
@page_type
77+
FIL_PAGE_ENCRYPTED
78+
SET SESSION innodb_interpreter = 'find_tablespace_file_name test/t1';
79+
SELECT @@session.innodb_interpreter_output INTO @space_file_name;
80+
SET SESSION innodb_interpreter = 'find_tablespace_physical_page_size test/t1';
81+
SELECT @@session.innodb_interpreter_output INTO @space_page_size;
82+
SET SESSION innodb_interpreter = 'destroy';
83+
# Kill the server
84+
# Corrupt the root page of table t1 in the user tablespace.
85+
# restart
86+
SET SESSION innodb_interpreter = 'init';
87+
SET SESSION innodb_interpreter = 'print_dblwr_has_encrypted_pages';
88+
SET SESSION innodb_interpreter = 'destroy';
89+
Pattern "Double write file has encrypted pages" found
90+
Pattern "\[Note\] \[MY-\d+\] \[InnoDB\] Recovered page \[page id: space=\d+, page number=\d+\] from the doublewrite buffer" found
91+
ALTER TABLE t1 ROW_FORMAT=COMPACT;
92+
# Ensure that dirty pages of table t1 is flushed.
93+
FLUSH TABLES t1 FOR EXPORT;
94+
UNLOCK TABLES;
95+
SET GLOBAL innodb_master_thread_disabled_debug=1;
96+
SET GLOBAL innodb_checkpoint_disabled = 1;
97+
BEGIN;
98+
INSERT INTO t1 VALUES (6, repeat('%', 12));
99+
SET SESSION innodb_interpreter = 'init';
100+
SET SESSION innodb_interpreter = 'open_table test/t1';
101+
# Identify the space_id of the given table.
102+
SET SESSION innodb_interpreter = 'find_space_id test/t1';
103+
SELECT @@session.innodb_interpreter_output INTO @space_id;
104+
# Find the root page number of the given table.
105+
SET SESSION innodb_interpreter = 'find_root_page_no test/t1';
106+
SELECT @@session.innodb_interpreter_output INTO @page_no;
107+
# Find the on-disk page type of the given page.
108+
SET @cmd = CONCAT('find_ondisk_page_type ', @space_id, ' ', @page_no);
109+
SET SESSION innodb_interpreter = @cmd;
110+
SELECT @@session.innodb_interpreter_output INTO @page_type;
111+
SELECT @page_type;
112+
@page_type
113+
FIL_PAGE_ENCRYPTED
114+
SET SESSION innodb_interpreter = 'find_tablespace_file_name test/t1';
115+
SELECT @@session.innodb_interpreter_output INTO @space_file_name;
116+
SET SESSION innodb_interpreter = 'find_tablespace_physical_page_size test/t1';
117+
SELECT @@session.innodb_interpreter_output INTO @space_page_size;
118+
SET SESSION innodb_interpreter = 'destroy';
119+
# Kill the server
120+
# Corrupt the root page of table t1 in the user tablespace.
121+
# restart
122+
SET SESSION innodb_interpreter = 'init';
123+
SET SESSION innodb_interpreter = 'print_dblwr_has_encrypted_pages';
124+
SET SESSION innodb_interpreter = 'destroy';
125+
Pattern "Double write file has encrypted pages" found
126+
Pattern "\[Note\] \[MY-\d+\] \[InnoDB\] Recovered page \[page id: space=\d+, page number=\d+\] from the doublewrite buffer" found
127+
ALTER TABLE t1 ROW_FORMAT=DYNAMIC;
128+
# Ensure that dirty pages of table t1 is flushed.
129+
FLUSH TABLES t1 FOR EXPORT;
130+
UNLOCK TABLES;
131+
SET GLOBAL innodb_master_thread_disabled_debug=1;
132+
SET GLOBAL innodb_checkpoint_disabled = 1;
133+
BEGIN;
134+
INSERT INTO t1 VALUES (6, repeat('%', 12));
135+
SET SESSION innodb_interpreter = 'init';
136+
SET SESSION innodb_interpreter = 'open_table test/t1';
137+
# Identify the space_id of the given table.
138+
SET SESSION innodb_interpreter = 'find_space_id test/t1';
139+
SELECT @@session.innodb_interpreter_output INTO @space_id;
140+
# Find the root page number of the given table.
141+
SET SESSION innodb_interpreter = 'find_root_page_no test/t1';
142+
SELECT @@session.innodb_interpreter_output INTO @page_no;
143+
# Find the on-disk page type of the given page.
144+
SET @cmd = CONCAT('find_ondisk_page_type ', @space_id, ' ', @page_no);
145+
SET SESSION innodb_interpreter = @cmd;
146+
SELECT @@session.innodb_interpreter_output INTO @page_type;
147+
SELECT @page_type;
148+
@page_type
149+
FIL_PAGE_ENCRYPTED
150+
SET SESSION innodb_interpreter = 'find_tablespace_file_name test/t1';
151+
SELECT @@session.innodb_interpreter_output INTO @space_file_name;
152+
SET SESSION innodb_interpreter = 'find_tablespace_physical_page_size test/t1';
153+
SELECT @@session.innodb_interpreter_output INTO @space_page_size;
154+
SET SESSION innodb_interpreter = 'destroy';
155+
# Kill the server
156+
# Corrupt the root page of table t1 in the user tablespace.
157+
# restart
158+
SET SESSION innodb_interpreter = 'init';
159+
SET SESSION innodb_interpreter = 'print_dblwr_has_encrypted_pages';
160+
SET SESSION innodb_interpreter = 'destroy';
161+
Pattern "Double write file has encrypted pages" found
162+
Pattern "\[Note\] \[MY-\d+\] \[InnoDB\] Recovered page \[page id: space=\d+, page number=\d+\] from the doublewrite buffer" found
163+
ALTER TABLE t1 ROW_FORMAT=COMPRESSED;
164+
# Ensure that dirty pages of table t1 is flushed.
165+
FLUSH TABLES t1 FOR EXPORT;
166+
UNLOCK TABLES;
167+
SET GLOBAL innodb_master_thread_disabled_debug=1;
168+
SET GLOBAL innodb_checkpoint_disabled = 1;
169+
BEGIN;
170+
INSERT INTO t1 VALUES (6, repeat('%', 12));
171+
SET SESSION innodb_interpreter = 'init';
172+
SET SESSION innodb_interpreter = 'open_table test/t1';
173+
# Identify the space_id of the given table.
174+
SET SESSION innodb_interpreter = 'find_space_id test/t1';
175+
SELECT @@session.innodb_interpreter_output INTO @space_id;
176+
# Find the root page number of the given table.
177+
SET SESSION innodb_interpreter = 'find_root_page_no test/t1';
178+
SELECT @@session.innodb_interpreter_output INTO @page_no;
179+
# Find the on-disk page type of the given page.
180+
SET @cmd = CONCAT('find_ondisk_page_type ', @space_id, ' ', @page_no);
181+
SET SESSION innodb_interpreter = @cmd;
182+
SELECT @@session.innodb_interpreter_output INTO @page_type;
183+
SELECT @page_type;
184+
@page_type
185+
FIL_PAGE_ENCRYPTED
186+
SET SESSION innodb_interpreter = 'find_tablespace_file_name test/t1';
187+
SELECT @@session.innodb_interpreter_output INTO @space_file_name;
188+
SET SESSION innodb_interpreter = 'find_tablespace_physical_page_size test/t1';
189+
SELECT @@session.innodb_interpreter_output INTO @space_page_size;
190+
SET SESSION innodb_interpreter = 'destroy';
191+
# Kill the server
192+
# Corrupt the root page of table t1 in the user tablespace.
193+
# restart
194+
SET SESSION innodb_interpreter = 'init';
195+
SET SESSION innodb_interpreter = 'print_dblwr_has_encrypted_pages';
196+
SET SESSION innodb_interpreter = 'destroy';
197+
Pattern "Double write file has encrypted pages" found
198+
Pattern "\[Note\] \[MY-\d+\] \[InnoDB\] Recovered page \[page id: space=\d+, page number=\d+\] from the doublewrite buffer" found
199+
CHECK TABLE t1;
200+
Table Op Msg_type Msg_text
201+
test.t1 check status OK
202+
SELECT f1, f2 FROM t1;
203+
f1 f2
204+
1 ############
205+
2 ++++++++++++
206+
3 ////////////
207+
4 ------------
208+
5 ............
209+
DROP TABLE t1;
210+
# Test End

0 commit comments

Comments
 (0)