02_重要的两个日志 redo log 和 binlog

这篇具有很好参考价值的文章主要介绍了02_重要的两个日志 redo log 和 binlog。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

02_重要的两个日志 redo log 和 binlog

MySQL 45 讲Note:

课程专栏名称:《MySQL实战45讲》课程

笔记参考:MYSQL45 讲

想要理解这两个日志 redo log 和 binlog ;我们需要对MySQL 的备份恢复机制有一个基本的了解。

之前你可能经常听 DBA 同事说,MySQL 可以恢复到半个月内任意一秒的状态,带着好奇的态度,这是怎样做到的呢?

如果你使用的是 ​ InnoDB 引擎,那么一般我们会使用 物理日志 redo log 和逻辑日志 binlog 来进行备份恢复。

redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。

一条SQL更新语句如何执行

在讲述日志内容之前,我们先回顾一下查询语句的执行过程:

一条查询语句的执行过程一般是经过连接器、分析器、优化器、执行器等功能模块,最后到达存储引擎。

在Mysql 执行更新语句的时候,查询语句的那一套流程,更新语句也是同样会走一遍。

与查询流程不一样的是,更新流程还涉及两个重要的日志模块,它们正是我们今天要讨论的主角:redo log(重做日志)和 binlog(归档日志)。

日志模块:redo log

粉板和账本

redo log 的机制,我们可以先看一下孔乙己中酒店掌柜记账的方式。

《孔乙己》这篇文章中的酒店掌柜有一个粉板,专门用来记录客人的赊账记录。如果赊账的人不多,那么他可以把顾客名和账目写在板上。但如果赊账的人多了,粉板总会有记不下的时候,这个时候掌柜一定还有一个专门记录赊账的账本。

如果有人要赊账或者还账的话,掌柜一般有两种做法:

  • 一种做法是直接把账本翻出来,把这次赊的账加上去或者扣除掉;
  • 另一种做法是先在粉板上记下这次的账,等打烊以后再把账本翻出来核算。

在生意红火柜台很忙时,掌柜一定会选择后者,因为前者操作实在是太麻烦了。首先,你得找到这个人的赊账总额那条记录。你想想,密密麻麻几十页,掌柜要找到那个名字,可能还得带上老花镜慢慢找,找到之后再拿出算盘计算,最后再将结果写回到账本上。

粉板和账本配合的整个过程,就是 MySQL 里经常说到的 WAL 技术,WAL 的全称是 Write-Ahead Logging,它的关键点就是先写日志,再写磁盘,也就是先写粉板,等不忙的时候再写账本。[先写内存,再写磁盘]

具体来说,当有一条记录需要更新的时候,InnoDB 引擎就会先把记录写到 redo log(粉板)里面,并更新内存,这个时候更新就算完成了。

同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面,而这个更新往往是在系统比较空闲的时候做,这就像打烊以后掌柜做的事。

操作流程

InnoDB 的 redo log 是固定大小的,比如可以配置为一组 4 个文件,每个文件的大小是 1GB,那么这块“粉板”总共就可以记录 4GB 的操作。从头开始写,写到末尾就又回到开头循环写,如下面所示。

02_重要的两个日志 redo log 和 binlog

里面有一个 write pos 和 check point 的概念:

write pos 是当前记录的位置,一边写一边后移,写到第 3 号文件末尾后就回到 0 号文件开头。

checkpoint 是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。

write pos 和 checkpoint 之间的是“粉板”上还空着的部分,可以用来记录新的操作。如果 write pos 追上 checkpoint,表示“粉板”满了,这时候不能再执行新的更新,得停下来先擦掉一些记录,把 checkpoint 推进一下。

有了 redo log,InnoDB 就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为crash-safe

crash-safe

crash-safe 是指在MySQL数据库发生异常崩溃时,数据库能够保证数据的完整性和一致性,从而避免数据丢失或数据损坏的情况。

redo log 用于保证 crash-safe 能力。

  • innodb_flush_log_at_trx_commit 这个参数设置成 1 的时候,表示每次事务的 redo log 都直接持久化到磁盘。这个参数我建议你设置成 1,这样可以保证 MySQL 异常重启之后数据不丢失。
  • sync_binlog 这个参数设置成 1 的时候,表示每次事务的 binlog 都持久化到磁盘。这个参数我也建议你设置成 1,这样可以保证 MySQL 异常重启之后 binlog 不丢失。

日志模块:binlog

上面聊到的粉板 redo log 是 InnoDB 引擎特有的日志而 Server 层也有自己的日志,称为 binlog(归档日志)

redo log 是 InnoDB ​两种日志有以下三点不同:

  1. redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
  2. redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
  3. redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

