1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

MDEV-33802 Weird read view after ROLLBACK of another transaction

Even after commit b8a6719889 there
is an anomaly where a locking read could return inconsistent results.
If a locking read would have to wait for a record lock, then by the
definition of a read view, the modifications made by the current lock
holder cannot be visible in the read view. This is because the read
view must exclude any transactions that had not been committed at the
time when the read view was created.

lock_rec_convert_impl_to_expl_for_trx(), lock_rec_convert_impl_to_expl():
Return an unsafe-to-dereference pointer to a transaction that holds or
held the lock, or nullptr if the lock was available.

lock_clust_rec_modify_check_and_lock(),
lock_sec_rec_read_check_and_lock(),
lock_clust_rec_read_check_and_lock():
Return DB_RECORD_CHANGED if innodb_strict_isolation=ON and the
lock was being held by another transaction.

The test case, which is based on a bug report by Zhuang Liu,
covers the function lock_sec_rec_read_check_and_lock().

Reviewed by: Vladislav Lesin
This commit is contained in:
Marko Mäkelä
2024-04-09 12:50:24 +03:00
parent a4cda66e2d
commit 4aa92911c7
3 changed files with 148 additions and 62 deletions

View File

@@ -82,7 +82,6 @@ SELECT * FROM t;
a b
10 20
10 20
disconnect consistent;
connection default;
TRUNCATE TABLE t;
INSERT INTO t VALUES(NULL, 1), (2, 2);
@@ -99,10 +98,40 @@ a b
COMMIT;
connection con_weird;
COMMIT;
disconnect con_weird;
connection default;
SELECT * FROM t;
a b
10 1
10 20
DROP TABLE t;
#
# MDEV-33802 Weird read view after ROLLBACK of other transactions
#
CREATE TABLE t(a INT PRIMARY KEY, b INT UNIQUE) ENGINE=InnoDB;
INSERT INTO t SET a=1;
BEGIN;
INSERT INTO t SET a=2;
connection consistent;
START TRANSACTION WITH CONSISTENT SNAPSHOT;
SELECT * FROM t FORCE INDEX (b) FOR UPDATE;
ERROR HY000: Record has changed since last read in table 't'
connection con_weird;
START TRANSACTION WITH CONSISTENT SNAPSHOT;
SELECT * FROM t FORCE INDEX (b) FOR UPDATE;
connection default;
ROLLBACK;
connection con_weird;
a b
1 NULL
1 NULL
SELECT * FROM t FORCE INDEX (b) FOR UPDATE;
a b
1 NULL
disconnect con_weird;
connection consistent;
SELECT * FROM t FORCE INDEX (b) FOR UPDATE;
a b
1 NULL
disconnect consistent;
connection default;
DROP TABLE t;

View File

@@ -79,7 +79,6 @@ COMMIT;
--connection consistent
--reap
SELECT * FROM t;
--disconnect consistent
--connection default
TRUNCATE TABLE t;
@@ -103,8 +102,48 @@ COMMIT;
--connection con_weird
--reap
COMMIT;
--disconnect con_weird
--connection default
SELECT * FROM t;
DROP TABLE t;
--echo #
--echo # MDEV-33802 Weird read view after ROLLBACK of other transactions
--echo #
CREATE TABLE t(a INT PRIMARY KEY, b INT UNIQUE) ENGINE=InnoDB;
INSERT INTO t SET a=1;
BEGIN; INSERT INTO t SET a=2;
--connection consistent
START TRANSACTION WITH CONSISTENT SNAPSHOT;
--disable_ps2_protocol
--error ER_CHECKREAD
SELECT * FROM t FORCE INDEX (b) FOR UPDATE;
--enable_ps2_protocol
--connection con_weird
START TRANSACTION WITH CONSISTENT SNAPSHOT;
send
SELECT * FROM t FORCE INDEX (b) FOR UPDATE;
--connection default
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = 'Sending data'
and info LIKE 'SELECT * FROM t %';
--source include/wait_condition.inc
ROLLBACK;
--connection con_weird
--reap
SELECT * FROM t FORCE INDEX (b) FOR UPDATE;
--disconnect con_weird
--connection consistent
SELECT * FROM t FORCE INDEX (b) FOR UPDATE;
--disconnect consistent
--connection default
DROP TABLE t;