深度理解Mysql(五):redo log

一.redo log作用

一句话总结:

redo log本质是保证事务提交后,修改过的数据绝对不会丢失

从前面的文章可知,mysql在修改数据时候,首先会把数据页加载到buffer pool中,然后修改内存中的数据,通过异步IO,会定时把数据刷入磁盘中,但是存在一个问题,如果数据在内存中修改成功,这个时候msyql宕机了,就会导致数据丢失,这个时候,就需要引入redo log;

也就是每次事务提交的时候,都会把数据写入到redo log中,如果更新过的数据还没有刷新到磁盘上,这个时候mysql宕机了,重启后,mysql会把redo log中的记录重新执行一遍,恢复之前事务提交的数据更新到缓存页,然后后台IO线程继续把缓存页中的数据刷新到磁盘上

注意

不是事务提交后,事务更新的缓存页立马刷新到磁盘中,这个是❌的,通过前面我们知道,缓存页刷新到磁盘中,是随机磁盘读写,性能是很差的,会导致mysql的并发量大大降低

🙋🏻‍♀️:所以才会引入redo log机制,又会有人问, 缓存页刷入磁盘和redo log刷入磁盘,都是刷入磁盘,他们又会有多大区别?

1.缓存页刷新到磁盘中,是随机磁盘读写,性能是很差的,会导致mysql的并发量大大降低,而且一个缓存页有16k大小,说实话,这个数据量是不小的
2.redo log刷入磁盘,是顺序写入,而且每次数据量小(几十个字节),仅仅记录 *** 对表空间xxx的数据页xxx的偏移量为xxx的地方更新了数据xxx ***

1.2 redo log格式

总结

日志类型(类似MLOG_1BYTE)+表空间号+数据页号+偏移量+修改几个字节的值+具体的值

根据修改数据页中的几个字节的值,redolog划分不同的类型:

MLOG_1BYTE 修改1字节的值

MLOG_2BYTE 修改2字节的值

MLOG_4BYTE 修改4字节的值

...

MLOG_WRITE_STRING 代表修改或插入一大串的值

如果修改类型是MLOG_WRITE_STRING,因为不知道具体修改数据的长度,所以需要记录修改多少字节 的数据,这个格式比较特殊,格式如下:

日志类型(MLOG_WRITE_STRING),表空间ID,数据页号,数据页中的偏移量,修改数据长度,具体修改的数据

redo log格式,说简单也简单,如果往深的说,涉及到索引什么的,也是非常复杂的,一般掌握到这个程度就可以了

二.redo log 如何写入

2.1 redo log是一条一条写入吗?

mysql开发人员为了提升并发量,不会一条一条的把数据写入到redolog中,而且批量写入,将数据先存放在内存中叫做redolog block,一个redolog block的大小是512字节,包含三部分,如图所示

在12字节的头部又划分为4个部分

包括4个字节的block no,就是块唯一编号;

2个字节的data length,就是block里写入了多少字节数据;

2个字节的first record group。这个是说每个事务都会有多个redo log,是一个redo log group,即一组redolog。那么在这个block里的第一组redo log的偏移量,就是这2个字节存储的;

4个字节的checkpoint on

当需要写入数据的时候,数据首先会写入到redolog block中,然后在通过一定的时机,将整个redolog block写入到redolog中,这样就能大大提升并发,如图所示:

2.2 redo log buffer

redolog写日志的时候,首先会把数据写入到缓存中,这就要涉及到一个新组件--redo log buffer 这个内存区域也是mysql在启动的时候向操作系统申请的一块连续的内存区域,然后他划分成多个redolog buffer,如图所示

innodb_log_buffer_size执行redo log buffer的大小,默认是16M,其实已经很大了,毕竟一个redolog block才512字节

2.3 redo log buffer 写入磁盘的时机

redo log在写入数据的时候,首先会在redolog buffer中找到能写入数据的redolog block,然后写入数据的时候,当满足下面四个条件的时候,会触发 redolog block刷新到磁盘中

(1)如果写入redo log buffer的日志已经占据了redo log buffer总容量的一半了,也就是超过了8MB的redo log在缓冲里了,此时就会把他们刷入到磁盘文件里去
(2)一个事务提交的时候,必须把他的那些redo log所在的redo log block都刷入到磁盘文件里去,只有这样,当事务提交之后,他修改的数据绝对不会丢失,因为redo log里有重做日志,随时可以恢复事务做的修改
(3)后台线程定时刷新,有一个后台线程每隔1秒就会把redo log buffer里的redo log block刷到磁盘文件里去
(4)MySQL关闭的时候,redo log block都会刷入到磁盘里去


上面最常见的就是第二第三条, 第四条基本不用考虑,关闭mysql,肯定会将内存中的数据都刷磁盘,第一种情况,能瞬间生成8M的redolog基本也是很难触发的,第二种情况,就是指一般我们执行事务的时候,一般一个事务可能就几十--几百毫秒,事务提交的时候,此时必须立马把这个事务的redolog都刷入磁盘,这样才能保证数据不会丢失

可以

innodb_log_file_size redo log 的大小,默认48M

innodb_log_files_in_group redo log 数量,默认2个

mysql默认有两个redolog文件,每个48M,一共96M,看了不大,实际上每个redolog才几个字节,两个文件能存放上百万条redolog文件了, 当第一个redolog写完后,就写第二个redolog文件,第二个满了,就重新覆盖写第一个redolog文件,以此类推

三.总结

到这里,分析完了redolog的知识点,ok,春节后了,要搬砖了,后面只能夜里加班更新了

相关推荐
tan180°3 小时前
MySQL表的操作(3)
linux·数据库·c++·vscode·后端·mysql
优创学社24 小时前
基于springboot的社区生鲜团购系统
java·spring boot·后端
why技术4 小时前
Stack Overflow,轰然倒下!
前端·人工智能·后端
幽络源小助理4 小时前
SpringBoot基于Mysql的商业辅助决策系统设计与实现
java·vue.js·spring boot·后端·mysql·spring
ai小鬼头6 小时前
AIStarter如何助力用户与创作者?Stable Diffusion一键管理教程!
后端·架构·github
简佐义的博客6 小时前
破解非模式物种GO/KEGG注释难题
开发语言·数据库·后端·oracle·golang
Code blocks6 小时前
使用Jenkins完成springboot项目快速更新
java·运维·spring boot·后端·jenkins
追逐时光者7 小时前
一款开源免费、通用的 WPF 主题控件包
后端·.net