MDEV-39681 delayed BF aborting with multi master load#5319
Conversation
Reason for the hanging, and occasional crashes turned out to be orphaned innodb lock wait request of a BF aborted local transaction, which had arrived in commit stage. Reason is that wsrep BF-abort marks a transaction a deadlock victim out-of-band, so (unlike native deadlock resolution) the victim can still own a live LOCK_WAIT request; if that orphaned waiter survives into commit/rollback, another transaction granting it calls lock_wait_end() cross-thread and corrupts the victim's state — surfacing as the lock_wait_end, que_thr_step, and rollback_finish assertions. This commit has fixes for claering lock wait status of BF aborted transactions. Commit has also a new mtr test: galera.galera_bf_abort_orphan_lock to work as regression test for the fix.
There was a problem hiding this comment.
Code Review
This pull request addresses an issue where a local transaction BF-aborted (wsrep victim) could park an orphaned lock wait request, leading to assertion failures during rollback. The fix ensures that transactions already chosen as victims return DB_DEADLOCK immediately instead of enqueuing new waiting locks, and cancels pending waits for wsrep BF-abort victims in lock_trx_handle_wait. A new test case has been added to verify the fix. The review feedback highlights some minor typos and spacing issues in the comments, a style violation regarding spacing around an assignment operator, and the use of the deprecated tx_isolation system variable in the test files.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| /* If this transaction has already been chosen as a victim — it must not | ||
| enqueue a new waiting lock request. | ||
| Return DB_DEADLOCK so that the caller rolls back instead of waiting. */ |
There was a problem hiding this comment.
| /* A wsrep BF-abort marks the victim out-of-band: unlike native deadlock | ||
| resolution it does not cancel the victim's waiting lock atomically with | ||
| setting the flag, so the victim can reach this point still owning a live | ||
| LOCK_WAIT request (with trx->lock.wait_thr set). | ||
| So for BF-abort victm, we cancel the pending wait | ||
| here, which also clears trx->lock.wait_thr. But, this must not be done for | ||
| the native deadlock case, which cancels lock in Deadlock::report() */ |
There was a problem hiding this comment.
There are a few typos and spacing issues in this comment:
victmshould bevictim.- There are double spaces after commas/periods (e.g.,
victm, weandthr. But). - There are double spaces before the closing comment marker
*/.
/* A wsrep BF-abort marks the victim out-of-band: unlike native deadlock
resolution it does not cancel the victim's waiting lock atomically with
setting the flag, so the victim can reach this point still owning a live
LOCK_WAIT request (with trx->lock.wait_thr set).
So for BF-abort victim, we cancel the pending wait
here, which also clears trx->lock.wait_thr. But, this must not be done for
the native deadlock case, which cancels lock in Deadlock::report() */| if (trx->lock.wait_lock) | ||
| { | ||
| mysql_mutex_lock(&lock_sys.wait_mutex); | ||
| if (lock_t *wait_lock= trx->lock.wait_lock) |
There was a problem hiding this comment.
Following the project's coding standards, there should be spaces around the assignment operator =.
if (lock_t *wait_lock = trx->lock.wait_lock)References
- Follow the project's specific coding standards (e.g., CODING_STANDARDS.md) for code formatting and spacing, such as spacing around assignment operators, rather than generic style guides like the Google C++ Style Guide. (link)
|
|
||
| # Victim: holds a granted lock on t_a (makes it a BF target), then locks t_b | ||
| --connect node_1_victim, 127.0.0.1, root, , test, $NODE_MYPORT_1 | ||
| SET SESSION tx_isolation = 'READ-COMMITTED'; |
| id c | ||
| 1 0 | ||
| connect node_1_victim, 127.0.0.1, root, , test, $NODE_MYPORT_1; | ||
| SET SESSION tx_isolation = 'READ-COMMITTED'; |
Reason for the hanging, and occasional crashes turned out to be orphaned innodb lock wait request of a BF aborted local transaction, which had arrived in commit stage.
Reason is that wsrep BF-abort marks a transaction a deadlock victim out-of-band, so (unlike native deadlock resolution) the victim can still own a live LOCK_WAIT request; if that orphaned waiter survives into commit/rollback, another transaction granting it calls lock_wait_end() cross-thread and corrupts the victim's state — surfacing as the lock_wait_end, que_thr_step, and rollback_finish assertions.
This commit has fixes for claering lock wait status of BF aborted transactions.
Commit has also a new mtr test: galera.galera_bf_abort_orphan_lock to work as regression test for the fix.