白日梦感觉作为研发同学的你可能真的没必要了解摸清楚关于redo log的这些机制。专注于写SQL完全能hold住日常的工作。

但是呢,感觉最好还是要了解一下,因为一般面试官都知道redo log是咋回事,其次是大家茶前饭后唠嗑时也能多少能插几句嘴

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

一、引出 redo log 的作用

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

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

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

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

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

二、思考一个问题:

你可以结合上图然后想一下:万一脏页还没来得及刷新到磁盘中,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 何时写入磁盘呢?

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

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

七、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,耗子尾汁! (已发布)

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

谈谈传说中的redo log是什么?有啥用?的更多相关文章

  1. [转]undo log与redo log原理分析

    数据库通常借助日志来实现事务,常见的有undo log.redo log,undo/redo log都能保证事务特性,这里主要是原子性和持久性,即事务相关的操作,要么全做,要么不做,并且修改的数据能得 ...

  2. Oracle Redo Log 机制 小结(转载)

    Oracle 的Redo 机制DB的一个重要机制,理解这个机制对DBA来说也是非常重要,之前的Blog里也林林散散的写了一些,前些日子看老白日记里也有说明,所以结合老白日记里的内容,对oracle 的 ...

  3. 关于MySQL redo log,挖些坑,慢慢填

    1. 为什么可以设置为多个redo log ? (innodb_log_files_in_group,默认值和推荐值都是2,我们线上设的统一为4): 2. 什么条件下会触发刷脏?除了master_th ...

  4. Oracle Dataguard Standby Redo Log的两个实验

    在Data Guard环境中,Standby Redo Log是一个比较特殊的日志类型.从最新的DG安装指导中,都推荐在Primary和Standby端,都配置Standby Redo Log. 简单 ...

  5. [置顶] How to dump redo log entry?

    1.转储针对特定数据块(4号文件的第10-20号数据块)修改的 redo entry select file#,name,blocks from v$datafile;      FILE# NAME ...

  6. redo log write和flush

    http://bbs.chinaunix.net/thread-1753130-1-1.html 在事务提交时innobase会调用ha_innodb.cc 中的innobase_commit,而in ...

  7. 14.7.2 Changing the Number or Size of InnoDB Redo Log Files 改变InnoDB Redo Log Files的数量和大小

    14.7.2 Changing the Number or Size of InnoDB Redo Log Files 改变InnoDB Redo Log Files的数量和大小 改变 InnoDB ...

  8. 14.4.4 Redo Log Buffer

    14.4.4 Redo Log Buffer redo log buffer 是内存区域持有数据被写入到redo log. Redo log buffer size 是通过 innodb_log_bu ...

  9. mysql redo log

    mysql> show variables like '%innodb_log_file_size%'; +----------------------+-----------+ | Varia ...

随机推荐

  1. 21迁移python项目到另一台电脑

    在虚拟环境中将第三方库打包到一个TXT文件:1,在项目保存在项目所在目录,文件可以自定义.pip freeze> requirements.txt命令2,将requirements.txt放入另 ...

  2. 它是世界上最好的语言,吊打PHP那种

    Scratch Scratch是麻省理工媒体实验室终身幼稚园组开发的一套电脑程序开发平台,旨在让程序设计语言初学者不需先学习语言语法便能设计产品.开发者期望通过学习Scratch,启发和激励用户在愉快 ...

  3. peterson算法(软件互斥 转)

    1. 背景        首先,看个例子,进程P1,P2共用一个变量COUNT,初始值为0                                                 因为P1,P ...

  4. java服务器部署开源项目(若依)

    1准备工作 (1)阿里云 centos_8_0_x64_20G_alibase_20200218.vhd [root@iZ2zeeqw5fxmm9zagf439aZ ~]# cat /etc/redh ...

  5. hibernate 基础知识

    1.hibernate的配置文件,一般放在classpath的根目录下,默认命名为hibernate.cfg.xml,代码例子如下: <!DOCTYPE hibernate-configurat ...

  6. java1.8安装及环境变量配置

    一.前言 虽然jdk1.9版本已经问世,但是许多其他的配套设施并不一定支持jdk1.9版本,所以这里仅带领你配置jdk1.8.而jdk1.9的操作也几乎是相同的. 本教程适用于windows10 64 ...

  7. 什么是低代码(Low-Code)?

    阿里云 云原生应用研发平台EMAS 彭群(楚衡) 一.前言 如果选择用一个关键词来代表即将过去的2020年,我相信所有人都会认同是"新冠".疫情来得太快就像龙卷风,短短数月就阻断了 ...

  8. diamond收集插件的自定义

    diamond是与graphite配合使用的一个数据收集的软件,关于这个配置的资料很多,使用起来也比较简单,详细的安装和配置会在后面的关于整套监控系统的文章里面写到,本篇是专门讲解怎么自定义这个数据收 ...

  9. [LeetCode题解]92. 反转链表 II | 一次遍历 + 反转

    解题思路 将链表分为三部分:[0, m).[m, n].(n, L],其中 L 为链表长度. 第一步:使用虚拟头节点 dummy,用于将 head 也能参与操作: 第二步:找到第 m-1 节点(fir ...

  10. 实验吧[WEB]——程序逻辑问题

    拿到题 通过查看网页源代码发现index.txt 通过index.txt我们获得了后端的源代码 我们可以通过我画出来的这两个重要的信息得知 第一个sql查询语句没有任何过滤说明存在SQL注入漏洞. 第 ...