summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Lenev <dlenev@mysql.com>2010-02-15 14:23:36 +0300
committerDmitry Lenev <dlenev@mysql.com>2010-02-15 14:23:36 +0300
commitbe3e256d25a853545c6ee04a8bf8e5b5907889c9 (patch)
tree39dde6eee8e819794694a0c0ad30156877e68e6a
parenteb0f09712e1b09955cc9e60d516ddf19336c9ffc (diff)
downloadmariadb-git-be3e256d25a853545c6ee04a8bf8e5b5907889c9.tar.gz
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). mysql-test/include/handler.inc: Added test for bug #51136 "Crash in pthread_rwlock_rdlock on TEMPORARY + HANDLER + LOCK + SP". mysql-test/r/flush.result: Updated test results (see flush.test). mysql-test/r/handler_innodb.result: Updated test results (see include/handler.inc). mysql-test/r/handler_myisam.result: Updated test results (see include/handler.inc). mysql-test/t/flush.test: Added additional coverage for bug #51136 "Crash in pthread_rwlock_rdlock on TEMPORARY + HANDLER + LOCK + SP". sql/mdl.h: When setting new value of transactional sentinel use pointer to the most recent ticket instead of value returned by MDL_context::mdl_savepoint(). This allows to handle correctly situation when the new value of sentinel should be the same as its current value (MDL_context::mdl_savepoint() returns NULL in this case).
-rw-r--r--mysql-test/include/handler.inc22
-rw-r--r--mysql-test/r/flush.result17
-rw-r--r--mysql-test/r/handler_innodb.result18
-rw-r--r--mysql-test/r/handler_myisam.result18
-rw-r--r--mysql-test/t/flush.test21
-rw-r--r--sql/mdl.h2
6 files changed, 97 insertions, 1 deletions
diff --git a/mysql-test/include/handler.inc b/mysql-test/include/handler.inc
index 9c6c6864e05..4b2e64e3bb5 100644
--- a/mysql-test/include/handler.inc
+++ b/mysql-test/include/handler.inc
@@ -1681,3 +1681,25 @@ handler t1 close;
--echo # Clean-up.
drop function f1;
drop tables t1, t2;
+
+
+--echo #
+--echo # Test for bug #51136 "Crash in pthread_rwlock_rdlock on TEMPORARY +
+--echo # HANDLER + LOCK + SP".
+--echo # Also see additional coverage for this bug in flush.test.
+--echo #
+--disable_warnings
+drop tables if exists t1, t2;
+--enable_warnings
+create table t1 (i int);
+create temporary table t2 (j int);
+handler t1 open;
+lock table t2 read;
+--echo # This commit should not release any MDL locks.
+commit;
+unlock tables;
+--echo # The below statement crashed before the bug fix as it
+--echo # has attempted to release metadata lock which was
+--echo # already released by commit.
+handler t1 close;
+drop tables t1, t2;
diff --git a/mysql-test/r/flush.result b/mysql-test/r/flush.result
index 2be426d3a4a..2136bcd92f1 100644
--- a/mysql-test/r/flush.result
+++ b/mysql-test/r/flush.result
@@ -94,3 +94,20 @@ unlock tables;
set global general_log= @old_general_log;
set global read_only= @old_read_only;
End of 5.1 tests
+#
+# Additional test for bug #51136 "Crash in pthread_rwlock_rdlock
+# on TEMPORARY + HANDLER + LOCK + SP".
+# Also see the main test for this bug in include/handler.inc.
+#
+drop tables if exists t1, t2;
+create table t1 (i int);
+create temporary table t2 (j int);
+flush tables with read lock;
+lock table t2 read;
+# This commit should not release any MDL locks.
+commit;
+# The below statement crashed before the bug fix as it
+# has attempted to release global shared metadata lock
+# which was already released by commit.
+unlock tables;
+drop tables t1, t2;
diff --git a/mysql-test/r/handler_innodb.result b/mysql-test/r/handler_innodb.result
index d0d35590e73..58083194b83 100644
--- a/mysql-test/r/handler_innodb.result
+++ b/mysql-test/r/handler_innodb.result
@@ -1667,3 +1667,21 @@ handler t1 close;
# Clean-up.
drop function f1;
drop tables t1, t2;
+#
+# Test for bug #51136 "Crash in pthread_rwlock_rdlock on TEMPORARY +
+# HANDLER + LOCK + SP".
+# Also see additional coverage for this bug in flush.test.
+#
+drop tables if exists t1, t2;
+create table t1 (i int);
+create temporary table t2 (j int);
+handler t1 open;
+lock table t2 read;
+# This commit should not release any MDL locks.
+commit;
+unlock tables;
+# The below statement crashed before the bug fix as it
+# has attempted to release metadata lock which was
+# already released by commit.
+handler t1 close;
+drop tables t1, t2;
diff --git a/mysql-test/r/handler_myisam.result b/mysql-test/r/handler_myisam.result
index 73ad8609376..dd199e40574 100644
--- a/mysql-test/r/handler_myisam.result
+++ b/mysql-test/r/handler_myisam.result
@@ -1664,6 +1664,24 @@ handler t1 close;
drop function f1;
drop tables t1, t2;
#
+# Test for bug #51136 "Crash in pthread_rwlock_rdlock on TEMPORARY +
+# HANDLER + LOCK + SP".
+# Also see additional coverage for this bug in flush.test.
+#
+drop tables if exists t1, t2;
+create table t1 (i int);
+create temporary table t2 (j int);
+handler t1 open;
+lock table t2 read;
+# This commit should not release any MDL locks.
+commit;
+unlock tables;
+# The below statement crashed before the bug fix as it
+# has attempted to release metadata lock which was
+# already released by commit.
+handler t1 close;
+drop tables t1, t2;
+#
# BUG #46456: HANDLER OPEN + TRUNCATE + DROP (temporary) TABLE, crash
#
CREATE TABLE t1 AS SELECT 1 AS f1;
diff --git a/mysql-test/t/flush.test b/mysql-test/t/flush.test
index 4172230a54d..d41ac3100b0 100644
--- a/mysql-test/t/flush.test
+++ b/mysql-test/t/flush.test
@@ -203,3 +203,24 @@ set global general_log= @old_general_log;
set global read_only= @old_read_only;
--echo End of 5.1 tests
+
+
+--echo #
+--echo # Additional test for bug #51136 "Crash in pthread_rwlock_rdlock
+--echo # on TEMPORARY + HANDLER + LOCK + SP".
+--echo # Also see the main test for this bug in include/handler.inc.
+--echo #
+--disable_warnings
+drop tables if exists t1, t2;
+--enable_warnings
+create table t1 (i int);
+create temporary table t2 (j int);
+flush tables with read lock;
+lock table t2 read;
+--echo # This commit should not release any MDL locks.
+commit;
+--echo # The below statement crashed before the bug fix as it
+--echo # has attempted to release global shared metadata lock
+--echo # which was already released by commit.
+unlock tables;
+drop tables t1, t2;
diff --git a/sql/mdl.h b/sql/mdl.h
index d43548fb65f..59bc1f64762 100644
--- a/sql/mdl.h
+++ b/sql/mdl.h
@@ -501,7 +501,7 @@ public:
void set_trans_sentinel()
{
- m_trans_sentinel= mdl_savepoint();
+ m_trans_sentinel= m_tickets.front();
}
MDL_ticket *trans_sentinel() const { return m_trans_sentinel; }