update 语句内部执行流程

  • 有了对这两个日志的概念性理解,我们再来看执行器和 InnoDB 引擎在执行这个简单的 update 语句时的内部流程。

    1. 执行器先找引擎取 ID=2 这一行。ID 是主键,引擎直接用树搜索找到这一行。如果 ID=2 这一行所在的数据页本来就在内存中,就直接返回给执行器;否则,需要先从磁盘读入内存,然后再返回。
    2. 执行器拿到引擎给的行数据,把这个值加上 1,比如原来是 N,现在就是 N+1,得到新的一行数据,再调用引擎接口写入这行新数据。
    3. 引擎将这行新数据更新到内存中,同时将这个更新操作记录到 redo log 里面,此时 redo log 处于 prepare 状态。然后告知执行器执行完成了,随时可以提交事务。
    4. 执行器生成这个操作的 binlog,并把 binlog 写入磁盘。
    5. 执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,更新完成。

update 语句的执行流程图,图中浅色框表示是在 InnoDB 内部执行的,深色框表示是在执行器中执行。

02_重要的两个日志 redo log 和 binlog

两阶段提交

你可能注意到了,最后三步看上去有点“绕”,将 redo log 的写入拆成了两个步骤:prepare 和 commit,这就是"两阶段提交"。

两阶段提交操作是为了让两份日志之间的逻辑一致; ​

两阶段提交的具体操作和不使用“两阶段提交”会发生的内容(反证证明需要两阶段提交操作)。

更新操作的两阶段提交

  • 当一条SQL语句执行时,如果需要修改InnoDB表的数据,那么会先将修改操作记录在redo log中,然后再将数据修改到内存中。【redo log处于 Prepare状态】
  • 之后执行器会生成这个操作的binlog,并把 binlog 写入磁盘
  • 当事务提交时,redo log会被刷入磁盘,保证数据的持久化。【执行器调用引擎的提交事务接口,引擎把刚刚写入的 redo log 改成提交(commit)状态,更新完成。

如果不使用“两阶段提交”,那么数据库的状态就有可能和用它的日志恢复出来的库的状态不一致

  1. 先写 redo log 后写 binlog

    1. 假设在 redo log 写完,binlog 还没有写完的时候,MySQL 进程异常重启。由于我们前面说过的,redo log 写完之后,系统即使崩溃,仍然能够把数据恢复回来,所以恢复后这一行 c 的值是 1。 但是由于 binlog 没写完就 crash 了,这时候 binlog 里面就没有记录这个语句。因此,之后备份日志的时候,存起来的 binlog 里面就没有这条语句。
    2. 然后你会发现,如果需要用这个 binlog 来恢复临时库的话,由于这个语句的 binlog 丢失,这个临时库就会少了这一次更新,恢复出来的这一行 c 的值就是 0,与原库的值不同。
  2. 先写 binlog 后写 redo log

    1. 如果在 binlog 写完之后 crash,由于 redo log 还没写,崩溃恢复以后这个事务无效,所以这一行 c 的值是 0。但是 binlog 里面已经记录了“把 c 从 0 改成 1”这个日志。
    2. 所以,在之后用 binlog 来恢复的时候就多了一个事务出来,恢复出来的这一行 c 的值就是 1,与原库的值不同。

怎样让数据库恢复到半个月内任意一秒的状态?

binlog 会记录所有的逻辑操作,并且是采用“追加写”的形式。如果你的 DBA 承诺说半个月内可以恢复,那么备份系统中一定会保存最近半个月的所有 binlog,同时系统会定期做整库备份。这里的“定期”取决于系统的重要性,可以是一天一备,也可以是一周一备。

当需要恢复到指定的某一秒时,比如某天下午两点发现中午十二点有一次误删表,需要找回数据,那你可以这么做:

  • 首先,找到最近的一次全量备份,如果你运气好,可能就是昨天晚上的一个备份,从这个备份恢复到临时库;
  • 然后,从备份的时间点开始,将备份的 binlog 依次取出来,重放到中午误删表之前的那个时刻。

这样你的临时库就跟误删之前的线上库一样了,然后你可以把表数据从临时库取出来,按需要恢复到线上库去。

小结

redo log 用于保证 crash-safe 能力,可以保证 MySQL 异常重启之后数据不丢失。

两阶段提交是跨系统维持数据逻辑一致性时常用的一个方案。

通过 binlog 日志的备份文件将数据恢复到临时库,从临时库的数据按需恢复数据。文章来源地址https://www.toymoban.com/news/detail-469067.html

