diff --git a/mysql-test/main/locking_clause.result b/mysql-test/main/locking_clause.result new file mode 100644 index 00000000000..0307711ee8e --- /dev/null +++ b/mysql-test/main/locking_clause.result @@ -0,0 +1,160 @@ +CREATE TABLE t1 ( a INT, b INT ); +INSERT INTO t1 VALUES (1, 1); +CREATE VIEW v1 AS SELECT * FROM t1; +CREATE TABLE t2 ( a INT ); +INSERT INTO t2 VALUES (1); +# +# The new non-standard keywords should still be useable as identifiers. +# The standard ones should not. +# +CREATE TABLE t ( of INT ); +CREATE TABLE t0 ( skip INT, locked INT, nowait INT ); +DROP TABLE t, t0; +CREATE PROCEDURE p0() BEGIN of: LOOP LEAVE of; END LOOP of; END| +CREATE PROCEDURE p1() BEGIN skip: LOOP LEAVE skip; END LOOP skip; END| +CREATE PROCEDURE p2() BEGIN locked: LOOP LEAVE locked; END LOOP locked; END| +CREATE PROCEDURE p3() BEGIN nowait: LOOP LEAVE nowait; END LOOP nowait; END| +DROP PROCEDURE p0; +DROP PROCEDURE p1; +DROP PROCEDURE p2; +DROP PROCEDURE p3; +# +# Test of the syntax. +# +# +# UPDATE ... +# +SELECT * FROM t1 FOR UPDATE; +a b +1 1 +SELECT * FROM t1 FOR UPDATE NOWAIT; +a b +1 1 +SELECT * FROM t1 FOR UPDATE SKIP LOCKED; +a b +1 1 +# +# Dual locking clauses +# +SELECT * FROM t1 JOIN t2 FOR UPDATE; +a b a +1 1 1 +SELECT * FROM t1 STRAIGHT_JOIN t2 FOR UPDATE; +a b a +1 1 1 +# +# Derived tables and views. +# +SELECT 1 FROM ( SELECT 1 ) AS t2 FOR UPDATE; +1 +1 +SELECT 1 FROM v1 FOR UPDATE; +1 +1 +# +# Test of syntax errors. +# +SELECT * FROM t1 FOR SHARE WAIT WAIT; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SHARE WAIT WAIT' at line 1 +SELECT * FROM t1 FOR SHARE WAIT NOWAIT; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SHARE WAIT NOWAIT' at line 1 +SELECT * FROM t1 FOR SHARE WAIT SKIP LOCKED; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SHARE WAIT SKIP LOCKED' at line 1 +SELECT 1 FOR UPDATE UNION SELECT 2; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'UNION SELECT 2' at line 1 +SELECT 1 LOCK IN SHARE MODE UNION SELECT 2; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'UNION SELECT 2' at line 1 +SELECT 1 FOR SHARE UNION SELECT 2; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'SHARE UNION SELECT 2' at line 1 +SELECT * FROM t1 LEFT JOIN t2 FOR UPDATE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'FOR UPDATE' at line 1 +SELECT * FROM t1 LEFT JOIN t2 FOR SHARE; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'FOR SHARE' at line 1 +SELECT * FROM t1 LEFT JOIN t2 FOR SHARE OF t1 FOR UPDATE OF t2; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'FOR SHARE OF t1 FOR UPDATE OF t2' at line 1 +SELECT * FROM t1 RIGHT JOIN t2 FOR SHARE OF t1 FOR UPDATE OF t2; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'FOR SHARE OF t1 FOR UPDATE OF t2' at line 1 +# +# Test of error messages. +# +CREATE DATABASE db1; +CREATE TABLE db1.t1 ( a INT, b INT ); +INSERT INTO t1 VALUES (10, 10); +SELECT MIN(a) FROM t1 FOR UPDATE SKIP LOCKED; +MIN(a) +1 +SELECT MAX(a) FROM t1 FOR UPDATE SKIP LOCKED; +MAX(a) +10 +SELECT SUM(a) FROM t1 FOR UPDATE SKIP LOCKED; +SUM(a) +11 +SELECT MIN(a) FROM t1 FOR UPDATE NOWAIT; +MIN(a) +1 +SELECT MAX(a) FROM t1 FOR UPDATE NOWAIT; +MAX(a) +10 +SELECT SUM(a) FROM t1 FOR UPDATE NOWAIT; +SUM(a) +11 +SELECT DISTINCT * FROM t1 FOR UPDATE SKIP LOCKED; +a b +1 1 +10 10 +SELECT DISTINCT * FROM t1 FOR UPDATE NOWAIT; +a b +1 1 +10 10 +SELECT MIN(b) FROM t1 GROUP BY a FOR UPDATE SKIP LOCKED; +MIN(b) +1 +10 +# +# Regression testing. +# +DROP DATABASE db1; +DROP VIEW v1; +DROP TABLE t1, t2; +# +# Bug#25972285: UNCLEAR ERROR MESSAGE FOR NOWAIT +# +CREATE USER test@localhost; +GRANT CREATE, SELECT, UPDATE on *.* to test@localhost; +CREATE USER test2@localhost; +GRANT CREATE, SELECT, UPDATE on *.* to test2@localhost; +CREATE TABLE t1 ( a INT ) ENGINE=InnoDB; +INSERT INTO t1 VALUES ( 1 ); +connect con1, localhost, test, , test; +BEGIN; +SELECT * FROM t1 WHERE a = 2 FOR UPDATE ; +a +connect con2,localhost,test2,,test; +BEGIN; +SELECT * FROM t1 FOR UPDATE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +COMMIT; +connection default; +disconnect con1; +disconnect con2; +DROP TABLE t1; +DROP USER test@localhost; +DROP USER test2@localhost; +# +# Bug#30237291: "SELECT ... INTO VAR_NAME FOR UPDATE" NOT WORKING IN +# MYSQL 8 +# +SELECT 1 FROM DUAL LIMIT 1 INTO @var FOR UPDATE; +Warnings: +Warning 1287 ' INTO FROM...' instead +SELECT 1 FROM DUAL LIMIT 1 FOR UPDATE INTO @var; +Warnings: +Warning 1287 ' INTO FROM...' instead +SELECT 1 FROM DUAL LIMIT 1 INTO @var FOR UPDATE INTO @var; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'INTO @var' at line 1 +SELECT 1 UNION SELECT 1 FOR UPDATE INTO @var; +Warnings: +Warning 1287 ' INTO FROM...' instead +SELECT 1 UNION SELECT 1 INTO @var FOR UPDATE; +Warnings: +Warning 1287 ' INTO FROM...' instead diff --git a/mysql-test/main/locking_clause.test b/mysql-test/main/locking_clause.test new file mode 100644 index 00000000000..407ac4e74f7 --- /dev/null +++ b/mysql-test/main/locking_clause.test @@ -0,0 +1,157 @@ +--source include/have_innodb.inc + +CREATE TABLE t1 ( a INT, b INT ); +INSERT INTO t1 VALUES (1, 1); + +CREATE VIEW v1 AS SELECT * FROM t1; + +CREATE TABLE t2 ( a INT ); +INSERT INTO t2 VALUES (1); + +--echo # +--echo # The new non-standard keywords should still be useable as identifiers. +--echo # The standard ones should not. +--echo # + +CREATE TABLE t ( of INT ); +CREATE TABLE t0 ( skip INT, locked INT, nowait INT ); +DROP TABLE t, t0; + +delimiter |; + +CREATE PROCEDURE p0() BEGIN of: LOOP LEAVE of; END LOOP of; END| +CREATE PROCEDURE p1() BEGIN skip: LOOP LEAVE skip; END LOOP skip; END| +CREATE PROCEDURE p2() BEGIN locked: LOOP LEAVE locked; END LOOP locked; END| +CREATE PROCEDURE p3() BEGIN nowait: LOOP LEAVE nowait; END LOOP nowait; END| + +delimiter ;| + +DROP PROCEDURE p0; +DROP PROCEDURE p1; +DROP PROCEDURE p2; +DROP PROCEDURE p3; + +--echo # +--echo # Test of the syntax. +--echo # + +--echo # +--echo # UPDATE ... +--echo # +SELECT * FROM t1 FOR UPDATE; +SELECT * FROM t1 FOR UPDATE NOWAIT; +SELECT * FROM t1 FOR UPDATE SKIP LOCKED; + +--echo # +--echo # Dual locking clauses +--echo # +SELECT * FROM t1 JOIN t2 FOR UPDATE; +SELECT * FROM t1 STRAIGHT_JOIN t2 FOR UPDATE; + +--echo # +--echo # Derived tables and views. +--echo # +SELECT 1 FROM ( SELECT 1 ) AS t2 FOR UPDATE; +SELECT 1 FROM v1 FOR UPDATE; + +--echo # +--echo # Test of syntax errors. +--echo # + +--error ER_PARSE_ERROR +SELECT * FROM t1 FOR SHARE WAIT WAIT; +--error ER_PARSE_ERROR +SELECT * FROM t1 FOR SHARE WAIT NOWAIT; +--error ER_PARSE_ERROR +SELECT * FROM t1 FOR SHARE WAIT SKIP LOCKED; +--error ER_PARSE_ERROR +SELECT 1 FOR UPDATE UNION SELECT 2; +--error ER_PARSE_ERROR +SELECT 1 LOCK IN SHARE MODE UNION SELECT 2; +--error ER_PARSE_ERROR +SELECT 1 FOR SHARE UNION SELECT 2; +--error ER_PARSE_ERROR +SELECT * FROM t1 LEFT JOIN t2 FOR UPDATE; +--error ER_PARSE_ERROR +SELECT * FROM t1 LEFT JOIN t2 FOR SHARE; +--error ER_PARSE_ERROR +SELECT * FROM t1 LEFT JOIN t2 FOR SHARE OF t1 FOR UPDATE OF t2; +--error ER_PARSE_ERROR +SELECT * FROM t1 RIGHT JOIN t2 FOR SHARE OF t1 FOR UPDATE OF t2; + +--echo # +--echo # Test of error messages. +--echo # + +CREATE DATABASE db1; +CREATE TABLE db1.t1 ( a INT, b INT ); +INSERT INTO t1 VALUES (10, 10); + +SELECT MIN(a) FROM t1 FOR UPDATE SKIP LOCKED; +SELECT MAX(a) FROM t1 FOR UPDATE SKIP LOCKED; +SELECT SUM(a) FROM t1 FOR UPDATE SKIP LOCKED; + +SELECT MIN(a) FROM t1 FOR UPDATE NOWAIT; +SELECT MAX(a) FROM t1 FOR UPDATE NOWAIT; +SELECT SUM(a) FROM t1 FOR UPDATE NOWAIT; + +SELECT DISTINCT * FROM t1 FOR UPDATE SKIP LOCKED; +SELECT DISTINCT * FROM t1 FOR UPDATE NOWAIT; + +SELECT MIN(b) FROM t1 GROUP BY a FOR UPDATE SKIP LOCKED; + +--echo # +--echo # Regression testing. +--echo # + +DROP DATABASE db1; +DROP VIEW v1; +DROP TABLE t1, t2; + +--echo # +--echo # Bug#25972285: UNCLEAR ERROR MESSAGE FOR NOWAIT +--echo # +CREATE USER test@localhost; +GRANT CREATE, SELECT, UPDATE on *.* to test@localhost; + +CREATE USER test2@localhost; +GRANT CREATE, SELECT, UPDATE on *.* to test2@localhost; + +CREATE TABLE t1 ( a INT ) ENGINE=InnoDB; +INSERT INTO t1 VALUES ( 1 ); + +connect (con1, localhost, test, , test); + +BEGIN; +SELECT * FROM t1 WHERE a = 2 FOR UPDATE ; + +connect (con2,localhost,test2,,test); +BEGIN; + +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 FOR UPDATE NOWAIT; + +COMMIT; + +connection default; +disconnect con1; +disconnect con2; + +DROP TABLE t1; +DROP USER test@localhost; +DROP USER test2@localhost; + +--echo # +--echo # Bug#30237291: "SELECT ... INTO VAR_NAME FOR UPDATE" NOT WORKING IN +--echo # MYSQL 8 +--echo # + +SELECT 1 FROM DUAL LIMIT 1 INTO @var FOR UPDATE; +SELECT 1 FROM DUAL LIMIT 1 FOR UPDATE INTO @var; + +# Double INTO should fail: +--error ER_PARSE_ERROR +SELECT 1 FROM DUAL LIMIT 1 INTO @var FOR UPDATE INTO @var; + +SELECT 1 UNION SELECT 1 FOR UPDATE INTO @var; +SELECT 1 UNION SELECT 1 INTO @var FOR UPDATE; diff --git a/mysql-test/suite/innodb/r/partition_locking.result b/mysql-test/suite/innodb/r/partition_locking.result new file mode 100644 index 00000000000..56bfe388517 --- /dev/null +++ b/mysql-test/suite/innodb/r/partition_locking.result @@ -0,0 +1,461 @@ +set @start_read_only= @@global.read_only; +set @start_autocommit= @@global.autocommit; +set default_storage_engine= innodb; +set @@global.autocommit= 0; +CREATE USER test@localhost; +grant CREATE, SELECT, UPDATE on *.* to test@localhost; +CREATE USER test2@localhost; +grant CREATE, SELECT, UPDATE on *.* to test2@localhost; +CREATE TABLE t1 ( +a char(2) NOT NULL, +b char(2) NOT NULL, +c int(10) unsigned NOT NULL, +d varchar(255) DEFAULT NULL, +e varchar(1000) DEFAULT NULL, +PRIMARY KEY (a, b, c), +KEY (a), +KEY (a, b) +) charset latin1 PARTITION BY KEY (a) PARTITIONS 20; +INSERT INTO t1 (a, b, c, d, e) VALUES +('07', '03', 343, '1', '07_03_343'), +('01', '04', 343, '2', '01_04_343'), +('01', '06', 343, '3', '01_06_343'), +('01', '07', 343, '4', '01_07_343'), +('01', '08', 343, '5', '01_08_343'), +('01', '09', 343, '6', '01_09_343'), +('03', '03', 343, '7', '03_03_343'), +('03', '06', 343, '8', '03_06_343'), +('03', '07', 343, '9', '03_07_343'), +('04', '03', 343, '10', '04_03_343'), +('04', '06', 343, '11', '04_06_343'), +('05', '03', 343, '12', '05_03_343'), +('11', '03', 343, '13', '11_03_343'), +('11', '04', 343, '14', '11_04_343') +; +CREATE TABLE t2 (a int, name VARCHAR(50), purchased DATE) +PARTITION BY RANGE (a) +(PARTITION p0 VALUES LESS THAN (3), +PARTITION p1 VALUES LESS THAN (7), +PARTITION p2 VALUES LESS THAN (9), +PARTITION p3 VALUES LESS THAN (11)); +INSERT INTO t2 VALUES +(1, 'desk organiser', '2003-10-15'), +(2, 'CD player', '1993-11-05'), +(3, 'TV set', '1996-03-10'), +(4, 'bookcase', '1982-01-10'), +(5, 'exercise bike', '2004-05-09'), +(6, 'sofa', '1987-06-05'), +(7, 'popcorn maker', '2001-11-22'), +(8, 'acquarium', '1992-08-04'), +(9, 'study desk', '1984-09-16'), +(10, 'lava lamp', '1998-12-25'); +CREATE TABLE t3 SELECT * FROM t1; +ALTER TABLE t3 ADD PRIMARY KEY (d); +ALTER TABLE t3 ADD KEY (a); +ALTER TABLE t3 ADD KEY (a, b); +ANALYZE TABLE t3; +Table Op Msg_type Msg_text +test.t3 analyze status Engine-independent statistics collected +test.t3 analyze status OK +######################################################################## +connect con1,localhost,test,,test; +BEGIN; +SELECT d,a,b,c FROM t1 partition (p0); +d a b c +SELECT d,a,b,c FROM t1 partition (p1); +d a b c +7 03 03 343 +8 03 06 343 +9 03 07 343 +SELECT d,a,b,c FROM t1 partition (p2); +d a b c +SELECT d,a,b,c FROM t1 partition (p3); +d a b c +SELECT d,a,b,c FROM t1 partition (p4); +d a b c +SELECT d,a,b,c FROM t1 partition (p5); +d a b c +SELECT d,a,b,c FROM t1 partition (p6); +d a b c +SELECT d,a,b,c FROM t1 partition (p7); +d a b c +SELECT d,a,b,c FROM t1 partition (p8); +d a b c +SELECT d,a,b,c FROM t1 partition (p9); +d a b c +2 01 04 343 +3 01 06 343 +4 01 07 343 +5 01 08 343 +6 01 09 343 +10 04 03 343 +11 04 06 343 +12 05 03 343 +SELECT d,a,b,c FROM t1 partition (p10); +d a b c +SELECT d,a,b,c FROM t1 partition (p11); +d a b c +13 11 03 343 +14 11 04 343 +SELECT d,a,b,c FROM t1 partition (p12); +d a b c +SELECT d,a,b,c FROM t1 partition (p13); +d a b c +SELECT d,a,b,c FROM t1 partition (p14); +d a b c +SELECT d,a,b,c FROM t1 partition (p15); +d a b c +SELECT d,a,b,c FROM t1 partition (p16); +d a b c +SELECT d,a,b,c FROM t1 partition (p17); +d a b c +1 07 03 343 +SELECT d,a,b,c FROM t1 partition (p18); +d a b c +SELECT d,a,b,c FROM t1 partition (p19); +d a b c +SELECT * FROM t1 WHERE a='01' FOR UPDATE ; +a b c d e +01 04 343 2 01_04_343 +01 06 343 3 01_06_343 +01 07 343 4 01_07_343 +01 08 343 5 01_08_343 +01 09 343 6 01_09_343 +SELECT * FROM t3 FORCE INDEX(a) WHERE a='01' FOR UPDATE ; +a b c d e +01 04 343 2 01_04_343 +01 06 343 3 01_06_343 +01 07 343 4 01_07_343 +01 08 343 5 01_08_343 +01 09 343 6 01_09_343 +connect con2,localhost,test,,test; +BEGIN; +SET SESSION innodb_lock_wait_timeout=1; +# +# SHARE ... +SELECT * FROM t1 LOCK IN SHARE MODE; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 LOCK IN SHARE MODE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 ORDER BY d LOCK IN SHARE MODE SKIP LOCKED; +a b c d e +07 03 343 1 07_03_343 +04 03 343 10 04_03_343 +04 06 343 11 04_06_343 +05 03 343 12 05_03_343 +11 03 343 13 11_03_343 +11 04 343 14 11_04_343 +03 03 343 7 03_03_343 +03 06 343 8 03_06_343 +03 07 343 9 03_07_343 +SELECT a,count(b) FROM t1 GROUP BY a ORDER BY a LOCK IN SHARE MODE SKIP LOCKED; +a count(b) +01 5 +03 3 +04 2 +05 1 +07 1 +11 2 +SELECT d,a,b,c FROM t1 partition (p1,p9,p11,p17) ORDER BY d +LOCK IN SHARE MODE SKIP LOCKED; +d a b c +1 07 03 343 +10 04 03 343 +11 04 06 343 +12 05 03 343 +13 11 03 343 +14 11 04 343 +7 03 03 343 +8 03 06 343 +9 03 07 343 +SELECT d,a,b,c FROM t1 ORDER BY d LOCK IN SHARE MODE SKIP LOCKED; +d a b c +1 07 03 343 +10 04 03 343 +11 04 06 343 +12 05 03 343 +13 11 03 343 +14 11 04 343 +7 03 03 343 +8 03 06 343 +9 03 07 343 +ANALYZE TABLE t3; +Table Op Msg_type Msg_text +test.t3 analyze status Engine-independent statistics collected +test.t3 analyze status OK +SELECT d,a,b,c FROM t3 ORDER BY d LOCK IN SHARE MODE SKIP LOCKED; +d a b c +1 07 03 343 +10 04 03 343 +11 04 06 343 +12 05 03 343 +13 11 03 343 +14 11 04 343 +7 03 03 343 +8 03 06 343 +9 03 07 343 +explain SELECT d,a,b,c FROM t3 ORDER BY d +LOCK IN SHARE MODE SKIP LOCKED; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 index NULL PRIMARY 257 NULL 14 +# +# UPDATE ... +SELECT * FROM t1 FOR UPDATE; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 FOR UPDATE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 ORDER BY a FOR UPDATE SKIP LOCKED; +a b c d e +03 03 343 7 03_03_343 +03 06 343 8 03_06_343 +03 07 343 9 03_07_343 +04 03 343 10 04_03_343 +04 06 343 11 04_06_343 +05 03 343 12 05_03_343 +07 03 343 1 07_03_343 +11 03 343 13 11_03_343 +11 04 343 14 11_04_343 +SELECT a,count(b) FROM t1 GROUP BY a ORDER BY a FOR UPDATE SKIP LOCKED; +a count(b) +03 3 +04 2 +05 1 +07 1 +11 2 +SELECT d,a,b,c FROM t1 partition (p1,p9,p11,p17) ORDER BY d +FOR UPDATE SKIP LOCKED; +d a b c +1 07 03 343 +10 04 03 343 +11 04 06 343 +12 05 03 343 +13 11 03 343 +14 11 04 343 +7 03 03 343 +8 03 06 343 +9 03 07 343 +SELECT d,a,b,c FROM t1 ORDER BY d FOR UPDATE SKIP LOCKED; +d a b c +1 07 03 343 +10 04 03 343 +11 04 06 343 +12 05 03 343 +13 11 03 343 +14 11 04 343 +7 03 03 343 +8 03 06 343 +9 03 07 343 +SELECT d,a,b,c FROM t3 ORDER BY d FOR UPDATE SKIP LOCKED; +d a b c +1 07 03 343 +10 04 03 343 +11 04 06 343 +12 05 03 343 +13 11 03 343 +14 11 04 343 +7 03 03 343 +8 03 06 343 +9 03 07 343 +connection con1; +COMMIT; +connection con1; +BEGIN; +SELECT * FROM t1 WHERE a='01' LOCK IN SHARE MODE ; +a b c d e +01 04 343 2 01_04_343 +01 06 343 3 01_06_343 +01 07 343 4 01_07_343 +01 08 343 5 01_08_343 +01 09 343 6 01_09_343 +SELECT * FROM t3 FORCE INDEX(a) WHERE a='01' LOCK IN SHARE MODE ; +a b c d e +01 04 343 2 01_04_343 +01 06 343 3 01_06_343 +01 07 343 4 01_07_343 +01 08 343 5 01_08_343 +01 09 343 6 01_09_343 +connection con2; +BEGIN; +SET SESSION innodb_lock_wait_timeout=1; +# +# SHARE ... +SELECT * FROM t1 LOCK IN SHARE MODE; +a b c d e +03 03 343 7 03_03_343 +03 06 343 8 03_06_343 +03 07 343 9 03_07_343 +01 04 343 2 01_04_343 +01 06 343 3 01_06_343 +01 07 343 4 01_07_343 +01 08 343 5 01_08_343 +01 09 343 6 01_09_343 +04 03 343 10 04_03_343 +04 06 343 11 04_06_343 +05 03 343 12 05_03_343 +11 03 343 13 11_03_343 +11 04 343 14 11_04_343 +07 03 343 1 07_03_343 +SELECT * FROM t1 LOCK IN SHARE MODE NOWAIT; +a b c d e +03 03 343 7 03_03_343 +03 06 343 8 03_06_343 +03 07 343 9 03_07_343 +01 04 343 2 01_04_343 +01 06 343 3 01_06_343 +01 07 343 4 01_07_343 +01 08 343 5 01_08_343 +01 09 343 6 01_09_343 +04 03 343 10 04_03_343 +04 06 343 11 04_06_343 +05 03 343 12 05_03_343 +11 03 343 13 11_03_343 +11 04 343 14 11_04_343 +07 03 343 1 07_03_343 +SELECT * FROM t1 ORDER BY d LOCK IN SHARE MODE SKIP LOCKED; +a b c d e +07 03 343 1 07_03_343 +04 03 343 10 04_03_343 +04 06 343 11 04_06_343 +05 03 343 12 05_03_343 +11 03 343 13 11_03_343 +11 04 343 14 11_04_343 +01 04 343 2 01_04_343 +01 06 343 3 01_06_343 +01 07 343 4 01_07_343 +01 08 343 5 01_08_343 +01 09 343 6 01_09_343 +03 03 343 7 03_03_343 +03 06 343 8 03_06_343 +03 07 343 9 03_07_343 +SELECT a,count(b) FROM t1 GROUP BY a ORDER BY a LOCK IN SHARE MODE SKIP LOCKED; +a count(b) +01 5 +03 3 +04 2 +05 1 +07 1 +11 2 +SELECT d,a,b,c FROM t1 partition (p1,p9,p11,p17) ORDER BY d +LOCK IN SHARE MODE SKIP LOCKED; +d a b c +1 07 03 343 +10 04 03 343 +11 04 06 343 +12 05 03 343 +13 11 03 343 +14 11 04 343 +2 01 04 343 +3 01 06 343 +4 01 07 343 +5 01 08 343 +6 01 09 343 +7 03 03 343 +8 03 06 343 +9 03 07 343 +SELECT d,a,b,c FROM t1 ORDER BY d LOCK IN SHARE MODE SKIP LOCKED; +d a b c +1 07 03 343 +10 04 03 343 +11 04 06 343 +12 05 03 343 +13 11 03 343 +14 11 04 343 +2 01 04 343 +3 01 06 343 +4 01 07 343 +5 01 08 343 +6 01 09 343 +7 03 03 343 +8 03 06 343 +9 03 07 343 +ANALYZE TABLE t3; +Table Op Msg_type Msg_text +test.t3 analyze status Engine-independent statistics collected +test.t3 analyze status OK +SELECT d,a,b,c FROM t3 ORDER BY d LOCK IN SHARE MODE SKIP LOCKED; +d a b c +1 07 03 343 +10 04 03 343 +11 04 06 343 +12 05 03 343 +13 11 03 343 +14 11 04 343 +2 01 04 343 +3 01 06 343 +4 01 07 343 +5 01 08 343 +6 01 09 343 +7 03 03 343 +8 03 06 343 +9 03 07 343 +explain SELECT d,a,b,c FROM t3 ORDER BY d +LOCK IN SHARE MODE SKIP LOCKED; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t3 index NULL PRIMARY 257 NULL 14 +# +# UPDATE ... +SELECT * FROM t1 FOR UPDATE; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 FOR UPDATE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 ORDER BY a FOR UPDATE SKIP LOCKED; +a b c d e +03 03 343 7 03_03_343 +03 06 343 8 03_06_343 +03 07 343 9 03_07_343 +04 03 343 10 04_03_343 +04 06 343 11 04_06_343 +05 03 343 12 05_03_343 +07 03 343 1 07_03_343 +11 03 343 13 11_03_343 +11 04 343 14 11_04_343 +SELECT a,count(b) FROM t1 GROUP BY a ORDER BY a FOR UPDATE SKIP LOCKED; +a count(b) +03 3 +04 2 +05 1 +07 1 +11 2 +SELECT d,a,b,c FROM t1 partition (p1,p9,p11,p17) ORDER BY d +FOR UPDATE SKIP LOCKED; +d a b c +1 07 03 343 +10 04 03 343 +11 04 06 343 +12 05 03 343 +13 11 03 343 +14 11 04 343 +7 03 03 343 +8 03 06 343 +9 03 07 343 +SELECT d,a,b,c FROM t1 ORDER BY d FOR UPDATE SKIP LOCKED; +d a b c +1 07 03 343 +10 04 03 343 +11 04 06 343 +12 05 03 343 +13 11 03 343 +14 11 04 343 +7 03 03 343 +8 03 06 343 +9 03 07 343 +SELECT d,a,b,c FROM t3 ORDER BY d FOR UPDATE SKIP LOCKED; +d a b c +1 07 03 343 +10 04 03 343 +11 04 06 343 +12 05 03 343 +13 11 03 343 +14 11 04 343 +7 03 03 343 +8 03 06 343 +9 03 07 343 +connection default; +disconnect con1; +disconnect con2; +DROP TABLE t1, t2, t3; +DROP USER test@localhost; +DROP USER test2@localhost; +set @@global.read_only= @start_read_only; +set @@global.autocommit= @start_autocommit; +set default_storage_engine= default; diff --git a/mysql-test/suite/innodb/r/skip_locked_nowait.result b/mysql-test/suite/innodb/r/skip_locked_nowait.result new file mode 100644 index 00000000000..9a48f97dbe3 --- /dev/null +++ b/mysql-test/suite/innodb/r/skip_locked_nowait.result @@ -0,0 +1,209 @@ +connect con1,localhost,root,,; +SET SESSION innodb_lock_wait_timeout=1; +connection default; +SET SESSION innodb_lock_wait_timeout=1; +# Case 1: Test primary index +CREATE TABLE t1( +seat_id INT, +state INT, +PRIMARY KEY(seat_id) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1,0), (2,0), (3,0), (4,0); +BEGIN; +SELECT * FROM t1 WHERE state = 0 LIMIT 2 LOCK IN SHARE MODE; +seat_id state +1 0 +2 0 +connection con1; +BEGIN; +SELECT * FROM t1 WHERE state = 0 LIMIT 2 LOCK IN SHARE MODE; +seat_id state +1 0 +2 0 +SELECT * FROM t1 WHERE state = 0 LIMIT 2 LOCK IN SHARE MODE SKIP LOCKED; +seat_id state +1 0 +2 0 +SELECT * FROM t1 WHERE state = 0 LIMIT 2 FOR UPDATE; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 WHERE state = 0 LIMIT 2 FOR UPDATE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 WHERE state = 0 LIMIT 2 FOR UPDATE SKIP LOCKED; +seat_id state +3 0 +4 0 +SELECT * FROM t1 WHERE seat_id > 0 LIMIT 2 FOR UPDATE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 WHERE seat_id > 0 LIMIT 2 FOR UPDATE SKIP LOCKED; +seat_id state +3 0 +4 0 +COMMIT; +connection default; +SELECT * FROM t1 WHERE state = 0 LIMIT 2 FOR UPDATE; +seat_id state +1 0 +2 0 +connection con1; +SELECT * FROM t1 WHERE state = 0 LIMIT 2 LOCK IN SHARE MODE; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 WHERE state = 0 LIMIT 2 LOCK IN SHARE MODE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 WHERE state = 0 LIMIT 2 LOCK IN SHARE MODE SKIP LOCKED; +seat_id state +3 0 +4 0 +SELECT * FROM t1 WHERE state = 0 LIMIT 2 FOR UPDATE; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 WHERE state = 0 LIMIT 2 FOR UPDATE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 WHERE state = 0 LIMIT 2 FOR UPDATE SKIP LOCKED; +seat_id state +3 0 +4 0 +SELECT * FROM t1 WHERE seat_id > 0 LIMIT 2 FOR UPDATE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 WHERE seat_id > 0 LIMIT 2 FOR UPDATE SKIP LOCKED; +seat_id state +3 0 +4 0 +COMMIT; +connection default; +COMMIT; +DROP TABLE t1; +# Case 2: Test primary index & secondary index +CREATE TABLE t1( +seat_id INT, +row_id INT, +state INT, +PRIMARY KEY(seat_id), +KEY(row_id) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1,1,0), (2,1,0), (3,2,0), (4,2,0); +# Test secondary key +BEGIN; +SELECT * FROM t1 WHERE state = 0 AND row_id = 1 LIMIT 1 FOR UPDATE NOWAIT; +seat_id row_id state +1 1 0 +connection con1; +BEGIN; +SELECT * FROM t1 WHERE state = 0 AND row_id = 1 LIMIT 1 FOR UPDATE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 WHERE state = 0 AND row_id = 1 LIMIT 1 FOR UPDATE SKIP LOCKED; +seat_id row_id state +2 1 0 +SELECT * FROM t1 WHERE state = 0 AND row_id > 0 LIMIT 1 FOR UPDATE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 WHERE state = 0 AND row_id > 0 LIMIT 1 FOR UPDATE SKIP LOCKED; +seat_id row_id state +2 1 0 +SELECT * FROM t1 WHERE state = 0 FOR UPDATE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 WHERE state = 0 FOR UPDATE SKIP LOCKED; +seat_id row_id state +2 1 0 +3 2 0 +4 2 0 +COMMIT; +connection default; +COMMIT; +BEGIN; +SELECT * FROM t1 WHERE seat_id = 1 FOR UPDATE NOWAIT; +seat_id row_id state +1 1 0 +connection con1; +BEGIN; +SELECT * FROM t1 WHERE state = 0 AND row_id = 1 LIMIT 1 FOR UPDATE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 WHERE state = 0 AND row_id = 1 LIMIT 1 FOR UPDATE SKIP LOCKED; +seat_id row_id state +2 1 0 +SELECT * FROM t1 WHERE state = 0 FOR UPDATE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT * FROM t1 WHERE state = 0 FOR UPDATE SKIP LOCKED; +seat_id row_id state +2 1 0 +3 2 0 +4 2 0 +COMMIT; +connection default; +COMMIT; +DROP TABLE t1; +# Case 3: Test primary index & spatial index +CREATE TABLE t1( +seat_id INT, +pos POINT NOT NULL, +state INT, +PRIMARY KEY(seat_id), +SPATIAL KEY(pos) +) ENGINE=InnoDB; +INSERT INTO t1 VALUES +(1,ST_PointFromText('POINT(1 0)'),0), +(2,ST_PointFromText('POINT(1 1)'),0), +(3,ST_PointFromText('POINT(2 0)'),0), +(4,ST_PointFromText('POINT(2 1)'),0), +(5,ST_PointFromText('POINT(3 0)'),0), +(6,ST_PointFromText('POINT(3 1)'),0); +BEGIN; +SET @g = ST_GeomFromText('POLYGON((0 0,0 2,2 2,0 2,0 0))'); +SELECT seat_id, state, ST_AsText(pos) FROM t1 FORCE INDEX (pos) +WHERE state = 0 AND MBRWithin(pos, @g) FOR UPDATE NOWAIT; +seat_id state ST_AsText(pos) +2 0 POINT(1 1) +connection con1; +BEGIN; +SET @g = ST_GeomFromText('POLYGON((0 0,0 4,4 4,0 4,0 0))'); +SELECT seat_id, state, ST_AsText(pos) FROM t1 FORCE INDEX (pos) +WHERE state = 0 AND MBRWithin(pos, @g) FOR UPDATE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT seat_id, state, ST_AsText(pos) FROM t1 FORCE INDEX (pos) +WHERE state = 0 AND MBRWithin(pos, @g) FOR UPDATE SKIP LOCKED; +seat_id state ST_AsText(pos) +6 0 POINT(3 1) +SELECT seat_id, state, ST_AsText(pos) FROM t1 +WHERE state = 0 FOR UPDATE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT seat_id, state, ST_AsText(pos) FROM t1 +WHERE state = 0 FOR UPDATE SKIP LOCKED; +seat_id state ST_AsText(pos) +5 0 POINT(3 0) +6 0 POINT(3 1) +COMMIT; +connection default; +COMMIT; +connection con1; +SET @g = ST_GeomFromText('POLYGON((0 0,0 3,3 3,0 3,0 0))'); +SELECT seat_id, state, ST_AsText(pos) FROM t1 FORCE INDEX (pos) +WHERE state = 0 AND MBRWithin(pos, @g) FOR UPDATE; +seat_id state ST_AsText(pos) +4 0 POINT(2 1) +2 0 POINT(1 1) +connection default; +BEGIN; +SELECT seat_id, state, ST_AsText(pos) FROM t1 +WHERE seat_id = 4 FOR UPDATE NOWAIT; +seat_id state ST_AsText(pos) +4 0 POINT(2 1) +connection con1; +SELECT seat_id, state, ST_AsText(pos) FROM t1 FORCE INDEX (pos) +WHERE state = 0 AND MBRWithin(pos, @g) FOR UPDATE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT seat_id, state, ST_AsText(pos) FROM t1 FORCE INDEX (pos) +WHERE state = 0 AND MBRWithin(pos, @g) FOR UPDATE SKIP LOCKED; +seat_id state ST_AsText(pos) +2 0 POINT(1 1) +SELECT seat_id, state, ST_AsText(pos) FROM t1 +WHERE state = 0 FOR UPDATE NOWAIT; +ERROR HY000: Lock wait timeout exceeded; try restarting transaction +SELECT seat_id, state, ST_AsText(pos) FROM t1 +WHERE state = 0 FOR UPDATE SKIP LOCKED; +seat_id state ST_AsText(pos) +1 0 POINT(1 0) +2 0 POINT(1 1) +3 0 POINT(2 0) +5 0 POINT(3 0) +6 0 POINT(3 1) +connection default; +COMMIT; +DROP TABLE t1; +disconnect con1; diff --git a/mysql-test/suite/innodb/t/partition_locking.test b/mysql-test/suite/innodb/t/partition_locking.test new file mode 100644 index 00000000000..e33df934a28 --- /dev/null +++ b/mysql-test/suite/innodb/t/partition_locking.test @@ -0,0 +1,178 @@ +# Test of SKIP LOCKED and NOWAIT on partitioned tables. +# Must have same results as not partitioned tables. +--source include/have_innodb.inc +--source include/have_partition.inc + +set @start_read_only= @@global.read_only; +set @start_autocommit= @@global.autocommit; +set default_storage_engine= innodb; +set @@global.autocommit= 0; + +CREATE USER test@localhost; +grant CREATE, SELECT, UPDATE on *.* to test@localhost; +CREATE USER test2@localhost; +grant CREATE, SELECT, UPDATE on *.* to test2@localhost; + +CREATE TABLE t1 ( +a char(2) NOT NULL, +b char(2) NOT NULL, +c int(10) unsigned NOT NULL, +d varchar(255) DEFAULT NULL, +e varchar(1000) DEFAULT NULL, +PRIMARY KEY (a, b, c), +KEY (a), +KEY (a, b) +) charset latin1 PARTITION BY KEY (a) PARTITIONS 20; + +INSERT INTO t1 (a, b, c, d, e) VALUES +('07', '03', 343, '1', '07_03_343'), +('01', '04', 343, '2', '01_04_343'), +('01', '06', 343, '3', '01_06_343'), +('01', '07', 343, '4', '01_07_343'), +('01', '08', 343, '5', '01_08_343'), +('01', '09', 343, '6', '01_09_343'), +('03', '03', 343, '7', '03_03_343'), +('03', '06', 343, '8', '03_06_343'), +('03', '07', 343, '9', '03_07_343'), +('04', '03', 343, '10', '04_03_343'), +('04', '06', 343, '11', '04_06_343'), +('05', '03', 343, '12', '05_03_343'), +('11', '03', 343, '13', '11_03_343'), +('11', '04', 343, '14', '11_04_343') +; + +CREATE TABLE t2 (a int, name VARCHAR(50), purchased DATE) +PARTITION BY RANGE (a) +(PARTITION p0 VALUES LESS THAN (3), + PARTITION p1 VALUES LESS THAN (7), + PARTITION p2 VALUES LESS THAN (9), + PARTITION p3 VALUES LESS THAN (11)); +INSERT INTO t2 VALUES +(1, 'desk organiser', '2003-10-15'), +(2, 'CD player', '1993-11-05'), +(3, 'TV set', '1996-03-10'), +(4, 'bookcase', '1982-01-10'), +(5, 'exercise bike', '2004-05-09'), +(6, 'sofa', '1987-06-05'), +(7, 'popcorn maker', '2001-11-22'), +(8, 'acquarium', '1992-08-04'), +(9, 'study desk', '1984-09-16'), +(10, 'lava lamp', '1998-12-25'); + +CREATE TABLE t3 SELECT * FROM t1; +ALTER TABLE t3 ADD PRIMARY KEY (d); +ALTER TABLE t3 ADD KEY (a); +ALTER TABLE t3 ADD KEY (a, b); +ANALYZE TABLE t3; +#SELECT * FROM t3; + +--echo ######################################################################## +connect (con1,localhost,test,,test); +BEGIN; +SELECT d,a,b,c FROM t1 partition (p0); +SELECT d,a,b,c FROM t1 partition (p1); +SELECT d,a,b,c FROM t1 partition (p2); +SELECT d,a,b,c FROM t1 partition (p3); +SELECT d,a,b,c FROM t1 partition (p4); +SELECT d,a,b,c FROM t1 partition (p5); +SELECT d,a,b,c FROM t1 partition (p6); +SELECT d,a,b,c FROM t1 partition (p7); +SELECT d,a,b,c FROM t1 partition (p8); +SELECT d,a,b,c FROM t1 partition (p9); +SELECT d,a,b,c FROM t1 partition (p10); +SELECT d,a,b,c FROM t1 partition (p11); +SELECT d,a,b,c FROM t1 partition (p12); +SELECT d,a,b,c FROM t1 partition (p13); +SELECT d,a,b,c FROM t1 partition (p14); +SELECT d,a,b,c FROM t1 partition (p15); +SELECT d,a,b,c FROM t1 partition (p16); +SELECT d,a,b,c FROM t1 partition (p17); +SELECT d,a,b,c FROM t1 partition (p18); +SELECT d,a,b,c FROM t1 partition (p19); + +SELECT * FROM t1 WHERE a='01' FOR UPDATE ; +SELECT * FROM t3 FORCE INDEX(a) WHERE a='01' FOR UPDATE ; + +connect (con2,localhost,test,,test); +BEGIN; +SET SESSION innodb_lock_wait_timeout=1; + +--echo # +--echo # SHARE ... +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 LOCK IN SHARE MODE; +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 LOCK IN SHARE MODE NOWAIT; +SELECT * FROM t1 ORDER BY d LOCK IN SHARE MODE SKIP LOCKED; +SELECT a,count(b) FROM t1 GROUP BY a ORDER BY a LOCK IN SHARE MODE SKIP LOCKED; +SELECT d,a,b,c FROM t1 partition (p1,p9,p11,p17) ORDER BY d + LOCK IN SHARE MODE SKIP LOCKED; +SELECT d,a,b,c FROM t1 ORDER BY d LOCK IN SHARE MODE SKIP LOCKED; +ANALYZE TABLE t3; +SELECT d,a,b,c FROM t3 ORDER BY d LOCK IN SHARE MODE SKIP LOCKED; +explain SELECT d,a,b,c FROM t3 ORDER BY d + LOCK IN SHARE MODE SKIP LOCKED; + +--echo # +--echo # UPDATE ... +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 FOR UPDATE; +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 FOR UPDATE NOWAIT; +SELECT * FROM t1 ORDER BY a FOR UPDATE SKIP LOCKED; +SELECT a,count(b) FROM t1 GROUP BY a ORDER BY a FOR UPDATE SKIP LOCKED; +SELECT d,a,b,c FROM t1 partition (p1,p9,p11,p17) ORDER BY d + FOR UPDATE SKIP LOCKED; +SELECT d,a,b,c FROM t1 ORDER BY d FOR UPDATE SKIP LOCKED; +SELECT d,a,b,c FROM t3 ORDER BY d FOR UPDATE SKIP LOCKED; + +connection con1; +COMMIT; + +connection con1; +BEGIN; +SELECT * FROM t1 WHERE a='01' LOCK IN SHARE MODE ; +SELECT * FROM t3 FORCE INDEX(a) WHERE a='01' LOCK IN SHARE MODE ; + +connection con2; +BEGIN; +SET SESSION innodb_lock_wait_timeout=1; + +--echo # +--echo # SHARE ... +SELECT * FROM t1 LOCK IN SHARE MODE; +SELECT * FROM t1 LOCK IN SHARE MODE NOWAIT; +SELECT * FROM t1 ORDER BY d LOCK IN SHARE MODE SKIP LOCKED; +SELECT a,count(b) FROM t1 GROUP BY a ORDER BY a LOCK IN SHARE MODE SKIP LOCKED; +SELECT d,a,b,c FROM t1 partition (p1,p9,p11,p17) ORDER BY d + LOCK IN SHARE MODE SKIP LOCKED; +SELECT d,a,b,c FROM t1 ORDER BY d LOCK IN SHARE MODE SKIP LOCKED; +ANALYZE TABLE t3; +SELECT d,a,b,c FROM t3 ORDER BY d LOCK IN SHARE MODE SKIP LOCKED; +explain SELECT d,a,b,c FROM t3 ORDER BY d + LOCK IN SHARE MODE SKIP LOCKED; + +--echo # +--echo # UPDATE ... +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 FOR UPDATE; +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 FOR UPDATE NOWAIT; +SELECT * FROM t1 ORDER BY a FOR UPDATE SKIP LOCKED; +SELECT a,count(b) FROM t1 GROUP BY a ORDER BY a FOR UPDATE SKIP LOCKED; +SELECT d,a,b,c FROM t1 partition (p1,p9,p11,p17) ORDER BY d + FOR UPDATE SKIP LOCKED; +SELECT d,a,b,c FROM t1 ORDER BY d FOR UPDATE SKIP LOCKED; +SELECT d,a,b,c FROM t3 ORDER BY d FOR UPDATE SKIP LOCKED; + +connection default; +disconnect con1; +disconnect con2; + +DROP TABLE t1, t2, t3; + +DROP USER test@localhost; +DROP USER test2@localhost; +set @@global.read_only= @start_read_only; +set @@global.autocommit= @start_autocommit; +set default_storage_engine= default; diff --git a/mysql-test/suite/innodb/t/skip_locked_nowait.test b/mysql-test/suite/innodb/t/skip_locked_nowait.test new file mode 100644 index 00000000000..d9fbadeb1e0 --- /dev/null +++ b/mysql-test/suite/innodb/t/skip_locked_nowait.test @@ -0,0 +1,207 @@ +# +# wl#8919 Implement NOWAIT and SKIP LOCKED +# +--source include/have_innodb.inc + + +connect (con1,localhost,root,,); +SET SESSION innodb_lock_wait_timeout=1; + +connection default; +SET SESSION innodb_lock_wait_timeout=1; + +--echo # Case 1: Test primary index +CREATE TABLE t1( + seat_id INT, + state INT, + PRIMARY KEY(seat_id) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES(1,0), (2,0), (3,0), (4,0); + +BEGIN; +SELECT * FROM t1 WHERE state = 0 LIMIT 2 LOCK IN SHARE MODE; + +connection con1; +BEGIN; + +SELECT * FROM t1 WHERE state = 0 LIMIT 2 LOCK IN SHARE MODE; + +SELECT * FROM t1 WHERE state = 0 LIMIT 2 LOCK IN SHARE MODE SKIP LOCKED; + +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 WHERE state = 0 LIMIT 2 FOR UPDATE; + +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 WHERE state = 0 LIMIT 2 FOR UPDATE NOWAIT; +SELECT * FROM t1 WHERE state = 0 LIMIT 2 FOR UPDATE SKIP LOCKED; + +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 WHERE seat_id > 0 LIMIT 2 FOR UPDATE NOWAIT; +SELECT * FROM t1 WHERE seat_id > 0 LIMIT 2 FOR UPDATE SKIP LOCKED; + +COMMIT; + +connection default; +SELECT * FROM t1 WHERE state = 0 LIMIT 2 FOR UPDATE; + +connection con1; +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 WHERE state = 0 LIMIT 2 LOCK IN SHARE MODE; + +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 WHERE state = 0 LIMIT 2 LOCK IN SHARE MODE NOWAIT; +SELECT * FROM t1 WHERE state = 0 LIMIT 2 LOCK IN SHARE MODE SKIP LOCKED; + +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 WHERE state = 0 LIMIT 2 FOR UPDATE; + +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 WHERE state = 0 LIMIT 2 FOR UPDATE NOWAIT; +SELECT * FROM t1 WHERE state = 0 LIMIT 2 FOR UPDATE SKIP LOCKED; + +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 WHERE seat_id > 0 LIMIT 2 FOR UPDATE NOWAIT; +SELECT * FROM t1 WHERE seat_id > 0 LIMIT 2 FOR UPDATE SKIP LOCKED; + +COMMIT; + +connection default; +COMMIT; + +DROP TABLE t1; + +--echo # Case 2: Test primary index & secondary index +CREATE TABLE t1( + seat_id INT, + row_id INT, + state INT, + PRIMARY KEY(seat_id), + KEY(row_id) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES(1,1,0), (2,1,0), (3,2,0), (4,2,0); + +--echo # Test secondary key +# Case 2a: secondary blocks secondary/primary +BEGIN; +SELECT * FROM t1 WHERE state = 0 AND row_id = 1 LIMIT 1 FOR UPDATE NOWAIT; + +connection con1; +BEGIN; +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 WHERE state = 0 AND row_id = 1 LIMIT 1 FOR UPDATE NOWAIT; +SELECT * FROM t1 WHERE state = 0 AND row_id = 1 LIMIT 1 FOR UPDATE SKIP LOCKED; + +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 WHERE state = 0 AND row_id > 0 LIMIT 1 FOR UPDATE NOWAIT; +SELECT * FROM t1 WHERE state = 0 AND row_id > 0 LIMIT 1 FOR UPDATE SKIP LOCKED; + +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 WHERE state = 0 FOR UPDATE NOWAIT; +SELECT * FROM t1 WHERE state = 0 FOR UPDATE SKIP LOCKED; + +COMMIT; + +connection default; +COMMIT; + +# Case 2b: primary blocks secondary/primary +BEGIN; +SELECT * FROM t1 WHERE seat_id = 1 FOR UPDATE NOWAIT; + +connection con1; +BEGIN; +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 WHERE state = 0 AND row_id = 1 LIMIT 1 FOR UPDATE NOWAIT; +SELECT * FROM t1 WHERE state = 0 AND row_id = 1 LIMIT 1 FOR UPDATE SKIP LOCKED; + +--error ER_LOCK_WAIT_TIMEOUT +SELECT * FROM t1 WHERE state = 0 FOR UPDATE NOWAIT; +SELECT * FROM t1 WHERE state = 0 FOR UPDATE SKIP LOCKED; + +COMMIT; + +connection default; +COMMIT; + +DROP TABLE t1; + +--echo # Case 3: Test primary index & spatial index +CREATE TABLE t1( + seat_id INT, + pos POINT NOT NULL, + state INT, + PRIMARY KEY(seat_id), + SPATIAL KEY(pos) +) ENGINE=InnoDB; + +INSERT INTO t1 VALUES +(1,ST_PointFromText('POINT(1 0)'),0), +(2,ST_PointFromText('POINT(1 1)'),0), +(3,ST_PointFromText('POINT(2 0)'),0), +(4,ST_PointFromText('POINT(2 1)'),0), +(5,ST_PointFromText('POINT(3 0)'),0), +(6,ST_PointFromText('POINT(3 1)'),0); + +# Case 3a: secondary blocks secondary/primary +BEGIN; +SET @g = ST_GeomFromText('POLYGON((0 0,0 2,2 2,0 2,0 0))'); +# the first 4 records in the rtree index page are locked +SELECT seat_id, state, ST_AsText(pos) FROM t1 FORCE INDEX (pos) +WHERE state = 0 AND MBRWithin(pos, @g) FOR UPDATE NOWAIT; + +connection con1; +BEGIN; +SET @g = ST_GeomFromText('POLYGON((0 0,0 4,4 4,0 4,0 0))'); +--error ER_LOCK_WAIT_TIMEOUT +SELECT seat_id, state, ST_AsText(pos) FROM t1 FORCE INDEX (pos) +WHERE state = 0 AND MBRWithin(pos, @g) FOR UPDATE NOWAIT; + +SELECT seat_id, state, ST_AsText(pos) FROM t1 FORCE INDEX (pos) +WHERE state = 0 AND MBRWithin(pos, @g) FOR UPDATE SKIP LOCKED; + +--error ER_LOCK_WAIT_TIMEOUT +SELECT seat_id, state, ST_AsText(pos) FROM t1 +WHERE state = 0 FOR UPDATE NOWAIT; + +SELECT seat_id, state, ST_AsText(pos) FROM t1 +WHERE state = 0 FOR UPDATE SKIP LOCKED; + +COMMIT; + +connection default; +COMMIT; + +# Case 3b: primary blockes secondary/primary +connection con1; +SET @g = ST_GeomFromText('POLYGON((0 0,0 3,3 3,0 3,0 0))'); +SELECT seat_id, state, ST_AsText(pos) FROM t1 FORCE INDEX (pos) +WHERE state = 0 AND MBRWithin(pos, @g) FOR UPDATE; + +connection default; +BEGIN; +SELECT seat_id, state, ST_AsText(pos) FROM t1 +WHERE seat_id = 4 FOR UPDATE NOWAIT; + +connection con1; +--error ER_LOCK_WAIT_TIMEOUT +SELECT seat_id, state, ST_AsText(pos) FROM t1 FORCE INDEX (pos) +WHERE state = 0 AND MBRWithin(pos, @g) FOR UPDATE NOWAIT; + +SELECT seat_id, state, ST_AsText(pos) FROM t1 FORCE INDEX (pos) +WHERE state = 0 AND MBRWithin(pos, @g) FOR UPDATE SKIP LOCKED; + +--error ER_LOCK_WAIT_TIMEOUT +SELECT seat_id, state, ST_AsText(pos) FROM t1 +WHERE state = 0 FOR UPDATE NOWAIT; + +SELECT seat_id, state, ST_AsText(pos) FROM t1 +WHERE state = 0 FOR UPDATE SKIP LOCKED; + +connection default; +COMMIT; + +DROP TABLE t1; + +disconnect con1;