summaryrefslogtreecommitdiffstats
path: root/mysql-test/suite/innodb/t/innodb-isolation.test
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 18:00:34 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 18:00:34 +0000
commit3f619478f796eddbba6e39502fe941b285dd97b1 (patch)
treee2c7b5777f728320e5b5542b6213fd3591ba51e2 /mysql-test/suite/innodb/t/innodb-isolation.test
parentInitial commit. (diff)
downloadmariadb-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.test357
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;