diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 18:00:34 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-05-04 18:00:34 +0000 |
commit | 3f619478f796eddbba6e39502fe941b285dd97b1 (patch) | |
tree | e2c7b5777f728320e5b5542b6213fd3591ba51e2 /mysql-test/suite/innodb/t/innodb-isolation.test | |
parent | Initial commit. (diff) | |
download | mariadb-3f619478f796eddbba6e39502fe941b285dd97b1.tar.xz mariadb-3f619478f796eddbba6e39502fe941b285dd97b1.zip |
Adding upstream version 1:10.11.6.upstream/1%10.11.6upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'mysql-test/suite/innodb/t/innodb-isolation.test')
-rw-r--r-- | mysql-test/suite/innodb/t/innodb-isolation.test | 357 |
1 files changed, 357 insertions, 0 deletions
diff --git a/mysql-test/suite/innodb/t/innodb-isolation.test b/mysql-test/suite/innodb/t/innodb-isolation.test new file mode 100644 index 00000000..6d347dc7 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-isolation.test @@ -0,0 +1,357 @@ + +#Note:- WL6742 has been removed from 5.7 (Bug 23046302), +# but we are keeping this test since it tests +# count(*) correctness for various isolation +# levels. + +--echo # +--echo # WL#6742 - Test the interaction of multiple transactions using +--echo # different isolation levels to make sure that the value returned +--echo # by count(*) always reflects the correct view of the table according +--echo # to the transaction's selected isolation level. +--echo # + +--source include/have_innodb.inc + +--disable_query_log +let $MYSQLD_DATADIR= `select @@datadir`; +let $initial_timeout=`select @@innodb_lock_wait_timeout`; +--enable_query_log + +--echo # +--echo # Traverse various indexes to get the right counts. +--echo # This especially tests count(*) which is pushed down to InnoDB in WL#6742. +--echo # +CREATE TABLE t1 ( + c1 INT AUTO_INCREMENT PRIMARY KEY, + c2 INT, + c3 INT, + c4 INT, + INDEX k2(c2) +) Engine=InnoDB; +let $1=10; +while ($1 > 0) { + INSERT INTO t1(c2,c3,c4) VALUES (1, 1, 1); + dec $1; +} + +CREATE TABLE t2 LIKE t1; +--enable_info +INSERT INTO t2 (SELECT * FROM t1); +--disable_info + +--source suite/innodb/include/innodb_isolation_selects.inc + +--echo # +--echo # Do some DML in the default connection and leave the transaction pending. +--echo # +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +BEGIN; +--enable_info +UPDATE t1 SET c2 = c2 * 3 WHERE c1 = 1; +DELETE FROM t1 WHERE c1 = 6; +--disable_info +--source suite/innodb/include/innodb_isolation_selects.inc + +--echo # +--echo # Start transactions of Repeatable Read, Read Committed, and Read Uncommitted +--echo # +--echo # Connection 1 REPEATABLE READ +--echo # +connect (con1,localhost,root,,); +SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ; +BEGIN; +--source suite/innodb/include/innodb_isolation_selects.inc +--enable_info +UPDATE t1 SET c2 = c2 * 5 WHERE c1 = 2; +DELETE FROM t1 WHERE c1 = 7; +INSERT INTO t1(c2,c3,c4) VALUES (100, 1, 1); +--disable_info +--source suite/innodb/include/innodb_isolation_selects.inc + +--echo # +--echo # Test a lock wait timeout during COUNT(*) +--echo # +SET innodb_lock_wait_timeout = 1; +--error ER_LOCK_WAIT_TIMEOUT +SELECT COUNT(*) FROM t1 FOR UPDATE; + + +--echo # +--echo # Connection 2 READ COMMITTED +--echo # +connect (con2,localhost,root,,); +SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED; +BEGIN; +--source suite/innodb/include/innodb_isolation_selects.inc +--enable_info +UPDATE t1 SET c2 = c2 * 7 WHERE c1 = 3; +DELETE FROM t1 WHERE c1 = 8; +INSERT INTO t1(c2,c3,c4) VALUES (1000, 1, 1); +--disable_info +--source suite/innodb/include/innodb_isolation_selects.inc + +--echo # +--echo # Connection 3 READ UNCOMMITTED +--echo # +connect (con3,localhost,root,,); +SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; +BEGIN; +--source suite/innodb/include/innodb_isolation_selects.inc +--enable_info +UPDATE t1 SET c2 = c2 * 11 WHERE c1 = 4; +INSERT INTO t1(c2,c3,c4) VALUES (10000, 1, 1); +DELETE FROM t1 WHERE c1 in(9); +--disable_info +--source suite/innodb/include/innodb_isolation_selects.inc + +--echo # +--echo # Connection default REPEATABLE READ +--echo # +connection default; +--source suite/innodb/include/innodb_isolation_selects.inc + +--echo # +--echo # Commit the 3 extra connections +--echo # +--echo # Connection 1 REPEATABLE READ +--echo # +connection con1; +--source suite/innodb/include/innodb_isolation_selects.inc + +--echo # +--echo # Connection 2 READ COMMITTED +--echo # +connection con2; +--source suite/innodb/include/innodb_isolation_selects.inc + +--echo # +--echo # Connection 3 READ UNCOMMITTED +--echo # +connection con3; +--source suite/innodb/include/innodb_isolation_selects.inc +COMMIT; +--source suite/innodb/include/innodb_isolation_selects.inc + +--echo # +--echo # Connection 2 READ COMMITTED +--echo # +connection con2; +--source suite/innodb/include/innodb_isolation_selects.inc +COMMIT; +--source suite/innodb/include/innodb_isolation_selects.inc + +--echo # +--echo # Connection 1 REPEATABLE READ +--echo # +connection con1; +--source suite/innodb/include/innodb_isolation_selects.inc + +--echo # +--echo # Select the first 5 records FOR UPDATE using count(*) in a subquery. +--echo # The second record is still pending so we get a lock timeout. +--echo # +SET innodb_lock_wait_timeout = 1; +--error ER_LOCK_WAIT_TIMEOUT +SELECT c1, c2 FROM t1 WHERE c1 < ((SELECT COUNT(*) FROM t1) / 2) FOR UPDATE; +--error ER_LOCK_WAIT_TIMEOUT +SELECT COUNT(*) FROM t1 FOR UPDATE; +COMMIT; +--source suite/innodb/include/innodb_isolation_selects.inc + +--echo # +--echo # Show The EXPLAIN output for these queries; +--echo # +# column 9 is the row count provided by handler::info(). In InnoDB, this is +# a statistical estimate. After the multi-transactional changes above, +# Solaris reports 10 rows which is correct, but other OSes report 9. +--replace_column 9 # +EXPLAIN SELECT * FROM t1; +--replace_column 9 # +EXPLAIN SELECT COUNT(*) FROM t1; +--replace_column 9 # +EXPLAIN SELECT COUNT(c1) FROM t1; +--replace_column 9 # +EXPLAIN SELECT COUNT(c2) FROM t1; +--replace_column 9 # +EXPLAIN SELECT COUNT(c3) FROM t1; +--replace_column 9 # +EXPLAIN SELECT SUM(c1) FROM t1; +--replace_column 9 # +EXPLAIN SELECT SUM(c2) FROM t1; +--replace_column 9 # +EXPLAIN SELECT AVG(c1), MAX(c1), MIN(c2), AVG(c3), SUM(c4) FROM t1; +--replace_column 9 # +EXPLAIN SELECT c1, c2 FROM t1 WHERE c1 > ((SELECT COUNT(*) FROM t1) / 2); +--replace_column 9 # +EXPLAIN SELECT COUNT(c2) FROM t1 WHERE c1 > ((SELECT COUNT(*) FROM t1) / 2); +--replace_column 9 # +EXPLAIN SELECT COUNT(*) FROM t1 WHERE c1 > (SELECT AVG(c1) FROM t1); + +--echo # +--echo # Make all indexes in t2 obsolete to the active repeatable read transaction +--echo # in the default connection. +--echo # +ALTER TABLE t2 row_format=redundant; + +--echo # +--echo # Connection default REPEATABLE READ +--echo # Do more DML in the default REPEATABLE READ transaction in order to use recently committed records. +--echo # +connection default; +--source suite/innodb/include/innodb_isolation_selects.inc +--enable_info +UPDATE t1 SET c4 = c2 * 10; +--disable_info +--source suite/innodb/include/innodb_isolation_selects.inc + +--echo # +--echo # Table t2 has been altered to a new row format. +--echo # The index should not be useable. +--echo # +--error ER_TABLE_DEF_CHANGED +SELECT COUNT(*) FROM t2; +--error ER_TABLE_DEF_CHANGED +SELECT * FROM t2; + +COMMIT; +SELECT COUNT(*) FROM t2; +--source suite/innodb/include/innodb_isolation_selects.inc + +--echo # +--echo # Connection 2 +--echo # +connection con2; +--source suite/innodb/include/innodb_isolation_selects.inc + +--echo # +--echo # Try COUNT(*) on a DISCARDED table. +--echo # +connection default; +CREATE TABLE t4 LIKE t1; +INSERT INTO t4 (SELECT * FROM t1); +SELECT COUNT(*) FROM t4; +ALTER TABLE t4 DISCARD TABLESPACE; +--error ER_TABLESPACE_DISCARDED +SELECT COUNT(*) FROM t4; + + +--echo # +--echo # Test the interaction of a repeatable read transaction +--echo # to changes that happen outside its view. +--echo # + +CREATE TABLE t5 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT, aa INT, bb TEXT) Engine=InnoDB; +INSERT INTO t5(b) VALUES ("inserted by client 1"); +INSERT INTO t5(b) VALUES ("inserted by client 1"); +INSERT INTO t5(b) VALUES ("inserted by client 1"); +INSERT INTO t5(b) VALUES ("inserted by client 1"); +UPDATE t5 SET aa=a, bb=b; +CREATE TABLE t6 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT, aa INT, bb TEXT) Engine=InnoDB; +INSERT INTO t6(b) VALUES ("inserted by client 1"); +INSERT INTO t6(b) VALUES ("inserted by client 1"); +INSERT INTO t6(b) VALUES ("inserted by client 1"); +INSERT INTO t6(b) VALUES ("inserted by client 1"); +UPDATE t6 SET aa=a, bb=b; +CREATE TABLE t7 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT, aa INT, bb TEXT) Engine=InnoDB; +INSERT INTO t7(b) VALUES ("inserted by client 1"); +INSERT INTO t7(b) VALUES ("inserted by client 1"); +INSERT INTO t7(b) VALUES ("inserted by client 1"); +INSERT INTO t7(b) VALUES ("inserted by client 1"); +UPDATE t7 SET aa=a, bb=b; +BEGIN; +SELECT * FROM t5; +SELECT COUNT(*) FROM t5; +SELECT * FROM t6; +SELECT COUNT(*) FROM t6; +SELECT * FROM t7; +SELECT COUNT(*) FROM t7; + +--echo # +--echo # Connection 1 +--echo # +connection con1; +INSERT INTO t5(b) VALUES ("inserted by client 2"); +UPDATE t5 SET a = 10 where a = 1; +UPDATE t5 SET b = "updated by client 2" where a = 2; +DELETE FROM t5 WHERE a = 3; +SELECT * FROM t5; +SELECT COUNT(*) FROM t5; +INSERT INTO t6(b) VALUES ("inserted by client 2"); +UPDATE t6 SET a = 10 where a = 1; +UPDATE t6 SET b = "updated by client 2" where a = 2; +DELETE FROM t6 WHERE a = 3; +SELECT * FROM t6; +SELECT COUNT(*) FROM t6; +INSERT INTO t7(b) VALUES ("inserted by client 2"); +UPDATE t7 SET a = 10 where a = 1; +UPDATE t7 SET b = "updated by client 2" where a = 2; +DELETE FROM t7 WHERE a = 3; +SELECT * FROM t7; +SELECT COUNT(*) FROM t7; + +--echo # +--echo # Connection default +--echo # +connection default; +SELECT * FROM t5; +INSERT INTO t5(b) VALUES ("inserted by client 1"); +SELECT * FROM t5; +UPDATE t5 SET a = a + 100; +SELECT * FROM t5; +SELECT COUNT(*) FROM t5; + +UPDATE t6 SET b = "updated by client 2"; +SELECT * FROM t6; +SELECT * FROM t6 LOCK IN SHARE MODE; +SELECT COUNT(*) FROM t6; + +DELETE FROM t7; +SELECT * FROM t7; +SELECT COUNT(*) FROM t7; + +COMMIT; +SELECT * FROM t5; +SELECT COUNT(*) FROM t5; +SELECT * FROM t6; +SELECT COUNT(*) FROM t6; +SELECT * FROM t7; +SELECT COUNT(*) FROM t7; + +--echo # +--echo # Cleanup +--echo # +DROP TABLE t1,t2,t4,t5,t6,t7; +disconnect con1; +disconnect con2; +disconnect con3; +--disable_query_log +eval set global innodb_lock_wait_timeout=$initial_timeout; +--enable_query_log + +--echo # +--echo # Bug #23596760: FORCE INDEX IS SKIPPED WHILE EXECUTING SELECT COUNT(*) +--echo # + +CREATE TABLE t1(c1 INT NOT NULL PRIMARY KEY, + c2 INT NOT NULL DEFAULT 1, + c3 char(20) DEFAULT '', + KEY c2_idx (c2)) ENGINE=InnoDB STATS_PERSISTENT=0; + +INSERT INTO t1(c1) VALUES (1), (2), (3); +INSERT INTO t1(c1) SELECT c1 + 10 FROM t1; +INSERT INTO t1(c1) SELECT c1 + 100 FROM t1; + +CREATE TABLE t2 STATS_PERSISTENT=0 SELECT * FROM t1; + +let query1= SELECT COUNT(*) FROM t1; +let query2= SELECT COUNT(*) FROM t1 FORCE INDEX(c2_idx); +let query3= SELECT COUNT(*) FROM t1, t2; +let query4= SELECT COUNT(*) FROM t1 FORCE INDEX(c2_idx), t2; + +eval EXPLAIN $query1; +eval EXPLAIN $query2; +eval EXPLAIN $query3; +eval EXPLAIN $query4; + +DROP TABLE t1, t2; |