From 6ddd01c27ab55242f8643e7efdd5f7bc9230a908 Mon Sep 17 00:00:00 2001
From: Dmitry Lenev <dlenev@mysql.com>
Date: Thu, 21 Jan 2010 23:43:03 +0300
Subject: Patch that changes metadata locking subsystem to use mutex per lock
 and condition variable per context instead of one mutex and one conditional
 variable for the whole subsystem.

This should increase concurrency in this subsystem.

It also opens the way for further changes which are necessary to solve
such bugs as bug #46272 "MySQL 5.4.4, new MDL: unnecessary deadlock"
and bug #37346 "innodb does not detect deadlock between update and alter
table".

Two other notable changes done by this patch:

- MDL subsystem no longer implicitly acquires global intention exclusive
  metadata lock when per-object metadata lock is acquired. Now this has
  to be done by explicit calls outside of MDL subsystem.
- Instead of using separate MDL_context for opening system tables/tables
  for purposes of I_S we now create MDL savepoint in the main context
  before opening tables and rollback to this savepoint after closing
  them. This means that it is now possible to get ER_LOCK_DEADLOCK error
  even not inside a transaction. This might happen in unlikely case when
  one runs DDL on one of system tables while also running DDL on some
  other tables. Cases when this ER_LOCK_DEADLOCK error is not justified
  will be addressed by advanced deadlock detector for MDL subsystem which
  we plan to implement.

mysql-test/include/handler.inc:
  Adjusted handler_myisam.test and handler_innodb.test to the fact that
  exclusive metadata locks on tables are now acquired according to
  alphabetical order of fully qualified table names instead of order
  in which tables are mentioned in statement.
mysql-test/r/handler_innodb.result:
  Adjusted handler_myisam.test and handler_innodb.test to the fact that
  exclusive metadata locks on tables are now acquired according to
  alphabetical order of fully qualified table names instead of order
  in which tables are mentioned in statement.
mysql-test/r/handler_myisam.result:
  Adjusted handler_myisam.test and handler_innodb.test to the fact that
  exclusive metadata locks on tables are now acquired according to
  alphabetical order of fully qualified table names instead of order
  in which tables are mentioned in statement.
mysql-test/r/mdl_sync.result:
  Adjusted mdl_sync.test to the fact that exclusive metadata locks on
  tables are now acquired according to alphabetical order of fully
  qualified table names instead of order in which tables are mentioned
  in statement.
mysql-test/t/mdl_sync.test:
  Adjusted mdl_sync.test to the fact that exclusive metadata locks on
  tables are now acquired according to alphabetical order of fully
  qualified table names instead of order in which tables are mentioned
  in statement.
sql/events.cc:
  Instead of using separate MDL_context for opening system tables we now
  create MDL savepoint in the main context before opening such tables
  and rollback to this savepoint after closing them. To support this
  change methods of THD responsible for saving/restoring open table
  state were changed to use Open_tables_backup class which in addition
  to Open_table_state has a member for this savepoint. As result code
  opening/closing system tables was changed to use Open_tables_backup
  instead of Open_table_state class as well.
sql/ha_ndbcluster.cc:
  Since manipulations with open table state no longer install proxy
  MDL_context it does not make sense to perform them in order to
  satisfy assert in mysql_rm_tables_part2(). Removed them per agreement
  with Cluster team. This has not broken test suite since scenario in
  which deadlock can occur and assertion fails is not covered by tests.
sql/lock.cc:
  MDL subsystem no longer implicitly acquires global intention exclusive
  metadata lock when per-object exclusive metadata lock is acquired.
  Now this has to be done by explicit calls outside of MDL subsystem.
sql/log.cc:
  Instead of using separate MDL_context for opening system tables we now
  create MDL savepoint in the main context before opening such tables
  and rollback to this savepoint after closing them. To support this
  change methods of THD responsible for saving/restoring open table
  state were changed to use Open_tables_backup class which in addition
  to Open_table_state has a member for this savepoint. As result code
  opening/closing system tables was changed to use Open_tables_backup
  instead of Open_table_state class as well.
