diff --git a/mysql-test/r/lock_multi_bug38499.result b/mysql-test/r/lock_multi_bug38499.result new file mode 100644 index 00000000000..fd0f2138a8d --- /dev/null +++ b/mysql-test/r/lock_multi_bug38499.result @@ -0,0 +1,19 @@ +DROP TABLE IF EXISTS t1; +CREATE TABLE t1( a INT, b INT ); +INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4); +# 1. test regular tables +# 1.1. test altering of columns that multiupdate doesn't use +# 1.1.1. normal mode +# 1.1.2. PS mode +# 1.2. test altering of columns that multiupdate uses +# 1.2.1. normal mode +# 1.2.2. PS mode +ALTER TABLE t1 ADD COLUMN a INT; +# 2. test UNIONs +# 2.1. test altering of columns that multiupdate doesn't use +# 2.1.1. normal mode +# 2.1.2. PS mode +# 2.2. test altering of columns that multiupdate uses +# 2.2.1. normal mode +# 2.2.2. PS mode +DROP TABLE t1; diff --git a/mysql-test/r/lock_multi_bug38691.result b/mysql-test/r/lock_multi_bug38691.result new file mode 100644 index 00000000000..74b9603d8e3 --- /dev/null +++ b/mysql-test/r/lock_multi_bug38691.result @@ -0,0 +1,17 @@ +DROP TABLE IF EXISTS t1,t2,t3; +CREATE TABLE t1 ( +a int(11) unsigned default NULL, +b varchar(255) default NULL, +UNIQUE KEY a (a), +KEY b (b) +); +INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3); +CREATE TABLE t2 SELECT * FROM t1; +CREATE TABLE t3 SELECT * FROM t1; +# test altering of columns that multiupdate doesn't use +# normal mode +# PS mode +# test altering of columns that multiupdate uses +# normal mode +# PS mode +DROP TABLE t1, t2, t3; diff --git a/mysql-test/t/lock_multi.test b/mysql-test/t/lock_multi.test index e3a577127fa..6c3c942b046 100644 --- a/mysql-test/t/lock_multi.test +++ b/mysql-test/t/lock_multi.test @@ -84,8 +84,6 @@ insert into t1 values(2,2); insert into t2 values(1,2); lock table t1 read; connection writer; -# mleich: IMHO the "send is not necessary because the update should not block. -# But it will save some runtime in case we block because of an error. send update t1,t2 set c=a where b=d; connection reader; @@ -191,8 +189,8 @@ connection locker; USE mysql; LOCK TABLES columns_priv WRITE, db WRITE, host WRITE, user WRITE; FLUSH TABLES; ---sleep 1 -# + + connection reader; USE mysql; # Note: This must be a multi-table select, otherwise the deadlock will not occur diff --git a/mysql-test/t/lock_multi_bug38499.test b/mysql-test/t/lock_multi_bug38499.test new file mode 100644 index 00000000000..8178987e802 --- /dev/null +++ b/mysql-test/t/lock_multi_bug38499.test @@ -0,0 +1,221 @@ +# Bug38499 flush tables and multitable table update with derived table cause crash +# MySQL >= 5.0 +# + +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + +connect (locker,localhost,root,,); +connect (writer,localhost,root,,); + +--connection default +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings +CREATE TABLE t1( a INT, b INT ); +INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4); + +--echo # 1. test regular tables +--echo # 1.1. test altering of columns that multiupdate doesn't use +--echo # 1.1.1. normal mode + +--disable_query_log +let $i = 100; +while ($i) { +--dec $i + +--connection writer + send UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0; + +--connection locker + ALTER TABLE t1 ADD COLUMN (c INT); + ALTER TABLE t1 DROP COLUMN c; + +--connection writer +--reap +} + +--echo # 1.1.2. PS mode + +--connection writer +PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0'; + +let $i = 100; +while ($i) { +--dec $i + +--connection writer +--send EXECUTE stmt + +--connection locker + ALTER TABLE t1 ADD COLUMN (c INT); + ALTER TABLE t1 DROP COLUMN c; + +--connection writer +--reap +} +--enable_query_log + +--echo # 1.2. test altering of columns that multiupdate uses +--echo # 1.2.1. normal mode + +--connection default + +--disable_query_log +let $i = 100; +while ($i) { + dec $i; + +--connection locker +--error 0,ER_DUP_FIELDNAME + ALTER TABLE t1 ADD COLUMN a int(11) unsigned default NULL; + UPDATE t1 SET a=b; + +--connection writer +--send UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0; + +--connection locker +--error 0,ER_CANT_DROP_FIELD_OR_KEY + ALTER TABLE t1 DROP COLUMN a; + +--connection writer +--error 0,ER_BAD_FIELD_ERROR # unknown column error +--reap +} +--enable_query_log + +--echo # 1.2.2. PS mode + +--disable_query_log +let $i = 100; +while ($i) { + dec $i; + +--connection locker +--error 0,ER_DUP_FIELDNAME + ALTER TABLE t1 ADD COLUMN a INT; + UPDATE t1 SET a=b; + +--connection writer + PREPARE stmt FROM 'UPDATE t1, (SELECT 1 FROM t1 t1i) d SET a = 0 WHERE 1=0'; +--send EXECUTE stmt + +--connection locker +--error 0,ER_CANT_DROP_FIELD_OR_KEY + ALTER TABLE t1 DROP COLUMN a; + +--connection writer +--error 0,ER_BAD_FIELD_ERROR # Unknown column 'a' in 'field list' +--reap +} +--enable_query_log +--connection default +ALTER TABLE t1 ADD COLUMN a INT; + +--echo # 2. test UNIONs +--echo # 2.1. test altering of columns that multiupdate doesn't use +--echo # 2.1.1. normal mode + +--disable_query_log +let $i = 100; +while ($i) { +--dec $i + +--connection writer + send UPDATE t1, ((SELECT 1 FROM t1 t1i) UNION (SELECT 2 FROM t1 t1ii)) e SET a = 0 WHERE 1=0; + +--connection locker + ALTER TABLE t1 ADD COLUMN (c INT); + ALTER TABLE t1 DROP COLUMN c; + +--connection writer +--reap +} + +--echo # 2.1.2. PS mode + +--connection writer +PREPARE stmt FROM 'UPDATE t1, ((SELECT 1 FROM t1 t1i) UNION (SELECT 2 FROM t1 t1ii)) e SET a = 0 WHERE 1=0'; + +let $i = 100; +while ($i) { +--dec $i + +--connection writer +--send EXECUTE stmt + +--connection locker + ALTER TABLE t1 ADD COLUMN (c INT); + ALTER TABLE t1 DROP COLUMN c; + +--connection writer +--reap +} +--enable_query_log + +--echo # 2.2. test altering of columns that multiupdate uses +--echo # 2.2.1. normal mode + +--connection default + +--disable_query_log +let $i = 100; +while ($i) { + dec $i; + +--connection locker +--error 0,ER_DUP_FIELDNAME + ALTER TABLE t1 ADD COLUMN a int(11) unsigned default NULL; + UPDATE t1 SET a=b; + +--connection writer +--send UPDATE t1, ((SELECT 1 FROM t1 t1i) UNION (SELECT 2 FROM t1 t1ii)) e SET a = 0 WHERE 1=0; + +--connection locker +--error 0,ER_CANT_DROP_FIELD_OR_KEY + ALTER TABLE t1 DROP COLUMN a; + +--connection writer +--error 0,ER_BAD_FIELD_ERROR # Unknown column 'a' in 'field list' +--reap +} +--enable_query_log + +--echo # 2.2.2. PS mode + +--disable_query_log +let $i = 100; +while ($i) { + dec $i; + +--connection locker +--error 0,ER_DUP_FIELDNAME + ALTER TABLE t1 ADD COLUMN a INT; + UPDATE t1 SET a=b; + +--connection writer + PREPARE stmt FROM 'UPDATE t1, ((SELECT 1 FROM t1 t1i) UNION (SELECT 2 FROM t1 t1ii)) e SET a = 0 WHERE 1=0'; +--send EXECUTE stmt + +--connection locker +--error 0,ER_CANT_DROP_FIELD_OR_KEY + ALTER TABLE t1 DROP COLUMN a; + +--connection writer +--error 0,ER_BAD_FIELD_ERROR # Unknown column 'a' in 'field list' +--reap +} +--enable_query_log +--connection default +DROP TABLE t1; + + +# Close connections +--disconnect locker +--disconnect writer + +# End of 5.0 tests + +# Wait till all disconnects are completed +--source include/wait_until_count_sessions.inc + diff --git a/mysql-test/t/lock_multi_bug38691.test b/mysql-test/t/lock_multi_bug38691.test new file mode 100644 index 00000000000..0458f31579e --- /dev/null +++ b/mysql-test/t/lock_multi_bug38691.test @@ -0,0 +1,141 @@ +# +# Bug#38691 segfault/abort in ``UPDATE ...JOIN'' while +# ``FLUSH TABLES WITH READ LOCK'' +# MySQL >= 5.0 +# + + +# Save the initial number of concurrent sessions +--source include/count_sessions.inc + +# Test to see if select will get the lock ahead of low priority update + +connect (locker,localhost,root,,); +connect (writer,localhost,root,,); + +--connection default +--disable_warnings +DROP TABLE IF EXISTS t1,t2,t3; +--enable_warnings + +CREATE TABLE t1 ( + a int(11) unsigned default NULL, + b varchar(255) default NULL, + UNIQUE KEY a (a), + KEY b (b) +); + +INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3); +CREATE TABLE t2 SELECT * FROM t1; +CREATE TABLE t3 SELECT * FROM t1; + +--echo # test altering of columns that multiupdate doesn't use + +--echo # normal mode + +--disable_query_log +let $i = 100; +while ($i) { +--dec $i + +--connection writer + send UPDATE t2 INNER JOIN (t1 JOIN t3 USING(a)) USING(a) + SET a = NULL WHERE t1.b <> t2.b; + +--connection locker + ALTER TABLE t2 ADD COLUMN (c INT); + ALTER TABLE t2 DROP COLUMN c; + +--connection writer +--reap +} + +--echo # PS mode + +--connection writer +PREPARE stmt FROM 'UPDATE t2 INNER JOIN (t1 JOIN t3 USING(a)) USING(a) + SET a = NULL WHERE t1.b <> t2.b'; + +let $i = 100; +while ($i) { +--dec $i + +--connection writer +--send EXECUTE stmt + +--connection locker + ALTER TABLE t2 ADD COLUMN (c INT); + ALTER TABLE t2 DROP COLUMN c; + +--connection writer +--reap +} +--enable_query_log + + +--echo # test altering of columns that multiupdate uses + +--echo # normal mode + +--connection default + +--disable_query_log +let $i = 100; +while ($i) { + dec $i; + +--connection locker +--error 0,ER_DUP_FIELDNAME + ALTER TABLE t2 ADD COLUMN a int(11) unsigned default NULL; + UPDATE t2 SET a=b; + +--connection writer +--send UPDATE t2 INNER JOIN (t1 JOIN t3 USING(a)) USING(a) SET a = NULL WHERE t1.b <> t2.b + +--connection locker +--error 0,ER_CANT_DROP_FIELD_OR_KEY + ALTER TABLE t2 DROP COLUMN a; + +--connection writer +--error 0,ER_BAD_FIELD_ERROR +--reap +} +--enable_query_log + +--echo # PS mode + +--disable_query_log +let $i = 100; +while ($i) { + dec $i; + +--connection locker +--error 0,ER_DUP_FIELDNAME + ALTER TABLE t2 ADD COLUMN a int(11) unsigned default NULL; + UPDATE t2 SET a=b; + +--connection writer + PREPARE stmt FROM 'UPDATE t2 INNER JOIN (t1 JOIN t3 USING(a)) USING(a) SET a = NULL WHERE t1.b <> t2.b'; +--send EXECUTE stmt + +--connection locker +--error 0,ER_CANT_DROP_FIELD_OR_KEY + ALTER TABLE t2 DROP COLUMN a; + +--connection writer +--error 0,ER_BAD_FIELD_ERROR +--reap + +} +--enable_query_log +--connection default +DROP TABLE t1, t2, t3; + + +# Close connections +--disconnect locker +--disconnect writer + +# Wait till all disconnects are completed +--source include/wait_until_count_sessions.inc +