Commit cb7078f5 authored by Alexander Nozdrin's avatar Alexander Nozdrin

Auto-merge from mysql-next-4284.

parents fe8d83a1 be3e256d
...@@ -1681,3 +1681,25 @@ handler t1 close; ...@@ -1681,3 +1681,25 @@ handler t1 close;
--echo # Clean-up. --echo # Clean-up.
drop function f1; drop function f1;
drop tables t1, t2; 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;
...@@ -94,3 +94,20 @@ unlock tables; ...@@ -94,3 +94,20 @@ unlock tables;
set global general_log= @old_general_log; set global general_log= @old_general_log;
set global read_only= @old_read_only; set global read_only= @old_read_only;
End of 5.1 tests 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;
...@@ -1667,3 +1667,21 @@ handler t1 close; ...@@ -1667,3 +1667,21 @@ handler t1 close;
# Clean-up. # Clean-up.
drop function f1; drop function f1;
drop tables t1, t2; 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;
...@@ -1664,6 +1664,24 @@ handler t1 close; ...@@ -1664,6 +1664,24 @@ handler t1 close;
drop function f1; drop function f1;
drop tables t1, t2; 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 # BUG #46456: HANDLER OPEN + TRUNCATE + DROP (temporary) TABLE, crash
# #
CREATE TABLE t1 AS SELECT 1 AS f1; CREATE TABLE t1 AS SELECT 1 AS f1;
......
...@@ -436,3 +436,29 @@ UNLOCK TABLES; ...@@ -436,3 +436,29 @@ UNLOCK TABLES;
# Reaping: DROP TABLE t1, t2 # Reaping: DROP TABLE t1, t2
# Connection default # Connection default
# Cleanup # Cleanup
#
# Test for bug #51134 "Crash in MDL_lock::destroy on a concurrent
# DDL workload".
#
drop tables if exists t1, t2, t3;
create table t3 (i int);
# Switching to connection 'con1'
# Lock 't3' so upcoming RENAME is blocked.
lock table t3 read;
# Switching to connection 'con2'
# Remember ID for this connection.
# Start statement which will try to acquire two instances
# of X metadata lock on the same object.
# Sending:
rename tables t1 to t2, t2 to t3;;
# Switching to connection 'default'
# Wait until RENAME TABLE is blocked on table 't3'.
# Kill RENAME TABLE.
kill query ID;
# Switching to connection 'con2'
# RENAME TABLE should be aborted but should not crash.
ERROR 70100: Query execution was interrupted
# Switching to connection 'con1'
unlock tables;
# Switching to connection 'default'
drop table t3;
...@@ -203,3 +203,24 @@ set global general_log= @old_general_log; ...@@ -203,3 +203,24 @@ set global general_log= @old_general_log;
set global read_only= @old_read_only; set global read_only= @old_read_only;
--echo End of 5.1 tests --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;
...@@ -1038,5 +1038,59 @@ disconnect con2; ...@@ -1038,5 +1038,59 @@ disconnect con2;
disconnect con3; disconnect con3;
--echo #
--echo # Test for bug #51134 "Crash in MDL_lock::destroy on a concurrent
--echo # DDL workload".
--echo #
--disable_warnings
drop tables if exists t1, t2, t3;
--enable_warnings
connect (con1, localhost, root, , );
connect (con2, localhost, root, , );
connection default;
create table t3 (i int);
--echo # Switching to connection 'con1'
connection con1;
--echo # Lock 't3' so upcoming RENAME is blocked.
lock table t3 read;
--echo # Switching to connection 'con2'
connection con2;
--echo # Remember ID for this connection.
let $ID= `select connection_id()`;
--echo # Start statement which will try to acquire two instances
--echo # of X metadata lock on the same object.
--echo # Sending:
--send rename tables t1 to t2, t2 to t3;
--echo # Switching to connection 'default'
connection default;
--echo # Wait until RENAME TABLE is blocked on table 't3'.
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = "Waiting for table" and info = "rename tables t1 to t2, t2 to t3";
--source include/wait_condition.inc
--echo # Kill RENAME TABLE.
--replace_result $ID ID
eval kill query $ID;
--echo # Switching to connection 'con2'
connection con2;
--echo # RENAME TABLE should be aborted but should not crash.
--error ER_QUERY_INTERRUPTED
--reap
--echo # Switching to connection 'con1'
connection con1;
unlock tables;
--echo # Switching to connection 'default'
connection default;
disconnect con1;
disconnect con2;
drop table t3;
# Wait till all disconnects are completed # Wait till all disconnects are completed
--source include/wait_until_count_sessions.inc --source include/wait_until_count_sessions.inc
...@@ -1532,6 +1532,7 @@ bool MDL_context::acquire_locks(MDL_request_list *mdl_requests, ...@@ -1532,6 +1532,7 @@ bool MDL_context::acquire_locks(MDL_request_list *mdl_requests,
{ {
MDL_request_list::Iterator it(*mdl_requests); MDL_request_list::Iterator it(*mdl_requests);
MDL_request **sort_buf, **p_req; MDL_request **sort_buf, **p_req;
MDL_ticket *mdl_svp= mdl_savepoint();
ssize_t req_count= static_cast<ssize_t>(mdl_requests->elements()); ssize_t req_count= static_cast<ssize_t>(mdl_requests->elements());
if (req_count == 0) if (req_count == 0)
...@@ -1565,12 +1566,16 @@ bool MDL_context::acquire_locks(MDL_request_list *mdl_requests, ...@@ -1565,12 +1566,16 @@ bool MDL_context::acquire_locks(MDL_request_list *mdl_requests,
return FALSE; return FALSE;
err: err:
/* Release locks we have managed to acquire so far. */ /*
Release locks we have managed to acquire so far.
Use rollback_to_savepoint() since there may be duplicate
requests that got assigned the same ticket.
*/
rollback_to_savepoint(mdl_svp);
/* Reset lock requests back to its initial state. */
for (req_count= p_req - sort_buf, p_req= sort_buf; for (req_count= p_req - sort_buf, p_req= sort_buf;
p_req < sort_buf + req_count; p_req++) p_req < sort_buf + req_count; p_req++)
{ {
release_lock((*p_req)->ticket);
/* Reset lock request back to its initial state. */
(*p_req)->ticket= NULL; (*p_req)->ticket= NULL;
} }
my_free(sort_buf, MYF(0)); my_free(sort_buf, MYF(0));
......
...@@ -501,7 +501,7 @@ public: ...@@ -501,7 +501,7 @@ public:
void set_trans_sentinel() void set_trans_sentinel()
{ {
m_trans_sentinel= mdl_savepoint(); m_trans_sentinel= m_tickets.front();
} }
MDL_ticket *trans_sentinel() const { return m_trans_sentinel; } MDL_ticket *trans_sentinel() const { return m_trans_sentinel; }
......
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