sql/mdl.cc:
  Changed metadata locking subsystem to use mutex per lock and condition
  variable per context instead of one mutex and one conditional variable
  for the whole subsystem.
  Changed approach to handling of global metadata locks. Instead of
  implicitly acquiring intention exclusive locks when user requests
  per-object upgradeable or exclusive locks now we require them to be
  acquired explicitly in the same way as ordinary metadata locks.
  In fact global lock are now ordinary metadata locks in new GLOBAL
  namespace.

  To implement these changes:
  - Removed LOCK_mdl mutex and COND_mdl condition variable.
  - Introduced MDL_lock::m_mutex mutexes which protect individual lock
    objects.
  - Replaced mdl_locks hash with MDL_map class, which has hash for
    MDL_lock objects as a member and separate mutex which protects this
    hash. Methods of this class allow to find(), find_or_create() or
    remove() MDL_lock objects in concurrency-friendly fashion (i.e.
    for most common operation, find_or_create(), we don't acquire
    MDL_lock::m_mutex while holding MDL_map::m_mutex. Thanks to MikaelR
    for this idea and benchmarks!). Added three auxiliary members to
    MDL_lock class (m_is_destroyed, m_ref_usage, m_ref_release) to
    support this concurrency-friendly behavior.
  - Introduced MDL_context::m_ctx_wakeup_cond condition variable to be
    used for waiting until this context's pending request can be
    satisfied or its thread has to perform actions to resolve potential
    deadlock. Context which want to wait add ticket corresponding to the
    request to an appropriate queue of waiters in MDL_lock object so
    they can be noticed when other contexts change state of lock and be
    awaken by them by signalling on MDL_context::m_ctx_wakeup_cond.
    As consequence MDL_ticket objects has to be used for any waiting
    in metadata locking subsystem including one which happens in
    MDL_context::wait_for_locks() method.
    Another consequence is that MDL_context is no longer copyable and
    can't be saved/restored when working with system tables.
  - Made MDL_lock an abstract class, which delegates specifying exact
    compatibility matrix to its descendants. Added MDL_global_lock child
    class for global lock (The old is_lock_type_compatible() method
    became can_grant_lock() method of this class). Added MDL_object_lock
    class to represent per-object lock (The old MDL_lock::can_grant_lock()
    became its method). Choice between two classes happens based on MDL
    namespace in MDL_lock::create() method.
  - Got rid of MDL_lock::type member as its meaning became ambigous for
    global locks.
  - To simplify waking up of contexts waiting for lock split waiting queue
    in MDL_lock class in two queues. One for pending requests for exclusive
    (including intention exclusive) locks and another for requests for
    shared locks.
  - Added virtual wake_up_waiters() method to MDL_lock, MDL_global_lock and
    MDL_object_lock classes which allows to wake up waiting contexts after
    state of lock changes. Replaced old duplicated code with calls to this
    method.
  - Adjusted MDL_context::try_acquire_shared_lock()/exclusive_lock()/
    global_shared_lock(), MDL_ticket::upgrade_shared_lock_to_exclusive_lock()
    and MDL_context::release_ticket() methods to use MDL_map and
    MDL_lock::m_mutex instead of single LOCK_mdl mutex and wake up
    waiters according to the approach described above. The latter method
    also was renamed to MDL_context::release_lock().
  - Changed MDL_context::try_acquire_shared_lock()/exclusive_lock() and
    release_lock() not to handle global locks. They are now supposed to
    be taken explicitly like ordinary metadata locks.
  - Added helper MDL_context::try_acquire_global_intention_exclusive_lock()
    and acquire_global_intention_exclusive_lock() methods.
  - Moved common code from MDL_context::acquire_global_shared_lock() and
    acquire_global_intention_exclusive_lock() to new method -
    MDL_context::acquire_lock_impl().
  - Moved common code from MDL_context::try_acquire_shared_lock(),
    try_acquire_global_intention_exclusive_lock()/exclusive_lock()
    to MDL_context::try_acquire_lock_impl().
  - Since acquiring of several exclusive locks can no longer happen under
    single LOCK_mdl mutex the approach to it had to be changed. Now we do
    it in one by one fashion. This is done in alphabetical order to avoid
    deadlocks. Changed MDL_context::acquire_exclusive_locks() accordingly
    (as part of this change moved code responsible for acquiring single
    exclusive lock to new MDL_context::acquire_exclusive_lock_impl()
    method).
  - Since we no longer have single LOCK_mdl mutex which protects all
    MDL_context::m_is_waiting_in_mdl members using these members to
    determine if we have really awaken context holding conflicting
    shared lock became inconvinient. Got rid of this member and changed
    notify_shared_lock() helper function and process of acquiring
    of/upgrading to exclusive lock not to rely on such information.
    Now in MDL_context::acquire_exclusive_lock_impl() and
    MDL_ticket::upgrade_shared_lock_to_exclusive_lock() we simply
    re-try to wake up threads holding conflicting shared locks after
    small time out.
  - Adjusted MDL_context::can_wait_lead_to_deadlock() and
    MDL_ticket::has_pending_conflicting_lock() to use per-lock
    mutexes instead of LOCK_mdl. To do this introduced
    MDL_lock::has_pending_exclusive_lock() method.
