Bug #116628 | Two concurent SERIALIZABLE transactions are not isolated properly. | ||
---|---|---|---|
Submitted: | 12 Nov 2024 10:43 | Modified: | 15 Nov 2024 10:23 |
Reporter: | Theodor Moroianu | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | MySQL Server: General | Severity: | S3 (Non-critical) |
Version: | 9.1.0 | OS: | Linux (Official container from dockerhub) |
Assigned to: | CPU Architecture: | x86 (AMD Ryzen 7 4800U) | |
Tags: | Isolation level, SERIALIZABLE, transactions |
[12 Nov 2024 10:43]
Theodor Moroianu
[12 Nov 2024 11:39]
MySQL Verification Team
Hi Mr. Moroianu, Thank you for your bug report. However, it is not a bug. Other transactions are waiting for the locks that first transaction in SERIALIZABLE mode is holding, but once first transaction commits, all locks are deallocated and the other transactions do not have anything to wait for, hence they can perform the changes on the table(s). SERIALIZABLE is on of the modes in concurrency control. But, when one transactions remains alone , then you do not have any concurrency ....... Not a bug.
[12 Nov 2024 12:36]
Theodor Moroianu
Thank you for your answer! However I think this is indeed a bug. The problem I am reporting is not a locking issue, but an isolation bug. The second transaction (conn_1) starts before the first one (conn_0) commits, hence it should not see the changes conn_0 makes. The PoC is essentially: 1. Transaction 1 and 2 start. 2. Transaction 1 makes some changes, commits. 3. Transaction 2 sees the changes made by transaction 1, violating SI. As you said, when the second transaction remains alone there is no concurrency, but the MVCC should ensure that the database view of the transaction is consistent. The second transaction should never see any changes made by the first one (even when committed), as this would violate the SERIALIZABLE isolation level.
[12 Nov 2024 13:08]
MySQL Verification Team
Hi Mr. Moroianu, We understand what you are writing about, but this is not a bug. However, what you describe is how another isolation level works and not how SERIALIZABLE works. This is SERIALIZABLE concurrency control, this is not REPEATABLE READ concurrency control. Only REPEATABLE READ does what you are describing. It is explained fully in SQL Standard and in the classical books on transaction processing, like this one: https://www.amazon.com/Transaction-Processing-Concepts-Techniques-Management/dp/1558601902 Not a bug ......
[12 Nov 2024 13:14]
MySQL Verification Team
Hi Mr. Moroianu, Let us help you a bit more, by quoting from the SQL Standard itself: " A serializable execution is defined to be an execution of the operations of concurrently executing SQL-transactions that produces the same effect as some serial execution of those same SQL-transactions " Here, "serial execution" means that transactions are executed one after another..... It is that simple ....... Not a bug.
[15 Nov 2024 10:23]
Theodor Moroianu
Thank you for your explanation! However, I still believe this is a bug. From the MySQL documentation (https://dev.mysql.com/doc/refman/8.0/en/innodb-transaction-isolation-levels.html) on Repeatable Read: Consistent reads within the same transaction read the snapshot established by the first read. This means that if you issue several plain (nonlocking) SELECT statements within the same transaction, these SELECT statements are consistent also with respect to each other. This constraint is broken, as the transaction 1 makes a snapshot before transaction 1 updates the table, but then sees those modifications. The bug does indeed occur under SERIALIZABLE, not REPEATABLE READ, but again the documentation states that SERIALIZABLE is more strict, so all constraints should be respected: This level (SERIALIZABLE) is like REPEATABLE READ, but InnoDB implicitly converts all plain SELECT statements to SELECT ... FOR SHARE if autocommit is disabled.
[15 Nov 2024 11:03]
MySQL Verification Team
Hi Mr. Moroianu, No, there is no bug here. SERIALIZABLE means that result of concurrent transactions is the same as if each transaction is executed one AFTER the other. That is, first one is started and finished and second one is then started. Regardless of the fact that those were concurrent transactions. These are definitions of this MVCC variant. Hence, finally, no this is not a bug.