-
Nisha Gopalakrishnan authored
CONSTRAINT Analysis ======== ALTER TABLE operation on a table with FOREIGN KEY CASCADE constraint while a concurrent DML operation is being performed on the table referenced may break the referential integrity. In the case of ALTER TABLE operation using COPY algorithm: a) The ALTER TABLE operation on the table with FOREIGN KEY CASCADE constraint, the data is copied from the original file to temp file and transaction is committed releasing InnoDB locks (also, as an optimization, InnoDB commits transaction and releases locks every time ALTER TABLE copies 10000 rows). b) Concurrently if DELETE operation is executed on the referenced table, it will trigger delete of records on the table being altered. This will end up deleting records from the original file since the rename of the temp file has not yet completed and locks on the original file are not held. c) The ALTER TABLE operation continues, renaming the temp file to the original file leaving behind orphaned rows. In the case of ALTER TABLE operation using INPLACE algorithm: a) The DELETE operation on the referenced table acquires an LOCK_IS on the table being altered due to the CASCADE FOREIGN KEY constraint. b) The ALTER TABLE operation tries to acquire LOCK_X during the commit phase of INPLACE alter and is added to the waiting queue since LOCK_IS is acquired by DELETE. c) DELETE operation upon finding the record to delete, tries to acquire LOCK_IX on the table and is added to the wait queue. This results in a deadlock with ALTER operation being rolled back. Fix: ==== a) INNODB has introduced a new handler API 'get_cascade_foreign_key_table_list()' which returns a full closure of all tables ordered by the dependency on FOREIGN KEY CASCADE constraint. b) A function called 'lock_fk_dependent_tables()' is added which locks the list of tables ordered by the FOREIGN KEY CASCADE constraint for the table being altered. It is invoked in two places. 1) Before the copy of data is invoked for the ALTER TABLE, COPY algorithm. 2) Before ALTER TABLE, INPLACE commit. This avoids the orphaned rows and deadlock. Please note that this is a temporary workaround which is necessary until WL#6049 "Meta-data locking for FOREIGN KEY tables" is implemented NOTE: Some of the test cases have been removed, since the condition of concurrent DDL/DML operation on a parent table while a DDL operation is performed on the the child table having a CASCADE foreign key constraint is restricted with this patch
Nisha Gopalakrishnan authoredCONSTRAINT Analysis ======== ALTER TABLE operation on a table with FOREIGN KEY CASCADE constraint while a concurrent DML operation is being performed on the table referenced may break the referential integrity. In the case of ALTER TABLE operation using COPY algorithm: a) The ALTER TABLE operation on the table with FOREIGN KEY CASCADE constraint, the data is copied from the original file to temp file and transaction is committed releasing InnoDB locks (also, as an optimization, InnoDB commits transaction and releases locks every time ALTER TABLE copies 10000 rows). b) Concurrently if DELETE operation is executed on the referenced table, it will trigger delete of records on the table being altered. This will end up deleting records from the original file since the rename of the temp file has not yet completed and locks on the original file are not held. c) The ALTER TABLE operation continues, renaming the temp file to the original file leaving behind orphaned rows. In the case of ALTER TABLE operation using INPLACE algorithm: a) The DELETE operation on the referenced table acquires an LOCK_IS on the table being altered due to the CASCADE FOREIGN KEY constraint. b) The ALTER TABLE operation tries to acquire LOCK_X during the commit phase of INPLACE alter and is added to the waiting queue since LOCK_IS is acquired by DELETE. c) DELETE operation upon finding the record to delete, tries to acquire LOCK_IX on the table and is added to the wait queue. This results in a deadlock with ALTER operation being rolled back. Fix: ==== a) INNODB has introduced a new handler API 'get_cascade_foreign_key_table_list()' which returns a full closure of all tables ordered by the dependency on FOREIGN KEY CASCADE constraint. b) A function called 'lock_fk_dependent_tables()' is added which locks the list of tables ordered by the FOREIGN KEY CASCADE constraint for the table being altered. It is invoked in two places. 1) Before the copy of data is invoked for the ALTER TABLE, COPY algorithm. 2) Before ALTER TABLE, INPLACE commit. This avoids the orphaned rows and deadlock. Please note that this is a temporary workaround which is necessary until WL#6049 "Meta-data locking for FOREIGN KEY tables" is implemented NOTE: Some of the test cases have been removed, since the condition of concurrent DDL/DML operation on a parent table while a DDL operation is performed on the the child table having a CASCADE foreign key constraint is restricted with this patch
Loading