sql/mdl.h:
  Changed metadata locking subsystem to use mutex per lock and condition
  variable per context instead of one mutex and one conditional variable
  for the whole subsystem. In order to implement this change:

  - Added MDL_key::cmp() method to be able to sort MDL_key objects
    alphabetically. Changed length fields in MDL_key class to uint16
    as 16-bit is enough for length of any key.
  - Changed MDL_ticket::get_ctx() to return pointer to non-const
    object in order to be able to use MDL_context::awake() method
    for such contexts.
  - Got rid of unlocked versions of can_wait_lead_to_deadlock()/
    has_pending_conflicting_lock() methods in MDL_context and
    MDL_ticket. We no longer has single mutex which protects all
    locks. Thus one always has to use versions of these methods
    which acquire per-lock mutexes.
  - MDL_request_list type of list now counts its elements.
  - Added MDL_context::m_ctx_wakeup_cond condition variable to be used
    for waiting until this context's pending request can be satisfied
    or its thread has to perform actions to resolve potential deadlock.
    Added awake() method to wake up context from such wait.
    Addition of condition variable made MDL_context uncopyable.
    As result we no longer can save/restore MDL_context when working
    with system tables. Instead we create MDL savepoint before opening
    those tables and rollback to it once they are closed.
  - MDL_context::release_ticket() became release_lock() method.
  - Added auxiliary MDL_context::acquire_exclusive_lock_impl() method
    which does all necessary work to acquire exclusive lock on one object
    but should not be used directly as it does not enforce any asserts
    ensuring that no deadlocks are possible.
  - Since we no longer need to know if thread trying to acquire exclusive
    lock managed to wake up any threads having conflicting shared locks
    (as, anyway, we will try to wake up such threads again shortly)
  - MDL_context::m_is_waiting_in_mdl member became unnecessary and
    notify_shared_lock() no longer needs to be friend of MDL_context.

  Changed approach to handling of global metadata locks. Instead of
  implicitly acquiring intention exclusive locks when user requests
  per-object upgradeable or exclusive locks now we require them to be
  acquired explicitly in the same way as ordinary metadata locks.

  - Added new GLOBAL namespace for such locks.
  - Added new type of lock to be requested MDL_INTENTION_EXCLISIVE.
  - Added MDL_context::try_acquire_global_intention_exclusive_lock()
    and acquire_global_intention_exclusive_lock() methods.
  - Moved common code from MDL_context::acquire_global_shared_lock()
    and acquire_global_intention_exclusive_lock() to new method -
    MDL_context::acquire_lock_impl().
  - Moved common code from MDL_context::try_acquire_shared_lock(),
    try_acquire_global_intention_exclusive_lock()/exclusive_lock()
    to MDL_context::try_acquire_lock_impl().
  - Added helper MDL_context::is_global_lock_owner() method to be
    able easily to find what kind of global lock this context holds.
  - MDL_context::m_has_global_shared_lock became unnecessary as
    global read lock is now represented by ordinary ticket.
  - Removed assert in MDL_context::set_lt_or_ha_sentinel() which became
    false for cases when we execute LOCK TABLES under global read lock
    mode.
