MVCC和InnoDB行锁
简单介绍下MVCC的原理
每个事务开启时,都会被分配到一个全局唯一且递增的事务id,即trx_id
,当每次事务对某些数据行进行修改时,都会将事务自身的trx_id
记录在数据行的隐藏列上。在事务开启的那一刻,MVCC机制会为事务生成一个当前mysql服务器上所有事务的快照。这个快照是按照如下方式实现的:
- 将当前服务端活跃的全部事务id记录在set中
- 当前活跃的事务最小id记为
min_trx_id
- 当前活跃的事务最大id记为
max_trx_id
当进行一次普通查询的时候,根据数据行上的trx_id进行判断。
- trx_id < min_trx_id,该行是在当前事务开启前就提交的,对当前事务可见。
- trx_id > max_trx_id,该行是在当前事务开启后开启的,对当前事务不可以。
- min_trx_id <= trx_id <= max_trx_id,该行处在最大最小事务id中间,则判断是否为set中的活跃事务的修改。若是,则不可见;若不是,则说明当前事务开启时已经提交,则可见。
对于隔离级别为可重复读而言,这个快照是在事务开启时生成的;对于读已提交,是在每次进行快照读的时刻生成的。
InnoDB行锁的概念
InnoDB的行锁(也称为临键锁) Next-Key Locks,是MySQL对外暴露的锁的基本单位,它会智能选择记录锁或间隙锁,锁住一行或多行或一个间隙。而记录锁又分为共享锁和排他锁,间隙锁的概念下面有一个插入意向锁。这些锁的关系大概是这样:
记录锁
所谓记录锁 Record Locks,就是锁住确定的一行行记录。它分为共享锁和排它锁。分别对应不同的SQL写法。
- 共享锁
共享锁 Shared Locks ,简称S锁。使用以下SQL可能触发:
SELECT ... LOCK IN SHARE MODE
之所以说“可能”触发,是因为它查到了数据库有确定的记录才会锁住这些记录,否则会变成间隙锁。这个其实很好理解,找到了数据,才锁它。如果没找到数据,就锁这个间隙。
- 排他锁
排他锁 Exclusive locks ,简称X锁。使用一下SQL可能触发:
SELECT ... FOR UPDATE
这里的“可能”含义与上面同理,不赘述。
间隙锁
间隙锁 Gap - Lock,顾名思义,锁住一个间隙。上文我们提到过,InnoDB默认的隔离级别是RR,但是通过间隙锁来一定程度上的解决了幻读的问题。它是怎么解决的呢?就是通过间隙锁来解决的。
上面两种SQL,如果没有查找到确定的记录,就会根据条件去锁住一个间隙。间隙锁是根据已有数据的一个左开右闭的区间。
什么意思呢?假如你的SQL查询的范围不同,那它锁住的区间就不同。比如:
-- 锁住(0, 5]
SELECT * FROM demo where id = 3;-- 锁住(10, 15]
SELECT * FROM demo where id = 11;
间隙锁其实是“共享”的。也就是说,多个事务可以获取同一个区间的间隙锁。
- 插入意向锁
插入意向锁 Insert Intention Locks,代表当前事务准备插入一行数据。使用INSERT语句会获得插入意向锁。
插入意向锁和插入意向锁之间是兼容的,只要插入的键值不同,就不会相互阻塞。比如以下两个SQL,在不同的事务中,哪怕它们在同一个间隙,只要没有间隙锁,就不会阻塞:
但如果两个事务插入同一个key,那就会阻塞。
插入意向锁可以保证两个事务插入key不同的数据的时候不冲突,提升并发性。
但是间隙锁会阻塞插入意向锁!这也可以理解,因为InnoDB想在RR隔离级别就解决幻读问题。所以A事务用SELECT语句获取了一个间隙锁,自然不希望B事务在这个期间往这个间隙插入一条新的记录。
MVCC和InnoDB行锁相关推荐
- MySQL · 引擎分析 · InnoDB行锁分析
前言 理解InnoDB行锁,分析一条SQL语句会加什么样的行锁,会锁住哪些数据范围对业务SQL设计和分析线上死锁问题都会有很大帮助.对于InnoDB的行锁,已经有多篇月报进行了介绍,这里笔者借鉴前面月 ...
- innodb行锁理解
innodb行锁的一些认识 InnoDB行锁是通过给索引上的索引项加锁来实现的,这一点与Oracle不同,后者是通过在数据块中对相应数据行加锁来实现的. InnoDB这种行锁实现特点意味着:只有通过索 ...
- 9、 InnoDB行锁
在 MySQL 中,InnoDB 行锁通过给索引上的索引项加锁来实现,如果没有索引,InnoDB 将通过隐藏的聚簇索引来对记录加锁. InnoDB 支持 3 种行锁定方式: 行锁(Record Loc ...
- MySQL高级 - 锁 - InnoDB行锁 - 争用情况查看
InnoDB 行锁争用情况 show status like 'innodb_row_lock%'; Innodb_row_lock_current_waits: 当前正在等待锁定的数量Innodb_ ...
- MySQL数据库锁机制之MyISAM引擎表锁和InnoDB行锁详解
MySQL中的锁概念 Mysql中不同的存储引擎支持不同的锁机制.比如MyISAM和MEMORY存储引擎采用的表级锁,BDB采用的是页面锁,也支持表级锁,InnoDB存储引擎既支持行级锁,也支持表级锁 ...
- MySQL探秘(七):InnoDB行锁算法
在上一篇<InnoDB一致性非锁定读>中,我们了解到InnoDB使用一致性非锁定读来避免在一般的查询操作(SELECT FOR UPDATE等除外)时使用锁.然而锁这个事情是无法避免的, ...
- InnoDB行锁的实现分析
InnoDB与MyISAM不同,它实现的是一个行级锁,而非MyISAM的表锁.锁的粒度越大,则发生死锁的概率越小.锁机制开销越小,但并发能力会越低.如果锁的粒度变细,则发生死锁的概率也会增大,锁机制的 ...
- mysql隐式锁定辅助索引_当Mysql - InnoDB行锁遇到复合主键和多列索引-Go语言中文社区...
背景 今天在配合其他项目组做系统压测,过程中出现了偶发的死锁问题.分析代码后发现有复合主键的update情况,更新复合主键表时只使用了一个字段更新,同时在事务内又有对该表的insert操作,结果出现了 ...
- MySQL高级 - 锁 - InnoDB行锁 - 总结
InnoDB存储引擎由于实现了行级锁定,虽然在锁定机制的实现方面带来了性能损耗可能比表锁会更高一些,但是在整体并发处理能力方面要远远由于MyISAM的表锁的.当系统并发量较高的时候,InnoDB的整体 ...
- MySQL高级 - 锁 - InnoDB行锁 - 行锁升级为表锁
无索引行锁升级为表锁 如果不通过索引条件检索数据,那么InnoDB将对表中的所有记录加锁,实际效果跟表锁一样. 查看当前表的索引 : show index from test_innodb_lock ...
最新文章
- 前端学习(3025):vue+element今日头条管理-侧边导航菜单
- 一款三搭_冬日穿搭指南!照着这八条万能公式穿,让你不冻还有型_
- ue4蓝图碰撞检测的类型_UE4_自定义相机碰撞组件
- Daily Scrum M2 11-19
- 计算机基础(八):linux编程规范总结
- 【图像检索】基于matlab GUI Hu不变矩图像检索【含Matlab源码 1508期】
- hp原装usb无线打印服务器,从USB转换到无线 | 无线打印中心 | 惠普中国
- html点击图片可以放全屏,html:点击图片放大到全屏,再次点击缩回
- 云服务器温控系统,服务器cpu温度监控软件
- vivado2017.4开发vc707(virtex7)(一)上电调试
- Git基础-生成SSH密钥+配置密钥到远程仓库中
- C++手动开启O2、O3优化略
- CISP注册信息安全专业人员知识体系大纲(CISE/CISO)
- Mac 自带php升级(5.6,7.0,7.1)
- 微信web开发者工具-移动调试iphone端的调试
- Error in `appstreamcli': double free or corruption (fasttop): 0x0000000002122000
- Pyside2 学习系列三:PyInstaller打包项目瘦身(超详细的Pyside2 攻略)
- 增加tensor维度 torch
- 通过距离感应器获取实际距离[FAQ04538][Sensor]java层获得P_sensor距离传感器当前真实值,不止0,1
- c语言 数组 随机数 初始化