mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-26554: Races between INSERT on child and DDL on parent table
The SQL layer never acquires metadata locks (MDL) on the tables that the tables that DML statement accesses is modifying. However, the storage engine must access the parent table in order to ensure that the child table will not refer to a non-existing record in the parent table. During certain DDL operations, the InnoDB table metadata (dict_table_t) may be be freed and rebuilt. This would cause a race condition with a concurrent INSERT that is attempting to report a FOREIGN KEY violation. We work around the insufficient MDL during DML by acquiring exclusive InnoDB table locks on all child tables during DDL. To avoid deadlocks, we will follow the following order of acquisition: 1. tables whose REFERENCES clauses point to the current table 2. the current table that is being subjected to DDL 3. mysql.innodb_table_stats 4. mysql.innodb_index_stats 5. the InnoDB dictionary tables (SYS_TABLES and so on) 6. exclusive dict_sys.latch
This commit is contained in:
@@ -43,16 +43,19 @@ SET DEBUG_SYNC='foreign_constraint_check_for_ins SIGNAL fk WAIT_FOR go';
|
||||
INSERT INTO child SET a=5;
|
||||
connection default;
|
||||
SET DEBUG_SYNC='now WAIT_FOR fk';
|
||||
SET foreign_key_checks=0;
|
||||
SET foreign_key_checks=0, innodb_lock_wait_timeout=0;
|
||||
TRUNCATE TABLE parent;
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
SET DEBUG_SYNC='now SIGNAL go';
|
||||
connection dml;
|
||||
ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`a`) REFERENCES `parent` (`a`) ON UPDATE CASCADE)
|
||||
SELECT * FROM parent;
|
||||
a
|
||||
3
|
||||
5
|
||||
SELECT * FROM child;
|
||||
a
|
||||
3
|
||||
5
|
||||
disconnect dml;
|
||||
connection default;
|
||||
SET DEBUG_SYNC = RESET;
|
||||
|
Reference in New Issue
Block a user