sql/mysql_priv.h:
  Instead of using separate MDL_context for opening system tables we now
  create MDL savepoint in the main context before opening such tables
  and rollback to this savepoint after closing them. To support this
  change methods of THD responsible for saving/restoring open table
  state were changed to use Open_tables_backup class which in addition
  to Open_table_state has a member for this savepoint. As result calls
  opening/closing system tables were changed to use Open_tables_backup
  instead of Open_table_state class as well.
sql/sp.cc:
  Instead of using separate MDL_context for opening system tables we now
  create MDL savepoint in the main context before opening such tables
  and rollback to this savepoint after closing them. To support this
  change methods of THD responsible for saving/restoring open table
  state were changed to use Open_tables_backup class which in addition
  to Open_table_state has a member for this savepoint. As result code
  opening/closing system tables was changed to use Open_tables_backup
  instead of Open_table_state class as well.
sql/sp.h:
  Instead of using separate MDL_context for opening system tables we now
  create MDL savepoint in the main context before opening such tables
  and rollback to this savepoint after closing them. To support this
  change methods of THD responsible for saving/restoring open table
  state were changed to use Open_tables_backup class which in addition
  to Open_table_state has a member for this savepoint. As result code
  opening/closing system tables was changed to use Open_tables_backup
  instead of Open_table_state class as well.
sql/sql_base.cc:
  close_thread_tables():
    Since we no longer use separate MDL_context for opening system
    tables we need to avoid releasing all transaction locks when
    closing system table. Releasing metadata lock on system table
    is now responsibility of THD::restore_backup_open_tables_state().
  open_table_get_mdl_lock(),
  Open_table_context::recover_from_failed_open():
    MDL subsystem no longer implicitly acquires global intention exclusive
    metadata lock when per-object upgradable or exclusive metadata lock is
    acquired. So this have to be done explicitly from these calls.
    Changed Open_table_context class to store MDL_request object for
    global intention exclusive lock acquired when opening tables.
  open_table():
    Do not release metadata lock if we have failed to open table as
    this lock might have been acquired by one of previous statements
    in transaction, and therefore should not be released.
  open_system_tables_for_read()/close_system_tables()/
  open_performance_schema_table():
    Instead of using separate MDL_context for opening system tables we now
    create MDL savepoint in the main context before opening such tables
    and rollback to this savepoint after closing them. To support this
    change methods of THD responsible for saving/restoring open table
    state were changed to use Open_tables_backup class which in addition
    to Open_table_state has a member for this savepoint. As result code
    opening/closing system tables was changed to use Open_tables_backup
    instead of Open_table_state class as well.
  close_performance_schema_table():
    Got rid of duplicated code.
sql/sql_class.cc:
  Instead of using separate MDL_context for opening system tables we now
  create MDL savepoint in the main context before opening such tables
  and rollback to this savepoint after closing them. To support this
  change methods of THD responsible for saving/restoring open table
  state were changed to use Open_tables_backup class which in addition
  to Open_table_state has a member for this savepoint. Also releasing
  metadata lock on system table is now responsibility of
  THD::restore_backup_open_tables_state().
  Adjusted assert in THD::cleanup() to take into account fact that now
  we also use MDL sentinel for global read lock.
sql/sql_class.h:
  Instead of using separate MDL_context for opening system tables we now
  create MDL savepoint in the main context before opening such tables
  and rollback to this savepoint after closing them. As result:
  - 'mdl_context' member was moved out of Open_tables_state to THD class.
    enter_locked_tables_mode()/leave_locked_tables_mode() had to follow.
  - Methods of THD responsible for saving/restoring open table state were
    changed to use Open_tables_backup class which in addition to
    Open_table_state has a member for this savepoint.
  Changed Open_table_context class to store MDL_request object for
  global intention exclusive lock acquired when opening tables.
sql/sql_delete.cc:
  MDL subsystem no longer implicitly acquires global intention exclusive
  metadata lock when per-object exclusive metadata lock is acquired.
  Now this has to be done by explicit calls outside of MDL subsystem.
