应查SELECT @@innodb_lock_wait_timeout获取当前会话实际值;SET GLOBAL仅影响新连接,SET SESSION仅影响当前连接,连接池复用连接不受SET SESSION影响。

能动态调,但必须分清作用域和生效范围——SET GLOBAL 立即生效,只影响新连接;SET SESSION 只改当前连接,对连接池里的复用连接无效。
怎么查当前生效值?别信猜测,直接看
执行 SHOW VARIABLES LIKE 'innodb_lock_wait_timeout' 拿到的是会话级值,但它可能继承自全局配置。如果你用的是连接池(比如 HikariCP、Druid),这个值大概率是连接初始化时读取的全局默认值,不是你后来临时 SET 过的。更准确的方式是查 SELECT @@innodb_lock_wait_timeout,它明确返回当前会话的实际值。
SET GLOBAL 和 SET SESSION 的实际影响差异
这两个命令看起来相似,但影响对象完全不同:
-
SET SESSION innodb_lock_wait_timeout = 5:只改当前连接,适合在关键事务前显式收紧,比如支付模块连接池初始化 SQL 里加这一句 -
SET GLOBAL innodb_lock_wait_timeout = 10:只对后续新建的连接生效,已存在的连接(包括连接池中正在复用的)完全不受影响 - 没 SUPER 权限?那就只能改
my.cnf+ 重启,或退而求其次,在应用层每个事务开头加SET SESSION innodb_lock_wait_timeout = ...
为什么设了还是报 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 自己秒级检测并回滚,根本不会等到超时
永久生效必须改配置文件,但要注意重启和挂载
在 my.cnf 的 [mysqld] 段下加一行:innodb_lock_wait_timeout = 10。但注意两点:
- MySQL(Linux)改完必须重启才能对所有新连接生效;不重启的话,只有后续新建连接读这个值
- 线上用 Docker 或 K8s?记得把新配置挂载进去,别只改了本地
my.cnf却没同步到镜像里 - 这个值设得太小(比如 1–2 秒)容易误杀正常短事务;设得太大(比如 >60 秒)又会让连接池线程卡住,拖垮整体响应
真正容易被忽略的是:参数再细,也救不了没索引的查询、没 commit 的事务、或者存储过程里一个没控制的 SLEEP(60)——它们都不触发行锁等待,innodb_lock_wait_timeout 完全不生效。


















