首页/数据/SQL 速查/锁等待与超时参数
变更与事务52 条

锁等待与超时参数

控制等锁的耐心:MySQL 有 innodb_lock_wait_timeout;PostgreSQL 默认无限等待,需要显式设置 lock_timeout / statement_timeout。

SQL 速查数据更新于 2026-10-13

锁等待超时参数是什么

锁等待不是无限期的,超时参数决定语句等多久,超时后报错放弃。MySQL 的分行锁等待用 innodb_lock_wait_timeout(默认 50 秒,超时报 1205),元数据锁等待由 lock_wait_timeout 控制(默认值极长);PostgreSQL 用 lock_timeout(默认 0 表示不限制)、statement_timeout(整条语句上限)与 deadlock_timeout(启动死锁检测前的等待)。这些参数是止损手段:把「无限期挂住」变成可观测的失败,便于重试或降级。

基本信息

MySQL 行锁参数innodb_lock_wait_timeout,默认 50 秒,可会话级调整,超时报 1205
MySQL 元数据锁参数lock_wait_timeout,默认值极长,DDL 排队时最常踩
PostgreSQL 参数lock_timeout(默认 0 不限制)、statement_timeout、deadlock_timeout(默认 1s)
PG 错误码55P03 表示拿不到锁,57014 表示语句被超时取消
设置方式MySQL SET SESSION innodb_lock_wait_timeout = 10;PG SET lock_timeout = '5s'

典型使用场景

  • 防止应用线程被锁等待无限期挂住,把阻塞变成可重试的失败
  • 监控超时次数,判断锁竞争是否在恶化
  • 批处理任务设置短超时,快速失败而不是长时间占着连接
  • 迁移与 DDL 脚本设置 lock_timeout,避免把线上查询排成长队
  • 排查 1205 与 55P03 报错背后的长事务

MySQL 参数调整

MySQL 参数调整
-- 查看当前设置
SHOW VARIABLES LIKE 'innodb_lock_wait_timeout';   # 默认 50 秒
SHOW VARIABLES LIKE 'lock_wait_timeout';          # 元数据锁等待,默认时间极长

-- 会话级调整:批处理与迁移脚本建议设短一些
SET SESSION innodb_lock_wait_timeout = 10;        # 10 秒拿不到锁就报 1205

-- 全局调整需谨慎,影响所有新连接
SET GLOBAL innodb_lock_wait_timeout = 20;

PostgreSQL 参数调整

PostgreSQL 参数调整
SHOW lock_timeout;          -- 0 表示不限制
SHOW statement_timeout;     -- 整条语句的执行上限

SET lock_timeout = '5s';        -- 5 秒拿不到锁就中止
SET statement_timeout = '30s';  -- 语句最长执行 30 秒
SET deadlock_timeout = '1s';    -- 等这么久仍拿不到锁才启动死锁检测

-- 迁移场景:短超时快速失败,避免阻塞线上查询
SET lock_timeout = '2s';
ALTER TABLE big_table ADD COLUMN note text;   -- 拿不到锁立即失败,稍后重试

参数速查

参数默认值作用
innodb_lock_wait_timeout(MySQL)50 秒行锁等待上限,超时报 1205
lock_wait_timeout(MySQL)约一年元数据锁等待上限,DDL 排队时最常踩
lock_timeout(PG)0(不限制)获取锁的等待上限
statement_timeout(PG)0(不限制)语句整体执行上限
deadlock_timeout(PG)1 秒启动死锁检测前愿意等待的时间
超时参数大多可以按会话设置(SET SESSION / SET),批处理与迁移脚本临时调短、快速失败最合适;全局值要根据业务容忍度谨慎调整,设得过短会让正常的长事务开始报错。
超时只是止损不是解决方案:频繁出现 1205 或锁超时说明存在长事务、缺索引或热点行竞争,应回到锁等待排查找根因,而不是继续把超时时间调大。

易错点

  • 把 innodb_lock_wait_timeout 调大来「解决」锁等待,结果变成应用线程长时间挂住
  • 忽视元数据锁等待(lock_wait_timeout),DDL 与线上查询互相排队引发故障
  • PostgreSQL 只设了 lock_timeout 而忘记 statement_timeout,慢查询依旧长时间占用资源
  • 应用不区分锁超时错误与业务错误,把本可重试的冲突直接返回给用户

数据来源与参考

  • MySQL 8.0 Reference Manual · InnoDB Lock Wait Timeout
  • PostgreSQL Documentation · Client Connection Defaults
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