MDEV-36122 Assertion failure ctx0->old_table->get_ref_count() == 1 in ha_innobase::commit_inplace_alter_table() #3889
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
trx_purge_close_tables()
: Before releasing any metadata locks (MDL), release all table references, in case anALTER TABLE…ALGORITHM=COPY
operation has confused our logic.trx_purge_table_acquire()
,trx_purge_table_open()
: Do not acquire any table reference before successfully acquiring a necessary metadata lock. In this way, if purge is waiting for MDL, a concurrentha_innobase::commit_inplace_alter_table(commit=true)
that is holding a conflictingMDL_EXCLUSIVE
will only observe its own reference on the table that it may need to replace.dict_table_open_on_id()
: Simplify the logic.dict_stats
: A helper for acquiring MDL and opening the tablesmysql.innodb_table_stats
andmysql.innodb_index_stats
.innodb_ft_aux_table_validate()
: Contiguously holddict_sys.latch
while accessing the table that we open withdict_table_open_on_name()
.lock_table_children()
: Do not hold a table reference while invokingdict_acquire_mdl_shared<false>()
, which may temporarily release and reacquire the shareddict_sys.latch
that we are holding.prepare_inplace_alter_table_dict()
: If an unexpected reference to the table exists, wait for the purge subsystem to release its table handle, similar to how we would do in caseFULLTEXT INDEX
existed. This function is supposed to be protected byMDL_EXCLUSIVE
on the table name. If purge is going to access the table again later during isALTER TABLE
operation, it will have access to an MDL compatible name for it and therefore should conflict with anyMDL_EXCLUSIVE
that would coverha_innobase::commit_inplace_alter_table(commit=true)
.ha_innobase::rename_table()
: Before locking the data dictionary, ensure that the purge subsystem is not holding a reference to the table due to the lack of metadata locking, related toFULLTEXT INDEX
or the row-level undo logging ofALTER IGNORE TABLE
.With these changes, no caller of
dict_acquire_mdl_shared<false>
should be holding a table reference.All remaining calls to
dict_table_open_on_name(dict_locked=false)
except the one infts_lock_table()
and possibly in the DDL recovery predicateinnodb_check_version()
should be protected by MDL, but there currently is no assertion that would enforce this.Release Notes
Some race conditions between InnoDB internal table access and DDL were fixed.
How can this PR be tested?
Stress test by the RQG grammar that reproduced the assertion failures.
Basing the PR against the correct MariaDB version
main
branch.This is a 10.11 version of #3856.
PR quality check