Skip to content

Commit 8873328

Browse files
committed
MDEV-32050: Look up tables in the purge coordinator
The InnoDB table lookup in purge worker threads is a bottleneck that can degrade a slow shutdown to utilize less than 2 threads. Let us fix that bottleneck by constructing a local lookup table that does not require any synchronization while the undo log records of the current batch are being processed. TRX_PURGE_TABLE_BUCKETS: The initial number of std::unordered_map hash buckets used during a purge batch. This could avoid some resizing and rehashing in trx_purge_attach_undo_recs(). purge_node_t::tables: A lookup table from table ID to an already looked up and locked table. Replaces many fields. trx_purge_attach_undo_recs(): Look up each table in the purge batch only once. trx_purge(): Close all tables and release MDL at the end of the batch. trx_purge_table_open(), trx_purge_table_acquire(): Open a table in purge and acquire a metadata lock on it. This replaces dict_table_open_on_id<true>() and dict_acquire_mdl_shared(). purge_sys_t::close_and_reopen(): In case of an MDL conflict, close and reopen all tables that are covered by the current purge batch. It may be that some of the tables have been dropped meanwhile and can be ignored. This replaces wait_SYS() and wait_FTS(). row_purge_parse_undo_rec(): Make purge_coordinator_task issue a MDL warrant to any purge_worker_task which might need it when innodb_purge_threads>1. purge_node_t::end(): Clear the MDL warrant. Reviewed by: Vladislav Lesin and Vladislav Vaintroub
1 parent 39bb5eb commit 8873328

19 files changed

+348
-312
lines changed

mysql-test/suite/innodb/r/innodb-index-debug.result

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
SET GLOBAL innodb_max_purge_lag_wait=0;
2+
connect stop_purge,localhost,root;
3+
START TRANSACTION WITH CONSISTENT SNAPSHOT;
4+
connection default;
15
CREATE TABLE t1(c1 INT NOT NULL, c2 INT, PRIMARY KEY(c1)) Engine=InnoDB;
26
SHOW CREATE TABLE t1;
37
Table Create Table
@@ -143,6 +147,7 @@ ERROR 23000: Duplicate entry '0' for key 'i'
143147
SET DEBUG_SYNC='now SIGNAL log2';
144148
connection con1;
145149
disconnect con1;
150+
disconnect stop_purge;
146151
connection default;
147152
SET DEBUG_SYNC='RESET';
148153
DROP TABLE t1;

mysql-test/suite/innodb/r/innodb-index-online.result

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,7 @@ COUNT(c22f)
437437
CHECK TABLE t1;
438438
Table Op Msg_type Msg_text
439439
test.t1 check status OK
440+
SET GLOBAL innodb_max_purge_lag_wait=0;
440441
ALTER TABLE t1 ADD UNIQUE INDEX c3p5(c3(5));
441442
ERROR 23000: Duplicate entry 'NULL' for key 'c3p5'
442443
UPDATE t1 SET c3 = NULL WHERE c3 = '';

