Bug #99138 | Gap locking behavior leads to unavoidable deadlocks | ||
---|---|---|---|
Submitted: | 1 Apr 2020 4:35 | Modified: | 14 Apr 2020 18:37 |
Reporter: | Nicholas Gaya | Email Updates: | |
Status: | Not a Bug | Impact on me: | |
Category: | MySQL Server: InnoDB storage engine | Severity: | S4 (Feature request) |
Version: | 8.0.19 | OS: | Linux |
Assigned to: | CPU Architecture: | x86 |
[1 Apr 2020 4:35]
Nicholas Gaya
[7 Apr 2020 12:48]
MySQL Verification Team
Hi Mr. Gava, Thank you for your feature request. However, I do not think that we can accommodate your request. The manner in which InnoDB storage engine works is based on the best solutions presented by numerous authors who have been building transactional processing for the ACID storage engines. This is the way that InnoDB SE functions since 2001, without changes. This is the only way which ensures the integrity of each table. Also, we can not force exclusivity on the gap locks, since that would lead to significant performance degradation. Last, but not least, what you have designed is a classical case where a transactional engine creates a deadlock. If you get a deadlock error, that means that InnoDB SE functions properly and exactly as desired and as it is designed. All you have to do is to re-submit transactions in questions from your application. So, in short, unfortunately, this feature request can not be implemented.
[8 Apr 2020 2:10]
Nicholas Gaya
Hi Sinisa, Thanks for your comment. Just because this is an old problem, doesn't mean it's impossible to fix. Looking through the bug tracker (see links at end) shows that this a common issue encountered by users so there is real value in finding a solution. > Also, we can not force exclusivity on the gap locks, since that would lead to significant performance degradation. What about giving the user the option to decide? For example you could add a "LOCK EXCLUSIVE" keyword for "SELECT ... FOR UPDATE" queries to indicate that the user wishes to acquire an exclusive lock. Examples: * https://bugs.mysql.com/bug.php?id=14647 * https://bugs.mysql.com/bug.php?id=20134 * https://bugs.mysql.com/bug.php?id=25847 * https://bugs.mysql.com/bug.php?id=43211 * https://bugs.mysql.com/bug.php?id=48911 * https://bugs.mysql.com/bug.php?id=95230 * https://bugs.mysql.com/bug.php?id=96748
[8 Apr 2020 12:33]
MySQL Verification Team
Hi Mr. Gaya, I truly do not think that adding such a command is a good idea. We try to follow SQL standard as much as possible, and this does not comply with standards. Another solution would be to add (yet) another global/session variable. However, this is not a good idea either. There are already too many of those, plus, your test case would also produce a deadlock with exclusive gap locks.
[13 Apr 2020 18:53]
Nicholas Gaya
Can you clarify why there would be a deadlock in the example with exclusive gap locking? I would expect the behavior to be: * T1 acquires an exclusive gap lock and successfully inserts a row. * T2 blocks on SELECT ... FOR UPDATE until T1 is complete, then proceeds with no issues.
[14 Apr 2020 12:23]
MySQL Verification Team
Hi Mr. Gaya, The reply is very simple. Even with current non-exclusive gap locks, you managed to produce a classical deadlock. Test that you submitted produced a deadlock with a record lock and a gap lock, which two concurrent threads issued in the opposite order. Hence, with exclusive gap locks, number of semaphore waits and deadlocks would have been much higher. That change would have produced a very high number of the regression bugs.
[14 Apr 2020 18:37]
Nicholas Gaya
> Test that you submitted produced a deadlock with a record lock and a gap lock, which two concurrent threads issued in the opposite order. This is incorrect. Both transactions perform the same operations in the same order, with different id values. Therefore no deadlock should occur with exclusive locking.
[15 Apr 2020 12:34]
MySQL Verification Team
Deadlock still occurred. Hence ,with exclusive locking it would occur more frequently, in many different scenarios then yours.