MySQL 为什么需要 redo log?__江南一点雨的博客-程序员信息网_为什么需要redolog

技术标签: dba  mysql  关于Spring Boot  数据库  


今天想和大家聊一聊 MySQL 中的 redo log,其实最早我是想聊两阶段提交的,后来想想可能有小伙伴还不了解 binlog,所以就先整了一篇 binlog:

binlog 大家懂了之后,接下来还差个 redo log,redo log 大家也懂了,那么再讲两阶段提交相信小伙伴们就很容易懂了,咱们一步一步来。

1. 谁的 redo log

学习 redo log,我觉得首先要搞明白一个问题,就是是谁的 redo log?

我们知道,MySQL 架构整体上分为两层:Server 层和存储引擎层,如下图:

前面松哥文章+视频跟大家聊的 binlog,是 MySQL 自己提供的 binlog,而 redo log 则不是 MySQL 提供的,而是存储引擎 InnoDB 自己提供的。所以在 MySQL 中就存在两类日志 binlog 和 redo log,存在两类日志既有历史原因(InnoDB 最早不是 MySQL 官方存储引擎)也有技术原因,这个咱们以后再细聊。

先把这个问题搞清楚,后面很多地方就容易懂了。

2. buffer pool

在正式介绍 redo log 之前,还有一个 buffer pool 需要大家了解。

小伙伴们知道,InnoDB 引擎存储数据的时候,是以页为单位的,每个数据页的大小默认是 16KB,我们可以通过如下命令来查看页的大小:

16384/1024=16

刚好是 16KB。

计算机在存储数据的时候,最小存储单元是扇区,一个扇区的大小是 512 字节,而文件系统(例如 XFS/EXT4)最小单元是块,一个块的大小是 4KB,也就是四个块组成一个 InnoDB 中的页。我们在 MySQL 中针对数据库的增删改查操作,都是操作数据页,说白了,就是操作磁盘。

但是大家想想,如果每一次操作都操作磁盘,那么就会产生海量的磁盘 IO 操作,如果是传统的机械硬盘,还会涉及到很多随机 IO 操作,效率低的令人发指。这严重影响了 MySQL 的性能。

为了解决这一问题,MySQL 引入了 buffer pool,也就是我们常说的缓冲池。

buffer pool 的主要作用就是缓存索引和表数据,以避免每一次操作都要进行磁盘 IO,通过 buffer pool 可以提高数据的访问速度。

通过如下命令可以查看 buffer pool 的默认大小:

134217728/1024/1024=128

默认大小是 128MB,因为松哥这里的 MySQL 是安装在 Docker 中,所以这个分配的小一些。一般来说,如果一个服务器只是运行了一个 MySQL 服务,我们可以设置 buffer pool 的大小为服务器内存大小的 75%~80%。

3. change buffer

在正式介绍 redo log 之前,还有一个 change buffer 需要大家了解。

前面我们说的 buffer pool 虽然提高了访问速度,但是增删改的效率并没有因此提升,当涉及到增删改的时候,还是需要磁盘 IO,那么效率一样低的令人发指。

为了解决这个问题,MySQL 中引入了 change buffer。change buffer 以前并不叫这个名字,以前叫 insert buffer,即只针对 insert 操作有效,现在改名叫 change buffer 了,不仅仅针对 insert 有效,对 delete 和 update 操作也是有效的,change buffer 主要是对非唯一的索引有效,如果字段是唯一性索引,那么更新的时候要去检查唯一性,依然无法避免磁盘 IO。

change buffer 就是说,当我们需要更改数据库中的数据的时候,我们把更改记录到内存中,等到将来数据被读取的时候,再将内存中的数据 merge 到 buffer pool 然后返回,此时 buffer pool 中的数据和磁盘中的数据就会有差异,有差异的数据我们称之为脏页,在满足条件的时候(redo log 写满了、内存写满了、其他空闲时候),InnoDB 会把脏页刷新回磁盘。这种方式可以有效降低写操作的磁盘 IO,提升数据库的性能。