sql/sql_help.cc:
  Instead of using separate MDL_context for opening system tables we now
  create MDL savepoint in the main context before opening such tables
  and rollback to this savepoint after closing them. To support this
  change methods of THD responsible for saving/restoring open table
  state were changed to use Open_tables_backup class which in addition
  to Open_table_state has a member for this savepoint. As result code
  opening/closing system tables was changed to use Open_tables_backup
  instead of Open_table_state class as well.
sql/sql_parse.cc:
  Adjusted assert reload_acl_and_cache() to the fact that global read
  lock now takes full-blown metadata lock.
sql/sql_plist.h:
  Added support for element counting to I_P_List list template.
  One can use policy classes to specify if such counting is needed
  or not needed for particular list.
sql/sql_show.cc:
  Instead of using separate MDL_context for opening tables for I_S
  purposes we now create MDL savepoint in the main context before
  opening tables and rollback to this savepoint after closing them.
  To support this and similar change for system tables methods of
  THD responsible for saving/restoring open table state were changed
  to use Open_tables_backup class which in addition to Open_table_state
  has a member for this savepoint. As result code opening/closing tables
  for I_S purposes was changed to use Open_tables_backup instead of
  Open_table_state class as well.
sql/sql_table.cc:
  mysql_rm_tables_part2():
    Since now global intention exclusive metadata lock is ordinary
    metadata lock we no longer can rely that by releasing MDL locks
    on all tables we will release all locks acquired by this routine.
    So in non-LOCK-TABLES mode we have to release all locks acquired
    explicitly.
  prepare_for_repair(), mysql_alter_table():
    MDL subsystem no longer implicitly acquires global intention
    exclusive metadata lock when per-object exclusive metadata lock
    is acquired. Now this has to be done by explicit calls outside of
    MDL subsystem.
sql/tztime.cc:
  Instead of using separate MDL_context for opening system tables we now
  create MDL savepoint in the main context before opening such tables
  and rollback to this savepoint after closing them. To support this
  change methods of THD responsible for saving/restoring open table
  state were changed to use Open_tables_backup class which in addition
  to Open_table_state has a member for this savepoint. As result code
  opening/closing system tables was changed to use Open_tables_backup
  instead of Open_table_state class as well.
  Also changed code not to use special mechanism for open system tables
  when it is not really necessary.
---
 mysql-test/r/handler_innodb.result | 34 +++++++++++++++-------------------
 mysql-test/r/handler_myisam.result | 34 +++++++++++++++-------------------
 mysql-test/r/mdl_sync.result       | 18 ++++++++++--------
 3 files changed, 40 insertions(+), 46 deletions(-)

(limited to 'mysql-test/r')

diff --git a/mysql-test/r/handler_innodb.result b/mysql-test/r/handler_innodb.result
index 807e8becea8..a3e3e325e7d 100644
--- a/mysql-test/r/handler_innodb.result
+++ b/mysql-test/r/handler_innodb.result
@@ -560,36 +560,36 @@ c1
 handler t1 close;
 handler t2 close;
 drop table t1,t2;
-drop table if exists t1,t2;
+drop table if exists t1, t0;
 create table t1 (c1 int);
 connection: default
 handler t1 open;
 handler t1 read first;
 c1
 connection: flush
-rename table t1 to t2;;
+rename table t1 to t0;;
 connection: waiter 
 connection: default
 #
 # RENAME placed two pending locks and waits.
-# When HANDLER t2 OPEN does open_tables(), it calls
+# When HANDLER t0 OPEN does open_tables(), it calls
 # mysql_ha_flush(), which in turn closes the open HANDLER for t1.
 # RENAME TABLE gets unblocked. If it gets scheduled quickly
 # and manages to complete before open_tables()
-# of HANDLER t2 OPEN, open_tables() and therefore the whole
-# HANDLER t2 OPEN succeeds. Otherwise open_tables() 
+# of HANDLER t0 OPEN, open_tables() and therefore the whole
+# HANDLER t0 OPEN succeeds. Otherwise open_tables() 
 # notices a pending or active exclusive metadata lock on t2
