At a glance
The number of InnoDB deadlocks detected in the last 5 minutes. A deadlock is two (or more) transactions each holding a lock the other needs, so InnoDB breaks the cycle by killing one of them with error 1213, Deadlock found when trying to get lock. For a DBA, this is “are concurrent transactions colliding on the same rows in incompatible lock orders?” A clean instance shows zero. Anything above zero means at least one transaction was rolled back, and if your application does not retry it, a user saw an error. This is why the alert fires at the first deadlock, not at a threshold.
Calculation
The engine readsInnodb_deadlocks from SHOW ENGINE INNODB STATUS, snapshots it, and reports the delta over the trailing 5 minutes:
SHOW ENGINE INNODB STATUS only retains the single most recent deadlock in its LATEST DETECTED DEADLOCK section, so the headline count and the drill-down detail can diverge: the count can read 4 while the detail shows only the last collision. To capture every deadlock for forensics you need innodb_print_all_deadlocks = ON, which writes each one to the MySQL error log; the card surfaces a hint to enable it when the count exceeds 1 but the detail shows only one event. The drill-down parses the latest deadlock’s two transaction blocks (the statements, the locks held, and the locks waited on) and the line naming which transaction InnoDB chose as the rollback victim (usually the one with the fewer rows modified, as it is cheaper to undo).
Worked example
A platform team runs a MySQL 8.0 primary behind an inventory service. On 18 Apr 26 at 20:05 BST, during an evening flash-sale, the card jumps to 6 deadlocks in 5m, tripping the> 0 alert for the first time in weeks. The drill-down shows the LATEST DETECTED DEADLOCK:
InnoDB rolled back T2 (fewer rows modified) and let T1 commit. The pattern is textbook: two checkout transactions decrementing stock for the same two SKUs but acquiring the row locks in opposite order. Under low traffic the windows never overlap; under flash-sale concurrency they collide constantly.
- One deadlock means one rolled-back transaction. If your application retries on 1213, the user never notices; if it does not, the user saw an error. The alert fires at the first deadlock because you cannot tell from the count alone whether a user was affected.
- Deadlocks are a concurrency and lock-ordering problem, not a hardware problem. Throwing CPU or memory at them does nothing. The fix is almost always consistent lock ordering, shorter transactions, or appropriate retry logic.
- The count and the detail can disagree. Native InnoDB status keeps only the latest deadlock. If the count is 6 but you can only see one collision, enable
innodb_print_all_deadlocksso every event lands in the error log for analysis.
Sibling cards to reference together
Reconciling against the source
Where to look in MySQL’s own tooling:RunWhy our number may legitimately differ from a raw status read:SHOW ENGINE INNODB STATUS\Gand read theLATEST DETECTED DEADLOCKsection for the most recent collision, plus theInnodb_deadlocksline for the lifetime counter. CheckSHOW GLOBAL STATUS LIKE 'Innodb_deadlocks';for the raw since-restart total (the card reports only the 5-minute delta of this). EnableSET GLOBAL innodb_print_all_deadlocks = ON;to write every deadlock to the error log (SELECT @@log_error;for the path), since the status output keeps only the latest one. Inspect live lock waits withSELECT * FROM performance_schema.data_lock_waits;and thesys.innodb_lock_waitsview to see contention before it becomes a deadlock.
Managed-service cross-checks:
Known limitations / FAQs
The card says 4 deadlocks butSHOW ENGINE INNODB STATUS only shows one. Why?
Native InnoDB status retains only the single most recent deadlock in its LATEST DETECTED DEADLOCK section. The counter increments for every deadlock, but the detail is overwritten each time. To see all four, enable innodb_print_all_deadlocks = ON so each one is written to the error log. The card’s count is correct; the native detail view is simply lossy by design.
Is a deadlock the same as a lock-wait timeout?
No, and conflating them leads to the wrong fix. A deadlock (error 1213) is a true cycle that InnoDB detects and resolves instantly by rolling back a victim. A lock-wait timeout (error 1205) is a transaction that waited longer than innodb_lock_wait_timeout for a lock that was never going to deadlock, just held too long. Deadlocks point at lock-ordering; timeouts point at long-held locks or an oversized innodb_lock_wait_timeout. This card counts only the former.
Should I always treat a deadlock as an incident?
Not necessarily, but always investigate. In a healthy concurrent system the occasional deadlock is expected and the correct response is application-side retry, not a code change. The alert fires at the first deadlock because the count alone cannot tell you whether the application retried the victim or surfaced an error to a user. If your retry logic is solid and the rate is low, log it and move on; if the rate is climbing or there is no retry logic, fix it.
How do I actually stop deadlocks?
Three durable techniques, in order of impact: (1) lock rows in a consistent order across all transactions (for example always sort ids ascending before updating), which converts most deadlocks into harmless brief waits; (2) keep transactions short so lock windows do not overlap; (3) add appropriate indexes so InnoDB locks fewer rows. Retry logic is a safety net, not a fix, it handles the deadlocks you could not design away.
Which transaction does InnoDB roll back?
InnoDB picks the victim it judges cheapest to undo, normally the transaction that has modified the fewest rows. This is why a small transaction can be rolled back in favour of a large one. You cannot reliably predict the victim, which is exactly why every transaction that might deadlock needs retry handling rather than assuming it will be the survivor.
Why did the count spike during a sale but never during normal traffic?
Deadlocks are a function of concurrency on the same rows. At low traffic, two transactions touching the same hot rows in opposite lock order rarely overlap in time. At high concurrency on a few hot SKUs, those windows overlap constantly and the latent lock-ordering bug becomes visible. The bug was always there; traffic exposed it. Fix the lock ordering and it stays at zero even at peak.
Does the counter include deadlocks on replicas?
The card reports the deadlock counter for the instance it is reading. A replica applying writes single-threaded rarely deadlocks against itself, but with parallel replication appliers it can. If you see deadlocks on a replica, check the parallel-applier settings; on the primary, deadlocks come from concurrent application transactions as described above.