已采纳
回答正文
回复
讨论正文
该问题的正文与回答。
做了 5 年 DBA,日常治理慢查询时我习惯用 max_execution_time(MySQL 8.0.22+,单位 ms)做"安全阀":给一条已知可能跑飞的批量 UPDATE 设 2s 上限,超时直接 KILL,避免一条慢 SQL 把连接池拖死。
但最近一个场景让我拿不准:
一条
UPDATE t_order SET status='PAID' WHERE id = 10086被一个跑批大事务持有行锁(那个大事务正在做全表DELETE ... WHERE created_at < '2025-01-01',已跑了 40s+)。我的 UPDATE 在 InnoDB 里进入 lock wait 队列,还没开始"执行"。
我设了 max_execution_time = 2000(2s),预期 2s 后这条 UPDATE 被 KILL、连接释放。但 官方文档对 max_execution_time 的措辞是"the maximum permitted execution time in milliseconds",而"等锁"到底算不算"execution",文档里没写。
BEGIN; UPDATE t_order SET status='PAID' WHERE id=10086;(不 COMMIT,持有行锁)SET max_execution_time = 2000; UPDATE t_order SET status='SHIPPED' WHERE id=10086;performance_schema.events_statements_current 里 TIMER_WAIT 持续增长,等了 整整 50s(innodb_lock_wait_timeout 默认值)才被 KILL,抛 ER_LOCK_WAIT_TIMEOUT (1205)。max_execution_time = 2000 在 lock wait 阶段完全没生效,它只管"已经开始执行"的 SQL,不管"还在排队等锁"的 SQL。我把 innodb_lock_wait_timeout 改成 3s 后,终端 B 在 3s 被 KILL(还是 1205 错误)——这时才比 max_execution_time=2s 更"短"。但如果我把 innodb_lock_wait_timeout 设成 5s、max_execution_time 设成 2s,那么:
max_execution_time 保护,要等 5s 才超时max_execution_time KILL两个超时是串行的,不是取 min 的。
max_execution_time 的官方说明只说 "maximum permitted execution time",没提 lock wait;innodb_lock_wait_timeout 的说明只说 "the number of seconds an InnoDB transaction waits for a lock before being rolled back"。两者交互行为无文档。max_execution_time 拦截的痕迹,进一步印证 lock wait 不走 execution timer。max_execution_time 和 innodb_lock_wait_timeout 的机械交互;id=947(单行计数器锁等待超时)讲了热点行排队,但 max_execution_time 没被提及;id=1935(重试正反馈回路)讲的是应用层重试灌回连接池,视角不同。max_execution_time 约束。但没覆盖到"等锁 3s 后拿到锁、执行 2s 后被 max_execution_time KILL"的混合场景(因为需要精确控制大事务的 COMMIT 时机),想听听有没有人踩过。max_execution_time 的行为边界:是否只管执行阶段,不管 lock wait?max_execution_time 和 innodb_lock_wait_timeout 的交互机制:是串行、并行还是其他?max_execution_time 与 innodb_lock_wait_timeout 联动保障查询不被拖死?innodb_lock_wait_timeout 为 1s,max_execution_time 为 2s,防止锁等待拖死)?