Mysql InnoDB如何保证事务

Mysql存储引擎InnoDB支持事务操作,即支持原子性、一致性、隔离性、持久性(ACID)特性。下面介绍一下InnoDB是怎样做到这几个特性的。
原子性:原子性是指事务中的语句要么全部执行成功、要么全部不执行,原子性是通过undo log实现的。
持久性:持久性是指事务一旦提交,它对数据库的改变就应该是永久性的,不会因为宕机等原因而丢失数据,持久性是通过redo log实现的。
一致性:事务前后的数据必须保持一致性。一致性是通过redo log+undo log实现的。
隔离性:隔离性是指,事务内部的操作与其他事务是隔离的,并发执行的各个事务之间不能互相干扰。隔离性是通过锁+MVCC来控制的。

redo log保障持久性能
InnoDB为了保证高速写入,不会直接写入库中,而是会写入redo log这种日志系统。redo log 分为两部分:一部分是内存中的重做日志缓冲(redo log buffer),是易丢失的;二部分是重做日志文件(redo log file),是持久的。InnoDB通过Force Log at Commit机制来实现持久性,当commit时,必须先将事务的所有日志写到重做日志文件进行持久化,待commit操作完成才算完成。所以事务提交以后,数据都写入了redo log中,即使发生宕机的故障,在机器恢复后,能够从redo log中恢复之前写入的数据而不丢失。

undo log保障原子性
为了满足事务的原子性,在操作任何数据之前,首先将数据备份到一个地方(这个存储数据备份的地方称为Undo Log),然后进行数据的修改。如果出现了错误或者用户执行了 ROLLBACK语句,系统可以利用Undo Log中的备份将数据恢复到事务开始之前的状态。此时数据库会生成一个和之前的语句相反的sql,例如之前是insert 语句,回滚时会执行一条delete语句来删除之前插入的数据,从而保障原子性能。

redo log+undo log保障一致性
如果事务中的sql全部成功执行,需要redo log来保障;如果执行失败,需要回滚,这需要undo log来保障。

锁+MVCC来保障隔离性
SQL标准中定义了四种隔离级别,并规定了每种隔离级别下上述几个问题是否存在。一般来说,隔离级别越低,系统开销越低,可支持的并发越高,但隔离性也越差。隔离级别与读问题的关系如下:
在这里插入图片描述

隔离性要求同一时刻只能有一个事务对数据进行写操作,InnoDB通过锁机制来保证这一点。
锁机制的基本原理可以概括为:事务在修改数据之前,需要先获得相应的锁;获得锁之后,事务便可以修改数据;该事务操作期间,这部分数据是锁定的,其他事务如果需要修改数据,需要等待当前事务提交或回滚后释放锁。

为了提高事务的并发性,InnoDB引入了MVCC(多版本并发控制),在同一时刻,不同的事务读取到的数据可能是不同的(即多版本)——在T5时刻,事务A和事务C可以读取到不同版本的数据。
在这里插入图片描述
MVCC最大的优点是读不加锁,因此读写不冲突,并发性能好。InnoDB实现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可见。

总结
mysql的存储引擎InnoDB通过redo log、undo log、锁、MVCC来支持事务操作,即满足了数据操作的正确,又兼顾了高性能。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值