MySQL日志系统

时间:2022-07-24
本文章向大家介绍MySQL日志系统,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

MySQL 日志系统

一. redo Log

  1. redo log 是 InnoDB 引擎特有的功能,是物理日志。
  2. 当 MySQL 执行更新操作时,InnoDB 引擎就会先把记录写到 redo log 里面,并更新内存,这个时候更新就算完成了。同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面,而这个更新往往是在系统比较空闲的时候做的。
  3. InnoDB 的 redo log 是固定大小的,比如可以配置为一组 4 个文件,每个文件的大小是 1GB,那么整个 redo log 就可以保存 4G 的数据。redo log 是每次从头开始写,写到末尾就又回到开头循环写。
  4. write pos 是当前记录的位置,一边写一边后移,写到第 3 号文件末尾后就回到 0 号文件开头。checkpoint 是当前要擦除的位置,也是往后推移并且循环的,擦除记录前要把记录更新到数据文件。
  5. write pos 和 checkpoint 之间的是 redo log 上可写的部分,可以用来记录新的操作。如果 write pos 追上 checkpoint,表示 redo log 已满,这时候不能再执行新的更新,得停下来先擦掉一些记录,把 checkpoint 推进一下。此时就需要把这部分 redo log 对应的内存脏页写入磁盘中。
  6. 有了 redo log,InnoDB 就可以保证即使数据库发生异常重启,之前提交的记录都不会丢失,这个能力称为 crash-safe

二. binlog

  1. binlog 是 MySQL server 层提供的日志。
  2. binlog 有两种模式,statement 格式的话是记sql语句, row格式会记录行的内容,记两条,更新前和更新后都有。
  3. binlog 和 redo log 的不同之处:
    1. redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
    2. redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
    3. redo log 是循环写的,空间固定会用完;binlog 是可以追加写入的。“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。
  4. 即使有了 redo log 来做 crash-safe,但是 binlog 仍然是必不可少的,原因如下:
    1. redo log 是 InnoDB 引擎所独有的,如果使用其他引擎就无能为力了;
    2. redo log 是循环写的,大小有限制,因此无法保存全量数据,并不具备 binlog 的归档能力

三. 更新操作执行流程

以下面这条SQL语句为例:

update T set c=c+1 where ID=2;

四. 两阶段提交

通过上述流程可以很明显看出,更新操作采用了两阶段提交算法,主要是为了保证 redo log 和 binlog 的数据一致性。两阶段提交是跨系统维持数据逻辑一致性时常用的一个方案。

五. MySQL 的崩溃恢复规则

MySQL 主要依赖 redo log 进行崩溃后的数据恢复。redo log 和 binlog 有一个共同的数据字段,叫 XID。崩溃恢复的时候,会按顺序扫描 redo log。如果碰到既有 prepare、又有 commit 的 redo log,就直接提交;如果碰到只有 parepare、而没有 commit 的 redo log,就拿着 XID 去 binlog 找对应的事务。 恢复崩溃规则如下:

  1. 如果 redo log 里面的事务是完整的,也就是已经有了 commit 标识,则直接提交;
  2. 如果 redo log 里面的事务只有完整的 prepare,则判断对应的事务 binlog 是否存在并完整: a. 如果是,则提交事务; b. 否则,回滚事务。

.