diff options
author | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2022-04-28 15:15:37 +0530 |
---|---|---|
committer | Thirunarayanan Balathandayuthapani <thiru@mariadb.com> | 2022-05-02 12:52:16 +0530 |
commit | fc391df54698fccf08e6299b208badc74c82cd1c (patch) | |
tree | eb766a55aa15a0025edc1e7d22de95dc38ce9dcd /storage | |
parent | a42e327afe07c4510ba2ffd349e86e6252d15c80 (diff) | |
download | mariadb-git-fc391df54698fccf08e6299b208badc74c82cd1c.tar.gz |
MDEV-28399 Assertion failure in dict_table_check_for_dup_indexes upon concurrent DML/DDL
Problem:
========
InnoDB DDL fails to remove the newly added table or index from
dictionary and index stub from the table cache if the alter
transaction encounters DEADLOCK error in commit phase.
Solution:
========
Restart the alter table transaction if it encounters DEADLOCK
in commit phase. So that index stubs and index, table removal from
dictionary can be done in rollback_inplace_alter_table()
- Added one assert in rollback_inplace_alter_table() to indicate that
the online log for the old table shouldn't exist.
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/handler/handler0alter.cc | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 1b184422a80..c2dc68f18d0 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -8884,6 +8884,7 @@ free_and_exit: } } + DBUG_ASSERT(!prebuilt->table->indexes.start->online_log); DBUG_ASSERT(prebuilt->table->indexes.start->online_status == ONLINE_INDEX_COMPLETE); @@ -10938,6 +10939,12 @@ ha_innobase::commit_inplace_alter_table( LOCK_X); } + DBUG_EXECUTE_IF("deadlock_table_fail", + { + error= DB_DEADLOCK; + trx_rollback_for_mysql(trx); + }); + if (error != DB_SUCCESS) { lock_fail: my_error_innodb( @@ -10945,6 +10952,16 @@ lock_fail: if (fts_exist) { purge_sys.resume_FTS(); } + + /* Deadlock encountered and rollbacked the + transaction. So restart the transaction + to remove the newly created table or + index from data dictionary and table cache + in rollback_inplace_alter_table() */ + if (trx->state == TRX_STATE_NOT_STARTED) { + trx_start_for_ddl(trx); + } + DBUG_RETURN(true); } else if ((ctx->new_table->flags2 & (DICT_TF2_FTS_HAS_DOC_ID | DICT_TF2_FTS)) |