【MySQL】当前读、快照读、MVCC
当前读:
select...lock in share mode (共享读锁)
select...for update
update , delete , insert
当前读, 读取的是最新版本, 并且对读取的记录加锁, 阻塞其他事务同时改动相同记录,避免出现安全问题。
例如,假设要update一条记录,但是另一个事务已经delete这条数据并且commit了,如果不加锁就会产生冲突。所以update的时候肯定要是当前读,得到最新的信息并且锁定相应的记录。
当前读的实现方式:next-key锁(行记录锁+Gap间隙锁)
间隙锁:只有在Read Repeatable、Serializable隔离级别才有,就是锁定范围空间或moh的数据,假设锁定id>3的数据,id有3,4,5,那么4,5和后面的数字都会被锁定,像6,7...,此时如果不锁定没有的数据,例如当加入了新的数据id=6,就会出现幻读,间隙锁避免了幻读。
1.对主键或唯一索引,如果当前读时,where条件全部精确命中(=或者in),这种场景本身就不会出现幻读,所以只会加行记录锁。
2.没有索引的列,当前读操作时,会加全表gap锁,生产环境务必避免!
3.非唯一索引列,如果where条件部分命中(>、<、like等)或者全未命中,则会加附近Gap间隙锁。例如,某表数据如下,gap锁会是(6,11],该区间内无法插入数据。

快照读
简单的select操作(不包括 select ... lock in share mode, select ... for update)。
Read Committed隔离级别:每次select都生成一个快照读。
Read Repeatable隔离级别:开启事务后第一个select语句才是快照读的地方,而不是一开启事务就快照读。
快照读的实现方式:undolog和MVCC
undolog:
每行除了数据外 还有
DB_TRX_ID: 6字节DB_TRX_ID字段,表示最后更新的事务id(update,delete,insert)。此外,删除在内部被视为更新,其中行中的特殊位被设置为将其标记为已软删除。
DB_ROLL_PTR: 7字节回滚指针,指向前一个版本的undolog记录,组成undo链表。如果更新了行,则撤消日志记录包含在更新行之前重建行内容所需的信息。
DB_ROW_ID: 6字节的DB_ROW_ID字段,包含一个随着新行插入而单调递增的行ID, 当由innodb自动产生聚集索引时,聚集索引会包括这个行ID的值,否则这个行ID不会出现在任何索引中。如果表中没有主键或合适的唯一索引, 也就是无法生成聚簇索引的时候, InnoDB会帮我们自动生成聚集索引, 聚簇索引会使用DB_ROW_ID的值来作为主键; 如果表中有主键或者合适的唯一索引, 那么聚簇索引中也就不会包含 DB_ROW_ID了 。
insert undo log: 只在事务回滚时需要, 事务提交就可以删掉了。
update undo log: 包括update 和 delete , 回滚和快照读 都需要。
多版本并发控制MVCC:
如图,开始只有最下面一行记录,
当事务1更改该行记录时,会进行如下操作:
事务1 先用排它锁锁住该行记录(当前读,读到最新数据然后独占),复制到undolog,即图中第二行记录;再更新字段, 把自己的事务id填入DB_TRX_ID, 让回滚指针DB_ROLL_PTR 指向undolog中修改前的原数据(开始只有最下面一行记录)
事务2操作也是一样, 产生了第三行记录。