通过如下命令我们可以查看 change buffer 的大小以及哪些操作会涉及到 change buffer:

  • innodb_change_buffer_max_size:这个配置表示 change buffer 的大小占整个缓冲池的比例,默认值是 25%,最大值是 50%
  • innodb_change_buffering:这个操作表示哪些写操作会用到 change buffer,默认的 all 表示所有写操作,我们也可以自己设置为 none/inserts/deletes/changes/purges 等。

不过 change buffer 和 buffer pool 都涉及到内存操作,数据不能持久化,那么,当存在脏页的时候,MySQL 如果突然挂了,就有可能造成数据丢失(因为内存中的数据还没写到磁盘上),但是我们在实际使用 MySQL 的时候,其实并不会有这个问题,那么问题是怎么解决的?那就得靠 redo log 了。

4. redo log 的诞生

在正式介绍 redo log 之前,还需要给大家普及一个概念:WAL。

WAL 全称是 Write-Ahead Logging 中文译作预写日志。啥意思呢?就是说 MySQL 的写操作并不是立刻更新到磁盘上,而是先记录在日志上,然后在合适的时间再更新到磁盘上,这样的好处是错开高峰期的磁盘 IO,提高 MySQL 的性能。

配合上前面的 buffer pool 和 change buffer,WAL 就是说在操作 buffer pool 和 change buffer 之前,会先把记录写到 redo log 日志中,然后再去更新 buffer pool 或者 change buffer,这样,即使系统突然崩了,将来也可以通过 redo log 恢复数据。当然,redo log 本身又分为:

  • 日志缓冲(redo log buffer),该部分日志是易失性的。
  • 重做日志(redo log file),这是磁盘上的日志文件,该部分日志是持久的。

那有人说,写 redo log 不就是磁盘 IO 吗?而写数据到磁盘也是磁盘 IO,既然都是磁盘 IO,那干嘛不把直接把数据写到磁盘呢?还费这事!

此言差矣。

写 redo log 跟写数据有一个很大的差异,那就是 redo log 是顺序 IO,而写数据涉及到随机 IO,写数据需要寻址,找到对应的位置,然后更新/添加/删除,而写 redo log 则是在一个固定的位置循环写入,是顺序 IO,所以速度要高于写数据。

如前文所说,redo log 涉及到两个东西:redo log buffer 和 redo log file,这两个东西我们分别来介绍。

4.1 redo log buffer

先来说 redo log buffer。

我们说数据的变化先写入 redo log 中,并不是上来就写磁盘,也是先写到内存中,即 redo log buffer,在时机成熟时,再写入磁盘,也就是 redo log file。

我们先来看看 redo log buffer 有多大:

16777216 ÷ 1024 ÷ 1024 = 16MB

可以看到,这个 redo log buffer 大小刚好是 16MB,如果你觉得这个值有点小,也可以自行修改其大小。

数据的变更都会首先记录在这块内存中。小伙伴们知道,MySQL 的增删改,如果我们没有显式的开启事务,MySQL 内部也是有一个事务存在的,当内部这个事务 commit 的时候,redo log buffer 会持久化到磁盘中。

具体来说,有如下几个持久化时机:

  1. innodb_flush_log_at_trx_commit

通过 innodb_flush_log_at_trx_commit 参数来控制持久化时机,该参数默认值为 1,如下图:

当然开发者可根据自己的实际需求修改该参数。该参数有三种取值,含义分别如下:

  • 0:每秒一次,将 redo log buffer 中的数据刷新到磁盘中。
  • 1:每次 commit 时,将 redo log buffer 中的数据刷新到磁盘中,即只要 commit 成功,磁盘上就有对应的 redo log 日志,这是最安全的情况,也是推荐使用的参数
  • 2:每次 commit 时,将 redo log buffer 中的数据刷新到操作系统缓存中,操作系统缓存中的数据每秒刷新一次,会持久化到磁盘中。

这是第一种 redo log buffer 持久化的时机。

  1. 当 redo log buffer 的使用量达到 innodb_log_buffer_size 的一半时,将其写入磁盘成为 redo log file。
  2. MySQL 关闭时,将 redo log buffer 写入磁盘成为 redo log file。

