1
0
mirror of https://github.com/MariaDB/server.git synced 2025-09-02 09:41:40 +03:00

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.
This commit is contained in:
Dmitry Lenev
2010-01-21 23:43:03 +03:00
parent c005126107
commit a63f8480db
24 changed files with 1595 additions and 848 deletions

View File

@@ -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