mysql事务及其实现原理

原文链接:mysql事务及其实现原理 – 编程屋

目录 

1 概述 

2 四大特性

2.1 原子性

2.2 隔离性

2.2.1 MVCC

2.2.2 undolog---MVCC

2.2.3 Read View---MVCC

2.3  持久性

2.3.1 二阶段提交

2.4 一致性


1 概述 

        相信大家刚接触mysql的时候,就知道mysql事务的四个特点,原子性,持久性,隔离性和一致性,但是大家是否有想过它们是如何如何靠着4个特性去解决mysql中常见问题的呢?最近查阅了一些资料,写篇博客记录一下。mysql的事务的实现方式和mysql的日志系统有关。 

原子性(Atomicity):语句要么全执行,要么全不执行,是事务最核心的特性,事务本身就是以原子性来定义的。实现主要基于undo log日志。

一致性(Consistency):事务追求的最终目标,一致性的实现即需要数据库层面的保障,也要应用层面的保障。

隔离性(Isolation):保证事务执行尽可能不受其他事务影响。InnoDB默认的隔离级别是可重复读

持久性(Durability):保证事务提交后不会因为宕机等原因导致数据丢失。实现主要基于redo log。

2 四大特性

2.1 原子性

原子性(Atomicity):语句要么全执行,要么全不执行,是事务最核心的特性,事务本身就是以原子性来定义的。实现主要基于undolog日志。

        对于mysql来说,同一个事物可以包含很多条sql语句,但如果前面几条sql执行成功了,但最后一条执行失败了,那么这个时候前面几条执行成功的sql语句也要回滚到之前的历史版本里面。只要保证了这个就可以保证事务的原子性。那么如何来操作呢?

保留之前数据的历史状态,只要没有提交,当需要回滚时,将历史数据拿来重新进行覆盖就可

2.2 隔离性

隔离性(Isolation):保证事务执行尽可能不受其他事务影响。InnoDB默认的隔离级别是可重复读

对于mysql来说,并行运行着许多事务,它们相互独立,互不干扰。那么它又是如何来实现的呢?大家一看牵扯到并行,那肯定就与锁有关,没错,mysql的隔离性实现方案的确和锁有关,但是对于mysql这样一种访问量超高的数据库而言,加锁无疑会会大大降低它的速率,其实为了解决这个问题,mysql还引进了mvcc(多版本并发控制)和锁一起来实现mysql的隔离性。

2.2.1 MVCC

什么是MVCC?

        MVCC即多版本并发控制。MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。

        MVCC在mysql Innodb中的实现主要是为了提高数据库并发性能,用更好的方式去处理读写冲突,做到即使有读写冲突时,也能做到不加锁,非阻塞并发读.解决了脏读,幻读,不可重复读等事务隔离问题,但不能解决更新丢失问题。

要想搞清楚MVCC,还需要搞清楚几个概念

当前读:

像select lock in share mode(共享锁),select for update;update,insert,delete(排他锁)这些操作都是一种当前读,为什么叫当前读?就是它读取的是记录的最新版本,读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。

快照读:

像不加锁的select就是快照读,即不加锁的非阻塞读;快照读的前提是隔离级别不是串行级别,串行级别下的快照读会退化成当前读;之所以出现快照读的情况,是基于并发性能的考虑,快照读的实现是基于多版本的并发,即MVCC,可以认为MVCC是行锁的一个变种,但它在很多情况下,避免了加锁操作,降低了开销,既然是基于多版本,快照读读取的并不一定是数据的最新版本,而有可能是之前的历史数据。

三者之间关系:

MVCC多版本并发控制是指维持一个数据的多个版本,使得读写操作没有冲突,快照读是mysql为实现MVCC的一个非阻塞功能。MVCC模块在mysql中的实现是由3个隐式字段undologredolog三个组件来实现的。        

2.2.2 undolog---MVCC

其实每行记录除了我们自定义的字段外,还有数据库隐式定义的DB_TRX_ID,DB_ROLL_PTR,DB_ROW_ID

DB_TRX_ID : 6字节,最近修改事务的id, 创建这条记录或者最后一次修改该记录的事务id

DB_ROLL_PTR : 7字节,回滚指针,指向这条记录的上一个版本,用于配合undolog,指向上一个旧版本

DB_ROW_ID : 6字节,隐藏的主键,如果数据表没有主键,那么innodb会自动生成一个6字节的row_id

画个图表示下: 

加入有一条事务编号为1的事务向表里面插入一条记录,那么此时此行数据的状态为:

之后进行一系列的修改:

undolog>>>>>回滚日志>>>>>记录的是数据的历史版本

 这样每次一对数据进行操作,undolog就会记录从而形成一个链表,链首是最新的记录,链尾是最旧的记录。但这个时候,undolog并不会无限制的增大,其会有一个purge线程清除没用的数据。

2.2.3 Read View---MVCC

        Read View是事务进行快照读操作的时候生产的读视图,在该事务执行快照读的那一刻,会生成一个数据系统当前的快照,记录并维护当前活跃事务的id,事务的id是递增的。

以上只是部分内容,为了维护方便,本文已迁移到新地址:mysql事务及其实现原理 – 编程屋

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值