InnoDB Deadlock Resolution: Selecting Victim Transaction, Updating Weights, Logging, and Wakeup
This article explains how InnoDB resolves a deadlock by ordering the involved transactions, selecting a victim based on priority, rollback cost and table modifications, updating transaction weights, optionally logging the deadlock details, and finally waking the victim transaction to roll back.
The article is based on MySQL 8.0.32 source code with the InnoDB storage engine and walks through the complete deadlock‑resolution process.
1. Selecting the Victim Transaction
After the deadlock detection phase, InnoDB must decide which transaction in the deadlock cycle will be rolled back. All transactions are first sorted by the time they entered the lock‑wait state and stored in a "deadlock array". The algorithm iterates over this array, comparing each transaction with the previously selected candidate using four steps:
Step 1: Prefer the lower‑priority transaction (priority ≤ 0) over a higher‑priority one.
Step 2: If both have the same priority, choose the one that modified a non‑transactional table (e.g., MyISAM).
Step 3: If still undecided, compare the rollback cost, which is the sum of the undo log size generated before waiting and the number of lock structures created.
Step 4: If all previous criteria are equal, select the transaction that entered the lock‑wait state later (the later entry in the deadlock array).
The iteration continues until a single victim transaction is identified.
2. Calculating and Updating Transaction Weights
During the preparation stage, InnoDB increases the weight of blocking transactions but does not apply it to the victim. After the victim is chosen, the system traverses the deadlock cycle, adding each waiting transaction's weight to the transaction it blocks, and finally resets the victim's weight to zero. All intermediate weight values are stored in a temporary weight array and later written back to the corresponding transaction objects.
3. Recording the Deadlock Log
If the system variable innodb_print_all_deadlocks is ON, the deadlock thread dumps detailed information to the MySQL error log. An example log entry looks like the following:
2024-07-07T13:00:15.602373Z 0 [Note] [MY-012468] [InnoDB] Transactions deadlock detected, dumping detailed information.
2024-07-07T13:00:15.602446Z 0 [Note] [MY-012469] [InnoDB] *** (1) TRANSACTION:
TRANSACTION 227599, ACTIVE 21 sec starting index read
... (truncated for brevity) ...
2024-07-07T13:00:15.605401Z 0 [Note] [MY-012469] [InnoDB] *** WE ROLL BACK TRANSACTION (2)The log is written only when log_error_verbosity is set to 3.
4. Waking Up the Victim Transaction
After the victim is selected, the deadlock thread marks the transaction so that, when it is later awakened, it knows it must roll back. The thread removes the lock structure from the transaction's trx_locks list (and from rec_hash or the table's locks list if it is a row lock or table lock, respectively) and triggers the waiting event stored in the transaction's event field.
5. Summary
Sort transactions in the deadlock cycle by lock‑wait entry time and store them in a deadlock array.
Iterate the array, selecting a candidate victim in the first round and refining the choice in subsequent rounds based on priority, non‑transactional table modifications, and rollback cost.
The final selected transaction is rolled back.
Depending on innodb_print_all_deadlocks , the deadlock details may be logged.
The victim transaction is marked and then awakened to perform its own rollback.
Aikesheng Open Source Community
The Aikesheng Open Source Community provides stable, enterprise‑grade MySQL open‑source tools and services, releases a premium open‑source component each year (1024), and continuously operates and maintains them.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.