Details
Description
When I tested serializable isolation levels on Mariadb, I found a write skew exception.
The test cases and results are as follows.
The execution demonstrates a write skew exception (A5B: r1[x]... .r2[y]... .w1[y]... .w2[x]... (c1 and c2 occur), ANSI).
Also, the result of this execution contains a circle of read-write dependencies, which is against the serializable isolation level.
In other words, the two concurrent transactions are not equivalent to the result of the serialized execution of the transaction. This is a contradiction to the definition of serializability.
Therefore, it seems to me that this is a logical bug for the isolation level.
--- session 0 ---
|
CREATE TABLE tYv10enE (ID INT AUTO_INCREMENT UNIQUE, VAL INT, c0 INT NULL UNIQUE KEY); |
INSERT INTO tYv10enE (VAL, c0) VALUES ((ROUND (RAND() * 100000)), 10989748); |
INSERT INTO tYv10enE (VAL, c0) VALUES ((ROUND (RAND() * 100000)), -1404643822); |
INSERT INTO tYv10enE (VAL, c0) VALUES ((ROUND (RAND() * 100000)), -335483076); |
INSERT INTO tYv10enE (VAL, c0) VALUES ((ROUND (RAND() * 100000)), 942162931); |
--- session 1 ---
|
BEGIN; |
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; |
--- session 2 ---
|
BEGIN; |
SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE; |
--- session 1 ---
|
BEGIN; |
--- session 2 ---
|
BEGIN; |
--- session 1 ---
|
SELECT * FROM tYv10enE WHERE (! ((1) | (1))) OR ( c0 <= 1 ); |
+----+-------+-------------+ |
| ID | VAL | c0 |
|
+----+-------+-------------+ |
| 2 | 58093 | -1404643822 |
|
| 3 | 67578 | -335483076 |
|
+----+-------+-------------+ |
2 rows in set (0.00 sec) |
--- session 2 ---
|
SELECT * FROM tYv10enE WHERE ((1) | (0)) IS UNKNOWN OR ( c0 >= 889101988 ); |
+----+-------+-----------+ |
| ID | VAL | c0 |
|
+----+-------+-----------+ |
| 4 | 63609 | 942162931 |
|
+----+-------+-----------+ |
1 row in set (0.00 sec) |
--- session 1 ---
|
DELETE FROM tYv10enE WHERE FALSE OR ( c0 >= 889101988 ); |
Query OK, 1 row affected (0.00 sec)
|
--- session 2 ---
|
DELETE FROM tYv10enE WHERE FALSE OR ( c0 <= 1 ); |
Query OK, 2 rows affected (0.00 sec) |
--- session 1 ---
|
COMMIT; |
--- session 2 ---
|
COMMIT; |
Attachments
Issue Links
- relates to
-
MDEV-6905 START TRANSACTION IF NOT EXISTS
-
- Open
-
-
MDEV-32652 Commit/rollback must emit an error when not inside active transaction
-
- Open
-
I converted the input to the .test file format of the mtr tool:
--source include/have_innodb.inc
--connect con1,localhost,root
--connect con2,localhost,root
--connection con1
--connection con2
--disconnect con2
--connection con1
--disconnect con1
--connection default
With this test I can reproduce the reported phenomenon. But:
If I ensure that the transactions will be created at the expected isolation level, there will be a locking conflict, just as expected:
--source include/have_innodb.inc
--connect con1,localhost,root
--connect con2,localhost,root
--connection con1
--connection con2
--disconnect con2
--connection con1
--disconnect con1
--connection default
mysqltest: At line 21: query 'DELETE FROM tYv10enE WHERE FALSE OR ( c0 <= 1 )' failed: ER_LOCK_WAIT_TIMEOUT (1205): Lock wait timeout exceeded; try restarting transaction
Last, please note that if you are testing transaction isolation, you’d better enable innodb_snapshot_isolation=ON (
MDEV-35124).The behaviour of START TRANSACTION or BEGIN seems to be different from the one that is described in MDEV-6905. If the previous transaction had been committed by the second BEGIN or START TRANSACTION, then also the isolation level change should have taken effect. I think that this anomaly would qualify as a SQL layer bug. I hope that serg can comment on this.