-# and the whole HANDLER t2 OPEN fails with ER_LOCK_DEADLOCK
+# and the whole HANDLER t0 OPEN fails with ER_LOCK_DEADLOCK
 # error.
 #
-handler t2 open;
-handler t2 close;
+handler t0 open;
+handler t0 close;
 connection: flush
 handler t1 read next;
 ERROR 42S02: Unknown table 't1' in HANDLER
 handler t1 close;
 ERROR 42S02: Unknown table 't1' in HANDLER
-drop table t2;
+drop table t0;
 drop table if exists t1;
 create temporary table t1 (a int, b char(1), key a(a), key b(a,b));
 insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
@@ -989,8 +989,8 @@ handler t1 close;
 #
 create table t1 (a int, key a (a));
 insert into t1 (a) values (1), (2), (3), (4), (5);
-create table t2 (a int, key a (a));
-insert into t2 (a) values (1), (2), (3), (4), (5);
+create table t0 (a int, key a (a));
+insert into t0 (a) values (1), (2), (3), (4), (5);
 begin;
 select * from t1;
 a
@@ -999,23 +999,19 @@ a
 3
 4
 5
-# --> connection con1
-lock table t2 read;
 # --> connection con2 
 # Sending:
-rename table t2 to t3, t1 to t2, t3 to t1;
+rename table t0 to t3, t1 to t0, t3 to t1;
 # --> connection con1 
 # Waiting for 'rename table ...' to get blocked...
 # --> connection default
-handler t2 open;
+handler t0 open;
 ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
-select * from t2;
+select * from t0;
 ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
 handler t1 open;
 commit;
 handler t1 close;
-# --> connection con1
-unlock tables;
 # --> connection con2
 # Reaping 'rename table ...'...
 # --> connection default
@@ -1024,7 +1020,7 @@ handler t1 read a prev;
 a
 5
 handler t1 close;
-drop table t2;
+drop table t0;
 #
 # Originally there was a deadlock error in this test.
 # With implementation of deadlock detector
diff --git a/mysql-test/r/handler_myisam.result b/mysql-test/r/handler_myisam.result
index adcbf068b97..f5c5bfebd15 100644
--- a/mysql-test/r/handler_myisam.result
+++ b/mysql-test/r/handler_myisam.result
@@ -559,36 +559,36 @@ c1
 handler t1 close;
 handler t2 close;
 drop table t1,t2;
-drop table if exists t1,t2;
+drop table if exists t1, t0;
 create table t1 (c1 int);
 connection: default
 handler t1 open;
 handler t1 read first;
 c1
 connection: flush
-rename table t1 to t2;;
+rename table t1 to t0;;
 connection: waiter 
 connection: default
 #
 # RENAME placed two pending locks and waits.
-# When HANDLER t2 OPEN does open_tables(), it calls
+# When HANDLER t0 OPEN does open_tables(), it calls
 # mysql_ha_flush(), which in turn closes the open HANDLER for t1.
 # RENAME TABLE gets unblocked. If it gets scheduled quickly
 # and manages to complete before open_tables()
-# of HANDLER t2 OPEN, open_tables() and therefore the whole
-# HANDLER t2 OPEN succeeds. Otherwise open_tables() 
+# of HANDLER t0 OPEN, open_tables() and therefore the whole
+# HANDLER t0 OPEN succeeds. Otherwise open_tables() 
 # notices a pending or active exclusive metadata lock on t2
-# and the whole HANDLER t2 OPEN fails with ER_LOCK_DEADLOCK
+# and the whole HANDLER t0 OPEN fails with ER_LOCK_DEADLOCK
 # error.
 #
-handler t2 open;
-handler t2 close;
+handler t0 open;
+handler t0 close;
 connection: flush
 handler t1 read next;
 ERROR 42S02: Unknown table 't1' in HANDLER
 handler t1 close;
 ERROR 42S02: Unknown table 't1' in HANDLER
-drop table t2;
+drop table t0;
 drop table if exists t1;
 create temporary table t1 (a int, b char(1), key a(a), key b(a,b));
 insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"),
