mysql事务实现原理

redo log:重做日志,用来实现事务的持久性,记录已成功提交事务的修改信息

 

mysql 为了提升性能不会把每次的修改(update,delete,insert)都实时同步到磁盘,而是会先存到Buffer Pool(缓冲池)里头,把这个当作缓存来用。然后使用后台线程去做缓冲池和磁盘之间的同步。

 

mysql读数据:会首先从缓冲池中读取,如果缓冲池中没有,则从磁盘读取在放入缓冲池;

 

mysql写数据:会首先写入缓冲池,缓冲池中的数据会定期同步到磁盘中;

 

那么问题来了,如果还没来的同步的时候宕机或断电了怎么办?还没来得及执行缓冲池和磁盘之间的同步。这样会导致丢部分已提交事务的修改信息!

所以引入了redo log来记录已成功提交事务的修改信息,并且会把redo log持久化到磁盘,系统重启之后在读取redo log恢复最新数据。

每次写入数据或者修改数据之前都会把修改后的信息记录到 redo log

redo log是用来恢复数据的 用于保障,已提交事务的持久化特性

 

 

 

undo log:回滚日志,用于实现事务的原子性,用于记录数据被修改前的信息

每次写入数据或者修改数据之前都会把修改前的信息记录到 undo log

 

并且回滚日志必须先于数据持久化到磁盘上

 

假如由于系统错误或者rollback操作而回滚的话可以根据undo log的信息来进行回滚到没被修改前的状态。

 

回滚操作就是要还原到原来的状态,undo log记录了数据被修改前的信息以及新增和被删除的数据信息,根据undo log生成回滚语句,比如:

(1) 如果在回滚日志里有新增数据记录,则生成删除该条的语句

(2) 如果在回滚日志里有删除数据记录,则生成生成该条的语句

(3) 如果在回滚日志里有修改数据记录,则生成修改到原先数据的语句

 

 

排他锁+mvcc:实现事务的隔离性(https://www.cnblogs.com/kismetv/p/10331633.html

排他锁:行锁的一种,加了行锁,其他事务只能读到加锁前的数据,且不能对数据进行修改。(众包发放酬劳会遇到前一条记录覆盖后一条记录,这个可以在面试中说一说)

mvcc:多版本并发控制协议。让多版本的数据共存。基于以下数据结构和和技术:

             1 )隐藏列:InnoDB中每行数据都有隐藏列,隐藏列中包含了本行数据的事务id、指向undo log的指针等。

 

2)基于undo log的版本链:前面说到每行数据的隐藏列中包含了指向undo log的指针,而每条undo log也会指向更早版本的undo log,从而形成一条版本链。

 

3)ReadView:通过隐藏列和版本链,MySQL可以将数据恢复到指定版本;但是具体要恢复到哪个版本,则需要根据ReadView来确定。所谓ReadView,是指事务(记做事务A)在读某一条数据前给整个事务系统(trx_sys)打快照,之后再进行读操作时,会将读取到的数据中的事务id与trx_sys快照比较,从而判断数据对该ReadView是否可见,即对事务A是否可见。

 

trx_sys中的主要内容,以及判断可见性的方法如下:

 

low_limit_id:表示生成ReadView时系统中应该分配给下一个事务的id。如果数据的事务id大于等于low_limit_id,则对该ReadView不可见。

up_limit_id:表示生成ReadView时当前系统中活跃的读写事务中最小的事务id。如果数据的事务id小于up_limit_id,则对该ReadView可见。

rw_trx_ids:表示生成ReadView时当前系统中活跃的读写事务的事务id列表。如果数据的事务id在low_limit_id和up_limit_id之间,则需要判断事务id是否在rw_trx_ids中:如果在,说明生成ReadView时事务仍在活跃中,因此数据对ReadView不可见;如果不在,说明生成ReadView时事务已经提交了,因此数据对ReadView可见。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值