Skip to content

Commit 68710e2

Browse files
author
Dmitry Lenev
committed
Fix for bug #51136 "Crash in pthread_rwlock_rdlock on
TEMPORARY + HANDLER + LOCK + SP". Server crashed when one: 1) Opened HANDLER or acquired global read lock 2) Then locked one or several temporary tables with LOCK TABLES statement (but no base tables). 3) Then issued any statement causing commit (explicit or implicit). 4) Issued statement which should have closed HANDLER or released global read lock. The problem was that when entering LOCK TABLES mode in the scenario described above we incorrectly set transactional MDL sentinel to zero. As result during commit all metadata locks were released (including lock for open HANDLER or global metadata shared lock). Indeed, attempt to release metadata lock for the second time which happened during HANLDER CLOSE or during release of GLR caused crash. This patch fixes problem by changing MDL_context's set_trans_sentinel() method to set sentinel to correct value (it should point to the most recent ticket).
1 parent 22bc48b commit 68710e2

File tree

6 files changed

+97
-1
lines changed

6 files changed

+97
-1
lines changed

mysql-test/include/handler.inc

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1681,3 +1681,25 @@ handler t1 close;
16811681
--echo # Clean-up.
16821682
drop function f1;
16831683
drop tables t1, t2;
1684+
1685+
1686+
--echo #
1687+
--echo # Test for bug #51136 "Crash in pthread_rwlock_rdlock on TEMPORARY +
1688+
--echo # HANDLER + LOCK + SP".
1689+
--echo # Also see additional coverage for this bug in flush.test.
1690+
--echo #
1691+
--disable_warnings
1692+
drop tables if exists t1, t2;
1693+
--enable_warnings
1694+
create table t1 (i int);
1695+
create temporary table t2 (j int);
1696+
handler t1 open;
1697+
lock table t2 read;
1698+
--echo # This commit should not release any MDL locks.
1699+
commit;
1700+
unlock tables;
1701+
--echo # The below statement crashed before the bug fix as it
1702+
--echo # has attempted to release metadata lock which was
1703+
--echo # already released by commit.
1704+
handler t1 close;
1705+
drop tables t1, t2;

mysql-test/r/flush.result

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,20 @@ unlock tables;
9494
set global general_log= @old_general_log;
9595
set global read_only= @old_read_only;
9696
End of 5.1 tests
97+
#
98+
# Additional test for bug #51136 "Crash in pthread_rwlock_rdlock
99+
# on TEMPORARY + HANDLER + LOCK + SP".
100+
# Also see the main test for this bug in include/handler.inc.
101+
#
102+
drop tables if exists t1, t2;
103+
create table t1 (i int);
104+
create temporary table t2 (j int);
105+
flush tables with read lock;
106+
lock table t2 read;
107+
# This commit should not release any MDL locks.
108+
commit;
109+
# The below statement crashed before the bug fix as it
110+
# has attempted to release global shared metadata lock
111+
# which was already released by commit.
112+
unlock tables;
113+
drop tables t1, t2;

mysql-test/r/handler_innodb.result

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1667,3 +1667,21 @@ handler t1 close;
16671667
# Clean-up.
16681668
drop function f1;
16691669
drop tables t1, t2;
1670+
#
1671+
# Test for bug #51136 "Crash in pthread_rwlock_rdlock on TEMPORARY +
1672+
# HANDLER + LOCK + SP".
1673+
# Also see additional coverage for this bug in flush.test.
1674+
#
1675+
drop tables if exists t1, t2;
1676+
create table t1 (i int);
1677+
create temporary table t2 (j int);
1678+
handler t1 open;
1679+
lock table t2 read;
1680+
# This commit should not release any MDL locks.
1681+
commit;
1682+
unlock tables;
1683+
# The below statement crashed before the bug fix as it
1684+
# has attempted to release metadata lock which was
1685+
# already released by commit.
1686+
handler t1 close;
1687+
drop tables t1, t2;

mysql-test/r/handler_myisam.result

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,6 +1664,24 @@ handler t1 close;
16641664
drop function f1;
16651665
drop tables t1, t2;
16661666
#
1667+
# Test for bug #51136 "Crash in pthread_rwlock_rdlock on TEMPORARY +
1668+
# HANDLER + LOCK + SP".
1669+
# Also see additional coverage for this bug in flush.test.
1670+
#
1671+
drop tables if exists t1, t2;
1672+
create table t1 (i int);
1673+
create temporary table t2 (j int);
1674+
handler t1 open;
1675+
lock table t2 read;
1676+
# This commit should not release any MDL locks.
1677+
commit;
1678+
unlock tables;
1679+
# The below statement crashed before the bug fix as it
1680+
# has attempted to release metadata lock which was
1681+
# already released by commit.
1682+
handler t1 close;
1683+
drop tables t1, t2;
1684+
#
16671685
# BUG #46456: HANDLER OPEN + TRUNCATE + DROP (temporary) TABLE, crash
16681686
#
16691687
CREATE TABLE t1 AS SELECT 1 AS f1;

mysql-test/t/flush.test

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,3 +203,24 @@ set global general_log= @old_general_log;
203203
set global read_only= @old_read_only;
204204

205205
--echo End of 5.1 tests
206+
207+
208+
--echo #
209+
--echo # Additional test for bug #51136 "Crash in pthread_rwlock_rdlock
210+
--echo # on TEMPORARY + HANDLER + LOCK + SP".
211+
--echo # Also see the main test for this bug in include/handler.inc.
212+
--echo #
213+
--disable_warnings
214+
drop tables if exists t1, t2;
215+
--enable_warnings
216+
create table t1 (i int);
217+
create temporary table t2 (j int);
218+
flush tables with read lock;
219+
lock table t2 read;
220+
--echo # This commit should not release any MDL locks.
221+
commit;
222+
--echo # The below statement crashed before the bug fix as it
223+
--echo # has attempted to release global shared metadata lock
224+
--echo # which was already released by commit.
225+
unlock tables;
226+
drop tables t1, t2;

sql/mdl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,7 @@ class MDL_context
501501

502502
void set_trans_sentinel()
503503
{
504-
m_trans_sentinel= mdl_savepoint();
504+
m_trans_sentinel= m_tickets.front();
505505
}
506506
MDL_ticket *trans_sentinel() const { return m_trans_sentinel; }
507507

0 commit comments

Comments
 (0)