MySQL 实现事务逻辑

实现事务逻辑

innodb 通过buffer pool ,logbuffer ,redo log,undo log 来实现事务,以一个update语句为例:

innodb 在收到一个update 语句后,会先根据条件找到数据所在的页,并将该页缓存在buffer pool中

执行update 语句,修改buffer pool中的数据,也就是内存的数据

针对update 语句生成一个redolog对象,并存入logbuffer中

针对update 语句生成undolog 日志,用于事务回滚

如果事务提交,那么则把redolog 对象进行持久化,后续还有其他机制将buffer pool中所修改的数据页持久化到磁盘

如果事务回滚,则利用undolog日志经行回滚

上图显示InnoDB存储引擎对于文件的存储方式,其中frm文件是表结构定义文件,记录每个表的表结构定义。

重做日志文件和归档文件

默认情况下,在InnoDB存储引擎的数据目录下会有两个名为ib_logfile0和ib_logfile1的文件,这就是InnoDB的重做日志文件(redo log fiel),它记录了对于InnoDB存储引擎的事务日志。

当InnoDB的数据存储文件发生错误时,重做日志文件就能派上用场。InnoDB存储引擎可以使用重做日志文件将数据恢复为正确状态,以此来保证数据的正确性和完整性。

每个InnoDB存储引擎至少有1个重做日志文件组(group),每个文件组下至少有2个重做日志文件,如默认的ib_logfile0和ib_logfile1。

为了得到更高的可靠性,用户可以设置多个镜像日志组,将不同的文件组放在不同的磁盘上,以此来提高重做日志的高可用性。

在日志组中每个重做日志文件的大小一致,并以循环写入的方式运行。InnoDB存储引擎先写入重做日志文件1,当文件被写满时,会切换到重做日志文件2,再当重做日志文件2也被写满时,再切换到重做日志文件1。

用户可以使用innodb_log_file_size来设置重做日志文件的大小,这对InnoDB存储引擎的性能有着非常大的影响。

如果重做日志文件设置的太大,数据丢失时,恢复时可能需要很长的时间;另一方面,如果设置的太小,重做日志文件太小会导致依据checkpoint的检查需要频繁刷新脏页到磁盘中,导致性能的抖动。

重做日志相关和Checkpoint的机制可以阅读我之前文章的相应章节。MySQL探秘(三):InnoDB的内存结构和特性

重做日志的落盘机制

InnoDB对于数据文件和日志文件的刷盘遵守WAL(Write ahead redo log) 和Force-log-at-commit两种规则,二者保证了事务的持久性。WAL要求数据的变更写入到磁盘前,首先必须将内存中的日志写入到磁盘;Force-log-at-commit要求当一个事务提交时,所有产生的日志都必须刷新到磁盘上,如果日志刷新成功后,缓冲池中的数据刷新到磁盘前数据库发生了宕机,那么重启时,数据库可以从日志中恢复数据

如上图所示,InnoDB在缓冲池中变更数据时,会首先将相关变更写入重做日志缓冲中,然后再按时或者当事务提交时写入磁盘,这符合Force-log-at-commit原则;当重做日志写入磁盘后,缓冲池中的变更数据才会依据checkpoint机制择时写入到磁盘中,这符合WAL原则。

在checkpoint择时机制中,就有重做日志文件写满的判断,所以,如前文所述,如果重做日志文件太小,经常被写满,就会频繁导致checkpoint将更改的数据写入磁盘,导致性能抖动。

操作系统的文件系统是带有缓存的,当InnoDB向磁盘写入数据时,有可能只是写入到了文件系统的缓存中,没有真正的“落袋为安”。

InnoDB的innodb_flush_log_at_trx_commit属性可以控制每次事务提交时InnoDB的行为。当属性值为0时,事务提交时,不会对重做日志进行写入操作,而是等待主线程按时写入;当属性值为1时,事务提交时,会将重做日志写入文件系统缓存,并且调用文件系统的fsync,将文件系统缓冲中的数据真正写入磁盘存储,确保不会出现数据丢失;当属性值为2时,事务提交时,也会将日志文件写入文件系统缓存,但是不会调用fsync,而是让文件系统自己去判断何时将缓存写入磁盘。日志的刷盘机制如下图所示。

innodb_flush_log_at_commit是InnoDB性能调优的一个基础参数,涉及InnoDB的写入效率和数据安全。当参数值为0时,写入效率最高,但是数据安全最低;参数值为1时,写入效率最低,但是数据安全最高;参数值为2时,二者都是中等水平。一般建议将该属性值设置为1,以获得较高的数据安全性,而且也只有设置为1,才能保证事务的持久性。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值