【MySQL】当前读、快照读、MVCC的更多相关文章
- MySQL——一致性非锁定读(快照读)&MVCC
MySQL--一致性非锁定读(快照读) MySQL数据库中读分为一致性非锁定读.一致性锁定读 一致性非锁定读(快照读),普通的SELECT,通过多版本并发控制(MVCC)实现. 一致性锁定读(当前读) ...
- mysql并发控制之快照读和当前读
上一篇简单的介绍了下MVCC(多版本并发控制)的原理,MVCC会对事物内操作的数据做多版本控制,从而实现并发环境下事物对数据写操作的阻塞不影响读操作的性能.而这个多版本控制的实现是由undo log来 ...
- mysql 快照读MVCC
mysql的读分快照读和当前读 快照读 是指写的同时,读不阻塞,达到并发的作用 这时候的读 是 记录的历史版本,存在于undo里,当然回滚时就的也是这个undo 当执行一条update语句时,记录本身 ...
- Innodb中的快照读和当前读
一.前言 上篇文章记录了对MVCC的相关理解,其中有提到快照读.其实在MVCC并发控制中,读操作可以分为两类:快照读(snapshot read)和当前读(current read) 二.什么是快 ...
- 《快照读、当前读和MVCC》
1.快照读 快照读是基于 MVCC 和 undo log 来实现的,适用于简单 select 语句,避免了幻读. 读已提交:一个事务内操作一条数据,可以查询到另一个已提交事务操作同一条数据的最新值.( ...
- 别再误解MySQL和「幻读」了
The so-called phantom problem occurs within a transaction when the same query produces different set ...
- 【Java面试】这应该是面试官最想听到的回答,Mysql如何解决幻读问题?
"Mysql如何解决幻读问题" 一个工作了4年小伙伴,去一个美团面试,遇到了这样一个问题. 大家好,我是Mic,一个工作了14年的Java程序员 关于这个问题,面试官想考察什么?我 ...
- SQL Server已提交读快照隔离级别的设置
如果要把SQL Server数据库事务隔离级别设置为已提交读快照隔离 如果直接运行下面的语句: ALTER Database [mydbname] SET READ_COMMITTED_SNAPSHO ...
- SQL Server 已提交读快照 测试
1. 打开数据库 已提交读快照 选项 2. 数据库 已提交读快照 模式下的测试 a) 测试表 Test b) 开启事务1,更新数据C2 = '200'(未提交) BEGIN TRAN ' WHERE ...
随机推荐
- Image 图片
随机矩阵画图 这一节我们讲解怎样在matplotlib中打印出图像.这里打印出的是纯粹的数字,而非自然图像.下面用 3x3 的 2D-array 来表示点的颜色,每一个点就是一个pixel. impo ...
- java 多线程中的wait方法的详解
java多线程中的实现方式存在两种: 方式一:使用继承方式 例如: PersonTest extends Thread{ String name; public PersonTest(String n ...
- 迭代加深搜索 C++解题报告 :[SCOI2005]骑士精神
题目 此题根据题目可知是迭代加深搜索. 首先应该枚举空格的位置,让空格像一个马一样移动. 但迭代加深搜索之后时间复杂度还是非常的高,根本过不了题. 感觉也想不出什么减枝,于是便要用到了乐观估计函数(O ...
- 利用insertd查出更新记录
DROP TABLE #tableCREATE TABLE #table(CompanyID VARCHAR(20),BillNo VARCHAR(40))UPDATE dbo.SD_Inv_Move ...
- css隐藏多余的文字并出现省略号
<meta charset="utf-8" /> <style> .txt{ width:200px; border:1px solid #ddd; ove ...
- 学以致用二十九-----python3连接mysql
在前面安装好mysql后,在一个项目中需要连接mysql,python是3.6版本 python3连接mysql需要安装pymysql模块 可以通过pip安装 查看pip 版本 pip --versi ...
- explicit_defaults_for_timestamp引发的狗血剧情
今天就碰到了一个较初级的问题,居然为找这个参数花了好半天时间,深以为不齿.需求是这样的,有个表的某个字段需要从datetime改成timestamp类型.原结构如下:create table tmp1 ...
- python操作Redis安装、支持存储类型、普通连接、连接池
一.python操作redis安装和支持存储类型 安装redis模块 pip3 install redis 二.Python操作Redis之普通连接 redis-py提供两个类Redis和Strict ...
- scrapy的入门使用(一)
1. scrapy项目实现流程 创建一个scrapy项目:scrapy startproject mySpider 生成一个爬虫:scrapy genspider 提取数据:完善spider,使用x ...
- 关于Apahce服务器安装中遇到的问题
在这篇中,将记录一下安装Apache服务器所遇到的一些问题,并简单讲一些Apache和Tomcat的区别: 1>apache安装中遇到的问题: 1.1 Apache目前不再提供编译好的exe安装 ...