1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

MDEV-22769 Shutdown hang or crash due to XA breaking locks

The background drop table queue in InnoDB is a work-around for
cases where the SQL layer is requesting DDL on tables on which
transactional locks exist.

One such case are XA transactions. Our test case exploits the
fact that the recovery of XA PREPARE transactions will
only resurrect InnoDB table locks, but not MDL that should
block any concurrent DDL.

srv_shutdown_t: Introduce the srv_shutdown_state=SRV_SHUTDOWN_INITIATED
for the initial part of shutdown, to wait for the background drop
table queue to be emptied.

srv_shutdown_bg_undo_sources(): Assign
srv_shutdown_state=SRV_SHUTDOWN_INITIATED
before waiting for the background drop table queue to be emptied.

row_drop_tables_for_mysql_in_background(): On slow shutdown, if
no active transactions exist (excluding ones that are in
XA PREPARE state), skip any tables on which locks exist.

row_drop_table_for_mysql(): Do not unnecessarily attempt to
drop InnoDB persistent statistics for tables that have
already been added to the background drop table queue.

row_mysql_close(): Relax an assertion, and free all memory
even if innodb_force_recovery=2 would prevent the background
drop table queue from being emptied.
This commit is contained in:
Marko Mäkelä
2020-06-05 14:59:33 +03:00
parent 138c11cce5
commit efc70da5fd
13 changed files with 94 additions and 50 deletions

View File

@ -5,11 +5,19 @@ XA START 'x';
UPDATE t1 set a=2;
XA END 'x';
XA PREPARE 'x';
connect con2,localhost,root;
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
XA START 'y';
INSERT INTO t2 VALUES (1);
XA END 'y';
XA PREPARE 'y';
connection default;
disconnect con1;
disconnect con2;
connect con1,localhost,root;
SELECT * FROM t1 LOCK IN SHARE MODE;
connection default;
DROP TABLE t2;
disconnect con1;
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SELECT * FROM t1;
@ -20,3 +28,5 @@ SELECT * FROM t1;
a
1
DROP TABLE t1;
SET GLOBAL innodb_fast_shutdown=0;
XA ROLLBACK 'y';

View File

@ -5,7 +5,7 @@
# MDEV-8841 - close tables opened by previous tests,
# so they don't get marked crashed when the server gets crashed
--disable_query_log
call mtr.add_suppression("Found 1 prepared XA transactions");
call mtr.add_suppression("Found [12] prepared XA transactions");
FLUSH TABLES;
--enable_query_log
@ -13,6 +13,9 @@ CREATE TABLE t1 (a INT) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1);
connect (con1,localhost,root);
XA START 'x'; UPDATE t1 set a=2; XA END 'x'; XA PREPARE 'x';
connect (con2,localhost,root);
CREATE TABLE t2 (a INT) ENGINE=InnoDB;
XA START 'y'; INSERT INTO t2 VALUES (1); XA END 'y'; XA PREPARE 'y';
connection default;
# innodb_force_recovery=2 prevents the purge and tests that the fix of
@ -25,6 +28,7 @@ connection default;
--let $shutdown_timeout=
disconnect con1;
disconnect con2;
connect (con1,localhost,root);
--send SELECT * FROM t1 LOCK IN SHARE MODE
@ -35,6 +39,8 @@ let $wait_condition=
info = 'SELECT * FROM t1 LOCK IN SHARE MODE';
--source include/wait_condition.inc
DROP TABLE t2;
--source include/restart_mysqld.inc
disconnect con1;
@ -45,3 +51,8 @@ XA ROLLBACK 'x';
SELECT * FROM t1;
DROP TABLE t1;
SET GLOBAL innodb_fast_shutdown=0;
--source include/restart_mysqld.inc
XA ROLLBACK 'y';