前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >insert唯一键冲突的加锁情况分析

insert唯一键冲突的加锁情况分析

作者头像
AsiaYe
发布2020-06-12 17:54:05
2.4K1
发布2020-06-12 17:54:05
举报
文章被收录于专栏:DBA随笔DBA随笔

//

insert唯一键冲突的加锁情况分析

//

今天分享的内容是MySQL里面insert语句在发生冲突的时候加锁情况,废话就不多说了,直接从例子开始吧。

首先创建表t,其中id为主键,c为唯一索引,然后插入5条数据,

代码语言:javascript
复制
mysql> show create table t\G
*************************** 1. row ***************************
       Table: t
Create Table: CREATE TABLE `t` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `c` int(11) DEFAULT NULL,
  `d` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `c` (`c`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

mysql> select * from t;
+----+------+------+
| id | c    | d    |
+----+------+------+
|  1 |    1 |    1 |
|  2 |    2 |    2 |
|  3 |    3 |    3 |
|  4 |    4 |    4 |
|  5 |    5 |    5 |
+----+------+------+
5 rows in set (0.00 sec)

接下来测试锁发生的场景:

从上面的图中不难看出,session A上的第一个insert操作是成功的,这容易理解,因为没有并发,表中的最大值是5。第二个insert操作因为重复的键值而报错,因为c=10的记录已经有了,按理说发生唯一键冲突之后,这条语句失败了,应该不对MySQL有影响才对,实际上,这个insert语句做了两件事情:

1、报唯一键冲突错误,返回

2、在(5,10]这个区间加上了next_key的共享锁

其中,第二点可以从show engine innodb status看出来:

代码语言:javascript
复制
------------
TRANSACTIONS
------------
Trx id counter 254732
Purge done for trx's n:o < 254730 undo n:o < 0 state: running but idle
History list length 208
LIST OF TRANSACTIONS FOR EACH SESSION:
---TRANSACTION 283902019123864, not started
0 lock struct(s), heap size 1136, 0 row lock(s)
---TRANSACTION 254731, ACTIVE 9 sec inserting
mysql tables in use 1, locked 1
LOCK WAIT 2 lock struct(s), heap size 1136, 1 row lock(s), undo log entries 1
MySQL thread id 5, OS thread handle 3124, query id 28 localhost ::1 root update
insert into t values (12,9,9)
------- TRX HAS BEEN WAITING 9 SEC FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 139 page no 4 n bits 80 index c of table `test`.`t` trx id 254731 lock_mode X locks gap before rec insert intention waiting
Record lock, heap no 7 PHYSICAL RECORD: n_fields 2; compact format; info bits 0
 0: len 4; hex 8000000a; asc     ;;
 1: len 4; hex 8000000a; asc     ;;

------------------
---TRANSACTION 254730, ACTIVE 89 sec
2 lock struct(s), heap size 1136, 1 row lock(s)
MySQL thread id 4, OS thread handle 8676, query id 18 localhost ::1 root cleaning up

上面的结果中,可以看到,当前该表上一共有2个锁结果,分别是x locks gap before rec和record lock,也就是(5,10)之间的间隙锁和c=10的记录锁。

还有一点要说明,在本例子中,冲突的是唯一索引,如果是主键冲突,那么聚集索引上也要添加共享next_key锁,而不是记录锁。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-06-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 DBA随笔 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档