• Marko Mäkelä's avatar
    MDEV-29504/MDEV-29849 TRUNCATE breaks FOREIGN KEY locking · e572c745
    Marko Mäkelä authored
    ha_innobase::referenced_by_foreign_key(): Protect the check with
    dict_sys.freeze(), to prevent races with TRUNCATE TABLE.
    The test innodb.instant_alter_crash has been adjusted for this
    additional locking.
    
    dict_table_is_referenced_by_foreign_key(): Removed (merged to
    the only caller).
    
    create_table_info_t::create_table(): Ignore missing indexes for
    FOREIGN KEY constraints if foreign_key_checks=0.
    
    create_table_info_t::create_table_update_dict(): Rewritten as
    a static function. Do not return any error.
    
    ha_innobase::create(): When trx!=nullptr and we are operating
    on a persistent table, do not rollback, commit, or release the
    data dictionary latch.
    
    ha_innobase::truncate(): Protect the entire critical section
    with an exclusive dict_sys.latch, so that
    ha_innobase::referenced_by_foreign_key() on referenced tables
    will return a consistent result. In case of a failure,
    invoke dict_load_foreigns() to restore also any FOREIGN KEY
    constraints.
    
    ha_innobase::free_foreign_key_create_info(): Define inline.
    
    lock_release(): Disregard innodb_evict_tables_on_commit_debug=ON
    when dict_sys.locked() holds. It would hold when fts_load_stopword()
    is invoked by create_table_info_t::create_table_update_dict().
    
    dict_sys_t::locked(): Return whether the current thread is holding
    the exclusive dict_sys.latch.
    
    dict_sys_t::frozen_not_locked(): Return whether any thread is
    holding a shared dict_sys.latch.
    
    In the test main.mysql_upgrade, the InnoDB persistent statistics
    will no longer be recalculated in ha_innobase::open() as part of
    CHECK TABLE ... FOR UPGRADE. They were deleted earlier in the test.
    
    Tested by: Matthias Leich
    e572c745
ha_innodb.cc 611 KB