MDEV-33802 Weird read view after ROLLBACK of other transactions.
In the case if some unique key fields are nullable, there can be
several records with the same key fields in unique index with at least
one key field equal to NULL, as NULL != NULL.
When transaction is resumed after waiting on the record with at least one
key field equal to NULL, and stored in persistent cursor record is
deleted, persistent cursor can be restored to the record with all key
fields equal to the stored ones, but with at least one field equal to
NULL. And such record is wrongly treated as a record with the same unique
key as stored in persistent cursor record one, what is wrong as
NULL != NULL.
The fix is to check if at least one unique field is NULL in restored
persistent cursor position, and, if so, then don't treat the record as
one with the same unique key as in the stored record key.
dict_index_t::nulls_equal was removed, as it was initially developed for
never existed in MariaDB "intrinsic tables", and there is no code, which
would set it to "true".
Reviewed by Marko Mäkelä.
2024-04-02 20:45:29 +03:00
|
|
|
--source include/have_innodb.inc
|
|
|
|
--source include/have_debug.inc
|
|
|
|
--source include/have_debug_sync.inc
|
|
|
|
--source include/count_sessions.inc
|
|
|
|
|
|
|
|
|
|
|
|
CREATE TABLE t(a INT PRIMARY KEY, b INT, c INT, UNIQUE KEY `b_c` (`b`,`c`))
|
|
|
|
ENGINE=InnoDB, STATS_PERSISTENT=0;
|
|
|
|
INSERT INTO t SET a = 1, c = 2;
|
|
|
|
|
|
|
|
--connect con1,localhost,root
|
|
|
|
BEGIN;
|
|
|
|
INSERT INTO t SET a=2, c=2;
|
|
|
|
|
|
|
|
--connection default
|
|
|
|
BEGIN;
|
2024-04-17 14:14:58 +03:00
|
|
|
SET DEBUG_SYNC="lock_wait_start SIGNAL select_locked";
|
MDEV-33802 Weird read view after ROLLBACK of other transactions.
In the case if some unique key fields are nullable, there can be
several records with the same key fields in unique index with at least
one key field equal to NULL, as NULL != NULL.
When transaction is resumed after waiting on the record with at least one
key field equal to NULL, and stored in persistent cursor record is
deleted, persistent cursor can be restored to the record with all key
fields equal to the stored ones, but with at least one field equal to
NULL. And such record is wrongly treated as a record with the same unique
key as stored in persistent cursor record one, what is wrong as
NULL != NULL.
The fix is to check if at least one unique field is NULL in restored
persistent cursor position, and, if so, then don't treat the record as
one with the same unique key as in the stored record key.
dict_index_t::nulls_equal was removed, as it was initially developed for
never existed in MariaDB "intrinsic tables", and there is no code, which
would set it to "true".
Reviewed by Marko Mäkelä.
2024-04-02 20:45:29 +03:00
|
|
|
--send SELECT * FROM t FORCE INDEX(b) FOR UPDATE
|
|
|
|
|
|
|
|
--connection con1
|
|
|
|
SET DEBUG_SYNC="now WAIT_FOR select_locked";
|
|
|
|
ROLLBACK;
|
|
|
|
|
|
|
|
--connection default
|
|
|
|
--echo # If the bug is not fixed, and the both unique index key fields are
|
|
|
|
--echo # NULL, there will be two (1, NULL, 2) rows in the result,
|
|
|
|
--echo # because cursor will be restored to (NULL, 2, 1) position for
|
|
|
|
--echo # secondary key instead of "supremum".
|
|
|
|
--reap
|
|
|
|
COMMIT;
|
|
|
|
|
|
|
|
SET DEBUG_SYNC="RESET";
|
|
|
|
|
|
|
|
--disconnect con1
|
|
|
|
DROP TABLE t;
|
|
|
|
--source include/wait_until_count_sessions.inc
|