DELETE FROM logs WHERE id <= 500000 ORDER BY id LIMIT 1000;
COMMIT;
SELECT COUNT(*) FROM performance_schema.data_locks;

清理历史日志改成 delete ... limit 10000 循环 100 次,每批之间 sleep 0.1 秒,跑到第 30 批时锁等待还是升到 40 秒。先别急着动参数,把报错原文和时间点记下来,顺序反了容易白折腾。

原因不复杂,delete 走的是同一个索引范围,每批都从头扫,扫过的行即使没删也要加锁。批次之间没有提交,锁一直累积在同一个事务里。sleep 只让出了 CPU,没让出锁。

「批量删除锁等待」确认了原因之后,改动尽量只碰那一处,顺手改的东西后面最容易出问题。动手前把原文件复制一份带时间戳,出问题立刻换回去,比现场分析快得多。

一次只改一处,改完立刻验证,几个改动叠在一起,出问题就说不清是谁导致的。

处理上按这个顺序:确认每批 delete 之后有 commit;按主键范围推进 每批从上一批最大 id 之后开始;把 limit 调小到 1000 观察锁等待曲线;删除条件补索引 避免每批全表扫。

改完只确认一件事:锁等待稳定在毫秒级 删除任务总时长可控 业务写入不再受影响。

作者 9823189