专栏首页用户7890857的专栏mysql日志:redo log、binlog、undo log 区别与作用
原创

mysql日志:redo log、binlog、undo log 区别与作用

1、mysql常用日志

  • 错误日志
  • 查询日志
  • 慢查询日志
  • 事务日志【redo log(重做日志)、undo log(回滚日志)】
  • 二进制日志【bin log】

主要介绍下redo log、undo log、bin log日志文件。

2、redo log

        概念:重做日志用来实现事务持久性,主要有两部分文件组成,重做日志缓冲(redo log buffer)以及重做日志文件(redo log),前者是在内存中,后者是在磁盘中。

作用:确保事务的持久性。防止在发生故障的时间点,尚有脏页未写入磁盘,在重启 mysql 服务的时候,根据 redo log 进行重做,从而达到事务的持久性这一特性。

  内容:物理格式的日志,记录的是物理数据页面的修改的信息,其 redo log 是顺序写入 redo log file 的物理文件中去的。

3、bin log

        概念:归档日志。记录了所有的DDL和DML语句(除查询语句外),以事件形式记录,是事务安全型。

作用:用于复制,在主从复制中,从库利用主库上的 binlog 进行重播,实现主从同步。用于数据库的基于时间点的还原。

  内容:逻辑格式的日志,可以简单认为就是执行过的事务中的 sql 语句。但又不完全是 sql 语句这么简单,而是包括了执行的 sql 语句(增删改)反向的信息,也就意味着 delete 对应着反向的 insert;update 对应着 update 执行前后的版本的信息;insert 对应着 delete 和 insert 本身的信息。

  binlog 有三种日志模式:

  • Statement(基于 SQL 语句的复制):
    • 优点:不需要记录每一行的变化,减少了binlog日志量,节约了IO,提高性能。
    • 由于记录的只是执行语句,为了这些语句能在slave上正确运行,因此还必须记录每条语句在执行的时候的一些相关信息,以保证所有语句能在slave得到和在master端执行时候相同 的结果。
  • Row(基于行的复制)
    • 优点:可以不记录执行的sql语句的上下文相关的信息,仅需要记录那一条记录被修改成什么了。所以rowlevel的日志内容会非常清楚的记录下每一行数据修改的细节。而且不会出现某些特定情况下的存储过程,以及trigger的调用和触发无法被正确复制的问题。
    • 缺点:所有的执行的语句当记录到日志中的时候,都将以每行记录的修改来记录,这样可能会产生大量的日志内容。
  • Mixed(混合模式)
    • 一般的语句修改使用statment格式保存binlog,如一些函数,statement无法完成主从复制的操作,则采用row格式保存binlog,MySQL会根据执行的每一条具体的sql语句来区分对待记录的日志形式,也就是在Statement和Row之间选择一种。

4、undo log

        概念:回滚日志,用来记录数据被修改前的信息。正好跟前面的重做日志进行相反操作。undo log主要记录的是数据的逻辑变化,为了在发生错误时回滚之前的操作,需要将之前的操作都记录下来,然后在发生错误时才可以回滚。

作用:保存了事务发生之前的数据的一个版本,可以用于回滚,同时可以提供多版本并发控制下的读(MVCC),也即非锁定读;

  内容:逻辑格式的日志,在执行 undo 的时候,仅仅是将数据从逻辑上恢复至事务之前的状态,而不是从物理页面上操作实现的,这一点是不同于 redo log 的。

5、redo log详解

mysql,如果每次更新操作都要写进磁盘,然后磁盘要找到对应记录,然后再更细,整个过程 io 成本、查找成本都很高。解决方案:WAL 技术(Write-Ahead Logging)。先写日志,再写磁盘。

  具体来说,当有一条记录需要更新的时候,InnoDB 引擎就会先把记录写到 redo log 里面,并更新内存,这个时候更新就算完成了。同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面,而这个更新往往是在系统比较空闲的时候做。InnoDB 的 redo log 是固定大小的,比如可以配置为一组 4 个文件,每个文件的大小是 1GB,那么总共就可以记录 4GB 的操作。从头开始写,写到末尾就又回到开头循环写,如下面这个图所示。

  write pos 是当前记录的位置,一边写一边后移,写到第 3 号文件末尾后就回到 0 号文件开头。checkpoint 是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。

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

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

6、bin log详解

  MySQL 整体来看,其实就有两块:一块是 Server 层,它主要做的是 MySQL 功能层面的事情;还有一块是引擎层,负责存储相关的具体事宜。redo log 是 InnoDB 引擎特有的日志,而 Server 层也有自己的日志,称为 binlog(归档日志)。

  这两种日志有以下三点不同。

  1. redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。

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

  3. redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写” 是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

7、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)状态,更新完成。

最后三步,将 redo log 的写入拆成了两个步骤:prepare 和 commit,这就是” 两阶段提交”。

8、两阶段提交

两阶段提交,是为了 binlog 和 redolog 两分日志之间的逻辑一致。redo log 和 binlog 都可以用于表示事务的提交状态,而两阶段提交就是让这两个状态保持逻辑上的一致。

  由于 redo log 和 binlog 是两个独立的逻辑,如果不用两阶段提交,要么就是先写完 redo log 再写 binlog,或者采用反过来的顺序。可能造成的问题:

  update 语句来做例子。假设当前 ID=2 的行,字段 c 的值是 0,再假设执行 update 语句过程中在写完第一个日志后,第二个日志还没有写完期间发生了 crash,会出现什么情况呢?

  1. 先写 redo log 后写 binlog。

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

  2. 先写 binlog 后写 redo log。

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

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

  扩容的时候,也就是需要再多搭建一些备库来增加系统的读能力的时候,现在常见的做法也是用全量备份加上应用 binlog 来实现的,这个 “不一致” 就会导致线上出现主从数据库不一致的情况。

9、undo log详解

  undo 用来回滚行记录到某个版本。undo log 一般是逻辑日志,根据每行记录进行记录。

  undo 日志用于记录事务开始前的状态,用于事务失败时的回滚操作;redo 日志记录事务执行后的状态,用来恢复未写入 data file 的已成功事务更新的数据。例如某一事务的事务序号为 T1,其对数据 X 进行修改,设 X 的原值是 0,修改后的值为 1,那么 Undo 日志为 <T1, X, 0>,Redo 日志为 < T1, X, 1>。

欢迎大家关注 CodingCode 公众号,获取一手资料,同时也欢迎私信交流。

CodingCode

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • mysql三大日志-binlog、redo log和undo log

    日志是mysql数据库的重要组成部分,记录着数据库运行期间各种状态信息。mysql日志主要包括错误日志、查询日志、慢查询日志、事务日志、二进制日志几大类。作为开...

    AlbertZhang
  • 必须了解的MySQL三种日志

    大家有没有想过为什么MySQL数据库可以实现主从复制,实现持久化,实现回滚的呢?其实关键在于MySQL里的三种log,分别是:

    java技术爱好者
  • 初探InnoDB存储引擎的架构设计

    首先,InnoDB会判读缓冲池里是否存在 id = 1 这条数据,如果不存在则从磁盘中加载到缓冲池中,而且还会对这行数据加独占锁,防止多个sql同时修改这行数据...

    Java技术江湖
  • 【图文详解】MySQL系列之redo log、undo log和binlog详解

    这篇文章主要介绍了MySQL系列之redo log、undo log和binlog详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要...

    一个会写诗的程序员
  • 必须了解的mysql三大日志-binlog、redo log和undo log

    日志是 mysql 数据库的重要组成部分,记录着数据库运行期间各种状态信息。mysql日志主要包括错误日志、查询日志、慢查询日志、事务日志、二进制日志几大类。

    架构师修炼
  • MySQL中的redolog,undolog,以及binlog的区别及各自作用是什么?

    MySQL中有六种日志文件, 分别是:重做日志(redo log)、回滚日志(undo log)、二进制日志(binlog)、错误日志(errorlog)、慢查...

    程序员白楠楠
  • 必须了解的mysql三大日志-binlog、redo log和undo log

    来自:https://juejin.im/post/6860252224930070536

    用户6543014
  • MySQL 中的重做日志,回滚日志以及二进制日志的简单总结

    来源:MSSQL123 , www.cnblogs.com/wy123/p/8365234.html 转自:ImportNew MySQL中有六种日志文件,分别...

    用户1257393
  • MySQL到底有多少种日志类型需要我们记住的!

    程序你好
  • MySQL到底有多少种日志类型需要我们记住的!

    MySQL中有六种日志文件,分别是:重做日志(redo log)、回滚日志(undo log)、二进制日志(binlog)、错误日志(errorlog)、慢查询...

    Java后端技术
  • 一文搞懂回滚和持久化

    这里面有几个关键的点:redo log是什么?为什么需要redo log?prepare状态的redo log是什么?redo log和binlog是否可以只选...

    用户8851537
  • MySQL 事务日志

    在写日志的时候,单个日志如果过大,对于读写和同步都会产生影响,所以在日志变大的时候,需要对日志进行一个分组。

    付威
  • 面试官的灵魂一击:你懂 MySQL 事务日志吗?

    大家都清楚,日志是 MySQL 数据库的重要组成部分,记录着数据库运行期间各种状态信息。MySQL 日志主要包括「错误日志」、「查询日志」、「慢查询日志」、「二...

    用户6543014
  • 技术分享 | Update更新慢、死锁等问题的排查思路分享

    在开始排错之前我们需要知道 Update 在 MySQL 中的生命周期是什么,MySQL 如何执行一个事务的。

    老叶茶馆
  • 《MySQL》系列 - 小胖问我:MySQL 日志到底有啥用?菜!

    事情是这样的,我负责我司的报表系统,小胖是我小弟。某天他手贱误删了一条生产的数据。被用户在群里疯狂投诉质问,火急火燎的跑来问我怎么办。我特么冷汗都出来了,训斥了...

    一个优秀的废人
  • MySQL这些题目你都会吗?

    1、MySQL偶尔会出现OOM(内存溢出)现象,导致MySQl服务重启,以下哪种方式能有效缓解OOM的情况发生( )

    MySQL轻松学
  • MYSQL 必考面试题10道(答案解释)

    MySQL偶尔会出现OOM(内存溢出)现象,导致MySQl服务重启,以下哪种方式能有效缓解OOM的情况发生()

    MySQL轻松学
  • 深入学习MySQL 02 日志系统:bin log,redo log,undo log

    上一篇文章中,我们了解了一条查询语句的执行过程,按理说这篇应该讲一条更新语句的执行过程,但这个过程比较复杂,涉及到了好几个日志与事物,所以先梳理一下3个重要的日...

    KEN DO EVERTHING
  • 重新学习MySQL数据库10:MySQL里的那些日志们

    本文是微信公众号【Java技术江湖】的《重新学习MySQL数据库》其中一篇,本文部分内容来源于网络,为了把本文主题讲得清晰透彻,也整合了很多我认为不错的技术博客...

    Java技术江湖

扫码关注云+社区

领取腾讯云代金券