到了这里,关于02_重要的两个日志 redo log 和 binlog的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MySQL 三大日志(bin log、redo log、undo log)

    redo log (重做日志) 是 InnoDB 存储引擎独有的,它让 MySQL有了崩溃恢复的能力,是事务中实现 持久化的重要操作 比如 MySQL 实例宕机了,重启时, InnoDB 存储引擎会使用 redo log 恢复数据,保 证数据的持久性与完整性 。 MySQL 中数据时以页为单位,查询一条记录,会从硬盘中把该

    2024年02月07日
    浏览(57)
  • 【数据库管理】④重做日志Redo Log

    重做日志(Redo log)是数据库管理系统中的一种机制,主要作用包括: 提供事务的持久性支持:重做日志记录了每个事务对数据库所做的修改操作,以便在系统故障或崩溃时,通过重新执行重做日志中未提交的事务来恢复数据。 支持数据库备份和恢复:重做日志可以用于还原

    2023年04月08日
    浏览(71)
  • 面试官问我为啥B+树一般都不超过3层?3层B+树能存多少数据?redo log与binlog的两阶段提交?

    我今天逛了一下CSDN,又发现了一条显眼的数据,大概是说 3层B+树足以容纳2000w条数据 。我当时就蒙了,3层对2000w,心想这B+树也太厉害了吧,由此勾起了我求知的欲望,我一定要搞明白他这2000w是怎么来的。 MySQL的执行流程如下图 前提: binlog本身不具备crash-safe能力 ,所以

    2024年02月11日
    浏览(42)
  • Mysql日志redo log、bin log、undo log 区别与作用及二阶段提交

    重做日志 作用:确保事务的持久性。防止在发生故障的时间点,尚有脏页未写入磁盘,在重启mysql服务的时候,根据redo log进行重做,从而达到事务的持久性这一特性。 内容:物理格式的日志,记录的是物理数据页面的修改的信息,其redo log是顺序写入redo log file的物理文件中

    2024年02月03日
    浏览(51)
  • oracle的redo与postgreSQL的WAL以及MySQL的binlog区别

    Oracle的redo日志、PostgreSQL的WAL(Write-Ahead Log)以及MySQL的binlog(二进制日志)都是数据库的事务日志,但它们在实现和功能上有一些区别。 1. 实现方式:    - Oracle的redo日志是通过在事务提交前将事务操作记录到磁盘上的重做日志文件中来实现的。    - PostgreSQL的WAL是通过在

    2024年02月09日
    浏览(37)
  • MySQL redo log

    重做日志,用于记录事务操作的变化,确保事务的 持久性 。redo log是在 事务开始 后(begin; 之后)就开始记录,不管事务是否提交都会记录下来,在异常发生时(如数据持久化过程中掉电), InnoDB 会使用redo log恢复到掉电前的时刻,保证数据的完整性。 undo log 称为 逻辑 日

    2024年02月09日
    浏览(36)
  • [MySQL]事务原理之redo log,undo log

    🌈键盘敲烂,年薪30万🌈 目录 一、log日志文件 📕 事务执行流程 📕 redo log 📕 undo log 二、总结 👀再来一遍ACID 1. 原子性: 原子性确保事务作为一个整体执行,要么全部执行成功,要么全部不执行。 2. 一致性: 一致性确保事务将数据库从一个状态转换为另一个状态。 3.

    2024年02月04日
    浏览(34)
  • MySQL - 为什么需要 redo log?

    为什么需要 redo log?: 数据恢复与一致性: Redo日志是数据库的事务日志,用于记录事务操作的细节,包括插入、更新和删除等。它确保了数据的持久性,即使在数据库发生崩溃或异常重启后,可以使用Redo日志来还原事务操作,以维护数据的一致性。 WAL机制支持: Redo日志是

    2024年02月06日
    浏览(30)
  • Oracle (7)Online Redo Log Files

    目录 一、Oracle Online Redo Log Files及其相关内容介绍 1、Online Redo Log Files简介 2、Online Redo Log Files特点 3、Online Redo Log Files文件组 4、多路复用文件 5、联机重做日志文件工作方式 6、LGWR什么时候写重做 7、LS和LSN 8、删除Redo文件成员 9、删除重做文件组 10、重新定位和重命名 11、什

    2024年02月06日
    浏览(43)
  • MySQL 8.0 Dynamic Redo Log Sizing翻译

    本文是 MySQL 8.0 Dynamic Redo Log Sizing [1] 这篇文章的翻译。如有翻译不当的地方,敬请谅解,请尊重原创和翻译劳动成果,转载的时候请注明出处。谢谢! 这篇博文将讨论MySQL 8.0.30中引入的最新功能/特性:重做日志动态调整大小(dynamic redo log sizing)。除了InnoDB 缓冲池(buffer pool)大

    2024年02月13日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包