前面我们说了修改一条数据总不能吧16kb的页全部持久化到磁盘上,于是有了redo日志,记录哪些修改的数据,redo日志也有自己的缓存区,并不是直接把数据记录到磁盘上,缓存区是innoDB_redo_buffer_size,默认是16mb,为了保证原子性,他会分为不同的组,当乐观插入的时候,只有一条数据需要插入,则type的个字节是1,代表只有一条插入,当悲观插入多条插入的时候,会有一个MLOG_MULTI_REC_END的日志,表示这组记录完毕,若系统宕机重启,解析redo日志时候,没有解析到这个,则前面解析的全部放弃。
Redo日志刷盘时机
我们前面说了mtr运行过程中产生一些redo日志,在mtr结束的时候会复制到log buffer中,可也不能一直在内存中,什么时候刷新到磁盘呢。
Log buffer空间不足的时候:
Log buffer大小是有限的,如果一直塞进去肯定会被填满,innoDB大叔认为如果写入log buffer的redo填满占了大约一半的时候,就需要持久化到磁盘上。
事务提交时候:
我们之前说过使用redo日志主要占用空间小,还是顺序写入,在事务提交时候,可以不吧buffer pool修改的数据刷新到磁盘上,但为了保证持久性,必须把这些redo日志刷新到磁盘上。
后台有个线程:
后台有个线程,大约每秒都会刷新一次log buffer 到磁盘。
正常关闭服务器:
做所谓的checkpoint时,也会刷新到磁盘。
其他一些情况。。
Redo日志文件组
Mysql的数据目录,用show variables like ‘datadir’查看,可以看到两个ib_logfile0和ib_logfile1的文件,log buffer中的日志默认就是刷新到磁盘上的这两个文件中。如果想修改redo文件,可以通过几个启动参调节:
Innodb_log_group_home_dir:该参数指定redo文件所在目录,默认就是在当前数据目录。
Innodb_log_file_Size:指定每个redo日志文件大小,在mysql5.7.21这个版本默认值是48M。
innoDB_log_files_in_group:该参数指定redo日志文件个数,默认是2,大为100。
所以从上可以看到,磁盘的redo日志文件不只一个,而是以日志文件组的形式出现。当redo日志刷新到磁盘时候,先刷新到ib_logfile0然后就是1,2,如果满了,就继续循环从0开始记录。
所以总的redo日志大小就是innodb_log_file_size * innodb_log_file_in_group
Redo日志文件格式
我们前面说过log buffer本质是个连续空间,划分若干个512字节的block。将log buffer中的redo日志刷新到磁盘本质就是把block刷新到磁盘,所以磁盘上的redo日志文件也是由各种512字节的block组成。
Redo日志文件组每个文件大小一样,格式一样,由两个部分组成:
前2048个字节,也就是前4个block存一些管理信息。
从2048个字节之后开始,开始存log buffer 的block镜像。
所以前面说循环存储redo日志是从2048个字节开始算。
前面我们说过普通的block组要就是三个部分,log block header,log block body,log block trailder三个部分。下面介绍下4个存储管理信息的block。
1、 Log file header:描述redo日志文件的整体信息。
这里面包含着五个参数:
A、 log_header_format:4个字节,redo日志版本,在mysql5.7.21中永远为1.
B、 Log_header_pad1:4个字节,做字节填充中。
C、 Log_header_start_lsn:8个字节,标记redo日志文件开始的LSN值,也就是文件偏移量的2048个字节对应的LSN值。
D、Log_header_cheator:32个字节,一个字符串,标记redo日志创建者是谁。正常运行时该值是mysql版本号,比如MySql5.7.21,使用mysqlbackup命令创建redo日志文件的该值为“ibbackup”和创建时间。
E、 Log_block_checksum:4个字节,block的效验值。
注意,mysql对block格式经常修改,如果阅读其他书籍发现不一样,可能因为版本不同。
2、 checkpoint1:记录关于checkpoint的一些属性:
这里面也包含五个参数:
A、 log_checkpoint_no:8个字节,服务器做checkpoint的编号,每次有新的就加1.
B、 Log_checkpoint_lsn:8个字节,服务器做checkpont结束时对应的LSN值,系统崩溃从这个值开始。
C、 Log_checkpoint_offset:8个字节,上个属性的LSN值在redo日志偏移量。
D、Log_checkpoint_log_buffer_size:8个字节,服务器在做checkpoint操作时对应的log buffer大小。
E、 Log_block_checksum:4个字节,block的效验值。
第三个参数未使用,忽略。
第三个参数checkpoint2和上面的checkpoint1一样。
文章来源:知乎平台 原文地址:https://zhuanlan.zhihu.com/p/419884316