MySQL中是如何insert数据的

正常insert数据,MySQL并不会显式加锁,而是通过聚簇索引的trx_id索引作为隐式锁来保护记录的。比如两个事务对一个非唯一的索引情况添加,会造成幻读

但在某些特殊情况下,隐式锁会转变为显式锁:

  • 记录之间有间隙锁
  • insert的记录与已有记录的唯一索引冲突

记录之间有间隙锁

每插入一条新记录,都需要看一下待插入记录的下一条记录上是否已经被加了间隙锁,如果已加间隙锁,此时会生成一个插入意向锁,然后锁的状态设置为等待状态(PS:MySQL 加锁时,是先生成锁结构,然后设置锁的状态,如果锁状态是等待状态,并不是意味着事务成功获取到了锁,只有当锁状态为正常状态时,才代表事务成功获取到了锁),现象就是 Insert 语句会被阻塞。

复制代码
# 事务 A
mysql> begin;
Query OK, 0 rows affected (0.01 sec)

mysql> select * from t_order where order_no = 1006 for update;

# 事务 B 插入一条记录
mysql> begin;
Query OK, 0 rows affected (0.01 sec)

mysql> insert into t_order(order_no, create_date) values(1010,now());
### 阻塞状态。。。。

可以看到,事务 B 的状态为等待状态(LOCK_STATUS: WAITING),因为向事务 A 生成的 next-key 锁(记录锁+间隙锁)范围(1005, +∞] 中插入了一条记录,所以事务 B 的插入操作生成了一个插入意向锁(LOCK_MODE: X,INSERT_INTENTION),锁的状态是等待状态,意味着事务 B 并没有成功获取到插入意向锁,因此事务 B 发生阻塞。

遇到唯一键冲突

插入失败,会对这条记录上S型锁

  • 如果主键索引重复,插入新记录的事务会给已存在的主键值重复的聚簇索引记录添加 S 型记录锁。
  • 如果唯一二级索引重复,插入新记录的事务都会给已存在的二级索引列值重复的二级索引记录添加 S 型 next-key 锁。(但假设有这么一种情况,目前表里有二级索引id=1~5的数据记录,事务A插入一个id=6,是可以的,不会被阻塞,也没有上显式锁其实,只有隐式锁。但假设事务B想再插入id=6的数据,A对id=6的隐式锁会升级为显式X锁,B此时相当于想申请id=6的S锁,会被阻塞)
相关推荐
白帽攻防录7 小时前
SRC 挖洞:Roundcube 预认证 SQL 注入深度复盘,CVE-2026-48842 preg_replace 转义绕过怎么打穿邮件系统
网络·数据库·sql·网络安全·sql注入
꯭自꯭闭꯭7 小时前
达梦SQL优化相关
linux·运维·数据库·sql
nhdh7 小时前
B+树揭秘:MySQL索引核心原理全解析
数据结构·b树·mysql
对空六课8 小时前
支持注意力分析的热力图工具有哪些?
前端·数据库·数据分析
南京码讯光电技术有限公司8 小时前
How to Design an Antenna System for an Industrial WiFi Module
数据库·人工智能
lusklusklusk9 小时前
Oracle数据库基础之2_体系结构
数据库·oracle
可乐ea9 小时前
从第一性原理构建 AI Agent:提示词、工具、技能与记忆全解剖
数据库·人工智能·工具调用·ai智能体·提示词工程·agent开发·智能体记忆
余槐i10 小时前
MySQL 深分页从 4 秒到 60 毫秒:延迟关联减少回表的实测与代价
mysql·性能优化·sql优化·执行计划·慢查询优化
东方护航数据恢复(深圳)10 小时前
医疗案例:HIS/PACS 数据库页损坏修复,医院不停诊完成恢复【东方护航数据恢复深圳店】
数据库·数据恢复·医疗·二次开盘
lusklusklusk11 小时前
Oracle数据库基础之11_Duplicate和Dataguard和RAC
数据库·oracle