数据库事务MVCC架构
数据库事务MVCC架构
MultiVersionConcurrencyControl多版本并发控制,MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问;在编程语言中实现事务内存。
百度百科
参考文档:
https:dev。mysql。comdocrefman5。7eninnodbmultiversioning。html
https:blog。csdn。netw2064004678articledetails83012387
https:baijiahao。baidu。coms?id1669272579360136533wfrspiderforpc
https:www。jianshu。compdd3724fc0f66
https:baijiahao。baidu。coms?id1629409989970483292wfrspiderforpc准备知识ACID原子性(Atomicity)一致性(Consistent)隔离性(Isolation)持久性(Durable)事务的自动提交
查看自动提交SELECTautocommit;SHOWVARIABLESLIKEautocommit;
关闭自动提交SETautocommitOFF;SETautocommit1;
这种修改方式只是在当前会话窗口生效,对其他会话窗口是不生效的常见事务控制语句commit提交事务rollback回滚事务savepointidentifier自定义保存点rollbacktoidentifier回滚到指定保存点releasesavepointidentifier删除保存点事务分类扁平事务:最简单也是最常用的一种事务,事务中的所有操作都是原子的,要么全部成功,要么什么都不做。带有保存点的扁平事务:般比较适合于长事务,事务处理到后面报错的时候,我们可以选择不全部回滚事务,而是回滚到我们自定义好的某一个保存点。整个事务仍然是需要使用commot或者rollback来结束。链事务:提交一个事务之后,释放掉我们不需要的数据,将必要的数据隐式地传给下一个事务。(注意:提交事务操作和开始下一个事务操作是一个原子操作)这就意味着下一个事务能看到上一个事务的结果。嵌套事务:事务的嵌套,存在父子事务。MySQL原生并不支持嵌套事务分布式事务:分布式事务通常就是在分布式环境下,多个数据库下运行不同的扁平事务。多个数据库环境下运行的扁平事务就合成了一个分布式事务。事务的隔离级别ReadUncommitted(未提交读):RU,最低的隔离级别,等于没有隔离,基本上没有数据库会使用这个级别。一个事务可以读取到其他事务未提交的数据,这种也叫做脏读。ReadCommitted(已提交读):RC,一个事务只能读取到其他事务已提交的数据,就是说在一个事务里面,执行同样的查询,会出现两次不一样的结果。Oracle和SQLServer数据库默认的数据库隔离级别。这种隔离级别解决了脏读问题,但是会出现不可重复读的问题。RepeatableRead(可重复读):RR,这种隔离级别解决了不可重复读问题,就是说在同一个事务中,执行相同的查询,结果都是一样的,但是这种级别会出现幻读问题(InnoDB引擎例外,InnoDB引擎通过间隙锁解决了幻读问题)。不可重复读和幻读本质上是一样的,但是不可重复读针对的是更新和删除操作,而幻读仅针对插入操作。Serializable(串行化):隔离的最高级别,也就是说所有的事务都是串行执行的,也就不存在并发事务,脏读,可重复读和幻读问题自然也就没有了。事务隔离的实现方案
LBCC和MVCCLBCC
LBCC(BasedConcurrencyControl),基于锁的并发控制。这种方案比较简单粗暴,就是一个事务去读取一条数据的时候,就上锁,不允许其他事务来操作(当然这个锁的实现也比较重要,如果我们只锁定当前一条数据依然无法解决幻读问题)。MVCC
MVCC(MultiVersionConcurrencyControl)
MVCC是通过保存数据在某个时间点的快照来实现的。不同存储引擎的MVCC。不同存储引擎的MVCC实现是不同的,典型的有乐观并发控制和悲观并发控制。特点每行数据都存在一个版本,每次数据更新时都更新该版本。修改时Copy出当前版本随意修改,各个事务之间无干扰。保存时比较版本号,如果成功(commit),则覆盖原记录;失败则放弃copy(rollback)
MVCC是通过保存数据在某个时间点的快照来实现的。不同存储引擎的MVCC。不同存储引擎的MVCC实现是不同的,典型的有乐观并发控制和悲观并发控制。InnoDB存储引擎MVCC的实现策略
在每一行数据中额外保存三列A6byteDBTRXID:事务号(删除当成特殊的删除)a7byteDBROLLPTR:回滚指针A6byteDBROWID:ID在插入新行时单调增加。如果InnoDB自动生成一个聚集索引,索引包含行ID值。否则,DBROWID列不会出现在任何索引中。
借用网上一张图片来展示mvcc工作模式
1、插入数据(insert):记录的版本号即当前事务的版本号
假设事务id为1,回滚指针为null
2、更新操作的时候,采用的是先标记旧的那行记录为已删除,并且删除版本号是事务版本号,然后插入一行新的记录的方式。
事务id为2回滚指针指向事务id1
3、删除操作的时候,就把事务版本号作为删除版本号。
事务id为3回滚指针指针指向上一个事务(假设事务3开始时事务2还没执行完则为1,若事务2执行完则为3。当然这里也和隔离级别有关)。
4、查询
事务id为4,此时根据快照查询。