Skip to content

Commit 4e553b5

Browse files
committed
Bug #29820184 REDO LOGS MAY SILENTLY BE IGNORED WHEN ENCRYPTED TABLE CANNOT BE DECRYPTED.
Problem: There is a difference in behavior between debug and release server when redo logs are to be applied to a table that cannot be decrypted. Debug server will abort the start and release will generate errors but will start up. This is because in log0recv.cc there is: if (space.first != TRX_SYS_SPACE && !fil_tablespace_open_for_recovery(space.first)) { /* Tablespace was dropped. It should not have been scanned unless it is an undo space that was under construction. */ ut_ad(!fil_tablespace_lookup_for_recovery(space.first) || fsp_is_undo_tablespace(space.first)); dropped = true; the call to fil_tablespace_lookup_for_recover will add space id to missing_ids which in turn will trigger this from srv0start.cc: if (srv_force_recovery == 0 && fil_check_missing_tablespaces()) { ib::error(ER_IB_MSG_1139); /* Set the abort flag to true. */ auto p = recv_recovery_from_checkpoint_finish(*log_sys, true); ut_a(p == nullptr); return (srv_init_abort(DB_ERROR)); } fil_check_missing_tablespaces will return true. For release the fil_tablespace_lookup_for_recover will not be called as it is inside a debug assert. The release version should be fixed and abort to start. Solution: Ensure that fil_tablespace_lookup_for_recover() is called for release build also. rb#22564 approved by Mayank Prasad <[email protected]>
1 parent 241f0a1 commit 4e553b5

File tree

4 files changed

+120
-2
lines changed

4 files changed

+120
-2
lines changed
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
CREATE TABLE t1(
2+
a INT NOT NULL PRIMARY KEY,
3+
c CHAR(200),
4+
b BLOB,
5+
INDEX(b(10))) ENGINE=innodb ROW_FORMAT=compressed ENCRYPTION='Y';
6+
CREATE TABLE t2(
7+
a INT NOT NULL PRIMARY KEY,
8+
c CHAR(200),
9+
b BLOB,
10+
INDEX(b(10))) ENGINE=innodb ROW_FORMAT=compressed ENCRYPTION='Y';
11+
CREATE TABLE t3(
12+
a INT NOT NULL PRIMARY KEY,
13+
c CHAR(200),
14+
b BLOB,
15+
INDEX(b(10))) ENGINE=innodb ENCRYPTION='Y';
16+
CREATE TABLE t4(
17+
a INT NOT NULL PRIMARY KEY,
18+
c CHAR(200),
19+
b BLOB,
20+
INDEX(b(10))) ENGINE=innodb ENCRYPTION='Y';
21+
# restart
22+
INSERT INTO t2 SELECT * FROM t1;
23+
INSERT INTO t3 SELECT * FROM t1;
24+
INSERT INTO t4 SELECT * FROM t1;
25+
COMMIT;
26+
SET GLOBAL innodb_flush_log_at_trx_commit=1;
27+
BEGIN;
28+
UPDATE t1 SET c = REPEAT('secret3', 20);
29+
UPDATE t2 SET c = REPEAT('secret4', 20);
30+
UPDATE t3 set c = REPEAT('secret4', 20);
31+
UPDATE t4 set c = REPEAT('secret4', 20);
32+
INSERT INTO t1 (a,c,b) VALUES (21, REPEAT('secret5',20), REPEAT('secret6',6000));
33+
INSERT INTO t2 (a,c,b) VALUES (21, REPEAT('secret7',20), REPEAT('secret8',6000));
34+
INSERT into t3 (a,c,b) VALUES (21, REPEAT('secret9',20), REPEAT('secre10',6000));
35+
INSERT into t4 (a,c,b) VALUES (21, REPEAT('secre11',20), REPEAT('secre12',6000));
36+
COMMIT;
37+
# Kill the server
38+
# Restart mysqld without keyring plugin
39+
# Restart mysqld with keyring plugin
40+
drop TABLE t1,t2,t3,t4;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
$KEYRING_PLUGIN_OPT
2+
--early-plugin-load="keyring_file=$KEYRING_PLUGIN"
3+
--loose-keyring_file_data=$MYSQLTEST_VARDIR/std_data/keys2.txt
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
CREATE TABLE t1(
2+
a INT NOT NULL PRIMARY KEY,
3+
c CHAR(200),
4+
b BLOB,
5+
INDEX(b(10))) ENGINE=innodb ROW_FORMAT=compressed ENCRYPTION='Y';
6+
7+
CREATE TABLE t2(
8+
a INT NOT NULL PRIMARY KEY,
9+
c CHAR(200),
10+
b BLOB,
11+
INDEX(b(10))) ENGINE=innodb ROW_FORMAT=compressed ENCRYPTION='Y';
12+
13+
CREATE TABLE t3(
14+
a INT NOT NULL PRIMARY KEY,
15+
c CHAR(200),
16+
b BLOB,
17+
INDEX(b(10))) ENGINE=innodb ENCRYPTION='Y';
18+
19+
CREATE TABLE t4(
20+
a INT NOT NULL PRIMARY KEY,
21+
c CHAR(200),
22+
b BLOB,
23+
INDEX(b(10))) ENGINE=innodb ENCRYPTION='Y';
24+
25+
--source include/restart_mysqld.inc
26+
27+
--source include/no_checkpoint_start.inc
28+
29+
--disable_query_log
30+
--let $i = 20
31+
BEGIN;
32+
WHILE ($i)
33+
{
34+
eval INSERT INTO t1(a,c,b) VALUES ($i, REPEAT('secret1',20), REPEAT('secret2',6000));
35+
dec $i;
36+
}
37+
--enable_query_log
38+
39+
INSERT INTO t2 SELECT * FROM t1;
40+
INSERT INTO t3 SELECT * FROM t1;
41+
INSERT INTO t4 SELECT * FROM t1;
42+
COMMIT;
43+
44+
# If checkpoint happens we will skip this test.
45+
# If no checkpoint happens, InnoDB refuses to
46+
# start as used encryption key is not found.
47+
48+
SET GLOBAL innodb_flush_log_at_trx_commit=1;
49+
BEGIN;
50+
UPDATE t1 SET c = REPEAT('secret3', 20);
51+
UPDATE t2 SET c = REPEAT('secret4', 20);
52+
UPDATE t3 set c = REPEAT('secret4', 20);
53+
UPDATE t4 set c = REPEAT('secret4', 20);
54+
INSERT INTO t1 (a,c,b) VALUES (21, REPEAT('secret5',20), REPEAT('secret6',6000));
55+
INSERT INTO t2 (a,c,b) VALUES (21, REPEAT('secret7',20), REPEAT('secret8',6000));
56+
INSERT into t3 (a,c,b) VALUES (21, REPEAT('secret9',20), REPEAT('secre10',6000));
57+
INSERT into t4 (a,c,b) VALUES (21, REPEAT('secre11',20), REPEAT('secre12',6000));
58+
COMMIT;
59+
60+
let $cleanup= drop TABLE t1,t2,t3,t4;
61+
--let CLEANUP_IF_CHECKPOINT= $cleanup;
62+
--source include/no_checkpoint_end.inc
63+
64+
--echo # Restart mysqld without keyring plugin
65+
66+
--error 1
67+
--exec $MYSQLD_CMD
68+
69+
--echo # Restart mysqld with keyring plugin
70+
--let $restart_parameters=restart:--early-plugin-load="keyring_file=$KEYRING_PLUGIN" --keyring-file-data=$MYSQLTEST_VARDIR/std_data/keys2.txt
71+
--source include/start_mysqld_no_echo.inc
72+
73+
drop TABLE t1,t2,t3,t4;

storage/innobase/log/log0recv.cc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1267,8 +1267,10 @@ void recv_apply_hashed_log_recs(log_t &log, bool allow_ibuf) {
12671267
!fil_tablespace_open_for_recovery(space.first)) {
12681268
/* Tablespace was dropped. It should not have been scanned unless it
12691269
is an undo space that was under construction. */
1270-
ut_ad(!fil_tablespace_lookup_for_recovery(space.first) ||
1271-
fsp_is_undo_tablespace(space.first));
1270+
1271+
if (fil_tablespace_lookup_for_recovery(space.first)) {
1272+
ut_ad(fsp_is_undo_tablespace(space.first));
1273+
}
12721274

12731275
dropped = true;
12741276
} else {

0 commit comments

Comments
 (0)