批量更新、删除或导入时,MySQL返回ERROR 1206: The total number of locks exceeds the lock table size。它看起来像表锁数量达到某个固定上限,但InnoDB真正报告的是用于管理锁的内存不足。
这与等待别的事务释放锁不是同一类故障。

错误1206和锁等待有什么区别
MySQL官方错误参考把1206定义为ER_LOCK_TABLE_FULL:总锁数量超过可用于锁管理的内存。错误1205则是Lock wait timeout exceeded,表示语句等待其他事务的锁超过时间。
增加innodb_lock_wait_timeout不能解决1206。它只改变等待时长,不会减少当前事务持有的锁或增加锁管理内存。
先找出哪个事务锁得太多
检查当前执行的批量UPDATE、DELETE、INSERT ... SELECT和长时间未提交事务。结合SHOW ENGINE INNODB STATUS、Performance Schema事务与数据锁视图,确认事务持续时间、修改行数和锁范围。
查询诊断信息时避免把业务数据和完整SQL参数写入公开日志。还要检查过滤条件是否缺少索引,导致扫描和锁定范围扩大。
为什么拆分大事务更稳妥
官方错误参考建议把大型操作拆成较小批次。例如按主键范围分段更新,每批提交后再处理下一段,可以释放已持有的锁并降低回滚、复制延迟和故障恢复成本。
拆批必须使用稳定且可重复的边界。不要用无排序的LIMIT循环删除,否则并发写入时可能遗漏或重复处理。
何时调整innodb_buffer_pool_size
MySQL官方同时建议通过增加innodb_buffer_pool_size提供更多锁管理内存,但应先核对主机物理内存、其他进程、连接开销和容器限制。调整前记录当前值、内存峰值与交换空间,并按版本支持方式修改。
缓冲池不能无限增大。把它设得过高可能触发主机或容器OOM,导致整个数据库被终止。
修复后的验收标准
在测试副本重放原操作,观察每批事务时间、锁数量、复制延迟和内存峰值,再逐步调整批次大小。可在萤光云或LightNode的隔离VPS演练。验收标准是1206不再出现、事务可控提交、无OOM和异常长回滚,并且并发业务延迟符合预期。
FAQ
问:重启MySQL能解决吗?答:重启会终止事务并释放锁,但不消除过大的单事务或容量配置问题,故障可能再次出现。
问:这是metadata lock吗?答:1206主要描述InnoDB锁管理内存不足,应结合数据锁与事务信息判断,不要只查元数据锁。
问:只加索引就够了吗?答:合适索引可缩小扫描范围,但一次修改海量行仍可能持有大量锁,需要拆批。
问:批次越小越好吗?答:过小会增加提交与日志开销,应按延迟、吞吐和复制表现测试平衡点。
问:MyISAM也会报同样错误吗?答:官方解释针对InnoDB,应先确认表的存储引擎和实际错误号。
温馨提示
温馨提示:上线批量数据维护前,先估算影响行数、回滚空间与复制压力。为长事务、锁数量和缓冲池内存建立监控,比故障后单纯调大参数更可靠。


