1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Fix for bug #50913 "Deadlock between open_and_lock_tables_derived

and MDL".

Concurrent execution of a multi-DELETE statement and ALTER
TABLE statement which affected one of the tables used in
the multi-DELETE sometimes led to deadlock.
Similar deadlocks might have occured when one performed
INSERT/UPDATE/DELETE on a view and concurrently executed
ALTER TABLE for the view's underlying table, or when one
concurrently executed TRUNCATE TABLE for InnoDB table and
ALTER TABLE for the same table.

These deadlocks were caused by a discrepancy between types of
metadata and thr_lock.cc locks acquired by those statements.

What happened was that multi-DELETE/TRUNCATE/DML-through-the-
view statement in the first connection acquired SR lock on a
table, then ALTER TABLE would come in in the second connection
and acquire SNW metadata lock and TL_WRITE_ALLOW_READ
thr_lock.c lock and then would start waiting for the first
connection during lock upgrade. After that the statement in
the first connection would try to acquire TL_WRITE lock on
table and would start waiting for the second connection,
creating a deadlock.

This patch solves this problem by ensuring that we acquire
SW metadata lock in all cases in which we acquiring write
thr_lock.c lock. This guarantees that deadlocks like the
one described above won't occur since all lock conflicts
in such situation are resolved within MDL subsystem.

This patch also adds assert which should guarantee that
such situations won't arise in future.
This commit is contained in:
Dmitry Lenev
2010-02-08 23:19:55 +03:00
parent f750b5f160
commit c7e7a7d20c
13 changed files with 256 additions and 3 deletions

View File

@ -302,3 +302,49 @@ LOCK TABLES t1 WRITE;
FLUSH TABLE t1;
DROP TABLE t1;
DROP VIEW v1;
#
# Test for bug #50913 "Deadlock between open_and_lock_tables_derived
# and MDL". Also see additional coverage in mdl_sync.test.
#
drop table if exists t1;
drop view if exists v1;
create table t1 (i int);
create view v1 as select i from t1;
begin;
select * from t1;
i
# Switching to connection 'con50913'.
# Sending:
alter table t1 add column j int;
# Switching to connection 'default'.
# Wait until ALTER TABLE gets blocked.
# The below statement should try to acquire SW lock on 't1'
# and therefore should get ER_LOCK_DEADLOCK error. Before
# bug fix it acquired SR lock and hung on thr_lock.c lock.
delete a from t1 as a where i = 1;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
# Unblock ALTER TABLE.
commit;
# Switching to connection 'con50913'.
# Reaping ALTER TABLE;
# Switching to connection 'default'.
begin;
select * from v1;
i
# Switching to connection 'con50913'.
# Sending:
alter table t1 drop column j;
# Switching to connection 'default'.
# Wait until ALTER TABLE gets blocked.
# The below statement should try to acquire SW lock on 't1'
# and therefore should get ER_LOCK_DEADLOCK error. Before
# bug fix it acquired SR lock and hung on thr_lock.c lock.
insert into v1 values (1);
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
# Unblock ALTER TABLE.
commit;
# Switching to connection 'con50913'.
# Reaping ALTER TABLE;
# Switching to connection 'default'.
drop view v1;
drop table t1;