前情提要
在执行增删改操作的时候,是基于Buffer Pool中的缓存页中的数据的。更新了缓存页中的数据后,会写入一条数据到Redo Log中。在提交事务的时候,会立马把Redo Log刷入磁盘(推荐方式),然后在RedoLog中写入binlog信息和一个commit标记,事务至此提交完毕。
FAQ
官网:
https://dev.mysql.com/doc/refman/8.0/en/innodb-redo-log.html
https://dev.mysql.com/doc/refman/8.0/en/optimizing-innodb-logging.html
RedoLog 保障了什么
当更新了缓存中的数据页后,缓存页还没有刷到磁盘上。MYSQL宕机,那么MYSQL重启后,会直接读取RedoLog中的内容,重做到Buffer Pool中,然后在刷到磁盘。因为 RedoLog 是顺序读写,所以效率很高。并且为了保证数据的不丢失,RedoLog也要设置成不经过OS Cache。
为什么要写入 RedoLog,直接刷到磁盘的缺点在哪里?
- 一个缓存页是16KB,刷盘比较耗时。而且你可能只修改了几个字节的数据。
- 缓存页刷入磁盘是随机读写。效率很低。而 RedoLog 是顺序读写,效率高
详细介绍
RedoLog的类型
根据数据页修改的字节数划分了不同的类型
- MLOG_1BYTE:修改了1个字节
- MLOG_2BYTE:修改了2个字节
- MLOG_4BYTE:修改了4个字节
- MLOG_WRITE_STRING:修改了一大串的值
RedoLog 的大致内容
MLOG_NBYTE,表空间ID,数据页号,数据页中的偏移量,具体修改的值
MLOG_WRITE_STRING,表空间ID,数据页号,数据页中的偏移量,修改的长度,具体修改的值
RedoLog 的写入方式
我们知道RedoLog的目的,是去保证我的数据页在内存,但是还没有同步到磁盘的时候,宕机导致的数据丢失。
所以在sql语句提交之前
,肯定会保存改动的 Redolog 到 redolog file文件。当改动数据还在内存,没有同步到磁盘就宕机的时候,会通过 RedoLog 文件里面找到改动点,进行同步到磁盘。
但是 RedoLogFile 的大小是固定的
,写入的日志数量是有限制的,并且它的目的只是去保证数据不丢失,数据落盘了,这些日志就没有用了,所以RedoLog采用的是循环覆盖写
的方式。
当 RedoLog 空间的大小满了的时候,会对以前数据进行覆盖
。为了保证被覆盖的数据不会丢失,在Redolog快满的时候,也会去进行刷脏
,刷脏后,对应的 Redolog 日志就无效可以被覆盖,所以RedoLog的写是循环写的方式。
当数据同步到磁盘后,RedoLog就会进行删除。
简单一句话,当32个文件被写满后,又会从第一个文件开始进行循环写入。
RedoLog Block
RedoLog中,包含着多个RedoLog Block。每个RedoLog大小是512KB;
在写入Redolog之前先写入内存中的RedoLog Block,然后再把RedoLog Block写入磁盘文件。具体的结构见图。
RedoLog buffer
好比Buffer Pool,基于内存中的一块连续空间。里面分配了多个空的RedoLog block。用来存放redolog。
- 在一个事务中,多个操作对应多个redo Log,对应着一组redolog,现在别的地方暂存,执行完了再把一组的redolog写入到内存中的redolog buffer中的block中
- 如果一个事务对应的redoLog太多,就会放到两个甚至多个redolog block中。
- 如果一个redolog group比较小,也可能会把多个redolog group合并在一个redolog block中。
刷盘时机
- 写入redolog buffer的日志占用了总容量(innodb_log_buffer_size)的50%。
- 事务提交的时候
- 后台线程定时刷新
- MYSQL关闭的时候
RedoLog的一些默认处理
版本 8.0.30 之前
磁盘上默认redolog数量:2个(innodb_log_files_in_group)
磁盘上默认redolog大小:48MB(innodb_log_file_size)
磁盘上的默认名:ib_logfile0,ib_logfile1
一般情况是向一个redolog中写,写满了就换下一个。所以redolog最多保存96MB的redolog,如果第二个写满了,就覆盖第一个日志文件里面原来的redolog版本 8.0.30 之后
磁盘文件的大小由 innodb_redo_log_capacity 配置,
InnoDB尝试维护32个相同大小的重做日志文件,
每个文件等于1/32 * innodb_redo_log_capacity
我们去磁盘发现,InnoDB维护了32个大小为104857600/32=3276800 的 redo 文件
我们发现有的文件是 _tmp
,代表这些文件是备用文件,还没有写入 RedoLog。
禁用 RedoLog
redoLog虽然尽可能的去保证了我们数据的一致性,但是,如果为了性能考虑,而不需要保证一致性也可以对RedoLog进行关闭。
查看RedoLog是否开启
-- 查看RedoLog是否开启
SHOW GLOBAL STATUS LIKE 'Innodb_redo_log_enabled';
从8.0.21开始,可以使用指令
-- 禁用RedoLog
ALTER INSTANCE disable INNODB REDO_LOG;