MySQL · 错误码速查
MySQL 错误 1205:等行锁超过 innodb_lock_wait_timeout(默认 50 秒),只回滚当前语句
一个 InnoDB 事务去改另一个事务锁住的行,等满 innodb_lock_wait_timeout 秒(默认 50)还没拿到锁,就报 1205。默认情况下只回滚这条等锁的语句,事务本身还开着,之前拿到的锁也还在。先找出是谁持锁不放,再考虑调参数。
官方原文
Lock wait timeout exceeded; try restarting transaction官方说明:InnoDB 在锁等待超时到期时报这个错;等待过久的那条语句被回滚(不是整个事务)。注意原文里的 “try restarting transaction” 容易让人以为事务已经整体回滚,默认并不是。
出处:MySQL 8.4 Error Reference:Server Error Message Reference 最后核对:
| 错误号 / 符号 | 1205 / ER_LOCK_WAIT_TIMEOUT | 出处 |
|---|---|---|
| SQLSTATE | HY000 | 出处 |
| 触发参数 | innodb_lock_wait_timeout:默认 50 秒,范围 1–1073741824,GLOBAL / SESSION 都能在线改 | 出处 |
| 默认回滚范围 | 当前语句(不是整个事务) | 出处 |
| 整事务回滚开关 | innodb_rollback_on_timeout:默认 OFF,不能在线改(Dynamic: No),需改配置后重启 | 出处 |
| 只作用于 | InnoDB 行锁;MySQL 表锁不在 InnoDB 内,这个超时不适用 | 出处 |
盈尺实测(测试库,非官方文档):MySQL 8.0.46 测试库,把 innodb_lock_wait_timeout 设为 5 时,等待方在 5.002 秒报 1205;报错后同一事务里之前的 INSERT 仍在。复现脚本、只读巡检 SQL 和样例 CSV 都在长文里。 看 1205 阻塞链实测长文 →
报 1205 之后,到底回滚了什么
- 默认:只回滚等锁并超时的那一条语句,不回滚整个事务。(InnoDB 系统变量、InnoDB Error Handling)
- 要整个事务回滚:用
--innodb-rollback-on-timeout启动服务器。这个变量默认 OFF,不能在线改,只能改配置后重启。 - 怎么重试:默认行为下重试这条语句;开了
innodb_rollback_on_timeout就重试整个事务。(InnoDB Error Handling) - 锁不会因此释放:官方原文是 “Locks are not released in a rollback of a single SQL statement.” 报了 1205、事务还开着时,这个事务之前拿到的锁仍然在。
应用如果捕获 1205 后继续往下执行并提交,事务里前面已经成功的写入会一起提交。会不会这样,取决于你的代码怎么处理异常;排查时值得专门看一眼。
1205 和死锁 1213 的区别
| 1205 锁等待超时 | 1213 死锁 | |
|---|---|---|
| 符号 / SQLSTATE | ER_LOCK_WAIT_TIMEOUT / HY000 | ER_LOCK_DEADLOCK / 40001 |
| 什么时候发生 | 等锁超过 innodb_lock_wait_timeout | InnoDB 检测到循环等待 |
| 回滚范围 | 默认只回滚当前语句 | 回滚整个事务 |
| 重试什么 | 默认重试语句 | 重试整个事务 |
另外,innodb_deadlock_detect 开启时(默认 ON),锁等待超时不适用于死锁:InnoDB 会立刻检测到死锁并回滚其中一个事务。只有关掉死锁检测,InnoDB 才靠 innodb_lock_wait_timeout 来回滚死锁中的事务。(InnoDB 系统变量、Deadlock Detection)
先查是谁堵住了你(3 条只读 SQL)
下面 3 条都只读,来自 MySQL 官方文档示例。要在 1205 出现的时段内执行;锁等待结束后,这些视图里就查不到了。
SELECT waiting_trx_id, waiting_pid, waiting_query,
blocking_trx_id, blocking_pid, blocking_query
FROM sys.innodb_lock_waits;这个视图默认按锁等待时长倒序排列,还有 wait_age_secs、locked_table_name、locked_index 等列,可以直接看出等了多久、卡在哪张表哪个索引上。
SELECT r.trx_id AS waiting_trx_id,
r.trx_mysql_thread_id AS waiting_thread,
r.trx_query AS waiting_query,
b.trx_id AS blocking_trx_id,
b.trx_mysql_thread_id AS blocking_thread,
b.trx_query AS blocking_query
FROM performance_schema.data_lock_waits w
JOIN information_schema.innodb_trx b
ON b.trx_id = w.blocking_engine_transaction_id
JOIN information_schema.innodb_trx r
ON r.trx_id = w.requesting_engine_transaction_id;-- 用 sys.innodb_lock_waits 里的 blocking_pid(例如 6)找线程号
SELECT THREAD_ID FROM performance_schema.threads WHERE PROCESSLIST_ID = 6;
-- 用线程号(例如 28)看它最后执行的语句
SELECT THREAD_ID, SQL_TEXT FROM performance_schema.events_statements_current WHERE THREAD_ID = 28\G
-- 还不够就看最近 10 条
SELECT THREAD_ID, SQL_TEXT FROM performance_schema.events_statements_history
WHERE THREAD_ID = 28 ORDER BY EVENT_ID;sys.innodb_lock_waits 里还有 sql_kill_blocking_query、sql_kill_blocking_connection 两列,会直接生成 KILL 语句。我们不建议在生产上直接执行:先确认阻塞事务在做什么、能不能等它提交,再决定。
要不要调 innodb_lock_wait_timeout
- 官方建议:交互性强的应用或 OLTP 系统可以调小,尽快给用户反馈,或把更新放进队列稍后处理;
- 长时间运行的后端操作(比如数仓里要等其他大批量写入完成的转换步骤)可以调大;
- 可以用
SET GLOBAL或SET SESSION在线改。改 GLOBAL 需要相应权限,只影响之后新连上来的客户端;任何客户端都能改自己的 SESSION 值。
官方同时给了降低 1205 和死锁概率的方向:在事务里“第一次修改数据”到“提交”之间做尽量少的工作,让锁持有时间最短、锁住的行最少;有时把工作拆到不同事务里也有帮助。(InnoDB Error Handling)
调参数只改变“等多久才报错”,不改变“谁在长时间持锁”。所以先做上一节的阻塞者排查。
版本说明
本页以 MySQL 8.4 官方文档为准(错误参考、参数表、sys 与 Performance Schema 页面)。5.7 / 8.0 的默认值和视图是否存在,请以对应版本文档为准;本页没有逐项核对旧版本差异,所以不列。
常见问题
mysql 1205 错误怎么解决?
先在报错时段用 sys.innodb_lock_waits 或 data_lock_waits + innodb_trx 找到 blocking_pid 和阻塞事务在做什么,再决定是让它尽快提交或回滚,还是缩短事务、调整 innodb_lock_wait_timeout。官方建议尽量缩短“第一次改数据到提交”之间的工作。
MySQL 锁等待超时时间怎么设置?默认多少?
参数是 innodb_lock_wait_timeout,默认 50 秒,最小 1,最大 1073741824,单位秒,GLOBAL 和 SESSION 都能在线设置。
1205 会回滚整个事务吗?
默认不会,只回滚当前语句,而且已经拿到的锁不会释放。要整个事务回滚,需要用 --innodb-rollback-on-timeout 启动(innodb_rollback_on_timeout 不能在线改)。
1205 和 1213 有什么区别?
1205 是等锁超时,默认只回滚语句,SQLSTATE HY000;1213 是死锁,回滚整个事务,SQLSTATE 40001。死锁检测开启时(默认),超时参数不作用于死锁。
表锁等待也会报 1205 吗?
innodb_lock_wait_timeout 只作用于 InnoDB 行锁;MySQL 表锁不在 InnoDB 内发生,这个超时不适用于表锁等待。
下一步
价格以对应页面当前标价为准。
出处(最后核对 2026-10-28)
- MySQL 8.4 Error Reference:Server Error Message Reference
- MySQL 8.4 Reference Manual 17.14:InnoDB Startup Options and System Variables(innodb_lock_wait_timeout 等)
- MySQL 8.4 Reference Manual 17.20.5:InnoDB Error Handling
- MySQL 8.4 Reference Manual:InnoDB INFORMATION_SCHEMA Transaction and Locking Information 示例
- MySQL 8.4 Reference Manual 30.4.3.9:sys.innodb_lock_waits 视图
- MySQL 8.4 Reference Manual 29.12.13.2:performance_schema.data_lock_waits 表
- MySQL 8.4 Reference Manual 17.7.5.2:Deadlock Detection
本页摘录并解读上面列出的官方文档,不是官方页面;官方文档更新后以官方为准。除标明「盈尺实测」的一段外,其余内容都来自官方文档。