Skip to content

Commit 05220e1

Browse files
author
Jon Olav Hauglid
committed
Bug #50786 Assertion `thd->mdl_context.trans_sentinel() == __null'
failed in open_ltable() The problem was too restrictive asserts that enforced that open_ltable() was called without any active HANDLERs, LOCK TABLES or global read locks. However, this can happen in several cases when opening system tables. The assert would, for example, be triggered when drop function was called from a connection with active HANDLERs as this would cause open_ltable() to be called for mysql.proc. The assert could also be triggered when using table-based general log (mysql.general_log). This patch removes the asserts since they will be triggered in several legitimate cases and because the asserts are no longer relevant due to changes in how locks are released. The patch also fixes set_needs_thr_lock_abort() that before ignored its parameter and always set the member variable to TRUE. Test case added to mdl_sync.test. Thanks to Dmitry Lenev for help with this bug! --BZR-- revision-id: [email protected] property-branch-nick: mysql-next-4284-bug50786 testament3-sha1: cb1ddf1b2a891d0ab662d0dc272f7857519060d3
1 parent cfb6f2e commit 05220e1

File tree

4 files changed

+152
-5
lines changed

4 files changed

+152
-5
lines changed

mysql-test/r/mdl_sync.result

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2244,3 +2244,51 @@ FLUSH TABLES WITH READ LOCK;
22442244
UNLOCK TABLES;
22452245
# Connection 1
22462246
SET DEBUG_SYNC= 'RESET';
2247+
#
2248+
# Bug#50786 Assertion `thd->mdl_context.trans_sentinel() == __null'
2249+
# failed in open_ltable()
2250+
#
2251+
DROP TABLE IF EXISTS t1, t2;
2252+
CREATE TABLE t1 (i INT);
2253+
CREATE TABLE t2 (i INT);
2254+
SET @old_general_log= @@global.general_log;
2255+
SET @@global.general_log= 1;
2256+
SET @old_log_output= @@global.log_output;
2257+
SET @@global.log_output= 'TABLE';
2258+
SET @old_sql_log_off= @@session.sql_log_off;
2259+
SET @@session.sql_log_off= 1;
2260+
# connection: con1
2261+
HANDLER t1 OPEN;
2262+
# connection: con3
2263+
SET @@session.sql_log_off= 1;
2264+
# connection: con2
2265+
SET DEBUG_SYNC= 'thr_multi_lock_after_thr_lock SIGNAL parked WAIT_FOR go';
2266+
# Sending:
2267+
SELECT 1;
2268+
# connection: con3
2269+
SET DEBUG_SYNC= 'now WAIT_FOR parked';
2270+
# connection: con1
2271+
# Sending:
2272+
SELECT 1;
2273+
# connection: con3
2274+
# Sending:
2275+
ALTER TABLE t1 ADD COLUMN j INT;
2276+
# connection: default
2277+
SET DEBUG_SYNC= 'now SIGNAL go';
2278+
# connection: con1
2279+
# Reaping SELECT 1
2280+
1
2281+
1
2282+
HANDLER t1 CLOSE;
2283+
# connection: con2
2284+
# Reaping SELECT 1
2285+
1
2286+
1
2287+
# connection: con3
2288+
# Reaping ALTER TABLE t1 ADD COLUMN j INT
2289+
# connection: default
2290+
DROP TABLE t1, t2;
2291+
SET DEBUG_SYNC= 'RESET';
2292+
SET @@global.general_log= @old_general_log;
2293+
SET @@global.log_output= @old_log_output;
2294+
SET @@session.sql_log_off= @old_sql_log_off;

mysql-test/t/mdl_sync.test

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3212,6 +3212,109 @@ SET DEBUG_SYNC= 'RESET';
32123212
disconnect con2;
32133213

32143214

