redo log 与 binlog
作者:互联网
一、重做日志(redo log)
InnoDB 存储引擎会使用重做日志文件恢复到掉电前的时刻,以此来保证数据的完整性。
- 采用 WAL(Write Ahead Log)策略,事务提交时,先写重做日志再修改页;
- 每个 InnoDB 存储引擎至少有 1 个重做日志文件组(group),每个文件组下至少有 2 个重做日志文件(如默认的 ib_logfile0 和 ib_logfile1);
- 可以设置多个镜像日志组,将不同的文件组放在不同磁盘上,以提高重做日志的高可用性;
- 在日志组中每个重做日志文件大小一致,并以循环写入的方式运行;
重做日志文件参数 | 作用 | 大小 |
---|---|---|
innodb_log_file_size | 指定每个重做日志文件的大小 | 最大 512GB |
innodb_log_files_in_group | 指定日志文件组中重做日志文件的数量 | 默认为 2 |
innodb_mirrored_log_groups | 指定日志镜像文件组的数量 | 默认为 1,表示只有一个日志文件组,没有镜像 |
innodb_log_group_home_dir | 指定日志文件组所在路径 | 默认 ./ 表示在 MySQL数据库的数据目录下 |
下图 1 以一个重做日志文件组中有四个重做日志文件为例,每个日志文件大小最大只能 512GB。
重做日志文件设置过大 —— 恢复时间长。
重做日志文件设置过小 —— 可能导致一个事务的日志需要多次切换重做日志文件。且会导致频繁地发生 async checkpoint,导致性能的抖动。
重做日志文件组
在每个组的第一个redo log file中,前四个块记录特定部分(2KB),之后才开始记录 log block。除了第一个 redo log file 中会记录,log group 中的其他 log file 不会记录这2KB,但是却会腾出这 2KB 的空间。
重做日志缓冲(内存中)写入磁盘的重做日志文件时,按 512 字节(一个扇区大小),因为扇区是写入的最小单位,因此可以保证写入必定是成功的。因此在重做日志的写入过程中不需要有 doublewrite。
重做日志格式
在 InnoDB 存储引擎中,对于各种不同的操作有着不同的重做日志格式。到 InooDB 1.2.x 版本为止,总共定义了 51 种重做日志类型(例如下图3 insert 语句和 delete 语句写入 redo_log_body 内容是不一样的)。虽然各种重做日志类型不同,但是它们有着基本的格式,下表 2 显示了重做日志条目的结构。
redo_log_type | space | page_no | redo_log_body |
---|
可以从上表 2 中看到,重做日志由 4 部分组成。
组成部分 | 作用 | 大小 |
---|---|---|
redo_log_type | 表示重做日志类型 | 1 字节 |
space | 表示表空间的 ID | 采用压缩方式,占用空间可能小于 4 字节 |
page_no | 表示页的偏移量 | 采用压缩方式 |
redo_log_body | 表示每个重做日志的数据部分 | 恢复时需要调用相应的函数进行解析 |
表空间ID + 页号 即可唯一定位需要进行修改的页。
重做日志块
redo log 是基于页的格式来记录的,innodb 的页大小默认是16KB(由 innodb_page_size变量控制),一个页中可以存放多个 redo log block
重做日志块(512B),
redo log恢复
假如数据在 LSN:10 000 的时候宕机了,则恢复 LSN:10 000 到 LSN:13 000 范围的日志,因为此时 CP 的 LSN 为 10 000。
刷盘时机
重做日志写入重做日志文件触发条件:
- 主线程中每秒会将重做日志缓冲写入磁盘的重做日文件中,不论事务是否提交。
- 参数
innodb_flush_log_at_trx_commit
控制,表示在提交(commit)操作时,处理重做日志的方式。 - 当重做日志缓冲池剩余空间小于1/2时,重做日志刷新到重做日志文件。
引发数据库刷脏页(flush)过程的情况:
- InnoDB 的 redo log 写满时,系统会停止所有的更新操作,把 checkpoint 往前推进(如图1),redo log 留出空间继续写。
- 系统内存不足时,淘汰一些数据页,如果是脏页则先刷到磁盘。
- MySQL 认为系统 ”空闲“ 时,只要有机会就刷一点 ”脏页“。
- MySQL 正常关闭时,MySQL 会把内存的脏页都 flush 到磁盘上。
二、二进制日志(binlog)
三、redo log 与 binlog 的区别
区别 | redo log | binlog |
---|---|---|
所处位置不同 | InnoDB 引擎特有 | MySQL 的 server 层实现的,所有的引擎都可以使用 |
记录内容不同 | 记录关于每个页的更改物理情况,即该日志是物理日志 | 记录一个事务的具体操作内容,即该日志是逻辑日志 |
写入方式不同 | 空间固定会用完,循环写入 | 不会覆盖以前的日志,追加写入 |
写入时间不同 | 在事务进行过程中,不断有重做日志条目(redo entry)被写入重做日志文件中 | 仅在事务提交前进行提交,即只写磁盘一次,不论这时该事务多大 |
redo log 是物理日志,记录的是“在某个数据页上做了什么修改”;
binlog 是逻辑日志,记录的是这个语句的原始逻辑,比如“给ID=2这一行的c字段加1 ”。
参考资料
[1]【图文详解】MySQL系列之redo log、undo log和binlog详解 https://cloud.tencent.com/developer/article/1801920
[2] MySQL技术内幕 InnoDB存储引擎 第2版
标签:binlog,log,文件,写入,日志,redo,重做 来源: https://blog.csdn.net/weixin_44691915/article/details/122860263