• Marko Mäkelä's avatar
    MDEV-17813 Crash in instant ALTER TABLE due to purge concurrently emptying table · 2c4844c9
    Marko Mäkelä authored
    Several race conditions between MDEV-15562 instant ALTER TABLE and purge
    were observed.
    
    The most obvious race condition resulted in a reported assertion failure in
    dict_index_t::instant_add_field(): instant.n_core_fields == n_core_fields
    would not hold if the table was emptied by purge after the time
    dict_table_t::prepare_instant() was called.
    
    During purge, it can turn out that the table is logically empty, only
    containing a metadata record. If the metadata record is of the type
    created by MDEV-11369 instant ADD COLUMN, it can be removed and
    dict_index_t::clear_instant_add() can be called. This will convert the
    table to the canonical non-instant format. (If the metadata record is
    of the MDEV-15562 type, then it can only be deleted if the table becomes
    empty as the result of rollback of an instant ALTER TABLE operation.)
    
    row_purge_remove_clust_if_poss_low(): Add a debug check that ensures
    that purge can never remove a MDEV-15562 metadata record.
    
    ha_innobase::open(): Add a comment about the necessity of rolling
    back any recovered instant ALTER TABLE transaction on the table.
    
    instant_metadata_lock(): An auxiliary function to acquire a page latch
    on the metadata record, to prevent race conditions.
    
    dict_table_t::prepare_instant(), dict_index_t::instant_add_field(),
    dict_table_t::rollback_instant(), innobase_instant_try():
    Invoke instant_metadata_lock() in order to prevent race conditions.
    
    dict_index_t::instant_add_field(): Correct debug assertions.
    The == was guaranteed by code in dict_table_t::prepare_instant()
    that was introduced in MDEV-15562. Due to the race condition,
    we could occasionally have <=, but never >= like the code was
    after MDEV-11369.
    
    ha_innobase_inplace_ctx::instant_column(): Wrapper for
    dict_table_t::instant_column(). Add debug assertions.
    2c4844c9
ha_innodb.cc 605 KB