Commit dce4c0f9 authored by Sergey Vojtovich's avatar Sergey Vojtovich Committed by Sergei Golubchik

MDEV-22339 - Assertion `str_length < len' failed

When acquiring SNW/SNRW/X MDL lock DDL/admin statements may abort pending
thr lock in concurrent connection with open HANDLER (or delayed insert
thread).

This may lead to a race condition when table->alias is accessed
concurrently by such threads. Either assertion failure or memory leak
is a practical consequence of this race condition.

Specifically HANDLER is opening a table and issuing alias.copy(), while
DDL executing get_lock_data()/alias.c_ptr()/realloc()/realloc_raw().

Fixed by perforimg table->init() before it is published via
thd->open_tables.
parent c5883deb
#
# MDEV-22339 - Assertion `str_length < len' failed in
# Binary_string::realloc_raw
#
CREATE TABLE t1(a INT) ENGINE=MyISAM;
connect con1, localhost, root;
disconnect con1;
connection default;
DROP TABLE t1;
--echo #
--echo # MDEV-22339 - Assertion `str_length < len' failed in
--echo # Binary_string::realloc_raw
--echo #
CREATE TABLE t1(a INT) ENGINE=MyISAM;
connect con1, localhost, root;
let $i=1000;
disable_query_log;
disable_result_log;
while ($i)
{
connection default;
HANDLER t1 OPEN;
send SELECT * FROM t1, t1 t1a1over8, t1 t1a2over8, t1 t1a3over8, t1 t1a4over8, t1 t1a5over8, t1 t1a6over8;
connection con1;
send REPAIR TABLE t1;
connection default;
reap;
HANDLER t1 CLOSE;
connection con1;
reap;
dec $i;
}
enable_query_log;
enable_result_log;
disconnect con1;
connection default;
DROP TABLE t1;
......@@ -1675,6 +1675,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx)
{
table= best_table;
table->query_id= thd->query_id;
table->init(thd, table_list);
DBUG_PRINT("info",("Using locked table"));
goto reset;
}
......@@ -1959,12 +1960,13 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx)
}
table->mdl_ticket= mdl_ticket;
table->reginfo.lock_type=TL_READ; /* Assume read */
table->init(thd, table_list);
table->next= thd->open_tables; /* Link into simple list */
thd->set_open_tables(table);
table->reginfo.lock_type=TL_READ; /* Assume read */
reset:
/*
Check that there is no reference to a condition from an earlier query
......@@ -1989,8 +1991,6 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx)
}
#endif
table->init(thd, table_list);
DBUG_RETURN(FALSE);
err_lock:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment