MDEV-17813 Crash in instant ALTER TABLE due to purge concurrently emptying table
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.
Showing
Please register or sign in to comment