@@ -986,8 +986,8 @@ handler t1 close;
 #
 create table t1 (a int, key a (a));
 insert into t1 (a) values (1), (2), (3), (4), (5);
-create table t2 (a int, key a (a));
-insert into t2 (a) values (1), (2), (3), (4), (5);
+create table t0 (a int, key a (a));
+insert into t0 (a) values (1), (2), (3), (4), (5);
 begin;
 select * from t1;
 a
@@ -996,23 +996,19 @@ a
 3
 4
 5
-# --> connection con1
-lock table t2 read;
 # --> connection con2 
 # Sending:
-rename table t2 to t3, t1 to t2, t3 to t1;
+rename table t0 to t3, t1 to t0, t3 to t1;
 # --> connection con1 
 # Waiting for 'rename table ...' to get blocked...
 # --> connection default
-handler t2 open;
+handler t0 open;
 ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
-select * from t2;
+select * from t0;
 ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
 handler t1 open;
 commit;
 handler t1 close;
-# --> connection con1
-unlock tables;
 # --> connection con2
 # Reaping 'rename table ...'...
 # --> connection default
@@ -1021,7 +1017,7 @@ handler t1 read a prev;
 a
 5
 handler t1 close;
-drop table t2;
+drop table t0;
 #
 # Originally there was a deadlock error in this test.
 # With implementation of deadlock detector
diff --git a/mysql-test/r/mdl_sync.result b/mysql-test/r/mdl_sync.result
index 0c9b6432e95..8c4d7272e29 100644
--- a/mysql-test/r/mdl_sync.result
+++ b/mysql-test/r/mdl_sync.result
@@ -23,7 +23,7 @@ SET DEBUG_SYNC= 'RESET';
 # Test coverage for basic deadlock detection in metadata
 # locking subsystem.
 #
-drop tables if exists t1, t2, t3, t4;
+drop tables if exists t0, t1, t2, t3, t4, t5;
 create table t1 (i int);
 create table t2 (j int);
 create table t3 (k int);
@@ -90,7 +90,7 @@ commit;
 #
 # Switching to connection 'deadlock_con1'.
 begin;
-insert into t1 values (2);
+insert into t2 values (2);
 #
 # Switching to connection 'default'.
 # Send:
@@ -98,11 +98,11 @@ rename table t2 to t0, t1 to t2, t0 to t1;;
 #
 # Switching to connection 'deadlock_con1'.
 # Wait until the above RENAME TABLE is blocked because it has to wait
-# for 'deadlock_con1' which holds shared metadata lock on 't1'.
+# for 'deadlock_con1' which holds shared metadata lock on 't2'.
 # 
 # The below statement should not wait as doing so will cause deadlock.
 # Instead it should fail and emit ER_LOCK_DEADLOCK statement.
-select * from t2;
+select * from t1;
 ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
 #
 # Let us check that failure of the above statement has not released
@@ -141,7 +141,7 @@ select * from t2;;
 # for an exclusive metadata lock to go away.
 # Send RENAME TABLE statement that will deadlock with the
 # SELECT statement and thus should abort the latter.
-rename table t1 to t0, t2 to t1, t0 to t2;;
+rename table t1 to t5, t2 to t1, t5 to t2;;
 #
 # Switching to connection 'deadlock_con1'.
 # Since the latest RENAME TABLE entered in deadlock with SELECT
@@ -156,15 +156,17 @@ ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
 # Commit transaction to unblock this RENAME TABLE.
 commit;
 #
-# Switching to connection 'deadlock_con3'.
-# Reap RENAME TABLE t1 TO t0 ... .
-#
 # Switching to connection 'deadlock_con2'.
 # Commit transaction to unblock the first RENAME TABLE.
 commit;
 #
 # Switching to connection 'default'.
 # Reap RENAME TABLE t2 TO t0 ... .
+#
+# Switching to connection 'deadlock_con3'.
+# Reap RENAME TABLE t1 TO t5 ... .
+#
+# Switching to connection 'default'.
 drop tables t1, t2, t3, t4;
 #
 # Now, test case which shows that deadlock detection empiric
-- 
cgit v1.2.1