Loading... # 前情提要 在执行增删改操作的时候,是基于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,直接刷到磁盘的缺点在哪里? 1. 一个缓存页是16KB,刷盘比较耗时。而且你可能只修改了几个字节的数据。 2. 缓存页刷入磁盘是随机读写。效率很低。而 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写入磁盘文件。具体的结构见图。 ![](/images/img-40.png) ## RedoLog buffer 好比Buffer Pool,基于内存中的一块连续空间。里面分配了多个空的RedoLog block。用来存放redolog。 + 在一个事务中,多个操作对应多个redo Log,对应着一组redolog,现在别的地方暂存,执行完了再把一组的redolog写入到内存中的redolog buffer中的block中 + 如果一个事务对应的redoLog太多,就会放到两个甚至多个redolog block中。 + 如果一个redolog group比较小,也可能会把多个redolog group合并在一个redolog block中。 ## 刷盘时机 1. 写入redolog buffer的日志占用了总容量(innodb_log_buffer_size)的50%。 2. 事务提交的时候 3. 后台线程定时刷新 4. 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 ``` ![](https://img.pelycloud.com/pelyblog/2024/01-10/659e73f95574c.png) 我们去磁盘发现,InnoDB维护了32个大小为104857600/32=3276800 的 redo 文件 ![](https://img.pelycloud.com/pelyblog/2024/01-10/659e745c870e4.png) 我们发现有的文件是 `_tmp`,代表这些文件是备用文件,还没有写入 RedoLog。 ## 禁用 RedoLog redoLog虽然尽可能的去保证了我们数据的一致性,但是,如果为了性能考虑,而不需要保证一致性也可以对RedoLog进行关闭。 查看RedoLog是否开启 ```mysql -- 查看RedoLog是否开启 SHOW GLOBAL STATUS LIKE 'Innodb_redo_log_enabled'; ``` 从8.0.21开始,可以使用指令 ```mysql -- 禁用RedoLog ALTER INSTANCE disable INNODB REDO_LOG; ``` 最后修改:2024 年 01 月 10 日 © 允许规范转载 赞 1 如果觉得我的文章对你有用,请点个赞吧~