mirror of
https://github.com/MariaDB/server.git
synced 2025-08-29 00:08:14 +03:00
This was a deadlock between LOCK TABLES/CREATE DATABASE in one connection and DROP DATABASE in another. It only happened if the table locked by LOCK TABLES was in the database to be dropped. The deadlock is similar to the one in Bug#48940, but with LOCK TABLES instead of an active transaction. The order of events needed to trigger the deadlock was: 1) Connection 1 locks table db1.t1 using LOCK TABLES. It will now have a metadata lock on the table name. 2) Connection 2 issues DROP DATABASE db1. This will wait inside the MDL subsystem for the lock on db1.t1 to go away. While waiting, it will hold the LOCK_mysql_create_db mutex. 3) Connection 1 issues CREATE DATABASE (database name irrelevant). This will hang trying to lock the same mutex. Since this is the connection holding the metadata lock blocking Connection 2, we have a deadlock. This deadlock would also happen for earlier trees without MDL, but there DROP DATABASE would wait for a table to be removed from the table definition cache. This patch fixes the problem by prohibiting CREATE DATABASE in LOCK TABLES mode. In the example above, this prevents Connection 1 from hanging trying to get the LOCK_mysql_create_db mutex. Note that other commands that use LOCK_mysql_create_db (ALTER/DROP DATABASE) are already prohibited in LOCK TABLES mode. Incompatible change: CREATE DATABASE is now disallowed in LOCK TABLES mode. Test case added to schema.test.
158 lines
4.4 KiB
Plaintext
158 lines
4.4 KiB
Plaintext
drop table if exists t1;
|
|
drop database if exists mysqltest;
|
|
drop database if exists client_test_db;
|
|
drop table t1;
|
|
ERROR 42S02: Unknown table 't1'
|
|
create table t1(n int);
|
|
insert into t1 values(1);
|
|
create temporary table t1( n int);
|
|
insert into t1 values(2);
|
|
create table t1(n int);
|
|
ERROR 42S01: Table 't1' already exists
|
|
drop table t1;
|
|
select * from t1;
|
|
n
|
|
1
|
|
create database mysqltest;
|
|
drop database if exists mysqltest;
|
|
create database mysqltest;
|
|
create table mysqltest.mysqltest (n int);
|
|
insert into mysqltest.mysqltest values (4);
|
|
select * from mysqltest.mysqltest;
|
|
n
|
|
4
|
|
drop database if exists mysqltest;
|
|
affected rows: 1
|
|
create database mysqltest;
|
|
use mysqltest;
|
|
drop table table1, table2, table3, table4, table5, table6,
|
|
table7, table8, table9, table10, table11, table12, table13,
|
|
table14, table15, table16, table17, table18, table19, table20,
|
|
table21, table22, table23, table24, table25, table26, table27,
|
|
table28;
|
|
ERROR 42S02: Unknown table 'table1,table2,table3,table4,table5,table6,table7,table8,table9,table10,table11,table12,table13,table'
|
|
drop table table1, table2, table3, table4, table5, table6,
|
|
table7, table8, table9, table10, table11, table12, table13,
|
|
table14, table15, table16, table17, table18, table19, table20,
|
|
table21, table22, table23, table24, table25, table26, table27,
|
|
table28, table29, table30;
|
|
ERROR 42S02: Unknown table 'table1,table2,table3,table4,table5,table6,table7,table8,table9,table10,table11,table12,table13,table'
|
|
use test;
|
|
drop database mysqltest;
|
|
flush tables with read lock;
|
|
create database mysqltest;
|
|
Got one of the listed errors
|
|
unlock tables;
|
|
create database mysqltest;
|
|
show databases;
|
|
Database
|
|
information_schema
|
|
mtr
|
|
mysql
|
|
mysqltest
|
|
test
|
|
flush tables with read lock;
|
|
drop database mysqltest;
|
|
Got one of the listed errors
|
|
unlock tables;
|
|
drop database mysqltest;
|
|
show databases;
|
|
Database
|
|
information_schema
|
|
mtr
|
|
mysql
|
|
test
|
|
drop database mysqltest;
|
|
ERROR HY000: Can't drop database 'mysqltest'; database doesn't exist
|
|
drop table t1;
|
|
flush tables with read lock;
|
|
create table t1(n int);
|
|
ERROR HY000: Can't execute the query because you have a conflicting read lock
|
|
unlock tables;
|
|
create table t1(n int);
|
|
show tables;
|
|
Tables_in_test
|
|
t1
|
|
drop table t1;
|
|
drop database if exists mysqltest;
|
|
drop table if exists t1;
|
|
create table t1 (i int);
|
|
create database mysqltest;
|
|
lock tables t1 read;
|
|
drop table t1;
|
|
show open tables;
|
|
drop database mysqltest;
|
|
select 1;
|
|
1
|
|
1
|
|
unlock tables;
|
|
drop table if exists t1,t2;
|
|
create table t1 (a int);
|
|
create table t2 (a int);
|
|
lock table t1 read;
|
|
drop table t2;
|
|
ERROR HY000: Table 't2' was not locked with LOCK TABLES
|
|
drop table t1;
|
|
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
|
|
unlock tables;
|
|
drop table t1,t2;
|
|
create table t1 (i int);
|
|
create table t2 (i int);
|
|
lock tables t1 read;
|
|
lock tables t2 read;
|
|
drop table t1;
|
|
ERROR HY000: Table 't1' was not locked with LOCK TABLES
|
|
drop table t1,t2;
|
|
ERROR HY000: Table 't1' was locked with a READ lock and can't be updated
|
|
unlock tables;
|
|
drop table t1,t2;
|
|
End of 5.0 tests
|
|
create database mysql_test;
|
|
create table mysql_test.t1(f1 int);
|
|
create table mysql_test.`#sql-347f_7` (f1 int);
|
|
create table mysql_test.`#sql-347f_8` (f1 int);
|
|
drop table mysql_test.`#sql-347f_8`;
|
|
drop database mysql_test;
|
|
|
|
# --
|
|
# -- Bug#29958: Weird message on DROP DATABASE if mysql.proc does not
|
|
# -- exist.
|
|
# --
|
|
DROP DATABASE IF EXISTS mysql_test;
|
|
CREATE DATABASE mysql_test;
|
|
DROP TABLE mysql.proc;
|
|
DROP DATABASE mysql_test;
|
|
Warnings:
|
|
Error 1146 Table 'mysql.proc' doesn't exist
|
|
|
|
# --
|
|
# -- End of Bug#29958.
|
|
# --
|
|
|
|
create database mysqltestbug26703;
|
|
use mysqltestbug26703;
|
|
create table `#mysql50#abc``def` ( id int );
|
|
create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
|
|
ERROR 42000: Incorrect table name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
|
|
create table `aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
|
|
create table `#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
|
|
create table `#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa` (a int);
|
|
ERROR 42000: Incorrect table name '#mysql50#aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'
|
|
use test;
|
|
drop database mysqltestbug26703;
|
|
End of 5.1 tests
|
|
|
|
# --
|
|
# -- Bug#37431 (DROP TABLE does not report errors correctly).
|
|
# --
|
|
DROP TABLE IF EXISTS t1;
|
|
DROP TABLE t1;
|
|
ERROR 42S02: Unknown table 't1'
|
|
SHOW WARNINGS;
|
|
Level Code Message
|
|
Error 1051 Unknown table 't1'
|
|
|
|
# --
|
|
# -- End of Bug#37431.
|
|
# --
|