[MDEV-24581] MDL race condition in trans_rollback_to_savepoint() Created: 2021-01-13 Updated: 2023-11-06 Resolved: 2023-11-06 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Locking, Storage Engine - InnoDB |
| Affects Version/s: | 10.0.11, 10.0, 10.1, 10.2, 10.3, 10.4, 10.5 |
| Fix Version/s: | 10.2.40, 10.3.31, 10.4.21, 10.5.12, 10.6.3 |
| Type: | Bug | Priority: | Major |
| Reporter: | Marko Mäkelä | Assignee: | Marko Mäkelä |
| Resolution: | Duplicate | Votes: | 0 |
| Labels: | race, upstream | ||
| Issue Links: |
|
||||||||||||||||||||||||
| Description |
|
In MariaDB Server 10.0.11, a change from MySQL 5.6.16 was applied. As far as I understand, the intention of the ha_rollback_to_savepoint_can_release_mdl() check is to ensure that no other transaction inside InnoDB is waiting for a lock on the table that the ROLLBACK TO SAVEPOINT would release. But, the check seems to be misplaced. We could have the following happen:
Note: In innobase_rollback_to_savepoint_can_release_mdl() there is another race that would be fixed by the first hunk of the following untested patch:
Note: I did not review whether this could break something in other implementations of handlerton::savepoint_rollback_can_release_mdl. |
| Comments |
| Comment by Sergei Golubchik [ 2023-11-06 ] |
|
server part of the change is done in |
| Comment by Marko Mäkelä [ 2023-11-06 ] |
|
I believe that this was fixed by The function innobase_rollback_to_savepoint_can_release_mdl() checks if trx->lock.trx_locks is 0. That read is not protected by trx->mutex, but a dirty read should be fine, because if the value is 0, then there can’t be any table locks, and therefore also no implicit or explicit record locks may be created. As I had pointed out, the optimization is not optimal: perhaps we could release some MDL, but the API does not let InnoDB tell which MDL can be released: it is an "all or nothing" deal. |