mysql-test/suite/innodb/r/innodb-table-online.result

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_encrypted');
274274
SET @rowlog_decrypt_1=
275275
(SELECT variable_value FROM information_schema.global_status
276276
WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_decrypted');
277+
SET GLOBAL innodb_max_purge_lag_wait=0;
277278
SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL rebuilt3 WAIT_FOR dml3_done';
278279
ALTER TABLE t1 ADD PRIMARY KEY(c22f), CHANGE c2 c22f INT;
279280
ERROR 42000: Multiple primary key defined

mysql-test/suite/innodb/r/row_format_redundant.result

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,14 @@ TRUNCATE TABLE t2;
4242
ERROR HY000: Table 't2' is read only
4343
TRUNCATE TABLE t3;
4444
ERROR HY000: Table 't3' is read only
45-
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0
45+
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0 --skip-innodb-fast-shutdown
4646
TRUNCATE TABLE t1;
4747
TRUNCATE TABLE t2;
4848
TRUNCATE TABLE t3;
4949
corrupted SYS_TABLES.MIX_LEN for test/t1
5050
corrupted SYS_TABLES.MIX_LEN for test/t2
5151
corrupted SYS_TABLES.MIX_LEN for test/t3
52-
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0
52+
# restart: --innodb-data-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-log-group-home-dir=MYSQLTEST_VARDIR/tmp/row_format_redundant --innodb-data-file-path=ibdata1:1M:autoextend --innodb-undo-tablespaces=0 --innodb-stats-persistent=0 --skip-innodb-fast-shutdown
5353
TRUNCATE TABLE t1;
5454
ERROR 42S02: Table 'test.t1' doesn't exist in engine
5555
TRUNCATE TABLE t2;

mysql-test/suite/innodb/t/innodb-index-debug.test

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@
66
--source include/big_test.inc
77

88
let $MYSQLD_DATADIR= `select @@datadir`;
9+
SET GLOBAL innodb_max_purge_lag_wait=0;
10+
connect (stop_purge,localhost,root);
11+
START TRANSACTION WITH CONSISTENT SNAPSHOT;
12+
connection default;
913

1014
#
1115
# Test for BUG# 12739098, check whether trx->error_status is reset on error.
@@ -155,6 +159,7 @@ SET DEBUG_SYNC='now SIGNAL log2';
155159
--connection con1
156160
reap;
157161
--disconnect con1
162+
--disconnect stop_purge
158163
--connection default
159164
SET DEBUG_SYNC='RESET';
160165
DROP TABLE t1;

mysql-test/suite/innodb/t/innodb-index-online.test

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,8 @@ SELECT
369369
connection con1;
370370
SELECT COUNT(c22f) FROM t1;
371371
CHECK TABLE t1;
372+
# Avoid a strange DEBUG_SYNC timeout on c3p5_created.
373+
SET GLOBAL innodb_max_purge_lag_wait=0;
372374

373375
# Create a column prefix index.
374376
--error ER_DUP_ENTRY

mysql-test/suite/innodb/t/innodb-table-online.test

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ SET @rowlog_decrypt_1=
255255
(SELECT variable_value FROM information_schema.global_status
256256
WHERE variable_name = 'innodb_encryption_n_rowlog_blocks_decrypted');
257257

258+
SET GLOBAL innodb_max_purge_lag_wait=0;
258259
# Accumulate and apply some modification log.
259260
SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL rebuilt3 WAIT_FOR dml3_done';
260261
--error ER_MULTIPLE_PRI_KEY

mysql-test/suite/innodb/t/row_format_redundant.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ TRUNCATE TABLE t2;
7878
--error ER_OPEN_AS_READONLY
7979
TRUNCATE TABLE t3;
8080

81-
--let $restart_parameters= $d
81+
--let $restart_parameters= $d --skip-innodb-fast-shutdown
8282
--source include/restart_mysqld.inc
8383

8484
TRUNCATE TABLE t1;

mysql-test/suite/parts/r/partition_special_innodb.result

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ Table Op Msg_type Msg_text
269269
test.t1 check status OK
270270
connection default;
271271
UNLOCK TABLES;
272+
SET GLOBAL innodb_max_purge_lag_wait=0;
272273
connection con2;
273274
DROP TABLE t1;
274275
connection default;
@@ -348,6 +349,7 @@ SELECT * FROM t1;
348349
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
349350
connection default;
350351
UNLOCK TABLES;
352+
SET GLOBAL innodb_max_purge_lag_wait=0;
351353
connection con2;
352354
DROP TABLE t1;
353355
disconnect con2;

mysql-test/suite/parts/t/partition_special_innodb.test

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ CHECK TABLE t1;
114114

115115
--connection default
116116
UNLOCK TABLES;
117+
# Avoid a MDL conflict between purge and the DROP TABLE below
118+
SET GLOBAL innodb_max_purge_lag_wait=0;
117119

118120
--connection con2
119121
DROP TABLE t1;
@@ -222,6 +224,8 @@ SELECT * FROM t1;
222224

223225
--connection default
224226
UNLOCK TABLES;
227+
# Avoid a MDL conflict between purge and the DROP TABLE below
228+
SET GLOBAL innodb_max_purge_lag_wait=0;
225229

226230
--connection con2
227231
DROP TABLE t1;

0 commit comments

Comments
 (0)