Skip to content
  • Nisha Gopalakrishnan's avatar
    c4e3acb3
    BUG#20367116: ALTER TABLE BREAKS ON DELETE CASCADE FOREIGN KEY · c4e3acb3
    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
    c4e3acb3
    BUG#20367116: ALTER TABLE BREAKS ON DELETE CASCADE FOREIGN KEY
    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
Loading