SQL数据库插入意向锁_并发写入优化

发布时间 - 2026-01-06 00:00:00    点击率:
插入意向锁是InnoDB在INSERT前加的特殊间隙锁,不阻塞其他插入意向锁,仅与间隙锁或临键锁冲突,旨在减少并发插入锁冲突、提升吞吐量,但不当使用易引发死锁或锁等待。

插入意向锁(Insert Intention Lock)是 InnoDB 在执行 INSERT 语句前加的一种特殊间隙锁(Gap Lock),它本身不阻塞其他插入意向锁,只在目标间隙已被其他事务加了互斥的间隙锁或临键锁(Next-Key Lock)时才会等待。它的核心作用是**减少并发插入时的锁冲突,提升写入吞吐量**,但用不好反而会引发死锁或锁等待。

插入意向锁怎么工作的?

当事务尝试向某个索引间隙(比如 id=5 和 id=10 之间)插入新记录时,InnoDB 不直接加传统间隙锁,而是加一个“插入意向锁”,标记“我打算往这儿插”。这个锁和别的插入意向锁兼容——多个事务可以同时在同一个间隙加插入意向锁,互不阻塞。

但它与以下锁冲突:

  • 另一个事务在相同间隙上持有间隙锁(如 SELECT ... FOR UPDATE 范围扫描未命中任何行)
  • 另一个事务在相同间隙上持有临键锁(如 UPDATE/DELETE 匹配到间隙边界)

例如:事务 A 执行 SELECT * FROM t WHERE id BETWEEN 5 AND 10 FOR UPDATE(没查到数据),会在 (5,10) 加间隙锁;此时事务 B 插入 id=7 就会被阻塞,因为其插入意向锁与该间隙锁冲突。

什么情况下插入意向锁会变成性能瓶颈?

常见于高并发写入、主键/唯一键分布密集、且存在范围锁操作的场景:

  • 批量导入时混用 SELECT FOR UPDATE:比如先查是否存在再插入(“检查后插入”逻辑),若查用范围条件加了间隙锁,后续插入就会排队
  • 自增主键 + 高频 INSERT … ON DUPLICATE KEY UPDATE:冲突更新可能触发临键锁,影响相邻插入
  • 非唯一索引上的并发插入:若插入值落在同一索引间隙,又恰有其他事务对该间隙加锁,就会卡住

怎么优化并发插入?

关键思路是:**避免让插入意向锁撞上不必要的间隙锁,同时减少锁粒度和持有时间**。

  • 用 INSERT IGNORE 或 ON DUPLICATE KEY UPDATE 替代“先查后插”:绕过显式加锁查询,减少间隙锁引入机会
  • 确保插入字段有合适索引:特别是唯一约束字段,让 InnoDB 快速定位冲突位置,避免全表/大范围间隙扫描
  • 控制事务粒度:插入操作尽量单事务完成,避免长事务持锁期间其他写入被阻塞
  • 必要时关闭 gap lock(谨慎!):设置 transaction_isolation = 'READ-COMMITTED' 可禁用间隙锁(除外键和唯一检查外),大幅降低插入意向锁冲突概率,但需确认业务能接受幻读

如何观察插入意向锁是否在起作用?

通过 InnoDB 状态诊断:

  • SELECT * FROM information_schema.INNODB_TRX 看当前运行事务
  • SELECT * FROM information_schema.INNODB_LOCK_WAITS 看锁等待链
  • SELECT * FROM information_schema.INNODB_LOCKS(MySQL 5.7+ 已废弃,8.0 用 performance_schema.data_locks)识别锁类型,插入意向锁显示为 INSERT_INTENTION

配合慢日志和应用层埋点,可定位具体哪条 INSERT 被阻塞、等在哪个间隙。


# mysql  # ai  # 性能瓶颈  # sql  # for  # select  # delete  # 并发  # 数据库  # 死锁  # 就会  # 加锁  # 主键  # 多个  # 已被  # 会在  # 落在  # 为其  # 只在 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Laravel Eloquent访问器与修改器是什么_Laravel Accessors & Mutators数据处理技巧  Laravel怎么进行浏览器测试_Laravel Dusk自动化浏览器测试入门  Laravel如何实现本地化和多语言支持_Laravel多语言配置与翻译文件管理  如何彻底删除建站之星生成的Banner?  Laravel怎么实现微信登录_Laravel Socialite第三方登录集成  英语简历制作免费网站推荐,如何将简历翻译成英文?  如何在IIS中新建站点并配置端口与IP地址?  Laravel怎么做缓存_Laravel Cache系统提升应用速度的策略与技巧  jQuery中的100个技巧汇总  Python函数文档自动校验_规范解析【教程】  品牌网站制作公司有哪些,买正品品牌一般去哪个网站买?  Linux后台任务运行方法_nohup与&使用技巧【技巧】  大型企业网站制作流程,做网站需要注册公司吗?  利用JavaScript实现拖拽改变元素大小  郑州企业网站制作公司,郑州招聘网站有哪些?  Laravel如何使用Facades(门面)及其工作原理_Laravel门面模式与底层机制  如何在万网主机上快速搭建网站?  Laravel Artisan命令怎么自定义_创建自己的Laravel命令行工具完全指南  高配服务器限时抢购:企业级配置与回收服务一站式优惠方案  如何有效防御Web建站篡改攻击?  宙斯浏览器视频悬浮窗怎么开启 边看视频边操作其他应用教程  夸克浏览器网页跳转延迟怎么办 夸克浏览器跳转优化  如何在IIS中配置站点IP、端口及主机头?  详解Oracle修改字段类型方法总结  Laravel如何编写单元测试和功能测试?(PHPUnit示例)  微信小程序 scroll-view组件实现列表页实例代码  如何在IIS中新建站点并解决端口绑定冲突?  Laravel Seeder填充数据教程_Laravel模型工厂Factory使用  Laravel中间件起什么作用_Laravel Middleware请求生命周期与自定义详解  高防服务器如何保障网站安全无虞?  网站广告牌制作方法,街上的广告牌,横幅,用PS还是其他软件做的?  Laravel怎么实现搜索功能_Laravel使用Eloquent实现模糊查询与多条件搜索【实例】  制作网站软件推荐手机版,如何制作属于自己的手机网站app应用?  Java垃圾回收器的方法和原理总结  Python自然语言搜索引擎项目教程_倒排索引查询优化案例  Laravel如何为API生成Swagger或OpenAPI文档  Laravel怎么在Controller之外的地方验证数据  EditPlus中的正则表达式 实战(2)  Laravel Telescope怎么调试_使用Laravel Telescope进行应用监控与调试  如何在浏览器中启用Flash_2025年继续使用Flash Player的方法【过时】  Laravel DB事务怎么使用_Laravel数据库事务回滚操作  C语言设计一个闪闪的圣诞树  Laravel如何使用withoutEvents方法临时禁用模型事件  JS中对数组元素进行增删改移的方法总结  Laravel集合Collection怎么用_Laravel集合常用函数详解  Win11摄像头无法使用怎么办_Win11相机隐私权限开启教程【详解】  iOS发送验证码倒计时应用  制作无缝贴图网站有哪些,3dmax无缝贴图怎么调?  开心动漫网站制作软件下载,十分开心动画为何停播?  东莞专业网站制作公司有哪些,东莞招聘网站哪个好?