3215+
--echo #
3216+
--echo # Bug#50786 Assertion `thd->mdl_context.trans_sentinel() == __null'
3217+
--echo # failed in open_ltable()
3218+
--echo #
3219+
3220+
--disable_warnings
3221+
DROP TABLE IF EXISTS t1, t2;
3222+
--enable_warnings
3223+
3224+
connect (con1,localhost,root);
3225+
connect (con2,localhost,root);
3226+
connect (con3,localhost,root);
3227+
connection default;
3228+
3229+
CREATE TABLE t1 (i INT);
3230+
CREATE TABLE t2 (i INT);
3231+
3232+
SET @old_general_log= @@global.general_log;
3233+
SET @@global.general_log= 1;
3234+
3235+
SET @old_log_output= @@global.log_output;
3236+
SET @@global.log_output= 'TABLE';
3237+
3238+
SET @old_sql_log_off= @@session.sql_log_off;
3239+
SET @@session.sql_log_off= 1;
3240+
3241+
--echo # connection: con1
3242+
connection con1;
3243+
HANDLER t1 OPEN;
3244+
3245+
--echo # connection: con3
3246+
connection con3;
3247+
SET @@session.sql_log_off= 1;
3248+
3249+
--echo # connection: con2
3250+
connection con2;
3251+
SET DEBUG_SYNC= 'thr_multi_lock_after_thr_lock SIGNAL parked WAIT_FOR go';
3252+
3253+
# The below statement will block on the debug sync point
3254+
# after it gets write lock on mysql.general_log table.
3255+
--echo # Sending:
3256+
--send SELECT 1
3257+
3258+
--echo # connection: con3
3259+
connection con3;
3260+
SET DEBUG_SYNC= 'now WAIT_FOR parked';
3261+
3262+
--echo # connection: con1
3263+
connection con1;
3264+
# This statement will block in open_ltable() when
3265+
# trying to write into mysql.general_log.
3266+
--echo # Sending:
3267+
--send SELECT 1
3268+
3269+
--echo # connection: con3
3270+
connection con3;
3271+
let $wait_condition=
3272+
SELECT COUNT(*) = 1 FROM information_schema.processlist
3273+
WHERE state = "Table lock" and info = "SELECT 1";
3274+
--source include/wait_condition.inc
3275+
# The ALTER below will try to abort the statement in connection con1,
3276+
# since the latter waits on a table-level lock while having a HANDLER
3277+
# open. This will cause mysql_lock_tables() in con1 fail which before
3278+
# triggered the assert.
3279+
--echo # Sending:
3280+
--send ALTER TABLE t1 ADD COLUMN j INT
3281+
3282+
--echo # connection: default
3283+
connection default;
3284+
let $wait_condition=
3285+
SELECT COUNT(*) = 1 FROM information_schema.processlist
3286+
WHERE state = "Waiting for table"
3287+
AND info = "ALTER TABLE t1 ADD COLUMN j INT";
3288+
--source include/wait_condition.inc
3289+
SET DEBUG_SYNC= 'now SIGNAL go';
3290+
3291+
--echo # connection: con1
3292+
connection con1;
3293+
--echo # Reaping SELECT 1
3294+
--reap
3295+
HANDLER t1 CLOSE;
3296+
3297+
--echo # connection: con2
3298+
connection con2;
3299+
--echo # Reaping SELECT 1
3300+
--reap
3301+
3302+
--echo # connection: con3
3303+
connection con3;
3304+
--echo # Reaping ALTER TABLE t1 ADD COLUMN j INT
3305+
--reap
3306+
3307+
--echo # connection: default
3308+
connection default;
3309+
DROP TABLE t1, t2;
3310+
SET DEBUG_SYNC= 'RESET';
3311+
disconnect con1;
3312+
disconnect con2;
3313+
disconnect con3;
3314+
SET @@global.general_log= @old_general_log;
3315+
SET @@global.log_output= @old_log_output;
3316+
SET @@session.sql_log_off= @old_sql_log_off;
3317+
32153318
# Check that all connections opened by test cases in this file are really
32163319
# gone so execution of other tests won't be affected by their presence.
32173320
--source include/wait_until_count_sessions.inc

sql/mdl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -540,7 +540,7 @@ class MDL_context
540540
always re-try reading it after small timeout and therefore
541541
will see the new value eventually.
542542
*/
543-
m_needs_thr_lock_abort= TRUE;
543+
m_needs_thr_lock_abort= needs_thr_lock_abort;
544544
}
545545
bool get_needs_thr_lock_abort() const
546546
{

sql/sql_base.cc

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4996,8 +4996,6 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type,
49964996
while ((error= open_table(thd, table_list, thd->mem_root, &ot_ctx, 0)) &&
49974997
ot_ctx.can_recover_from_failed_open())
49984998
{
4999-
/* We never have an open HANDLER, LOCK TABLES or GRL here. */
5000-
DBUG_ASSERT(thd->mdl_context.trans_sentinel() == NULL);
50014999
/*
50025000
Even though we have failed to open table we still need to
50035001
call release_transactional_locks() to release metadata locks which
@@ -5048,8 +5046,6 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type,
50485046
close_thread_tables(thd);
50495047
table_list->table= NULL;
50505048
table_list->mdl_request.ticket= NULL;
5051-
/* We never have an open HANDLER, LOCK TABLES or GRL here. */
5052-
DBUG_ASSERT(thd->mdl_context.trans_sentinel() == NULL);
50535049
thd->mdl_context.rollback_to_savepoint(ot_ctx.start_of_statement_svp());
50545050
goto retry;
50555051
}

0 commit comments

Comments
 (0)