mirror of
https://github.com/MariaDB/server.git
synced 2025-08-08 11:22:35 +03:00
MDEV-32899 InnoDB is holding shared dict_sys.latch while waiting for FOREIGN KEY child table lock on DDL
lock_table_children(): A new function to lock all child tables of a table. We will only hold dict_sys.latch while traversing dict_table_t::referenced_set. To prevent a race condition with std::set::erase() we will copy the pointers to the child tables to a local vector. Once we have acquired MDL and references to all child tables, we can safely release dict_sys.latch, wait for the locks, and finally release the references. dict_acquire_mdl_shared(): A new variant that takes mdl_context as a parameter. lock_table_for_trx(): Assert that we are not holding dict_sys.latch. ha_innobase::truncate(): When foreign_key_checks=ON, assert that no child tables exist (other than the current table). In any case, we will invoke lock_table_children() so that the child table metadata can be safely updated. (It is possible that a child table is being created concurrently with TRUNCATE TABLE.) ha_innobase::delete_table(): Before and after acquiring exclusive locks on the current table as well as all child tables, check that FOREIGN KEY constraints will not be violated. In this way, we can reject impossible DROP TABLE without having to wait for locks first. This fixes up commit2ca1123464
(MDEV-26217) and commitc3c53926c4
(MDEV-26554).
This commit is contained in:
committed by
Daniel Black
parent
5f2dcd112b
commit
b2654ba826
@@ -1077,10 +1077,23 @@ BEGIN;
|
||||
--error ER_NO_REFERENCED_ROW_2
|
||||
INSERT INTO child SET a=1;
|
||||
connection default;
|
||||
--error ER_TRUNCATE_ILLEGAL_FK
|
||||
TRUNCATE TABLE parent;
|
||||
--error ER_ROW_IS_REFERENCED_2
|
||||
DROP TABLE parent;
|
||||
SET innodb_lock_wait_timeout=0;
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
RENAME TABLE parent TO transparent;
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
ALTER TABLE parent FORCE, ALGORITHM=COPY;
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
ALTER TABLE parent FORCE, ALGORITHM=INPLACE;
|
||||
SET innodb_lock_wait_timeout=0, foreign_key_checks=0;
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
TRUNCATE TABLE parent;
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
DROP TABLE parent;
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
ALTER TABLE parent FORCE, ALGORITHM=COPY;
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
ALTER TABLE parent FORCE, ALGORITHM=INPLACE;
|
||||
@@ -1095,7 +1108,13 @@ TRUNCATE TABLE parent;
|
||||
ALTER TABLE parent FORCE, ALGORITHM=COPY;
|
||||
ALTER TABLE parent FORCE, ALGORITHM=INPLACE;
|
||||
ALTER TABLE parent ADD COLUMN b INT, ALGORITHM=INSTANT;
|
||||
DROP TABLE child, parent;
|
||||
SET foreign_key_checks=ON;
|
||||
--error ER_TRUNCATE_ILLEGAL_FK
|
||||
TRUNCATE TABLE parent;
|
||||
ALTER TABLE parent FORCE, ALGORITHM=COPY;
|
||||
ALTER TABLE parent FORCE, ALGORITHM=INPLACE;
|
||||
RENAME TABLE parent TO transparent;
|
||||
DROP TABLE child, transparent;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-26217 Failing assertion: list.count > 0 in ut_list_remove
|
||||
|
Reference in New Issue
Block a user