直接执行show variables like 'innodb_lock_wait_timeout'即可查看当前会话生效值,该值可能继承自全局配置;set session仅影响当前连接,set global仅对新连接生效,已复用的连接池连接不受影响。

怎么查当前值?别猜,直接看
执行 SHOW VARIABLES LIKE 'innodb_lock_wait_timeout' 就能拿到当前生效值。注意:它返回的是会话级值,但可能继承自全局——所以得结合上下文判断。如果用连接池(比如 HikariCP、pymysql pool),你看到的很可能是连接初始化时读取的全局默认值,不是你临时 SET 过的。
SET SESSION 和 SET GLOBAL 有什么实际区别?
关键不在“设没设成”,而在“谁受影响”:
-
SET SESSION innodb_lock_wait_timeout = 15:只改当前连接,适合在应用启动后、执行关键事务前显式收紧,比如支付模块的连接池初始化 SQL 里加这一句 -
SET GLOBAL innodb_lock_wait_timeout = 15:新建立的连接才用这个值,已存在的连接(包括连接池里正在复用的)完全不受影响——别指望改完就立刻全量切换 - 没权限执行
SET GLOBAL?那就只能靠配置文件 + 重启,或退而求其次,在应用层每个事务开头加SET SESSION
my.cnf 里怎么写才算真正落地?
在 [mysqld] 段下加一行就行:innodb_lock_wait_timeout = 15。但要注意两点:
- 改完必须重启 MySQL 才能对所有新连接生效;不重启的话,只有后续新建连接读这个值
- 如果线上用的是容器化部署(比如 Docker 或 K8s),记得把新配置挂载进去,别只改了本地 my.cnf 却没同步到镜像里
为什么设了还是报 Lock wait timeout exceeded?
这个参数只管「等锁」,不管「执行慢」或「锁太久」:
- 如果
UPDATE ... WHERE unindexed_column = ?扫全表,它会持锁几十秒——innodb_lock_wait_timeout不会打断它,只会让别人等它时超时 - 频繁报错,第一反应不该是调大,而是查
SHOW ENGINE INNODB STATUS\G里 waiting 的是谁、被谁堵着,再看information_schema.INNODB_TRX找长事务 - 死锁(
ERROR 1213 (HY000): Deadlock found)和这个参数无关,InnoDB 自己秒级检测并回滚,根本不会等到超时
真正容易被忽略的是:参数设得再细,也救不了没索引的查询、没 commit 的事务、或者存储过程里一个没控制的 SLEEP(60) —— 它们都不触发行锁等待,innodb_lock_wait_timeout 完全不生效。











