ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
This one confuses people because it often appears on a simple UPDATE, from code that "doesn't use transactions". Retrying sometimes works, and raising the timeout sometimes seems to help. Neither fixes anything. Here's what's going on.
What the error means
InnoDB locks rows (and gaps between rows) as statements run. When your statement needs a lock someone else holds, it waits, for up to innodb_lock_wait_timeout seconds (default 50). If the lock isn't released in time, your statement fails with 1205.
Two details matter:
- By default only the statement is rolled back, not the whole transaction (unless
innodb_rollback_on_timeout=ON). Your application must decide whether to roll back or retry. - It isn't a deadlock. A deadlock (error 1213) is detected immediately and one transaction is chosen as the victim. A lock wait timeout means someone held a lock for a long time and never released it.
"But I'm not using transactions"
With autocommit on, every statement is its own transaction, and it still takes locks while it runs. More importantly, the other side usually is in a transaction:
- a batch job updating 2 million rows in one statement,
- application code that ran
BEGIN, updated a row, then made a slow HTTP call, - a connection where autocommit was turned off by an ORM or pool setting and never committed,
- someone's SQL client window with an uncommitted
UPDATE.
Find the blocker
MySQL 8.0 shows who is waiting on whom:
SELECT
r.trx_mysql_thread_id AS waiting_thread,
r.trx_query AS waiting_query,
b.trx_mysql_thread_id AS blocking_thread,
b.trx_query AS blocking_query,
b.trx_started AS blocking_started
FROM performance_schema.data_lock_waits w
information_schema.INNODB_TRX r r.trx_id w.REQUESTING_ENGINE_TRANSACTION_ID
information_schema.INNODB_TRX b b.trx_id w.BLOCKING_ENGINE_TRANSACTION_ID;
