mirror of
https://github.com/MariaDB/server.git
synced 2025-07-20 10:18:13 +02:00

AVOID DEADLOCK AFTER RESTORE Analysis -------- Accessing the restored NDB table in an active multi-statement transaction was resulting in deadlock found error. MySQL Server needs to discover metadata of NDB table from data nodes after table is restored from backup. Metadata discovery happens on the first access to restored table. Current code mandates this statement to be the first one in the transaction. This is because discover needs exclusive metadata lock on the table. Lock upgrade at this point can lead to MDL deadlock and the code was written at the time when MDL deadlock detector was not present. In case when discovery attempted in the statement other than the first one in transaction ER_LOCK_DEADLOCK error is reported pessimistically. Fix: --- Removed the constraint as any potential deadlock will be handled by deadlock detector. Also changed code in discover to keep metadata locks of active transaction. Same issue was present in table auto repair scenario. Same fix is added in repair path also.
70 lines
1.7 KiB
Text
70 lines
1.7 KiB
Text
-- source include/have_ndb.inc
|
|
-- source include/count_sessions.inc
|
|
|
|
--echo #
|
|
--echo # 18075170 - sql node restart required to avoid deadlock after
|
|
--echo # restore
|
|
--echo #
|
|
# Test Auto Discover option within a transaction
|
|
# and make sure the transaction is not broken.
|
|
CREATE TABLE t1 (id INT) ENGINE=NDBCluster;
|
|
CREATE TABLE t2 (id INT) ENGINE=NDBCluster;
|
|
|
|
INSERT INTO t1 VALUES (1);
|
|
INSERT INTO t2 VALUES (1);
|
|
|
|
-- source include/ndb_backup.inc
|
|
|
|
DROP TABLE t1;
|
|
DROP TABLE t2;
|
|
|
|
-- source include/ndb_restore_master.inc
|
|
|
|
SET autocommit = 0;
|
|
SELECT * FROM t1;
|
|
|
|
# Without fix below select was resulting in DEADLOCK error. With fix select
|
|
# should succeed.
|
|
SELECT * FROM t2;
|
|
ROLLBACK;
|
|
SET autocommit = 1;
|
|
|
|
drop table t1;
|
|
drop table t2;
|
|
|
|
#
|
|
# Checking lock preservation in transaction
|
|
#
|
|
# Using existing backup to create the scenario. Tables are deleted as part of
|
|
# above test cleanup. Thus restoring the backup will bring the system to
|
|
# required state.
|
|
-- source include/ndb_restore_master.inc
|
|
|
|
SET autocommit = 0;
|
|
SELECT * FROM t1;
|
|
SELECT * FROM t2;
|
|
|
|
connect(con2, localhost, root);
|
|
--SEND ALTER TABLE t1 ADD val INT
|
|
|
|
connection default;
|
|
# Alter from con2 will be in waiting state as there is a lock on t1 from
|
|
# default connection due to active transaction. We check for this condition
|
|
# then releasing the lock by rollbacking active transaction.
|
|
let $wait_condition=
|
|
SELECT count(*) = 1 FROM information_schema.processlist WHERE state
|
|
LIKE "Waiting%" AND info = "ALTER TABLE t1 ADD val INT";
|
|
--source include/wait_condition.inc
|
|
ROLLBACK;
|
|
SET autocommit = 1;
|
|
|
|
connection con2;
|
|
--REAP
|
|
|
|
disconnect con2;
|
|
connection default;
|
|
drop table t1;
|
|
drop table t2;
|
|
|
|
# Wait till all disconnects are completed
|
|
-- source include/wait_until_count_sessions.inc
|