【mysql】redo log日志是什么?有啥用?

您所在的位置:网站首页 sql_log_bin是什么 【mysql】redo log日志是什么?有啥用?

【mysql】redo log日志是什么?有啥用?

2023-11-15 12:41| 来源: 网络整理| 查看: 265

文章目录 引出 redo log 的作用思考一个问题: redo log blockredo log bufferredo log的刷盘时机推荐参数 相关文章: redo log日志是什么?有啥用? 详细分析MySQL事务日志(redo log和undo log的区别) MYSQL的日志(redo log,binlog)顺序读写,数据文件随机读写以及linux底层原理 MySQL 中Redo日志与Binlog日志顺序一致性问题

引出 redo log 的作用

二进制日志(binlog)是server层的,主要用来做主从复制和即时点恢复时使用的。而事务日志(redo log)是InnoDB存储引擎层的,用来保证事务安全的。

前面我们一起学习了MySQL undo log相关的知识点,看下面这张脑图: 在这里插入图片描述 磁盘上的数据文件叫表空间文件,表空间有挺多的,比如系统表空间、undo log 表空间、你也可以让create出来的每张table都有自己单独的表空间。总之MySQL会将表空间数据页通过磁盘IO加载进缓存页中。

SQL执行器会执行你发送给MySQL的SQL语句,MySQL为了提高的性能,对于增、删、改这种操作都是在内存中完成的,所谓的内存就是上图中BufferPool。比如上图中的SQL执行器执行了一条update xxx where id = 1语句,然后这个id = 1数据行所在的数据页就会被你修改成脏数据页。

此外MySQL还有专门的后台线程等其他机制负责将脏数据页刷新同步回磁盘。

redo log是 引擎层的操作日志。内存中数据刷盘涉及到索引、裂分页,比较耗时,因此适合后台慢慢处理和批量刷新。批量处理是非时时的,会导致断电数据丢失。先把数据写入redo log日志,好处是顺序写,速度快,断电后有可以据此恢复数据。 顺序写参见 MYSQL的日志(redo log,binlog)顺序读写,数据文件随机读写以及linux底层原理

思考一个问题:

你可以结合上图然后想一下:万一脏页还没来得及刷新到磁盘中,MySQL就挂了,怎么办呢?

对于业务代码来说,方才执行的事务是OK的,甚至前端都接受到了请求成功的响应。那结果修改的数据没同步回磁盘,MySQL宕机了会不会导致真实数据和逻辑上的数据不一致呢?

其实不会的!

MySQL使用redo log解决了这个问题,redo故名思义:重做。

当发生事务(增、删、改)时会导致缓存页变成脏页,于此同时MySQL会将事务涉及到的:对 XXX表空间中的XXX数据页XXX偏移量的地方做了XXX更新。

所以MySQL意外宕机重启也没关系。只要在重启时解析redo log中的事务然后重放一遍。将Buffer Pool中的缓存页重做成脏页。后续再在合适的时机将该脏页刷入磁盘即可。

于是对于业务方来说,everything is ok!

redo log侧重于重做!redo log中记录的是物理层面的数据页、偏移量。应对的问题是:MySQL异常宕机后,如何将没来得及提交的事物数据重做出来。

而后面文章中和大家分享的bin log中记录了你对XXX表条件为XXX处的数据作了什么修改,这是些都是逻辑上的概念。

redo log block

首先你得知道,redo并不是一条条直接写入磁盘中去的!

在MySQL的设定中,redolog是按块,一块一块的写入到磁盘中去的。

你可以类比一下数据是按页为单位来组织的,就更容易理解为啥redo log 要按照block来组织redo。 本质上就是两个字:优化

log block长成下面这这样:分成Header、Body、Trailer三部分 总共512字节。而且是覆盖写入。

在这里插入图片描述 我粗略解读一下这幅脑图。

首先既然MySQL会写redo log,说明你的sql会对缓存页造成修改,也就意味着会走MySQL设定的事物那一套机制。既然是MySQL事务,大概率就是一组增、删、改。如果每个增、删、改都会有一个对应的redo log的话,那也就是说你的事务会产生好多redolog。这些redo会先被持续不断的写入到log block中,同一个事物产生的redo log会被标记为一个redo log group。

redo log buffer

了解redo log block之后,白日梦还要跟你介绍一下 redo log buffer。

这个redo log buffer 中会划分出多个rodo log block。redo log buffer 占用一块连续的内存空间,默认大小16MB。且MySQL允许我们通过参数innodb_log_buffer_size动态的调整它。增大它的大小可以让MySQL处理大事物是不必写入磁盘。进而提升写IO性能。

引入rodo log buffer之后,就可以勾勒出这样一副脑图。

在这里插入图片描述 如图,产生的redo log 先写入redo log block。然后redo log block其实就在redo log buffer 中。

看到这里不知道你有没有想到这样一个问题:redo log buffer再怎么神奇毕竟也是仅仅在内存中,此时万一MySQL宕机了怎么办?redolog-buffer中的数据丢失了怎么办?毕竟没有写到磁盘上,MySQL重启后100%没办法将其恢复出来。

其实你并不用担心这种情况!

因为在MySQL的设定中,当你要Commit事务时,redolog才会持久化进磁盘,既然你没有commit,碰巧MySQL又宕机了。那让MySQL正常重启就好了啊,反正你没有commit,MySQL也也没有必要帮你恢复什么。

那 redo log buffer 何时写入磁盘呢?

事物提交时把它对应的那些redo log写入到磁盘中去(这个动作可由相关参数控制,下文会说)当redo log buffer 使用量达到了参数innndb_log_buffer_size的一半时,会触发落盘。会有一个后台线程,每隔1秒就会将redo log block刷新到磁盘文件中去。MySQL关闭时也会将其落盘。 redo log的刷盘时机

承接上面描述的场景:事务提交时,率先将redo log持久化进磁盘。

那你如何控制MySQL,让MySQL在Commit事务时率先将redo log持久化呢?

MySQL提供了参数innodb_flush_log_at_trx_commit

该参数有几个选项:0、1、2

想要保证ACID四大特性推荐设置为1:表示当你commit时,MySQL必须将rodolog-buffer中的数据刷新进磁盘中。确保只要commit是成功的,磁盘上就得有对应的rodolog日志。这也是最安全的情况。

设置为0:每秒写一次日志并将其刷新到磁盘。

设置为2:表示当你commit时,将redolog-buffer中的数据刷新进OS Cache中,然后依托于操作系统每秒刷新一次的机制将数据同步到磁盘中,也存在丢失的风险。

推荐参数

始终设置 innodb_flush_log_at_trx_commit=1

如果启用了二进制日志记录,请设置 sync_binlog=1。

这也是大家常说的双1设置。前者保证redolog的不丢失、后者保证了binlog的不丢失。

参考: 《谈谈传说中的redo log日志是什么?有啥用?》



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3