当前位置: 首页 > news >正文

mysql中insert … select锁范围

1、执行 insert … select 的时候,对目标表也不是锁全表,而是只锁住需要访问的资源。

例如,

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;insert into t values(null, 1,1);
insert into t values(null, 2,2);
insert into t values(null, 3,3);
insert into t values(null, 4,4);create table t2 like t
insert into t2(c,d)  (select c+1, d from t force index(c) order by c desc limit 1);

这个语句的加锁范围,就是表 t 索引 c 上的 (3,4]和 (4,supremum]这两个 next-key lock,以及主键索引上 id=4 这一行。

它的执行流程也比较简单,从表 t 中按照索引 c 倒序,扫描第一行,拿到结果写入到表 t2 中。因此整条语句的扫描行数是 1。

2、insert select加了什么锁,唯一索引查询出现死锁场景

  • 在 T1 时刻,启动 session A,并执行 insert 语句,此时在索引 c 的 c=5 上加了记录锁。注意,这个索引是唯一索引,因此退化为记录锁
  • 在 T2 时刻,session B 要执行相同的 insert 语句,发现了唯一键冲突,加上读锁(0,5];
  • 同样地,session C 也在索引 c 上,c=5 这一个记录上,加了读锁(0,5]。
  • T3 时刻,session A 回滚。
  • 这时候,session B 和 session C 都试图继续执行插入操作,都要加上写锁。两个 session 都要等待对方的行锁,所以就出现了死锁。

3. insert into … on duplicate key update怎么加锁

insert into … on duplicate key update 这个语义的逻辑是,插入一行数据,如果碰到唯一键约束,就执行后面的更新语句。

insert into t values(11,10,10) on duplicate key update d=100;

索引 c 上 (5,10] 加一个排他的 next-key lock(写锁)。

4. 总结

  • insert … select 是很常见的在两个表之间拷贝数据的方法。
  • 在可重复读隔离级别下,这个语句会给 select 的表里扫描到的记录和间隙加读锁。
  • 而如果 insert 和 select 的对象是同一个表,则有可能会造成循环写入。这种情况下,我们需要引入用户临时表来做优化。
  • insert 语句如果出现唯一键冲突,会在冲突的唯一值上加共享的 next-key lock(S 锁)。因此,碰到由于唯一键约束导致报错后,要尽快提交或回滚事务,避免加锁时间过长。
  • 如果在 insert … select 执行期间有其他线程操作原表,会导致逻辑错误。其实,这是不会的,如果不加锁,就是快照读。一条语句执行期间,它的一致性视图是不会修改的,所以即使有其他事务修改了原表的数据,也不会影响这条语句看到的数据。

相关文章:

  • 如何解决由触发器导致 MySQL 内存溢出?
  • 在文件夹下快速创建vue项目搭建vue框架详细步骤
  • uniapp swiper设置高度以及切换时滚动条回到顶部,下滑加载
  • 如何解决浏览器兼容问题2.0
  • 搜狐新闻Hybrid AI引擎端侧离线大语言模型探索
  • 数据结构小记【Python/C++版】——散列表篇
  • 《Ubuntu20.04环境下的ROS进阶学习0》
  • ​如何防止网络攻击?
  • Java中 图的基础知识介绍
  • 【 React 】对React中类组件和函数组件的理解?有什么区别?
  • 【Linux】文件系统和软硬链接
  • EPDM和钉钉集成审批工作—移动端直接处理审批节点,高效协同!
  • Java开发从入门到精通(一):Java 数据库编程
  • 小程序学习 1
  • Vue源码系列讲解——内置组件篇【一】(keep-alive)
  • [数据结构]链表的实现在PHP中
  • angular2 简述
  • canvas绘制圆角头像
  • CSS3 变换
  • FineReport中如何实现自动滚屏效果
  • Java 网络编程(2):UDP 的使用
  • PyCharm搭建GO开发环境(GO语言学习第1课)
  • Spring Cloud Feign的两种使用姿势
  • XForms - 更强大的Form
  • 实战|智能家居行业移动应用性能分析
  • mysql 慢查询分析工具:pt-query-digest 在mac 上的安装使用 ...
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • (AtCoder Beginner Contest 340) -- F - S = 1 -- 题解
  • (webRTC、RecordRTC):navigator.mediaDevices undefined
  • (笔试题)分解质因式
  • (翻译)Quartz官方教程——第一课:Quartz入门
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (四)图像的%2线性拉伸
  • ****三次握手和四次挥手
  • *_zh_CN.properties 国际化资源文件 struts 防乱码等
  • .NET C# 使用GDAL读取FileGDB要素类
  • .net websocket 获取http登录的用户_如何解密浏览器的登录密码?获取浏览器内用户信息?...
  • .NET 跨平台图形库 SkiaSharp 基础应用
  • .NET 中小心嵌套等待的 Task,它可能会耗尽你线程池的现有资源,出现类似死锁的情况
  • .NET开源项目介绍及资源推荐:数据持久层
  • .Net转Java自学之路—基础巩固篇十三(集合)
  • @column注解_MyBatis注解开发 -MyBatis(15)
  • @vue-office/excel 解决移动端预览excel文件触发软键盘
  • [Android]使用Git将项目提交到GitHub
  • [android学习笔记]学习jni编程
  • [AS3]URLLoader+URLRequest+JPGEncoder实现BitmapData图片数据保存
  • [C#C++]类CLASS
  • [cocos2d-x]关于CC_CALLBACK
  • [Contiki系列论文之2]WSN的自适应通信架构
  • [Docker]十二.Docker consul集群搭建、微服务部署,Consul集群+Swarm集群部署微服务实战
  • [Head First设计模式]策略模式
  • [HTML]Web前端开发技术18(HTML5、CSS3、JavaScript )HTML5 基础与CSS3 应用——喵喵画网页
  • [IE编程] IE8 新增的C++开发接口
  • [javaSE] 数据结构(二叉查找树-插入节点)
  • [Kubernetes] etcd 单机和集群部署