Details
-
Bug
-
Status: Closed (View Workflow)
-
Critical
-
Resolution: Fixed
-
10.6, 10.11, 11.0(EOL), 11.1(EOL), 11.2(EOL), 11.4
Description
Related to MDEV-33955, I asked mleich to test if there are any problems if a TRUNCATE TABLE on the InnoDB persistent statistics table is being executed concurrently with DDL operations. He produced an rr replay trace that would hit an assertion failure when a FULLTEXT INDEX is being dropped:
10.6 0ccdf54b644352f42e1768bc660be7ab50c1e9d2 |
mariadbd: /data/Server/10.6C/storage/innobase/lock/lock0lock.cc:3484: ib_lock_t* lock_table_create(dict_table_t*, unsigned int, trx_t*, ib_lock_t*): Assertion `!trx->dict_operation_lock_mode || (strstr(table->name.m_name, "/FTS_") && strstr(table->name.m_name, "_CONFIG") + sizeof("_CONFIG") == table->name.m_name + strlen(table->name.m_name) + 1)' failed.
|
...
|
#7 0x0000556b211ff54c in lock_table_create (table=table@entry=0x64013650, type_mode=type_mode@entry=1, trx=trx@entry=0x388167814180, c_lock=c_lock@entry=0x0) at /data/Server/10.6C/storage/innobase/lock/lock0lock.cc:3484
|
#8 0x0000556b211ffd9d in lock_table_low (table=table@entry=0x64013650, mode=mode@entry=LOCK_IX, thr=thr@entry=0x49be3ba983d8, trx=trx@entry=0x388167814180) at /data/Server/10.6C/storage/innobase/lock/lock0lock.cc:3778
|
#9 0x0000556b212000de in lock_table (table=0x64013650, fktable=fktable@entry=0x0, mode=mode@entry=LOCK_IX, thr=thr@entry=0x49be3ba983d8) at /data/Server/10.6C/storage/innobase/lock/lock0lock.cc:3837
|
#10 0x0000556b2131c785 in row_sel_step (thr=thr@entry=0x49be3ba983d8) at /data/Server/10.6C/storage/innobase/row/row0sel.cc:2396
|
#11 0x0000556b21277dea in que_thr_step (thr=thr@entry=0x49be3ba983d8) at /data/Server/10.6C/storage/innobase/que/que0que.cc:564
|
#12 0x0000556b2127838c in que_run_threads_low (thr=thr@entry=0x49be3ba983d8) at /data/Server/10.6C/storage/innobase/que/que0que.cc:644
|
#13 0x0000556b21278453 in que_run_threads (thr=0x49be3ba983d8) at /data/Server/10.6C/storage/innobase/que/que0que.cc:664
|
#14 0x0000556b21278b54 in que_eval_sql (info=info@entry=0x49be3801c750, sql=sql@entry=0x556b219bb1e8 "PROCEDURE DELETE_FROM_INDEX_STATS () IS\nBEGIN\nDELETE FROM \"mysql/innodb_index_stats\" WHERE\ndatabase_name = :database_name AND\ntable_name = :table_name AND\nindex_name = :index_name;\nEND;\n",
|
trx=trx@entry=0x388167814180) at /data/Server/10.6C/storage/innobase/que/que0que.cc:703
|
#15 0x0000556b214695da in dict_stats_exec_sql (pinfo=pinfo@entry=0x49be3801c750, sql=sql@entry=0x556b219bb1e8 "PROCEDURE DELETE_FROM_INDEX_STATS () IS\nBEGIN\nDELETE FROM \"mysql/innodb_index_stats\" WHERE\ndatabase_name = :database_name AND\ntable_name = :table_name AND\nindex_name = :index_name;\nEND;\n",
|
trx=trx@entry=0x388167814180) at /data/Server/10.6C/storage/innobase/dict/dict0stats.cc:550
|
#16 0x0000556b2146986b in dict_stats_delete_from_index_stats (database_name=database_name@entry=0x3ac06a0752a0 "test", table_name=table_name@entry=0x3ac06a075440 "t1", index_name=0x49be39ece890 "ftidx", trx=trx@entry=0x388167814180) at /data/Server/10.6C/storage/innobase/dict/dict0stats.cc:4332
|
#17 0x0000556b211b4248 in commit_try_norebuild (ha_alter_info=ha_alter_info@entry=0x3ac06a076090, ctx=ctx@entry=0x49be38014ca0, altered_table=altered_table@entry=0x3ac06a076150, old_table=0x49be38049318, trx=trx@entry=0x388167814180, table_name=0x49be38075ced "t1")
|
at /data/Server/10.6C/storage/innobase/handler/handler0alter.cc:10631
|
#18 0x0000556b2119e655 in ha_innobase::commit_inplace_alter_table (this=<optimized out>, altered_table=0x3ac06a076150, ha_alter_info=0x3ac06a076090, commit=true) at /data/Server/10.6C/storage/innobase/handler/handler0alter.cc:11471
|
The reduced state of SQL statements related to this table looks like the following:
CREATE TABLE IF NOT EXISTS t1 (col1 INT, col2 INT, col3 INT, col4 TEXT) ENGINE = InnoDB; |
ALTER TABLE t1 ADD FULLTEXT KEY ftidx ( col4 ); |
ALTER TABLE t1 DROP KEY ftidx; |
As far as I can tell, the problem is that commit_try_norebuild() is invoking dict_stats_delete_from_index_stats(), even though earlier in ha_innobase::commit_inplace_alter_table() we failed to acquire exclusive locks on both statistics tables:
if (table_stats && index_stats |
&& !strcmp(table_stats->name.m_name, TABLE_STATS_NAME) |
&& !strcmp(index_stats->name.m_name, INDEX_STATS_NAME) |
&& !(error = lock_table_for_trx(table_stats,
|
trx, LOCK_X))) {
|
error = lock_table_for_trx(index_stats, trx, LOCK_X);
|
}
|
In the rr replay trace that I analyzed, we had table_stats=nullptr. The function commit_try_rebuild() takes a parameter statistics_exist, which will prevent access to statistics tables in such cases, but the corresponding parameter is missing from commit_try_norebuild().
Attachments
Issue Links
- relates to
-
MDEV-15020 Server hangs due to InnoDB persistent statistics or innodb_stats_auto_recalc
- Closed
-
MDEV-33955 Concurrent DDL on InnoDB table and REPAIR on InnoDB stats table leads to "table not found" error
- Open