diff options
author | Michael Widenius <monty@askmonty.org> | 2013-07-02 20:43:35 +0300 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2013-07-02 20:43:35 +0300 |
commit | 99aae21ed25b42ee3cf62815ecfc8204de8b6fd0 (patch) | |
tree | ac9a51c525b3ad668a7c8dbde44e34e14771c512 | |
parent | b7b2a7ce81bf9d1bbcac9e0b3b0b19e271f2c276 (diff) | |
download | mariadb-git-99aae21ed25b42ee3cf62815ecfc8204de8b6fd0.tar.gz |
mdl_sync now works.
mysql-test/r/mdl_sync.result:
Full merge with 5.6
mysql-test/t/mdl_sync.test:
Full merge with 5.6
sql/debug_sync.cc:
Full merge with 5.6
sql/debug_sync.h:
Full merge with 5.6
sql/mdl.cc:
Full merge with 5.6
sql/sql_base.cc:
Removed code not in 5.6 anymore
-rw-r--r-- | mysql-test/r/ctype_utf8.result | 2 | ||||
-rw-r--r-- | mysql-test/r/ctype_utf8mb4.result | 2 | ||||
-rw-r--r-- | mysql-test/r/ctype_utf8mb4_innodb.result | 2 | ||||
-rw-r--r-- | mysql-test/r/mdl_sync.result | 233 | ||||
-rw-r--r-- | mysql-test/t/mdl_sync.test | 319 | ||||
-rw-r--r-- | sql/debug_sync.cc | 24 | ||||
-rw-r--r-- | sql/debug_sync.h | 3 | ||||
-rw-r--r-- | sql/mdl.cc | 11 | ||||
-rw-r--r-- | sql/sql_base.cc | 15 | ||||
-rw-r--r-- | sql/sql_table.cc | 24 | ||||
-rw-r--r-- | sql/table.cc | 7 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 2 | ||||
-rw-r--r-- | storage/myisammrg/ha_myisammrg.cc | 4 |
13 files changed, 529 insertions, 119 deletions
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index d25c454913d..714b4183594 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -1229,7 +1229,7 @@ DROP TABLE t1; SET NAMES utf8; DROP TABLE IF EXISTS t1; Warnings: -Note 1051 Unknown table 't1' +Note 1051 Unknown table 'test.t1' CREATE TABLE t1(a VARCHAR(255), KEY(a)) ENGINE=MyISAM DEFAULT CHARSET=utf8; INSERT INTO t1 VALUES('uuABCDEFGHIGKLMNOPRSTUVWXYZ̈bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb'); INSERT INTO t1 VALUES('uu'); diff --git a/mysql-test/r/ctype_utf8mb4.result b/mysql-test/r/ctype_utf8mb4.result index e20d58b0a93..c87ec5ce44a 100644 --- a/mysql-test/r/ctype_utf8mb4.result +++ b/mysql-test/r/ctype_utf8mb4.result @@ -1256,7 +1256,7 @@ DROP TABLE t1; SET NAMES utf8mb4; DROP TABLE IF EXISTS t1; Warnings: -Note 1051 Unknown table 't1' +Note 1051 Unknown table 'test.t1' CREATE TABLE t1(a VARCHAR(255), KEY(a)) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4; Warnings: Warning 1071 Specified key was too long; max key length is 1000 bytes diff --git a/mysql-test/r/ctype_utf8mb4_innodb.result b/mysql-test/r/ctype_utf8mb4_innodb.result index 2db7066d478..b0e5bcef176 100644 --- a/mysql-test/r/ctype_utf8mb4_innodb.result +++ b/mysql-test/r/ctype_utf8mb4_innodb.result @@ -1231,7 +1231,7 @@ DROP TABLE t1; SET NAMES utf8mb4; DROP TABLE IF EXISTS t1; Warnings: -Note 1051 Unknown table 't1' +Note 1051 Unknown table 'test.t1' CREATE TABLE t1(a VARCHAR(255), KEY(a)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; Warnings: Warning 1071 Specified key was too long; max key length is 767 bytes diff --git a/mysql-test/r/mdl_sync.result b/mysql-test/r/mdl_sync.result index b2e71faf741..0d4d1232281 100644 --- a/mysql-test/r/mdl_sync.result +++ b/mysql-test/r/mdl_sync.result @@ -5,7 +5,7 @@ create table t2 (i int); connection: default lock tables t2 read; connection: con1 -set debug_sync='mdl_upgrade_shared_lock_to_exclusive SIGNAL parked WAIT_FOR go'; +set debug_sync='mdl_upgrade_lock SIGNAL parked WAIT_FOR go'; alter table t1 rename t3; connection: default set debug_sync= 'now WAIT_FOR parked'; @@ -16,7 +16,7 @@ connection: con1 connection: default unlock tables; connection: con2 -ERROR 42S02: Unknown table 't1' +ERROR 42S02: Unknown table 'test.t1' drop table t3; SET DEBUG_SYNC= 'RESET'; # @@ -48,8 +48,13 @@ select count(*) from t1; count(*) 0 insert into t1 values (1), (1); +# Check that SU lock is compatible with it. To do this use ALTER TABLE +# which will fail when constructing .frm and thus obtaining SU metadata +# lock. +alter table t1 add index (not_exist); +ERROR 42000: Key column 'not_exist' doesn't exist in table # Check that SNW lock is compatible with it. To do this use ALTER TABLE -# which will fail after opening the table and thus obtaining SNW metadata +# which will fail during copying the table and thus obtaining SNW metadata # lock. alter table t1 add primary key (c1); ERROR 23000: Duplicate entry '1' for key 'PRIMARY' @@ -139,8 +144,13 @@ select count(*) from t1; count(*) 3 insert into t1 values (1); +# Check that SU lock is compatible with it. To do this use ALTER TABLE +# which will fail when constructing .frm and thus obtaining SU metadata +# lock. +alter table t1 add index (not_exist); +ERROR 42000: Key column 'not_exist' doesn't exist in table # Check that SNW lock is compatible with it. To do this use ALTER TABLE -# which will fail after opening the table and thus obtaining SNW metadata +# which will fail during copying the table and thus obtaining SNW metadata # lock. alter table t1 add primary key (c1); ERROR 23000: Duplicate entry '1' for key 'PRIMARY' @@ -244,8 +254,13 @@ select count(*) from t1; count(*) 3 insert into t1 values (1); +# Check that SU lock is compatible with it. To do this use ALTER TABLE +# which will fail when constructing .frm and thus obtaining SU metadata +# lock. +alter table t1 add index (not_exist); +ERROR 42000: Key column 'not_exist' doesn't exist in table # Check that SNW lock is compatible with it. To do this use ALTER TABLE -# which will fail after opening the table and thus obtaining SNW metadata +# which will fail during copying the table and thus obtaining SNW metadata # lock. alter table t1 add primary key (c1); ERROR 23000: Duplicate entry '1' for key 'PRIMARY' @@ -334,8 +349,13 @@ c1 # effects of concurrent insert. select * from t1; insert into t1 values (1); +# Check that SU lock is compatible with it. To do this use ALTER TABLE +# which will fail when constructing .frm and thus obtaining SU metadata +# lock. +alter table t1 add index (not_exist); +ERROR 42000: Key column 'not_exist' doesn't exist in table # Check that SNW lock is not compatible with SW lock. -# Again we use ALTER TABLE which fails after opening +# Again we use ALTER TABLE which fails during copying # the table to avoid upgrade of SNW -> X. # Sending: alter table t1 add primary key (c1);; @@ -397,15 +417,111 @@ rename table t2 to t1; # Switching to connection 'default'. # # -# 5) Acquire SNW lock on the table. We have to use DEBUG_SYNC for -# this, to prevent SNW from being immediately upgraded to X. +# 5) Acquire SU lock on the table. We have to use DEBUG_SYNC for +# this, to prevent SU from being immediately upgraded to X. # -set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish'; +set debug_sync= 'alter_opened_table SIGNAL locked WAIT_FOR finish'; +# Sending: +alter table t1 add primary key (c1);; +# +# Switching to connection 'mdl_con1'. +set debug_sync= 'now WAIT_FOR locked'; +# Check that S, SH, SR and SW locks are compatible with it. +handler t1 open; +handler t1 close; +select column_name from information_schema.columns where +table_schema='test' and table_name='t1'; +column_name +c1 +select count(*) from t1; +count(*) +5 +delete from t1 limit 1; +# Check that SU lock is incompatible with SU lock. +# Sending: +alter table t1 add primary key (c1);; +# +# Switching to connection 'mdl_con2'. +# Check that the above ALTER is blocked because of SU lock. +# Unblock ALTERs. +set debug_sync= 'now SIGNAL finish'; +# +# Switching to connection 'default'. +# Reaping first ALTER TABLE. +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +# +# Switching to connection 'mdl_con1'. +# Reaping another ALTER TABLE. +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +# +# Switching to connection 'default'. +set debug_sync= 'alter_opened_table SIGNAL locked WAIT_FOR finish'; # Sending: alter table t1 add primary key (c1);; # # Switching to connection 'mdl_con1'. set debug_sync= 'now WAIT_FOR locked'; +# Check that SNRW lock is incompatible with SU lock. +# Sending: +lock table t1 write;; +# +# Switching to connection 'mdl_con2'. +# Check that the above LOCK TABLES is blocked because of SU lock. +# Unblock ALTER and thus LOCK TABLES. +set debug_sync= 'now SIGNAL finish'; +# +# Switching to connection 'default'. +# Reaping ALTER TABLE. +ERROR 23000: Duplicate entry '1' for key 'PRIMARY' +# +# Switching to connection 'mdl_con1'. +# Reaping LOCK TABLES +insert into t1 values (1); +unlock tables; +# +# Switching to connection 'default'. +set debug_sync= 'alter_opened_table SIGNAL locked WAIT_FOR finish'; +# Sending: +alter table t1 add primary key (c1);; +# +# Switching to connection 'mdl_con1'. +set debug_sync= 'now WAIT_FOR locked'; +# Check that X lock is incompatible with SU lock. +# Sending: +rename table t1 to t2;; +# +# Switching to connection 'mdl_con2'. +# Check that the above RENAME is blocked because of SU lock. +# Unblock ALTER and thus RENAME TABLE. +set debug_sync= 'now SIGNAL finish'; +# +# Switching to connection 'default'. +# Now we have ALTER TABLE with SU->SNW and RENAME TABLE with pending +# X-lock. In this case ALTER TABLE should be chosen as victim. +# Reaping ALTER TABLE. +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +# +# Switching to connection 'mdl_con1'. +# Reaping RENAME TABLE +# Revert back to original state of things. +rename table t2 to t1; +# +# There is no need to check that upgrade from SNW/SNRW to X is +# blocked by presence of another SU lock because SNW/SNRW is +# incompatible with SU anyway. +# +# Switching to connection 'default'. +# +# +# 6) Acquire SNW lock on the table. We have to use DEBUG_SYNC for +# this, to prevent SNW from being immediately upgraded to X. +# +set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish'; +# Sending: +alter table t1 add primary key (c1), lock=shared, algorithm=copy;; +# +# Switching to connection 'mdl_con1'. +set debug_sync= 'now WAIT_FOR locked'; # Check that S, SH and SR locks are compatible with it. handler t1 open; handler t1 close; @@ -433,13 +549,13 @@ ERROR 23000: Duplicate entry '1' for key 'PRIMARY' # Reaping DELETE. # # Switching to connection 'default'. -set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish'; +set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish'; # Sending: -alter table t1 add primary key (c1);; +alter table t1 add primary key (c1), lock=shared, algorithm=copy;; # # Switching to connection 'mdl_con1'. set debug_sync= 'now WAIT_FOR locked'; -# Check that SNW lock is incompatible with SNW lock. +# Check that SU lock is incompatible with SNW lock. # Sending: alter table t1 add primary key (c1);; # @@ -456,10 +572,14 @@ ERROR 23000: Duplicate entry '1' for key 'PRIMARY' # Reaping another ALTER TABLE. ERROR 23000: Duplicate entry '1' for key 'PRIMARY' # +# Note that we can't easily check SNW vs SNW locks since +# SNW is only used by ALTER TABLE after upgrading from SU +# and SU is also incompatible with SNW. +# # Switching to connection 'default'. -set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish'; +set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish'; # Sending: -alter table t1 add primary key (c1);; +alter table t1 add primary key (c1), lock=shared, algorithm=copy;; # # Switching to connection 'mdl_con1'. set debug_sync= 'now WAIT_FOR locked'; @@ -482,9 +602,9 @@ insert into t1 values (1); unlock tables; # # Switching to connection 'default'. -set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish'; +set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish'; # Sending: -alter table t1 add primary key (c1);; +alter table t1 add primary key (c1), algorithm=copy, lock=shared;; # # Switching to connection 'mdl_con1'. set debug_sync= 'now WAIT_FOR locked'; @@ -513,7 +633,7 @@ rename table t2 to t1; # Switching to connection 'default'. # # -# 6) Acquire SNRW lock on the table. +# 7) Acquire SNRW lock on the table. # # lock table t1 write; @@ -560,12 +680,12 @@ unlock tables; lock table t1 write; # # Switching to connection 'mdl_con1'. -# Check that SNW lock is incompatible with SNRW lock. +# Check that SU lock is incompatible with SNRW lock. # Sending: alter table t1 add primary key (c1);; # # Switching to connection 'default'. -# Check that the above ALTER is blocked because of UNWR lock. +# Check that the above ALTER is blocked because of SNRW lock. # Unblock ALTER. unlock tables; # @@ -573,6 +693,10 @@ unlock tables; # Reaping ALTER TABLE. ERROR 23000: Duplicate entry '1' for key 'PRIMARY' # +# Note that we can't easily check SNW vs SNRW locks since +# SNW is only used by ALTER TABLE after upgrading from SU +# and SU is also incompatible with SNRW. +# # Switching to connection 'default'. lock table t1 write; # @@ -616,7 +740,7 @@ rename table t2 to t1; # Switching to connection 'default'. # # -# 7) Now do the same round of tests for X lock. We use additional +# 8) Now do the same round of tests for X lock. We use additional # table to get long-lived lock of this type. # create table t2 (c1 int); @@ -744,7 +868,7 @@ rename table t1 to t2;; # # Switching to connection 'mdl_con1'. # Check that RENAME has acquired X lock on t1 and is waiting for t2. -# Check that SNW lock is incompatible with X lock. +# Check that SU lock is incompatible with X lock. # Sending: alter table t1 add primary key (c1);; # @@ -761,7 +885,11 @@ ERROR 42S01: Table 't2' already exists # Switching to connection 'mdl_con1'. # Reaping ALTER. ERROR 23000: Duplicate entry '1' for key 'PRIMARY' -# +# +# Note that we can't easily check SNW vs X locks since +# SNW is only used by ALTER TABLE after upgrading from SU +# and SU is also incompatible with X. +# # Switching to connection 'mdl_con2'. # Prepare for blocking RENAME TABLE. lock tables t2 read; @@ -822,6 +950,9 @@ rename table t3 to t1; # are pending. I.e. let us test rules for priorities between # different types of metadata locks. # +# Note: No tests for pending SU lock as this lock requires +# even stronger active or pending lock. +# # # Switching to connection 'mdl_con2'. # @@ -1138,6 +1269,9 @@ unlock tables; # transactional context. Obviously we are mostly interested # in conflicting types of locks. # +# Note: No tests for active/pending SU lock since +# ALTER TABLE is in its own transaction. +# # # 1) Let us check how various locks used within transactional # context interact with active/pending SNW lock. @@ -1154,9 +1288,9 @@ count(*) # We have to use DEBUG_SYNC facility as otherwise SNW lock # will be immediately released (or upgraded to X lock). insert into t2 values (1), (1); -set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish'; +set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish'; # Sending: -alter table t2 add primary key (c1);; +alter table t2 add primary key (c1), algorithm=copy, lock=shared;; # # Switching to connection 'default'. set debug_sync= 'now WAIT_FOR locked'; @@ -1199,9 +1333,9 @@ count(*) # # Switching to connection 'mdl_con1'. # Create an active SNW lock on t1. -set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish'; +set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish'; # Sending: -alter table t1 add primary key (c1);; +alter table t1 add primary key (c1), algorithm=copy, lock=shared;; # # Switching to connection 'default'. set debug_sync= 'now WAIT_FOR locked'; @@ -1986,7 +2120,7 @@ drop tables t1, t2; # create table t1 (i int); # Ensure that ALTER waits once it has acquired SNW lock. -set debug_sync='after_open_table_mdl_shared SIGNAL parked1 WAIT_FOR go1'; +set debug_sync='alter_table_copy_after_lock_upgrade SIGNAL parked1 WAIT_FOR go1'; # Sending: alter table t1 add column j int; # @@ -2293,13 +2427,18 @@ set global log_output=@save_log_output; # drop tables if exists t1, t2; create table t1 (i int); +insert into t1 values(1); # Let us check that we won't deadlock if during filling # of I_S table we encounter conflicting metadata lock # which owner is in its turn waiting for our connection. lock tables t1 read; +# Switching to connection 'con46044_2'. +# Sending: +update t1 set i = 2; # Switching to connection 'con46044'. +# Waiting until UPDATE t1 SET ... is blocked. # Sending: -create table t2 select * from t1 for update;; +create table t2 select * from t1;; # Switching to connection 'default'. # Waiting until CREATE TABLE ... SELECT ... is blocked. # First let us check that SHOW FIELDS/DESCRIBE doesn't @@ -2329,6 +2468,7 @@ unlock tables; # Switching to connection 'con46044'. # Reaping CREATE TABLE ... SELECT ... . drop table t2; +# Reaping UPDATE t1 statement # # Let us also check that queries to I_S wait for conflicting metadata # locks to go away instead of skipping table with a warning in cases @@ -2338,9 +2478,13 @@ drop table t2; # We check same three queries to I_S in this new situation. # Switching to connection 'con46044_2'. lock tables t1 read; +# Switching to connection 'con46044_3'. +# Sending: +update t1 set i = 3; # Switching to connection 'con46044'. +# Waiting until UPDATE t1 SET ... is blocked. # Sending: -create table t2 select * from t1 for update;; +create table t2 select * from t1;; # Switching to connection 'default'. # Waiting until CREATE TABLE ... SELECT ... is blocked. # Let us check that SHOW FIELDS/DESCRIBE gets blocked. @@ -2356,11 +2500,16 @@ unlock tables; Field Type Null Key Default Extra i int(11) YES NULL drop table t2; +# Reaping UPDATE t1 statement # Switching to connection 'con46044_2'. lock tables t1 read; +# Switching to connection 'con46044_3'. +# Sending: +update t1 set i = 4; # Switching to connection 'con46044'. +# Waiting until UPDATE t1 SET ... is blocked. # Sending: -create table t2 select * from t1 for update;; +create table t2 select * from t1;; # Switching to connection 'default'. # Waiting until CREATE TABLE ... SELECT ... is blocked. # Check that I_S query which reads only .FRMs gets blocked. @@ -2376,11 +2525,16 @@ unlock tables; column_name i drop table t2; +# Reaping UPDATE t1 statement # Switching to connection 'con46044_2'. lock tables t1 read; +# Switching to connection 'con46044_3'. +# Sending: +update t1 set i = 5; # Switching to connection 'con46044'. +# Waiting until UPDATE t1 SET ... is blocked. # Sending: -create table t2 select * from t1 for update;; +create table t2 select * from t1;; # Switching to connection 'default'. # Waiting until CREATE TABLE ... SELECT ... is blocked. # Finally, check that I_S query which does full-blown table open @@ -2397,6 +2551,7 @@ unlock tables; table_name table_type auto_increment table_comment t2 BASE TABLE NULL drop table t2; +# Reaping UPDATE t1 statement # Switching to connection 'default'. # Clean-up. drop table t1; @@ -2414,7 +2569,7 @@ c1 c2 c3 3 3 0 # # Switching to connection 'con46273'. -set debug_sync='after_lock_tables_takes_lock SIGNAL alter_table_locked WAIT_FOR alter_go'; +set debug_sync='alter_table_copy_after_lock_upgrade SIGNAL alter_table_locked WAIT_FOR alter_go'; alter table t1 add column e int, rename to t2;; # # Switching to connection 'default'. @@ -2558,9 +2713,9 @@ drop table if exists t1; set debug_sync= 'RESET'; create table t1 (i int) engine=InnoDB; # Switching to connection 'con50913_1'. -set debug_sync= 'thr_multi_lock_after_thr_lock SIGNAL parked WAIT_FOR go'; +set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL parked WAIT_FOR go'; # Sending: -alter table t1 add column j int; +alter table t1 add column j int, ALGORITHM=COPY; # Switching to connection 'default'. # Wait until ALTER TABLE gets blocked on a sync point after # acquiring thr_lock.c lock. @@ -2600,7 +2755,7 @@ i # Switching to connection 'default'. # Start ALTER TABLE which will acquire SNW lock and # table lock and get blocked on sync point. -set debug_sync= 'thr_multi_lock_after_thr_lock SIGNAL parked WAIT_FOR go'; +set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL parked WAIT_FOR go'; # Sending: alter table t1 add column j int; # Switching to connection 'con1'. @@ -2889,7 +3044,7 @@ SET DEBUG_SYNC= 'now SIGNAL blocked'; # Reaping: DROP DATABASE db1 # Connection con2 # Reaping: DROP TABLE db1.t1 -ERROR 42S02: Unknown table 't1' +ERROR 42S02: Unknown table 'db1.t1' # Connection default SET DEBUG_SYNC= 'RESET'; # @@ -2934,12 +3089,16 @@ CREATE TABLE m1(a INT) engine=MERGE UNION=(t1, t2); INSERT INTO t1 VALUES (1), (2); INSERT INTO t2 VALUES (3), (4); # Connection con1 -SET DEBUG_SYNC= 'mdl_upgrade_shared_lock_to_exclusive SIGNAL upgrade WAIT_FOR continue'; +# We need EXECUTE 2 since ALTER TABLE does SU => SNW => X and we want +# to stop at the second upgrade. +SET DEBUG_SYNC= 'mdl_upgrade_lock SIGNAL upgrade WAIT_FOR continue EXECUTE 2'; # Sending: ALTER TABLE m1 engine=MERGE UNION=(t2, t1); # Connection con2 # Waiting for ALTER TABLE to try lock upgrade SET DEBUG_SYNC= 'now WAIT_FOR upgrade'; +SET DEBUG_SYNC= 'now SIGNAL continue'; +SET DEBUG_SYNC= 'now WAIT_FOR upgrade'; # Sending: DELETE FROM t2 WHERE a = 3; # Connection default diff --git a/mysql-test/t/mdl_sync.test b/mysql-test/t/mdl_sync.test index 197cad536e4..59c0a84e1ef 100644 --- a/mysql-test/t/mdl_sync.test +++ b/mysql-test/t/mdl_sync.test @@ -38,7 +38,7 @@ lock tables t2 read; connection con1; --echo connection: con1 -set debug_sync='mdl_upgrade_shared_lock_to_exclusive SIGNAL parked WAIT_FOR go'; +set debug_sync='mdl_upgrade_lock SIGNAL parked WAIT_FOR go'; --send alter table t1 rename t3 connection default; @@ -110,8 +110,13 @@ select column_name from information_schema.columns where table_schema='test' and table_name='t1'; select count(*) from t1; insert into t1 values (1), (1); +--echo # Check that SU lock is compatible with it. To do this use ALTER TABLE +--echo # which will fail when constructing .frm and thus obtaining SU metadata +--echo # lock. +--error ER_KEY_COLUMN_DOES_NOT_EXITS +alter table t1 add index (not_exist); --echo # Check that SNW lock is compatible with it. To do this use ALTER TABLE ---echo # which will fail after opening the table and thus obtaining SNW metadata +--echo # which will fail during copying the table and thus obtaining SNW metadata --echo # lock. --error ER_DUP_ENTRY alter table t1 add primary key (c1); @@ -230,8 +235,13 @@ select column_name from information_schema.columns where table_schema='test' and table_name='t1'; select count(*) from t1; insert into t1 values (1); +--echo # Check that SU lock is compatible with it. To do this use ALTER TABLE +--echo # which will fail when constructing .frm and thus obtaining SU metadata +--echo # lock. +--error ER_KEY_COLUMN_DOES_NOT_EXITS +alter table t1 add index (not_exist); --echo # Check that SNW lock is compatible with it. To do this use ALTER TABLE ---echo # which will fail after opening the table and thus obtaining SNW metadata +--echo # which will fail during copying the table and thus obtaining SNW metadata --echo # lock. --error ER_DUP_ENTRY alter table t1 add primary key (c1); @@ -359,8 +369,13 @@ select column_name from information_schema.columns where table_schema='test' and table_name='t1'; select count(*) from t1; insert into t1 values (1); +--echo # Check that SU lock is compatible with it. To do this use ALTER TABLE +--echo # which will fail when constructing .frm and thus obtaining SU metadata +--echo # lock. +--error ER_KEY_COLUMN_DOES_NOT_EXITS +alter table t1 add index (not_exist); --echo # Check that SNW lock is compatible with it. To do this use ALTER TABLE ---echo # which will fail after opening the table and thus obtaining SNW metadata +--echo # which will fail during copying the table and thus obtaining SNW metadata --echo # lock. --error ER_DUP_ENTRY alter table t1 add primary key (c1); @@ -477,8 +492,13 @@ select column_name from information_schema.columns where select * from t1; --enable_result_log insert into t1 values (1); +--echo # Check that SU lock is compatible with it. To do this use ALTER TABLE +--echo # which will fail when constructing .frm and thus obtaining SU metadata +--echo # lock. +--error ER_KEY_COLUMN_DOES_NOT_EXITS +alter table t1 add index (not_exist); --echo # Check that SNW lock is not compatible with SW lock. ---echo # Again we use ALTER TABLE which fails after opening +--echo # Again we use ALTER TABLE which fails during copying --echo # the table to avoid upgrade of SNW -> X. --echo # Sending: --send alter table t1 add primary key (c1); @@ -570,16 +590,144 @@ rename table t2 to t1; connection default; --echo # --echo # ---echo # 5) Acquire SNW lock on the table. We have to use DEBUG_SYNC for ---echo # this, to prevent SNW from being immediately upgraded to X. +--echo # 5) Acquire SU lock on the table. We have to use DEBUG_SYNC for +--echo # this, to prevent SU from being immediately upgraded to X. --echo # -set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish'; +set debug_sync= 'alter_opened_table SIGNAL locked WAIT_FOR finish'; +--echo # Sending: +--send alter table t1 add primary key (c1); +--echo # +--echo # Switching to connection 'mdl_con1'. +connection mdl_con1; +set debug_sync= 'now WAIT_FOR locked'; +--echo # Check that S, SH, SR and SW locks are compatible with it. +handler t1 open; +handler t1 close; +select column_name from information_schema.columns where + table_schema='test' and table_name='t1'; +select count(*) from t1; +delete from t1 limit 1; +--echo # Check that SU lock is incompatible with SU lock. +--echo # Sending: +--send alter table t1 add primary key (c1); +--echo # +--echo # Switching to connection 'mdl_con2'. +connection mdl_con2; +--echo # Check that the above ALTER is blocked because of SU lock. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for table metadata lock" and + info = "alter table t1 add primary key (c1)"; +--source include/wait_condition.inc +--echo # Unblock ALTERs. +set debug_sync= 'now SIGNAL finish'; +--echo # +--echo # Switching to connection 'default'. +connection default; +--echo # Reaping first ALTER TABLE. +--error ER_DUP_ENTRY +--reap +--echo # +--echo # Switching to connection 'mdl_con1'. +connection mdl_con1; +--echo # Reaping another ALTER TABLE. +--error ER_DUP_ENTRY +--reap +--echo # +--echo # Switching to connection 'default'. +connection default; +set debug_sync= 'alter_opened_table SIGNAL locked WAIT_FOR finish'; --echo # Sending: --send alter table t1 add primary key (c1); --echo # --echo # Switching to connection 'mdl_con1'. connection mdl_con1; set debug_sync= 'now WAIT_FOR locked'; +--echo # Check that SNRW lock is incompatible with SU lock. +--echo # Sending: +--send lock table t1 write; +--echo # +--echo # Switching to connection 'mdl_con2'. +connection mdl_con2; +--echo # Check that the above LOCK TABLES is blocked because of SU lock. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for table metadata lock" and + info = "lock table t1 write"; +--source include/wait_condition.inc +--echo # Unblock ALTER and thus LOCK TABLES. +set debug_sync= 'now SIGNAL finish'; +--echo # +--echo # Switching to connection 'default'. +connection default; +--echo # Reaping ALTER TABLE. +--error ER_DUP_ENTRY +--reap +--echo # +--echo # Switching to connection 'mdl_con1'. +connection mdl_con1; +--echo # Reaping LOCK TABLES +--reap +insert into t1 values (1); +unlock tables; +--echo # +--echo # Switching to connection 'default'. +connection default; +set debug_sync= 'alter_opened_table SIGNAL locked WAIT_FOR finish'; +--echo # Sending: +--send alter table t1 add primary key (c1); +--echo # +--echo # Switching to connection 'mdl_con1'. +connection mdl_con1; +set debug_sync= 'now WAIT_FOR locked'; +--echo # Check that X lock is incompatible with SU lock. +--echo # Sending: +--send rename table t1 to t2; +--echo # +--echo # Switching to connection 'mdl_con2'. +connection mdl_con2; +--echo # Check that the above RENAME is blocked because of SU lock. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for table metadata lock" and + info = "rename table t1 to t2"; +--source include/wait_condition.inc +--echo # Unblock ALTER and thus RENAME TABLE. +set debug_sync= 'now SIGNAL finish'; +--echo # +--echo # Switching to connection 'default'. +connection default; +--echo # Now we have ALTER TABLE with SU->SNW and RENAME TABLE with pending +--echo # X-lock. In this case ALTER TABLE should be chosen as victim. +--echo # Reaping ALTER TABLE. +--error ER_LOCK_DEADLOCK +--reap +--echo # +--echo # Switching to connection 'mdl_con1'. +connection mdl_con1; +--echo # Reaping RENAME TABLE +--reap +--echo # Revert back to original state of things. +rename table t2 to t1; +--echo # +--echo # There is no need to check that upgrade from SNW/SNRW to X is +--echo # blocked by presence of another SU lock because SNW/SNRW is +--echo # incompatible with SU anyway. +--echo # +--echo # Switching to connection 'default'. +connection default; +--echo # +--echo # +--echo # 6) Acquire SNW lock on the table. We have to use DEBUG_SYNC for +--echo # this, to prevent SNW from being immediately upgraded to X. +--echo # +set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish'; +--echo # Sending: +--send alter table t1 add primary key (c1), lock=shared, algorithm=copy; +--echo # +--echo # Switching to connection 'mdl_con1'. +connection mdl_con1; +set debug_sync= 'now WAIT_FOR locked'; --echo # Check that S, SH and SR locks are compatible with it. handler t1 open; handler t1 close; @@ -614,14 +762,14 @@ connection mdl_con1; --echo # --echo # Switching to connection 'default'. connection default; -set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish'; +set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish'; --echo # Sending: ---send alter table t1 add primary key (c1); +--send alter table t1 add primary key (c1), lock=shared, algorithm=copy; --echo # --echo # Switching to connection 'mdl_con1'. connection mdl_con1; set debug_sync= 'now WAIT_FOR locked'; ---echo # Check that SNW lock is incompatible with SNW lock. +--echo # Check that SU lock is incompatible with SNW lock. --echo # Sending: --send alter table t1 add primary key (c1); --echo # @@ -648,11 +796,15 @@ connection mdl_con1; --error ER_DUP_ENTRY --reap --echo # +--echo # Note that we can't easily check SNW vs SNW locks since +--echo # SNW is only used by ALTER TABLE after upgrading from SU +--echo # and SU is also incompatible with SNW. +--echo # --echo # Switching to connection 'default'. connection default; -set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish'; +set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish'; --echo # Sending: ---send alter table t1 add primary key (c1); +--send alter table t1 add primary key (c1), lock=shared, algorithm=copy; --echo # --echo # Switching to connection 'mdl_con1'. connection mdl_con1; @@ -687,9 +839,9 @@ unlock tables; --echo # --echo # Switching to connection 'default'. connection default; -set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish'; +set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish'; --echo # Sending: ---send alter table t1 add primary key (c1); +--send alter table t1 add primary key (c1), algorithm=copy, lock=shared; --echo # --echo # Switching to connection 'mdl_con1'. connection mdl_con1; @@ -730,7 +882,7 @@ rename table t2 to t1; connection default; --echo # --echo # ---echo # 6) Acquire SNRW lock on the table. +--echo # 7) Acquire SNRW lock on the table. --echo # --echo # lock table t1 write; @@ -794,13 +946,13 @@ lock table t1 write; --echo # --echo # Switching to connection 'mdl_con1'. connection mdl_con1; ---echo # Check that SNW lock is incompatible with SNRW lock. +--echo # Check that SU lock is incompatible with SNRW lock. --echo # Sending: --send alter table t1 add primary key (c1); --echo # --echo # Switching to connection 'default'. connection default; ---echo # Check that the above ALTER is blocked because of UNWR lock. +--echo # Check that the above ALTER is blocked because of SNRW lock. let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and @@ -815,6 +967,10 @@ connection mdl_con1; --error ER_DUP_ENTRY --reap --echo # +--echo # Note that we can't easily check SNW vs SNRW locks since +--echo # SNW is only used by ALTER TABLE after upgrading from SU +--echo # and SU is also incompatible with SNRW. +--echo # --echo # Switching to connection 'default'. connection default; lock table t1 write; @@ -879,7 +1035,7 @@ rename table t2 to t1; connection default; --echo # --echo # ---echo # 7) Now do the same round of tests for X lock. We use additional +--echo # 8) Now do the same round of tests for X lock. We use additional --echo # table to get long-lived lock of this type. --echo # create table t2 (c1 int); @@ -1083,7 +1239,7 @@ select count(*) = 1 from information_schema.processlist where state = "Waiting for table metadata lock" and info = "rename table t1 to t2"; --source include/wait_condition.inc ---echo # Check that SNW lock is incompatible with X lock. +--echo # Check that SU lock is incompatible with X lock. --echo # Sending: --send alter table t1 add primary key (c1); --echo # @@ -1110,7 +1266,11 @@ connection mdl_con1; --echo # Reaping ALTER. --error ER_DUP_ENTRY --reap ---echo # +--echo # +--echo # Note that we can't easily check SNW vs X locks since +--echo # SNW is only used by ALTER TABLE after upgrading from SU +--echo # and SU is also incompatible with X. +--echo # --echo # Switching to connection 'mdl_con2'. connection mdl_con2; --echo # Prepare for blocking RENAME TABLE. @@ -1208,6 +1368,9 @@ rename table t3 to t1; --echo # are pending. I.e. let us test rules for priorities between --echo # different types of metadata locks. --echo # +--echo # Note: No tests for pending SU lock as this lock requires +--echo # even stronger active or pending lock. +--echo # --echo # --echo # Switching to connection 'mdl_con2'. @@ -1657,6 +1820,9 @@ connection default; --echo # transactional context. Obviously we are mostly interested --echo # in conflicting types of locks. --echo # +--echo # Note: No tests for active/pending SU lock since +--echo # ALTER TABLE is in its own transaction. +--echo # --echo # --echo # 1) Let us check how various locks used within transactional @@ -1673,9 +1839,9 @@ connection mdl_con1; --echo # We have to use DEBUG_SYNC facility as otherwise SNW lock --echo # will be immediately released (or upgraded to X lock). insert into t2 values (1), (1); -set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish'; +set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish'; --echo # Sending: ---send alter table t2 add primary key (c1); +--send alter table t2 add primary key (c1), algorithm=copy, lock=shared; --echo # --echo # Switching to connection 'default'. connection default; @@ -1724,9 +1890,9 @@ select count(*) from t1; --echo # Switching to connection 'mdl_con1'. connection mdl_con1; --echo # Create an active SNW lock on t1. -set debug_sync= 'after_open_table_mdl_shared SIGNAL locked WAIT_FOR finish'; +set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL locked WAIT_FOR finish'; --echo # Sending: ---send alter table t1 add primary key (c1); +--send alter table t1 add primary key (c1), algorithm=copy, lock=shared; --echo # --echo # Switching to connection 'default'. connection default; @@ -2845,7 +3011,7 @@ drop tables t1, t2; create table t1 (i int); --echo # Ensure that ALTER waits once it has acquired SNW lock. -set debug_sync='after_open_table_mdl_shared SIGNAL parked1 WAIT_FOR go1'; +set debug_sync='alter_table_copy_after_lock_upgrade SIGNAL parked1 WAIT_FOR go1'; --echo # Sending: --send alter table t1 add column j int @@ -3345,18 +3511,33 @@ drop tables if exists t1, t2; --enable_warnings connect (con46044, localhost, root,,); connect (con46044_2, localhost, root,,); +connect (con46044_3, localhost, root,,); connection default; create table t1 (i int); +insert into t1 values(1); --echo # Let us check that we won't deadlock if during filling --echo # of I_S table we encounter conflicting metadata lock --echo # which owner is in its turn waiting for our connection. lock tables t1 read; +--echo # Switching to connection 'con46044_2'. +connection con46044_2; +--echo # Sending: +--send update t1 set i = 2 + --echo # Switching to connection 'con46044'. connection con46044; + +--echo # Waiting until UPDATE t1 SET ... is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for table level lock" and + info = "update t1 set i = 2"; +--source include/wait_condition.inc + --echo # Sending: ---send create table t2 select * from t1 for update; +--send create table t2 select * from t1; --echo # Switching to connection 'default'. connection default; @@ -3364,7 +3545,7 @@ connection default; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table level lock" and - info = "create table t2 select * from t1 for update"; + info = "create table t2 select * from t1"; --source include/wait_condition.inc --echo # First let us check that SHOW FIELDS/DESCRIBE doesn't @@ -3395,6 +3576,10 @@ connection con46044; --reap drop table t2; +connection con46044_2; +--echo # Reaping UPDATE t1 statement +--reap + --echo # --echo # Let us also check that queries to I_S wait for conflicting metadata --echo # locks to go away instead of skipping table with a warning in cases @@ -3407,10 +3592,23 @@ drop table t2; connection con46044_2; lock tables t1 read; +--echo # Switching to connection 'con46044_3'. +connection con46044_3; +--echo # Sending: +send update t1 set i = 3; + --echo # Switching to connection 'con46044'. connection con46044; + +--echo # Waiting until UPDATE t1 SET ... is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for table level lock" and + info = "update t1 set i = 3"; +--source include/wait_condition.inc + --echo # Sending: ---send create table t2 select * from t1 for update; +--send create table t2 select * from t1; --echo # Switching to connection 'default'. connection default; @@ -3418,7 +3616,7 @@ connection default; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table level lock" and - info = "create table t2 select * from t1 for update"; + info = "create table t2 select * from t1"; --source include/wait_condition.inc --echo # Let us check that SHOW FIELDS/DESCRIBE gets blocked. @@ -3447,14 +3645,31 @@ connection default; --reap drop table t2; +connection con46044_3; +--echo # Reaping UPDATE t1 statement +--reap + --echo # Switching to connection 'con46044_2'. connection con46044_2; lock tables t1 read; +--echo # Switching to connection 'con46044_3'. +connection con46044_3; +--echo # Sending: +--send update t1 set i = 4 + --echo # Switching to connection 'con46044'. connection con46044; + +--echo # Waiting until UPDATE t1 SET ... is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for table level lock" and + info = "update t1 set i = 4"; +--source include/wait_condition.inc + --echo # Sending: ---send create table t2 select * from t1 for update; +--send create table t2 select * from t1; --echo # Switching to connection 'default'. connection default; @@ -3462,7 +3677,7 @@ connection default; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table level lock" and - info = "create table t2 select * from t1 for update"; + info = "create table t2 select * from t1"; --source include/wait_condition.inc --echo # Check that I_S query which reads only .FRMs gets blocked. @@ -3491,14 +3706,31 @@ connection default; --reap drop table t2; +connection con46044_3; +--echo # Reaping UPDATE t1 statement +--reap + --echo # Switching to connection 'con46044_2'. connection con46044_2; lock tables t1 read; +--echo # Switching to connection 'con46044_3'. +connection con46044_3; +--echo # Sending: +--send update t1 set i = 5 + --echo # Switching to connection 'con46044'. connection con46044; + +--echo # Waiting until UPDATE t1 SET ... is blocked. +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for table level lock" and + info = "update t1 set i = 5"; +--source include/wait_condition.inc + --echo # Sending: ---send create table t2 select * from t1 for update; +--send create table t2 select * from t1; --echo # Switching to connection 'default'. connection default; @@ -3506,7 +3738,7 @@ connection default; let $wait_condition= select count(*) = 1 from information_schema.processlist where state = "Waiting for table level lock" and - info = "create table t2 select * from t1 for update"; + info = "create table t2 select * from t1"; --source include/wait_condition.inc --echo # Finally, check that I_S query which does full-blown table open @@ -3536,11 +3768,16 @@ connection default; --reap drop table t2; +connection con46044_3; +--echo # Reaping UPDATE t1 statement +--reap + --echo # Switching to connection 'default'. connection default; --echo # Clean-up. disconnect con46044; disconnect con46044_2; +disconnect con46044_3; drop table t1; @@ -3563,7 +3800,7 @@ select * from t1 where c2 = 3; --echo # --echo # Switching to connection 'con46273'. connection con46273; -set debug_sync='after_lock_tables_takes_lock SIGNAL alter_table_locked WAIT_FOR alter_go'; +set debug_sync='alter_table_copy_after_lock_upgrade SIGNAL alter_table_locked WAIT_FOR alter_go'; --send alter table t1 add column e int, rename to t2; --echo # @@ -3826,9 +4063,9 @@ create table t1 (i int) engine=InnoDB; --echo # Switching to connection 'con50913_1'. connection con50913_1; -set debug_sync= 'thr_multi_lock_after_thr_lock SIGNAL parked WAIT_FOR go'; +set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL parked WAIT_FOR go'; --echo # Sending: ---send alter table t1 add column j int +--send alter table t1 add column j int, ALGORITHM=COPY --echo # Switching to connection 'default'. connection default; @@ -3897,7 +4134,7 @@ select * from t1; connection default; --echo # Start ALTER TABLE which will acquire SNW lock and --echo # table lock and get blocked on sync point. -set debug_sync= 'thr_multi_lock_after_thr_lock SIGNAL parked WAIT_FOR go'; +set debug_sync= 'alter_table_copy_after_lock_upgrade SIGNAL parked WAIT_FOR go'; --echo # Sending: --send alter table t1 add column j int @@ -4562,7 +4799,9 @@ connect(con2, localhost, root); --echo # Connection con1 connection con1; -SET DEBUG_SYNC= 'mdl_upgrade_shared_lock_to_exclusive SIGNAL upgrade WAIT_FOR continue'; +--echo # We need EXECUTE 2 since ALTER TABLE does SU => SNW => X and we want +--echo # to stop at the second upgrade. +SET DEBUG_SYNC= 'mdl_upgrade_lock SIGNAL upgrade WAIT_FOR continue EXECUTE 2'; --echo # Sending: --send ALTER TABLE m1 engine=MERGE UNION=(t2, t1) @@ -4570,6 +4809,8 @@ SET DEBUG_SYNC= 'mdl_upgrade_shared_lock_to_exclusive SIGNAL upgrade WAIT_FOR co connection con2; --echo # Waiting for ALTER TABLE to try lock upgrade SET DEBUG_SYNC= 'now WAIT_FOR upgrade'; +SET DEBUG_SYNC= 'now SIGNAL continue'; +SET DEBUG_SYNC= 'now WAIT_FOR upgrade'; --echo # Sending: --send DELETE FROM t2 WHERE a = 3 diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc index 1f3c86c5b67..750f770552e 100644 --- a/sql/debug_sync.cc +++ b/sql/debug_sync.cc @@ -1,4 +1,4 @@ -/* Copyright (c) 2009, 2010, Oracle and/or its affiliates. +/* Copyright (c) 2009, 2011, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -10,8 +10,8 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + along with this program; if not, write to the Free Software Foundation, + 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ /* see include/mysql/service_debug_sync.h for debug sync documentation */ @@ -82,8 +82,6 @@ struct st_debug_sync_globals }; static st_debug_sync_globals debug_sync_global; /* All globals in one object */ -extern uint opt_debug_sync_timeout; - /** Callbacks from C files. */ @@ -112,14 +110,11 @@ static void init_debug_sync_psi_keys(void) const char* category= "sql"; int count; - if (PSI_server == NULL) - return; - count= array_elements(all_debug_sync_mutexes); - PSI_server->register_mutex(category, all_debug_sync_mutexes, count); + mysql_mutex_register(category, all_debug_sync_mutexes, count); count= array_elements(all_debug_sync_conds); - PSI_server->register_cond(category, all_debug_sync_conds, count); + mysql_cond_register(category, all_debug_sync_conds, count); } #endif /* HAVE_PSI_INTERFACE */ @@ -783,7 +778,7 @@ static bool debug_sync_set_action(THD *thd, st_debug_sync_action *action) point decremented it to 0. In this case the following happened: - an error message was reported with my_error() and - - the statement was killed with thd->killed= KILL_QUERY. + - the statement was killed with thd->killed= THD::KILL_QUERY. If a statement reports an error, it must not call send_ok(). The calling functions will not call send_ok(), if we return TRUE @@ -985,7 +980,7 @@ static bool debug_sync_eval_action(THD *thd, char *action_str) DBUG_ENTER("debug_sync_eval_action"); DBUG_ASSERT(thd); DBUG_ASSERT(action_str); - DBUG_PRINT("debug_sync", ("action_str='%s'", action_str)); + DBUG_PRINT("debug_sync", ("action_str: '%s'", action_str)); /* Get debug sync point name. Or a special command. @@ -1450,8 +1445,13 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action) sig_wait, sig_glob, error));}); if (error == ETIMEDOUT || error == ETIME) { + // We should not make the statement fail, even if in strict mode. + const bool save_abort_on_warning= thd->abort_on_warning; + thd->abort_on_warning= false; push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_DEBUG_SYNC_TIMEOUT, ER(ER_DEBUG_SYNC_TIMEOUT)); + thd->abort_on_warning= save_abort_on_warning; + DBUG_EXECUTE_IF("debug_sync_abort_on_timeout", DBUG_ABORT();); break; } error= 0; diff --git a/sql/debug_sync.h b/sql/debug_sync.h index 4d29d6e7508..bf1b3167dbc 100644 --- a/sql/debug_sync.h +++ b/sql/debug_sync.h @@ -32,6 +32,9 @@ class THD; #if defined(ENABLED_DEBUG_SYNC) +/* Command line option --debug-sync-timeout. See mysqld.cc. */ +extern MYSQL_PLUGIN_IMPORT uint opt_debug_sync_timeout; + /* Default WAIT_FOR timeout if command line option is given without argument. */ #define DEBUG_SYNC_DEFAULT_WAIT_TIMEOUT 300 diff --git a/sql/mdl.cc b/sql/mdl.cc index 22d9d4e53e5..dd7d3f0fbf4 100644 --- a/sql/mdl.cc +++ b/sql/mdl.cc @@ -1872,6 +1872,8 @@ MDL_context::find_ticket(MDL_request *mdl_request, if (mdl_request->key.is_equal(&ticket->m_lock->key) && ticket->has_stronger_or_equal_type(mdl_request->type)) { + DBUG_PRINT("info", ("Adding mdl lock %d to %d", + mdl_request->type, ticket->m_type)); *result_duration= duration; return ticket; } @@ -2168,6 +2170,7 @@ MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout) struct timespec abs_timeout; MDL_wait::enum_wait_status wait_status; DBUG_ENTER("MDL_context::acquire_lock"); + DBUG_PRINT("enter", ("lock_type: %d", mdl_request->type)); /* Do some work outside the critical section. */ set_timespec(abs_timeout, lock_wait_timeout); @@ -2182,6 +2185,7 @@ MDL_context::acquire_lock(MDL_request *mdl_request, ulong lock_wait_timeout) MDL_lock, MDL_context and MDL_request were updated accordingly, so we can simply return success. */ + DBUG_PRINT("info", ("Got lock without waiting")); DBUG_RETURN(FALSE); } @@ -2393,8 +2397,9 @@ MDL_context::upgrade_shared_lock(MDL_ticket *mdl_ticket, MDL_request mdl_xlock_request; MDL_savepoint mdl_svp= mdl_savepoint(); bool is_new_ticket; - DBUG_ENTER("MDL_context::upgrade_shared_lock"); + DBUG_PRINT("enter",("new_type: %d lock_wait_timeout: %lu", new_type, + lock_wait_timeout)); DEBUG_SYNC(get_thd(), "mdl_upgrade_lock"); /* @@ -2701,8 +2706,8 @@ void MDL_context::release_lock(enum_mdl_duration duration, MDL_ticket *ticket) { MDL_lock *lock= ticket->m_lock; DBUG_ENTER("MDL_context::release_lock"); - DBUG_PRINT("enter", ("db=%s name=%s", lock->key.db_name(), - lock->key.name())); + DBUG_PRINT("enter", ("db: '%s' name: '%s'", + lock->key.db_name(), lock->key.name())); DBUG_ASSERT(this == ticket->get_ctx()); mysql_mutex_assert_not_owner(&LOCK_open); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index c7ac0695cf1..acc4f09cec4 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2952,7 +2952,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, } /* No table in the locked tables list. In case of explicit LOCK TABLES - this can happen if a user did not include the able into the list. + this can happen if a user did not include the table into the list. In case of pre-locked mode locked tables list is generated automatically, so we may only end up here if the table did not exist when locked tables list was created. @@ -2972,19 +2972,6 @@ bool open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, if (! (flags & MYSQL_OPEN_HAS_MDL_LOCK)) { /* - Check if we're trying to take a write lock in a read only transaction. - */ - if (table_list->mdl_request.type >= MDL_SHARED_WRITE && - thd->tx_read_only && - !(flags & (MYSQL_OPEN_HAS_MDL_LOCK | - MYSQL_LOCK_LOG_TABLE | - MYSQL_LOCK_IGNORE_GLOBAL_READ_ONLY))) - { - my_error(ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION, MYF(0)); - DBUG_RETURN(true); - } - - /* We are not under LOCK TABLES and going to acquire write-lock/ modify the base table. We need to acquire protection against global read lock until end of this statement in order to have diff --git a/sql/sql_table.cc b/sql/sql_table.cc index f2c203744f4..626344ef93d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2221,9 +2221,10 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, bool dont_log_query) { TABLE_LIST *table; - char path[FN_REFLEN + 1], *alias= NULL; + char path[FN_REFLEN + 1], wrong_tables_buff[160], *alias= NULL; + String wrong_tables(wrong_tables_buff, sizeof(wrong_tables_buff)-1, + system_charset_info); uint path_length= 0; - String wrong_tables; int error= 0; int non_temp_tables_count= 0; bool foreign_key_error=0; @@ -2234,6 +2235,7 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, String built_trans_tmp_query, built_non_trans_tmp_query; DBUG_ENTER("mysql_rm_table_no_locks"); + wrong_tables.length(0); /* Prepares the drop statements that will be written into the binary log as follows: @@ -2453,9 +2455,17 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, . ./sql/datadict.cc +32 /Alfranio - TODO: We need to test this. */ if (if_exists) - push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, - ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), - table->table_name); + { + char buff[FN_REFLEN]; + String tbl_name(buff, sizeof(buff), system_charset_info); + tbl_name.length(0); + tbl_name.append(db); + tbl_name.append('.'); + tbl_name.append(table->table_name); + push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE, + ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), + tbl_name.c_ptr_safe()); + } else { non_tmp_error = (drop_temporary ? non_tmp_error : TRUE); @@ -2513,7 +2523,9 @@ int mysql_rm_table_no_locks(THD *thd, TABLE_LIST *tables, bool if_exists, { if (wrong_tables.length()) wrong_tables.append(','); - wrong_tables.append(String(table->table_name,system_charset_info)); + wrong_tables.append(db); + wrong_tables.append('.'); + wrong_tables.append(table->table_name); } DBUG_PRINT("table", ("table: 0x%lx s: 0x%lx", (long) table->table, table->table ? (long) table->table->s : (long) -1)); diff --git a/sql/table.cc b/sql/table.cc index 197132d8d0a..fb81fe2616a 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -998,10 +998,15 @@ static int open_binary_frm(THD *thd, TABLE_SHARE *share, uchar *head, } key_part->store_length=key_part->length; } + + /* + Add primary key to end of extended keys for non unique keys for + storage engines that supports it. + */ keyinfo->ext_key_parts= keyinfo->user_defined_key_parts; keyinfo->ext_key_flags= keyinfo->flags; keyinfo->ext_key_part_map= 0; - if (share->use_ext_keys && i) + if (share->use_ext_keys && i && !(keyinfo->flags & HA_NOSAME)) { keyinfo->ext_key_part_map= 0; for (j= 0; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 68d5cb512f6..9a5d4d60c15 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -11225,7 +11225,7 @@ ha_innobase::info_low( KEY *key_info= table->key_info+i; key_part_map ext_key_part_map= - key_info->ext_key_part_map; + key_info->ext_key_part_map; if (key_info->user_defined_key_parts != key_info->ext_key_parts) diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index d919fb59502..7772b0bb15e 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -512,7 +512,7 @@ int ha_myisammrg::add_children_list(void) DDL on implicitly locked underlying tables of a MERGE table. */ if (! thd->locked_tables_mode && - parent_l->mdl_request.type == MDL_SHARED_NO_WRITE) + parent_l->mdl_request.type == MDL_SHARED_UPGRADABLE) child_l->mdl_request.set_type(MDL_SHARED_NO_WRITE); /* Link TABLE_LIST object into the children list. */ if (this->children_last_l) @@ -1372,8 +1372,6 @@ int ha_myisammrg::reset(void) int ha_myisammrg::extra_opt(enum ha_extra_function operation, ulong cache_size) { DBUG_ASSERT(this->file->children_attached); - if ((specialflag & SPECIAL_SAFE_MODE) && operation == HA_EXTRA_WRITE_CACHE) - return 0; return myrg_extra(file, operation, (void*) &cache_size); } |