Details
-
Bug
-
Status: Confirmed (View Workflow)
-
Major
-
Resolution: Unresolved
-
10.11, 11.4, 11.8, 12.3, 13.1, 10.11.19, 11.4.13, 11.8.9, 12.3.3
-
None
-
Not for Release Notes
Description
In ha_innobase::commit_inplace_alter_table(), DBUG_PRINT("to_be_dropped", ("table: %s", ctx->old_table->name.m_name)) runs after trx->commit(deleted). If the table was rebuilt, commit_try_rebuild() has called trx->drop_table(*ctx->old_table), and trx_t::commit() has already freed ctx->old_table (dict_sys.remove() -> dict_mem_table_free()).
The DBUG_PRINT is only evaluated when the keyword to_be_dropped is enabled, e.g. with debug_dbug='d', or after SET debug_dbug='+d,x' followed by SET debug_dbug='-d,x', which leaves "d" with an empty keyword list, i.e. all keywords enabled (MDEV-21361). On an ASAN debug build (of our MDEV-10267 branch; handler0alter.cc differs from main only in inplace_alter_table()):
CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB;
|
SET debug_dbug='d,to_be_dropped';
|
ALTER TABLE t1 FORCE;
|
 |
ERROR: AddressSanitizer: heap-use-after-free ... READ of size 8
|
#0 ha_innobase::commit_inplace_alter_table storage/innobase/handler/handler0alter.cc
|
freed by:
|
dict_mem_table_free storage/innobase/dict/dict0mem.cc:223
|
dict_sys_t::remove storage/innobase/dict/dict0dict.cc:1776
|
trx_t::commit storage/innobase/dict/drop.cc:275
|
ha_innobase::commit_inplace_alter_table storage/innobase/handler/handler0alter.cc
|
Any ALTER TABLE that rebuilds the table in place triggers it (FORCE, ENGINE=InnoDB, OPTIMIZE TABLE, the first FULLTEXT index on a table without an FTS_DOC_ID column), also on an empty table; ALGORITHM=COPY, INSTANT and in-place changes without a rebuild do not. A debug build without ASAN printed the stale name (test/#sql-ib19) and did not crash. The code is the same from 10.6 (MDEV-25506 moved the drop of the old table into trx->commit()) to main.
Fix: print ctx->tmp_name, which is the same name (asserted before the commit) and stays valid until the ctx is destroyed, or drop the DBUG_PRINT.