6 MySQL日志系统
说明
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用来记录执行情况的,侧重执行的动作
执行流程
在执行器阶段的数据执行流程:
区别
- redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 层实现的,所有引擎都可以使用。
- redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给 ID=2 这一行的 c 字段加 1 ”。
- 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-ost
Obline DDL工具