From 0ede71256f58f0298f473277e9f03d62fc81a85a Mon Sep 17 00:00:00 2001 From: Dmitry Lenev Date: Wed, 3 Feb 2010 08:32:38 +0300 Subject: [PATCH] Fix for bug #50784 "MDL: Assertion `m_tickets.is_empty() || m_tickets.front() == m_trans_sentinel'". Debug build of server crashed due to assert failure in MDL subsystem when one tried to execute multi-table REPAIR or OPTIMIZE in autocommit=0 mode. The assert failure occured when multi-table REPAIR or OPTIMIZE started processing of second table from its table list and tried to acquire upgradable metadata lock on this table. The cause of the assert failure were MDL locks left over from processing of previous table. It turned out that in autocommit=0 mode close_thread_tables() which happens at the end of table processing doesn't release metadata locks. This fix solves problem by releasing locks explicitly using MDL_context::release_trans_locks() call. --- mysql-test/r/repair.result | 14 ++++++++++++++ mysql-test/t/repair.test | 15 +++++++++++++++ sql/sql_table.cc | 2 ++ 3 files changed, 31 insertions(+) diff --git a/mysql-test/r/repair.result b/mysql-test/r/repair.result index 77eb927a21f..6ab5ecb7e18 100644 --- a/mysql-test/r/repair.result +++ b/mysql-test/r/repair.result @@ -169,3 +169,17 @@ test.t1 repair Error Table 't1' was locked with a READ lock and can't be updated test.t1 repair status Operation failed UNLOCK TABLES; DROP TABLE t1; +# +# Test for bug #50784 "MDL: Assertion `m_tickets.is_empty() || +# m_tickets.front() == m_trans_sentinel'" +# +drop tables if exists t1, t2; +create table t1 (i int); +create table t2 (j int); +set @@autocommit= 0; +repair table t1, t2; +Table Op Msg_type Msg_text +test.t1 repair status OK +test.t2 repair status OK +set @@autocommit= default; +drop tables t1, t2; diff --git a/mysql-test/t/repair.test b/mysql-test/t/repair.test index ec4c9b3cae8..3c55f06ff4c 100644 --- a/mysql-test/t/repair.test +++ b/mysql-test/t/repair.test @@ -173,3 +173,18 @@ REPAIR TABLE t1; UNLOCK TABLES; DROP TABLE t1; + + +--echo # +--echo # Test for bug #50784 "MDL: Assertion `m_tickets.is_empty() || +--echo # m_tickets.front() == m_trans_sentinel'" +--echo # +--disable_warnings +drop tables if exists t1, t2; +--enable_warnings +create table t1 (i int); +create table t2 (j int); +set @@autocommit= 0; +repair table t1, t2; +set @@autocommit= default; +drop tables t1, t2; diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 7f369507237..24127ee6c7d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5030,6 +5030,7 @@ send_result_message: trans_commit_stmt(thd); trans_commit_implicit(thd); close_thread_tables(thd); + thd->mdl_context.release_transactional_locks(); table->table=0; // For query cache /* @@ -5059,6 +5060,7 @@ err: trans_rollback_stmt(thd); trans_rollback(thd); close_thread_tables(thd); // Shouldn't be needed + thd->mdl_context.release_transactional_locks(); if (table) table->table=0; DBUG_RETURN(TRUE);