对mysql中redolog undolog binlog的一些理解

本文介绍了数据库优化中的ChangeBuffer和WAL技术。ChangeBuffer用于减少磁盘IO,将数据变更缓存并适时合并写入,提高性能。WAL(Write-ahead Logging)确保事务的原子性和持久性,通过redoLog和undoLog保证数据一致性。redoLog记录数据页修改,先于实际写入,提高效率;undoLog用于事务回滚,保证原子性。
摘要由CSDN通过智能技术生成

一、ChangeBuffer技术

1.1、一般我们执行sql的修改语句时:

  • 先把记录加载到内存中(系统调用)
  • 然后修改内存中的数据,
  • 事务提交后再写回磁盘。(系统调用)
    如果数据库数据更新的频率非常低,那么这样更新方式数据库也可以接受,但是在更新非常频繁的情况下,大量的离散IO(系统调用)会成为数据库的瓶颈,影响数据库的性能。

1.2、在更新频繁的场景下,如何降低磁盘的IO并保证事务呢?

这就涉及到ChangeBuffer技术了,在满足ChangeBuffer缓存操作的条件下,InnoDB并不会立即把数据的变更操作写入磁盘,而是将这些对数据页的操作缓存到ChangeBuffer中,数据库找合适的机会再将操作Merge到数据库中。
通过ChangeBuffer技术,我们可以把对数据库的多次离散访问合并为一次数据库访问,并且用户的更新线程中不需要实际访问磁盘,大大提升了数据库性能。

1.3、ChangeBuffer有一个很大的问题:如果InnoDB实例在运行期间掉电,ChangeBuffer中的缓存会丢失,从而造成数据库数据的不一致,影响数据库事务的原子性和一致性。于是就有了WAL技术。

二、WAL技术(Write-ahead logging,预写式日志)

在使用WAL的系统中,所有的修改都先被写入到日志中,然后再被应用到系统状态中,日志通常包含redoundo两部分信息。

  • redoLog称为重做日志,每当有操作时,在数据变更之前将操作写入RedoLog,这样当发生掉电之类的情况时系统可以在重启后继续操作;
  • UndoLog称为撤销日志,当一些变更执行到一半无法完成时,可以根据撤销日志恢复到变更之间的状态;

2.1、redo Log保证持久性(ACID 中的D)

redo Log如其名侧重于重做!它记录的是数据库中每个页的修改,而不是某一行或某几行修改成怎样,可以用来恢复提交后的物理数据页,且只能恢复到最后一次提交的位置。
redo log用到了WAL(Write-Ahead Logging)技术,这个技术的核心就在于修改记录前,一定要先写日志,并保证日志先落盘,才能算事务提交完成
有了redo log再修改数据时,InnoDB引擎会把更新记录先写在redo log中,在修改Buffer Pool中的数据,当提交事务时,调用fsync把redo log刷入磁盘。至于缓存中更新的数据文件何时刷入磁盘,则由后台线程异步处理。
(注意:此时redo log的事务状态是prepare,还未真正提交成功,要等bin log日志写入磁盘完成才会变更为commit,事务才算真正提交完成)

这样一来保证了对内存中数据修改的持久性,因为一旦事务提交了,即使刷脏页之前MySQL意外宕机也没关系,只要在重启时解析redo log中的更改记录进行重放,重新刷盘即可。

思考一个问题:只要每次把修改后的数据页直接刷盘不就好了,为什么还要用redo log刷盘?不都是刷盘吗?有什么区别?

实际上,数据页大小是16KB,刷盘比较耗时,可能就修改了数据页的几byte数据,没有必要把整页的数据刷盘。而且数据页刷盘都是随机写,因为一个数据页对应的位置可能是在硬盘文件的随机位置,所以性能很差。

如果是写redo log,一行记录就占了几十byte,只要包含了表空间号、数据页号、磁盘文件偏移量、修改值,再加上是顺序写,所以刷盘效率很高。

所以用 redo log 形式记录修改内容,性能会远远超过刷数据页的方式,这也让数据库的并发能力更强。
2.2、undo Log保证原子性(ACID 中的A)以及MVCC

想要保证事务的原子性,就需要在发生异常时,对已经执行的操作进行回滚,在MySQL中恢复机制是通过undo log(回滚日志)实现的,所有事务进行的修改都会先被记录到这个回滚日志,然后再执行其他相关的操作。如果执行过程中遇到异常的话,我们直接利用回滚日志中的信息将数据回滚到修改之前的样子。并且,回滚日志会先于数据持久化到磁盘上。这样就保证了即使遇到数据库突然宕机等情况,当用户再次启动数据库的时候,数据库还能够通过查询回滚日志来回滚将之前未完成的事务。

另外,MVCC的实现依赖:隐藏字段、Read View、undo log。在底层实现中,InnoDB通过数据行的DB_TRX_ID和Read View来判断数据的可见性,如不可见,则通过数据行DB_ROLL_PTR找到undo log中的历史版本。每个事务读到的数据版本可能是不一样的,在同一个事物里,用户只能看到该事务创建Read View之前已经提交的修改和该事务本身做的修改。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值