MySQL并发写入如何避免锁竞争_使用队列缓冲与批量插入优化

张开发
2026/4/11 4:52:53 15 分钟阅读

分享文章

MySQL并发写入如何避免锁竞争_使用队列缓冲与批量插入优化
根本原因是InnoDB在REPEATABLE READ下间隙锁扩大锁定范围导致非等值更新或唯一索引冲突时出现锁等待链应引入内存队列缓冲写请求Go用changoroutine、Python用queue.Queue定时批量写入并设置超时丢弃防OOM。MySQL高并发写入时死锁或超时的根本原因不是因为SQL写得不好而是InnoDB默认用REPEATABLE READ隔离级别 行锁 间隙锁在主键/索引不连续、非等值条件或范围更新时会锁住本不该锁的索引区间。比如INSERT ... ON DUPLICATE KEY UPDATE在唯一索引冲突时会先加S锁再升级X锁多个线程同时撞上同一条记录就容易形成锁等待链。常见错误现象Lock wait timeout exceeded、Deadlock found when trying to get lock、CPU不高但写入QPS卡在几百上不去。关键判断如果写入量一过500 QPS就开始抖动且SHOW ENGINE INNODB STATUS里频繁出现lock struct(s)和waiting for this lock to be granted基本可以确认是锁竞争瓶颈不是磁盘或网络问题。用内存队列缓冲写请求Go/Python示例别让每个HTTP请求直连MySQL中间加一层轻量队列把“秒级突发”压平成“毫秒级匀速”。重点不是选Kafka而是用语言原生结构快速落地。使用场景日志埋点、订单快照、IoT设备心跳上报——数据可丢、可延后、结构简单。实操建议Go用chan []byte 单独goroutine消费每100ms或积满100条触发一次INSERT INTO ... VALUES (...), (...), (...)Python用queue.Queue(maxsize1000)配合threading.Timer定期flush避免用asyncio.Queue——MySQL驱动多数不真正异步务必设置队列超时丢弃防止下游MySQL挂了导致内存OOM比如Go里用select { case ch 注意INSERT ... VALUES批量插入100行比100次单行插入快5–10倍但超过500行后单次执行时间变长反而增加锁持有时间建议控制在50–200行/批。批量插入前必须做三件事很多人以为只要改成批量就万事大吉结果发现锁更严重了——因为没处理好主键生成、唯一约束和事务粒度。 Trenz AI驱动的社交电商营销平台专为TikTok Shop设计

更多文章