谈谈传说中的redo log是什么?有啥用?

白日梦感受做为研发同窗的你可能真的不必了解摸清楚关于redo log的这些机制。专一于写SQL彻底能hold住平常的工做。html

可是呢,感受最好仍是要了解一下,由于通常面试官都知道redo log是咋回事,其次是你们茶前饭后唠嗑时也能多少能插几句嘴前端

文章公号 首发!连载中!关注微信公号回复:“抽奖” 还可参加抽📖活动
mysql

1、引出 redo log 的做用

继续咱们的MySQL专题。首先回顾一下前面白日梦同你分享过的知识点。面试

前面咱们一块儿学习了MySQL undo log相关的知识点,看下面这张脑图:sql

磁盘上的数据文件叫表空间文件,表空间有挺多的,好比系统表空间、undo log 表空间、你也可让create出来的每张table都有本身单独的表空间。总之MySQL会将表空间数据页经过磁盘IO加载进缓存页中。数据库

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

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


2、思考一个问题:

你能够结合上图而后想一下:万一脏页还没来得及刷新到磁盘中,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处的数据做了什么修改,这是些都是逻辑上的概念。


3、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。


4、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 什么时候写入磁盘呢?

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

5、redo log的刷盘时机

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

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

MySQL提供了参数innodb_flush_log_at_trx_commit

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

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

  • 设置为0:每秒写一第二天志并将其刷新到磁盘。

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


6、推荐参数

  • 始终设置 innodb_flush_log_at_trx_commit=1

  • 若是启用了二进制日志记录,请设置 sync_binlog=1

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

关于sync_binlog参数,计划在第X、X、篇文章中分享binlog知识点的时候会再说起,欢迎关注!


7、redo log group

redo log group说的是:由N个大小相同的redo log组成一个redo log group。N的值默认为2。

你能够像下面这样查看你的MySQL的redo log group状况。

默认单个redo log文件的大小是48MB。你也能够经过上图中的innndb_log_files_size修改它。

日志文件的总大小(innodb_log_file_size* innodb_log_files_in_group)不能超过略小于512GB的最大值。

例如,一对255 GB的日志文件已达到限制,但没有超过该限制。

一样你能够像下面这样查看磁盘上的 redo log 文件。它们的大小和上图中的innodb_log_file_size相同。

innodb将log buffer中的redo log block刷新到上图中的logfile中时,以追加的方式循环写入。也就是首先在ib_logfile0的尾部追加,写满后再写ib_logfile1。当ib_logfile1写满时,状况一部分ib_logfile0接着追加写。

redo log file的大小对innodb性能影响很是大。一般来讲要设置的足够大,大到可让MySQL支持1小时线上高峰流量的接入而不切换。可是设置的过大,数据恢复的时间比较长。设置太小致使循环切换redo log file。

能聊聊:日志刷盘规则之 check point 和 LSN机制吗?


参考:

https://dev.mysql.com/doc/refman/5.7/en/innodb-redo-log.html

https://dev.mysql.com/doc/refman/5.7/en/replication-solutions-unexpected-replica-halt.html

https://dev.mysql.com/doc/refman/5.7/en/innodb-init-startup-configuration.html

https://dev.mysql.com/doc/refman/5.7/en/innodb-parameters.html#sysvar_innodb_flush_log_at_trx_commit

https://dev.mysql.com/doc/refman/5.7/en/innodb-init-startup-configuration.html


推荐阅读

  1. 你们常说的基数是什么?(已发布)
  2. 讲讲什么是慢查!如何监控?如何排查?(已发布)
  3. 对NotNull字段插入Null值有啥现象?(已发布)
  4. 能谈谈 date、datetime、time、timestamp、year的区别吗?(已发布)
  5. 了解数据库的查询缓存和BufferPool吗?谈谈看!(已发布)
  6. 你知道数据库缓冲池中的LRU-List吗?(已发布)
  7. 谈谈数据库缓冲池中的Free-List?(已发布)
  8. 谈谈数据库缓冲池中的Flush-List?(已发布)
  9. 了解脏页刷回磁盘的时机吗?(已发布)
  10. 用十一张图讲清楚,当你CRUD时BufferPool中发生了什么!以及BufferPool的优化!(已发布)
  11. 据说过表空间没?什么是表空间?什么是数据表?(已发布)
  12. 谈谈MySQL的:数据区、数据段、数据页、数据页究竟长什么样?了解数据页分裂吗?谈谈看!(已发布)
  13. 谈谈MySQL的行记录是什么?长啥样?(已发布)
  14. 了解MySQL的行溢出机制吗?(已发布)
  15. 说说fsync这个系统调用吧! (已发布)
  16. 简述undo log、truncate、以及undo log如何帮你回滚事物! (已发布)
  17. 我劝!这位年轻人不讲MVCC,耗子尾汁! (已发布)


文章公号 首发!连载中!关注微信公号回复:“抽奖” 还可参加抽📖活动

相关文章
相关标签/搜索