diff options
author | Dmitry Lenev <dlenev@mysql.com> | 2010-02-15 13:23:34 +0300 |
---|---|---|
committer | Dmitry Lenev <dlenev@mysql.com> | 2010-02-15 13:23:34 +0300 |
commit | eb0f09712e1b09955cc9e60d516ddf19336c9ffc (patch) | |
tree | 34f7770c9a35a8f2e093f9073c804ce696ae9071 /mysql-test/t/lock_multi.test | |
parent | d5a498abc668763053d46c83e61827f78a4bad0d (diff) | |
download | mariadb-git-eb0f09712e1b09955cc9e60d516ddf19336c9ffc.tar.gz |
Fix for bug #51134 "Crash in MDL_lock::destroy on a concurrent
DDL workload".
When a RENAME TABLE or LOCK TABLE ... WRITE statement which
mentioned the same table several times were aborted during
the process of acquring metadata locks (due to deadlock
which was discovered or because of KILL statement) server
might have crashed.
When attempt to acquire all locks requested had failed we
went through the list of requests and released locks which
we have managed to acquire by that moment one by one. Since
in the scenario described above list of requests contained
duplicates this led to releasing the same ticket twice and
a crash as result.
This patch solves the problem by employing different approach
to releasing locks in case of failure to acquire all locks
requested.
Now we take a MDL savepoint before starting acquiring locks
and simply rollback to it if things go bad.
mysql-test/r/lock_multi.result:
Updated test results (see lock_multi.test).
mysql-test/t/lock_multi.test:
Added test case for bug #51134 "Crash in MDL_lock::destroy
on a concurrent DDL workload".
sql/mdl.cc:
MDL_context::acquire_locks():
When attempt to acquire all locks requested has failed do
not go through the list of requests and release locks which
we have managed to acquire one by one.
Since list of requests can contain duplicates such approach
may lead to releasing the same ticket twice and a crash as
result.
Instead use the following approach - take a MDL savepoint
before starting acquiring locks and simply rollback to it
if things go bad.
Diffstat (limited to 'mysql-test/t/lock_multi.test')
-rw-r--r-- | mysql-test/t/lock_multi.test | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test index 1080b44c448..c34dcb05dd4 100644 --- a/mysql-test/t/lock_multi.test +++ b/mysql-test/t/lock_multi.test @@ -1038,5 +1038,59 @@ disconnect con2; 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 --source include/wait_until_count_sessions.inc |