那如果 redo log buffer 中的数据还没有磁盘,MySQL 就挂了该怎么办?没写入磁盘,说明你还没 commit,既然没 commit,那就数据修改操作都还没有完成,那只能丢了就丢了,如果已经 commit 了,那么数据就会持久化到 redo log file 中,此时即使 MySQL 挂了,将来 MySQL 重启恢复了,数据也是可以被恢复的。具体的恢复逻辑,就涉及到两阶段提交了,这个松哥在后面的文章中再和大家详细介绍。

4.2 redo log 落盘

还有一个需要大家注意的问题就是 redo log 落盘,落盘的数据从哪里来?是从 redo log 日志中来还是从 buffer pool 中来?

在前面的文章中我们说过:binlog 是一种逻辑日志,他里边所记录的是一条 SQL 语句的原始逻辑,例如给某一个字段 +1,这区别于 redo log 的物理日志,物理日志记录的是在某个数据页上做了什么修改。

由于 redo log 并没有记录数据页的完整数据,所以正常的落盘其实用不到 redo log,数据落盘的时机到了时,直接拿着将脏页(buffer pool)持久化到磁盘中即可。

好啦,今天就和大家分享这么多,redo log 还有一些内容,我们在后面的文章中再继续聊~

参考资料:

  • https://www.cnblogs.com/ZhuChangwu/p/14096575.html
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/u012702547/article/details/123505499

智能推荐

2022-2028全球在线托福平台行业调研及趋势分析报告_恒州诚思的博客-程序员信息网

据恒州诚思调研统计,2021年全球在线托福平台市场规模约 亿元,2017-2021年年复合增长率CAGR约为 %,预计未来将持续保持平稳增长的态势,到2028年市场规模将接近 亿元,未来六年CAGR为 %。本文调研和分析全球在线托福平台发展现状及未来趋势,核心内容如下:(1)全球市场总体规模,按收入进行了统计分析,历史数据2017-2021年,预测数据2022至2028年。(2)全球市场竞争格局,全球范围内主要生产商在线托福平台及市场份额,数据2017-2021年。(3)中国市场竞争格局,中国市场主

带你一周hold住HTML+CSS系列视频及相关文档_chunzhen3605的博客-程序员信息网

HTML是一种基本的WEB网页设计语言,HTML是一个基于XML的置标语言,看起来与HTML有 些相象,只有一些小的但重要的区,本质上说,HTML是一个过渡技术,结合了部分XML 的强大功能及大多数HTML的简单特性。本文档用通俗易懂的语言系统的讲解了CSS在开发网页时的应用,从最基础到最后怎...

计算机专业第五轮学科评估排名,第五轮学科评估排行榜-第二轮双一流淘汰名单预测..._这样哈的博客-程序员信息网

选择科目测一测我能上哪些大学选择科目领取你的专属报告>选择省份关闭请选择科目确定v>最近,教育部正式发布了《第五轮学科评估工作方案》,对第五轮学科评估中的一些工作进行了相关安排。本期,我将为大家带来一份关于第五轮学科评估的排名榜以及预测一下第二轮双一流淘汰名单,全文仅供参考。一、第五轮学科评估排行榜截至目前,教育部学位与研究生教育发展中心已经印发了《关于公布的通知》,第五轮学科评估即将...

用 100 行代码手写一个 Hystrix_小眼睛聊技术的博客-程序员信息网

