At a glance
InnoDB Deadlocks (last 5m) counts the number of times in the past five minutes that the InnoDB storage engine detected two or more transactions waiting on each other’s locks in a cycle and forcibly rolled one back to break the deadlock. The rolled-back transaction fails with error 1213 (“Deadlock found when trying to get lock; try restarting transaction”). A handful of deadlocks under heavy concurrent write load is survivable if the application retries; a sustained stream points to a lock-ordering or hot-row contention problem that surfaces to shoppers as failed checkouts and “please try again” errors.
| What it tracks | The count of InnoDB-detected deadlocks within the trailing 5-minute window. Each deadlock represents one transaction the engine chose as the victim and rolled back to resolve a lock cycle. |
| Data source | The InnoDB deadlock counter exposed via SHOW ENGINE INNODB STATUS (LATEST DETECTED DEADLOCK section) and the Innodb_deadlocks value where the information_schema / performance_schema instrumentation is enabled. |
| Time window | 5m (trailing five-minute window, refreshed live). |
| Alert trigger | >0. Any deadlock in the window flags the card, because in a well-ordered schema deadlocks should be rare. The sensitivity threshold is tunable for write-heavy workloads that expect a low background rate. |
| Why it matters | A deadlock means a transaction failed. If the application does not retry, that is a lost order, a stuck job, or a user-facing error. A rising count signals contention that worsens under load. |
| Sensitivity | Sensitivity card: the alert threshold and sustained-duration window are tunable per profile so a known low background rate does not page needlessly. |
| Roles | owner, engineering, operations |
Calculation
InnoDB performs automatic deadlock detection: when it finds a cycle in the lock wait-for graph (transaction A holds a lock B wants, while B holds a lock A wants), it selects the transaction that has done the least work as the victim, rolls it back, and lets the other proceed. Each such event increments the engine’s deadlock counter. This card samples that counter and reports the delta over the trailing five-minute window, so the value is “how many deadlocks happened in the last 5 minutes”, not a lifetime total. The raw counter behind it isInnodb_deadlocks (or, on builds without that status variable, the LATEST DETECTED DEADLOCK block from SHOW ENGINE INNODB STATUS, which records the most recent event with the two conflicting transactions and the locks involved). Because the value is a windowed delta, a single burst of three deadlocks during a flash-sale minute reads as 3, then decays back to 0 as that minute ages out of the window. The >0 alert is deliberately strict: a healthy schema with consistent lock ordering produces zero deadlocks for long stretches, so any non-zero value is worth a look. Calculated automatically from your MariaDB data; see the worked example for a typical reading.
Worked example
An engineering team runs a BigCommerce-backed inventory service on a single MariaDB primary. A flash sale starts at 12:00 BST on 21 Apr 26 and concurrent stock-decrement transactions spike. Snapshot taken at 12:04.| Window minute | Deadlocks | Victim statement (digest) | Note |
|---|---|---|---|
| 12:00 to 12:01 | 0 | n/a | Normal pre-sale load |
| 12:01 to 12:02 | 2 | UPDATE stock SET qty = qty - ? WHERE sku_id = ? | Two threads hit the same hot SKU row |
| 12:02 to 12:03 | 5 | same digest | Contention rising with traffic |
| 12:03 to 12:04 | 7 | same digest | Card now reads 7 in the 5m window |
>0 band. The engineer reads three things:
- It is a single hot row, not a schema-wide problem. Every victim is the same statement digest hitting the
stocktable for popular SKUs. The deadlocks cluster on the rows everyone is buying. This is contention, not a missing index. - The application is retrying, mostly. Most victims are retried by the app and succeed on the second attempt, so the customer-visible failure rate is far lower than 7. But the retries add latency, which shows up on Query Latency p95 (ms) climbing in the same window.
- The fix is a lock-strategy change, not more hardware. Throwing CPU at this will not help; the rows are serialised by the lock. The durable fix is to reduce time-in-transaction (shorter transactions hold locks for less time), apply consistent lock ordering, or move to an atomic
UPDATE ... WHERE qty >= ?pattern that avoids the read-then-write race.
- Read the victim digest, not just the count. Seven deadlocks all on one statement is one bug; seven deadlocks across seven statements is a systemic lock-ordering problem. The native
SHOW ENGINE INNODB STATUSoutput names the conflicting statements. - Deadlocks and latency move together under contention. A deadlock spike with no latency change is odd; usually the same contention that causes deadlocks also queues other transactions. Pair the two cards.
- Retries hide the count but not the cost. A well-behaved application retries and the order still completes, so deadlocks can look harmless. The hidden cost is added latency and CPU; if the count is high, fix the contention rather than relying on retries forever.
Sibling cards
| Card | Why pair it with InnoDB Deadlocks | What the combination tells you |
|---|---|---|
| Query Latency p95 (ms) | Retries from deadlocks add latency. | Deadlocks up plus p95 up equals contention serialising your write path. |
| Query Latency p99 (ms) | Tail latency captures the retried transactions. | A p99 spike with deadlocks shows the worst-affected users feel the contention most. |
| Query Error Rate % | Un-retried deadlocks surface as error 1213. | Deadlocks up plus error rate up equals the application is NOT retrying; orders are failing. |
| Slow-Query Rate % | Long-running transactions hold locks longer. | Slow queries plus deadlocks equals a transaction holding locks far too long; shorten it. |
| Queries per Second (live) | Contention scales with concurrency. | A QPS spike that triggers deadlocks confirms the problem is load-driven hot-row contention. |
| MariaDB Health Score | Deadlocks pull the composite down via the error and latency inputs. | A health-score dip during a write burst often traces straight back to this card. |
| Slow Queries During Checkout Window (5m) | Cross-channel: ties contention to the checkout path. | Deadlocks co-occurring with a checkout drop is a direct revenue link. |
Reconciling against the source
Where to look on the server:Why our number may legitimately differ:SHOW ENGINE INNODB STATUS\Gand read the LATEST DETECTED DEADLOCK section. This names the two transactions, the locks each held and waited on, the exact statements, and which one InnoDB rolled back. It is the single most useful diagnostic for this card.SHOW GLOBAL STATUS LIKE 'Innodb_deadlocks';for the running counter (where the build exposes it). Sample it twice and diff to get a per-window rate that matches the card.SELECT * FROM information_schema.INNODB_TRX;to see currently running transactions and how long they have been open (long-open transactions are the usual deadlock culprits). Enableinnodb_print_all_deadlocks = ONto log every deadlock to the error log, not just the latest, so you can reconcile the full count over the window rather than only the most recent event.
| Reason | Direction | Why |
|---|---|---|
| Single-event status block | Native shows fewer | SHOW ENGINE INNODB STATUS only retains the LATEST deadlock; the card counts all in the window. Use innodb_print_all_deadlocks to see the full set. |
| Window alignment | Brief | The card’s trailing 5-minute window may straddle two of your manual samples; align the boundaries before comparing. |
| Counter reset on restart | Lower after restart | Innodb_deadlocks resets to 0 when the server restarts; the card’s windowed delta is unaffected but a lifetime comparison will not match. |
SHOW ENGINE INNODB STATUS is available to the application user, and deadlock detail is also written to the engine log you can download from the provider console. There is no separate managed metric for deadlocks; reconcile via the engine status and the error log.
Known limitations / FAQs
The card shows deadlocks but my application is not throwing errors. Why? Because your application is retrying. A well-written client catches error 1213 and replays the transaction, which usually succeeds on the second attempt. The order completes, so the user sees nothing, but the deadlock still happened and still cost latency and CPU. The card surfaces the underlying contention even when retries mask it. Are a few deadlocks normal? Under heavy concurrent writes to popular rows, a low background rate can be expected, and a retrying application absorbs it. The>0 default is strict on purpose, but you can raise the threshold and sustained-duration window in the Sensitivity tab so a known background rate does not page. What matters is the trend: a stable low rate is tolerable, a climbing rate is not.
How do I actually fix recurring deadlocks?
Read the LATEST DETECTED DEADLOCK block to identify the conflicting statements, then apply the standard remedies in order: (1) shorten transactions so locks are held for less time; (2) enforce a consistent order in which rows and tables are locked across all code paths; (3) replace read-then-write patterns with atomic single-statement updates; (4) add or fix indexes so the engine locks fewer rows. More hardware does not help, because the contention is logical, not resource-bound.
What is the difference between a deadlock and a lock wait timeout?
A deadlock is a detected cycle that InnoDB breaks immediately by rolling one transaction back (error 1213). A lock wait timeout is a transaction that waited longer than innodb_lock_wait_timeout for a lock that was never released in a cycle (error 1205). They are different failures; this card counts deadlocks only. Persistent lock wait timeouts point to long-running transactions rather than cycles.
Does this card see deadlocks across a Galera cluster?
Galera adds a second class of conflict: cluster-level certification failures (sometimes called “brake” or cluster conflicts) that look like deadlocks to the application. Classic single-node InnoDB deadlocks are counted here; Galera certification conflicts surface through the wsrep_local_cert_failures counter and relate more closely to the Galera flow-control and cluster cards. If you run Galera and see deadlock-like errors, check both.
Why does the count drop back to zero so quickly?
The value is a trailing 5-minute window, not a cumulative total. A burst of deadlocks shows up immediately, then decays as those minutes age out of the window. If you want the lifetime count, read Innodb_deadlocks from SHOW GLOBAL STATUS directly; if you want a full audit trail, enable innodb_print_all_deadlocks.
Can deadlocks corrupt data?
No. A deadlock is resolved cleanly: InnoDB rolls the victim transaction back in full, leaving the database consistent. The risk is not corruption, it is the failed transaction itself (a lost write the application must retry) and the latency the contention adds.