This error occurs when a transaction waits too long (default 50 seconds) to acquire a row lock. It happens due to uncommitted transactions holding locks, missing indexes, or high contention. You can fix it by increasing the timeout, identifying blocking sessions, or optimizing queries.
ERROR 1205 indicates that an InnoDB transaction exceeded the innodb_lock_wait_timeout threshold while waiting to obtain an exclusive lock on a row. This is MySQL's safety mechanism to prevent transactions from being perpetually blocked when they cannot acquire necessary locks. By default, MySQL waits 50 seconds before timing out. The error message suggests restarting the transaction, which is the recommended action—either retry immediately or investigate why the blocking transaction hasn't completed. This error is distinct from a deadlock: a lock wait timeout rolls back only the current statement (by default), while a deadlock rolls back the entire transaction.
Connect to MySQL and run:
SHOW FULL PROCESSLIST;Look for processes with a long Time value (especially those in a "sleep" state with no active command). These are likely holding locks. Note the process ID (first column) of any suspicious connection.
Once you've identified the blocking process ID, terminate it:
KILL <process_id>;For example:
KILL 42;Make sure this connection isn't actively processing important work before killing it. Check the Command and Time columns to verify it's idle.
Ensure your application code always commits or rolls back transactions, even in exception handlers:
const connection = await mysql.createConnection(config);
try {
await connection.query("START TRANSACTION");
// Your query logic here
await connection.query("COMMIT");
} catch (error) {
await connection.query("ROLLBACK");
throw error;
} finally {
connection.close();
}Enable autocommit by default to prevent accidentally holding locks:
SET SESSION autocommit = 1;Missing indexes force InnoDB to scan entire tables, locking far more rows than necessary. Identify columns frequently used in WHERE clauses of UPDATE/DELETE statements:
SHOW CREATE TABLE your_table;Add indexes for columns in lock-heavy queries:
CREATE INDEX idx_column_name ON your_table(column_name);This reduces the number of rows locked per operation, decreasing contention.
If timeouts occur despite optimization, you can increase the timeout (default 50 seconds). This is a short-term fix; address root causes first.
Check current value:
SHOW VARIABLES LIKE "innodb_lock_wait_timeout";Increase the timeout at runtime (session-level):
SET SESSION innodb_lock_wait_timeout = 100;Or globally:
SET GLOBAL innodb_lock_wait_timeout = 100;For permanent configuration, add to /etc/my.cnf:
[mysqld]
innodb_lock_wait_timeout = 100By default, MySQL rolls back only the statement that timed out, not the entire transaction (since version 5.0.13). If you prefer automatic rollback of the entire transaction, set:
SET GLOBAL innodb_rollback_on_timeout = 1;Or in /etc/my.cnf:
[mysqld]
innodb_rollback_on_timeout = 1This ensures the transaction doesn't leave behind partially committed data. However, the default behavior (statement-only rollback) is usually preferred to preserve the rest of the transaction.
Lock wait timeout differs from deadlock detection. A deadlock occurs when two transactions each hold a lock the other needs (circular dependency), causing InnoDB to immediately detect and roll back one transaction. A lock wait timeout is unidirectional—one transaction simply waiting too long for a lock. On high-concurrency systems, deadlock detection (innodb_deadlock_detect) can slow performance; some systems disable it and rely on innodb_lock_wait_timeout instead.
For heavily contended workloads, consider using row-level locking hints (SELECT ... FOR UPDATE NOWAIT) to fail fast rather than wait. Monitor lock_structs and lock_rows in INFORMATION_SCHEMA.INNODB_TRX and INNODB_LOCKS for visibility into active locks and waiting transactions.
EE_WRITE (3): Error writing file
How to fix "EE_WRITE (3): Error writing file" in MySQL
CR_PARAMS_NOT_BOUND (2031): No data supplied for parameters
How to fix "CR_PARAMS_NOT_BOUND (2031): No data supplied for parameters" in MySQL
CR_DNS_SRV_LOOKUP_FAILED (2070): DNS SRV lookup failed
How to fix "CR_DNS_SRV_LOOKUP_FAILED (2070): DNS SRV lookup failed" in MySQL
ERROR 1146: Table 'database.table' doesn't exist
How to fix "ERROR 1146: Table doesn't exist" in MySQL
ERROR 1040: Too many connections
How to fix "ERROR 1040: Too many connections" in MySQL