说明

MySQL写数据的时候需要用到日志记录,它不会马上写数据到磁盘,而是在空闲的时候记录

redo log(重做日志)和 binlog(归档日志)。

引用

redolog

redolog 是引擎层日志,只有Innodb有

可以类比 酒馆赊酒、记账流程:先记录在粉板上,然后空闲或记录满的时候再记录在记录到账单中。

如果每一次的更新操作都需要写进磁盘,然后磁盘也要找到对应的那条记录,然后再更新,整个过程 IO 成本、查找成本都很高。
为了解决这个问题,MySQL 采用了先写到日志中,再写磁盘。

具体来说,当有一条记录需要更新的时候,InnoDB 引擎就会先把记录写到 redo log(粉板)里面,并更新内存,这个时候更新就算完成了。同时,InnoDB 引擎会在适当的时候,将这个操作记录更新到磁盘里面,而这个更新往往是在系统比较空闲的时候做,这就像打烊以后掌柜做的事。

为了解决redolog被写满的情况(粉板被写满了,则需要先记录在清空粉板),redolog 配置环形记录区,如下
环形

write_pos 是当前写数据的位置
checkpoint 是已经擦除的位置

write_pos-checkpoint中间是可以用的位置,若write_pos追上checkpoint,则说明没有空间了,需要停止写入,先擦除

因此,及时数据写入未完成,只要redolog在,恢复之后依然可以继续写入,称为crash-safe

binlog

binlog归档日志,是server层日志

binlog用来记录数据库的执行语句,以追加的方式存储,我们的每一句SQL都会写入binlog中

binlog 与 redolog 合作与分工

redolog用来写磁盘的,侧重数据的保存
binlog用来记录执行情况的,侧重执行的动作

执行流程

在执行器阶段的数据执行流程:
执行流程

区别

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

一致性解决

采用两阶段提交的方式, 先redolog准备,然后binlog提交,再是redolog提交

undolog

rowlog

MySQL 5.6 版本开始引入的 Online DDL,对重建表做了在线更新,用到了rowlog

  • 在Innodb重建表alter table A engine=InnoDB的时候会建立临时表,
  • 这个临时表会扫描主键索引并将值记录在临时表中
  • 这过程中会将新的数据记录在rowlog中
  • 表迁移完成后将rowlog的数据更新在临时表中
  • 临时表文件替换原表文件

MySQL 5.6 以下版本在迁移过程中表不可用,不会生成rowlog

对于大表来说,过程会有比较高的IO和CPU消耗,建议使用github上的gh-ostObline DDL工具