熔断与降级离小眼睛家不远的地方,开了一个熟食店。店内有两个窗口总能排起长龙,一个窗口是选好的凉菜让师傅调味,一个窗口是买到的扒鸡让胖师傅现场脱骨。顾客的正常的流程,大致是这个样子滴:炎炎夏日,邀三五好友,喝杯啤酒吹吹牛皮,岂不美哉。可能大家跟小眼睛想法一致,小店的生意日渐火爆。这天,小眼睛选好了菜,付了钱,正准备排队让师傅调口味、脱骨。目测两个窗口排队时间不会少于 20 分钟,加之几个朋友轮番催促,果断放弃,拎着菜直接回家。于是我到流程就变成了:当下游的服务(调料...

gyp ERR! configure error gyp ERR! stack Error: Can‘t find Python executable “python“_单身girl的博客-程序员信息网

报错内容 :第一个报错gyp ERR! configure errorgyp ERR! stack Error: Can’t find Python executable “python”, you can set the PYTHON env variable.gyp ERR! stack at PythonFinder.failNoPython报错内容第二个Starting installation…Please restart this script from an admini

python 转码报错decoding Unicode is not supported_Java不是C的博客-程序员信息网

PythonUnicodeDecodeError: 'ascii' codec can't decode byte 0xe6 in position 937: ordinal not in range(128) Logged from file scraper.py,u = unicode("辣", "utf-8")unicode(u'foo', 'utf-8')以上这种转

随便推点

【论文笔记】QBSUM: 基于查找的文本摘要数据集_啦啦伟vv的博客-程序员信息网_文本摘要数据集

QBSUM: a Large-Scale Query-Based Document Summarization Dataset fromReal-world Applications基于查询的文档摘要旨在提取或生成直接回答或与搜索查询相关的文档的摘要。这是一项重要的技术,可以有益于各种应用程序,例如搜索引擎、文档级机器阅读理解和聊天机器人。目前,为基于查询的摘要设计的数据集数量不足,现有数据集的规模和质量也有限。此外,据我们所知,没有公开可用的基于中文查询的文档摘要数据集。在本文中,我们提出了 QBSUM

视频关键帧提取_天地一扁舟的博客-程序员信息网

引子:最近在帮老师做项目,涉及到视频和图形图像处理这方面的内容。我觉得作为一个程序猿,不仅仅着眼于小的细节,对自己整体方向的把握也需要一个比较好的规划,我们的目标是:当一个好的程序猿。项目整体的架构是:ubuntu+python+django+apache+html+mongodb。当时卡在视频关键帧提取这一块好长时间,也没人指导我自己该怎么做,谁让我们程序猿自学能力要强呢?网

人在校园的日子 _wjp16351的博客-程序员信息网

有次期考,考完某门课程后回到宿舍,大伙都兴高采烈的在交流答案,这时 老大冒出一句:完拉~!我小纸条夹在试卷里面交上去了!!众人皆倒。     结果老大重修……     这是俺大三时的真实故事。     当年大学刚报到的时候,宿舍有一哥们A毛发特旺盛,留络腮胡子。等我们看 了一周看习惯了,辅导员看不下去强令他刮了。当天他回去之后坐在床上正照镜子感 叹,另外一哥们B回来盯着看了半天,忽然冲出去,正在我

Python进阶之atexit模块使用_公众号菜鸟童靴的博客-程序员信息网_atexit python

微信搜索“菜鸟童靴”,选择“关注公众号”我们一起开启Python进阶之旅!如何让Python在退出时强制运行一段代码,说起这个需求,我们就不得不说Python atexit模块了:退出处理器 atexit 模块定义了清理函数的注册和反注册函数. 被注册的函数会在解释器正常终止时执行. atexit 会按照注册顺序的逆序执行; 如果你注册了 A, B 和 C, 那么在解释器终止时会依序执行 C, B, A.看完这段介绍,有点类似栈的原理,后进先出1、举个例子说明...

实战PyQt5: 050-选项卡控件QTabWidget_seniorwizard的博客-程序员信息网_pyqt5 tabwidget

QTabWidget简介在GUI应用软件中,多页面的切换的使用范围十分广泛,在操作过程中,用户使用鼠标点击不同的标题栏就可以方便展示不同页面的内容,众多界面共用一块显示区域,在有限的就显示区域中可以很方便地位用户显示更多的信息。Qt为多页面切换的实现提供了一个专门的控件QTabWidget, 它可以实现在同一区域中自由切换不同页面的内容,该控件是一个容器类控件,并提供友好的页面切换方式。QTabWidget常用方法有:addTab(): 添加一个标签; insertTab(): 在指定位置

计算机网络——Socket实验1_上山打老虎D的博客-程序员信息网_socket实验

一、实验目的学习网络编程基本概念、InetAddress的应用、URL的应用、URLConnection的应用二、实验内容InetAddress类和URLConnection类的使用三、实验环境使用Windows操作系统;Internet连接 Eclipse+Java开发环境四、实验步骤1 InetAddress类1.1 InetAddress类的简介Internet上的主机有两种表示地址的方式:域名和IP地址。有时候需要通过域名来查找它对应的IP地址,有时候

推荐文章

热门文章

相关标签