《MySQL实战45讲》读后感 02|日志系统:一条SQL更新语句如何执行的

说明:本来是打算写一些个人心得的,后来发现文中大量高质量的QA都非常精典,所以粘过来了,如有侵权请联系我删除哈

收获到的知识点

  • 当一个表有更新的时候,跟这个表相关的所有缓存都会失效,所以这条语句就会把表T上所有缓存结果清空。(MySQL8.*版本已去掉了查询缓存模块)
  • MySQL中的2种日志类型分别是 redo log(重做日志) 和 binlog(归档日志)

之所以存在这2种类型的日志(redo log、binlog),是由于最开始MySQL里并没有InnoDB引擎的,MySQL自带的引擎是MyISAM,但是MyISAM是不支持事务的,也没有crash-safe的能力,binlog只能用于归档,而InnoDB是另一个公司(名叫芬兰公司Heikki)以插件形式引入MySQL的(集成版本从MySQL4.0开始),

之间的差异点

  • redo log是InnoDB引擎特有的日志,其它引擎不会使用redo log,binlog是MySQL的Server层实现的,其它引擎都可以使用
  • redo log(重做日志) 也叫物理日志,记录的是“在某个数据页做了什么修改”; binlog(归档日志)也叫逻辑日志,记录的是这个语句的原始逻辑
  • redo log(重做日志) 是循环写的,总大小是固定的,所以每次都会擦除重写;binlog(归档日志)是追加写入的,“追加写”是指 binlog 文件写到一定大小后会切换到下一个,并不会覆盖以前的日志。

既然InnoDB引擎这2种日志都会写入,那么当一sql(比如update)执行时,redo log(重做日志) 和 binlog(归档日志)他们的写入顺序是怎么样呢

在这里插入图片描述

从上面的流程中可以看到redo log(重做日志)的写入拆成了2个步骤:prepare和commit, 这就是“两阶段提交”

为什么要拆成“两阶段提交”

作者已经解释了很清楚了,无论是先直接写入哪一个到磁盘,都存在数据不一致的风险,这里就不展开讨论了,这里想和大家聊的是难道拆成“两阶段提交”都可以解决这个问题吗?

答案是肯定的。看大师精典回复

Q:老师,我想问下如果提交事务的时候正好重启那么redo log和binlog会怎么处理?此时redo log处于prepare阶段,如果不接受这条log,但是binlog已经接受,还是说binlog会去检查redo log的状态,状态为prepare的不会恢复?2018-11-16
A:作者回复
好问题👍🏿表示中间那段你都听明白了👍🏿

Binlog如果已经接受,那么redolog是prepare, binlog已经完整了对吧,这时候崩溃恢复过程会认可这个事务,提交掉。 (你可以分析下这种情况下,是否符合我们要达到的“用binlog恢复的库跟原库逻辑相同” 这个要求)

看来MySQL Server每次启动都会去检查binlog的,如果没有出现异常的话,正常执行是要等到redo log commit才算完,但是崩溃恢复过程的话,可以接受“redo log prepeare & binlog完整写入”的数据

InnoDB引擎需要多写一份redo log产生的磁盘IO性能开销,怎么做到优化呢

看大师精典回复吧

Q: 老师,我这想请教两个问题:
1.写redo日志也是写io(我理解也是外部存储)。同样耗费性能。怎么能做到优化呢
2.数据库只有redo commit 之后才会真正提交到数据库吗
2018-11-16
A: 作者回复

  1. Redolog是顺序写,并且可以组提交,还有别的一些优化,收益最大是是这两个因素;

2.是这样,正常执行是要commit 才算完,但是崩溃恢复过程的话,可以接受“redolog prepare 并且binlog完整” 的情况
2018-11-16

前一个问题中老师提到的“binlog完整”,怎么才算完整

Q:老师,有个疑问,怎么知道binlog是完整的?这个想不通
2018-11-16
A:作者回复
一个事务的完整binlog是有固定格式,也就是说有固定结尾的😄

关于文中提到的WAL,先写日志再写磁盘问题,刚刚update立即select结果能正确吗

Q: 老师,您好。您说MySQL 使用WAL,先写日志再写磁盘。请教一个问题,
执行一条Update 语句后,马上又执行一条 select * from table limit 10。
如果刚刚update的记录,还没持久化到磁盘中,而偏偏这个时候的查询条件,又包含了刚刚update的记录。
那么这个时候,是从日志中获取刚刚update的最新结果,还是说,先把日志中的记录先写磁盘,再返回最新结果?

为什么redo log(重做日志) 也叫物理日志呢

Q: binlog为什么说是逻辑日志呢?它里面有内容也会存储成物理文件,怎么说是逻辑而不是物理
2018-11-16
A:作者回复
这样理解哈。
逻辑日志可以给别的数据库,别的引擎使用,已经大家都讲得通这个“逻辑”;
物理日志就只有“我”自己能用,别人没有共享我的“物理格式”

个人理解

redo log(重做日志)是InnoDB引擎为事务服务的
binlog(归档日志)是用于故障恢复的(比如异常重启、恢复临时库、扩容增加备库)

课堂问题

前面我说到定期全量备份的周期“取决于系统重要性,有的是一天一备,有的是一周一备”。那么在什么场景下,一天一备会比一周一备更有优势呢?或者说,它影响了这个数据库系统的哪个指标?

A: 关于“一天一备会比一周一备更有优势”我谈谈的我观点:
binlog一般情况下是崩溃时用来恢复的,恢复时间越短,对业务的影响越小,一天一备的话只需要利用昨天的备份+今天截止到目前的增量binlog,增量数据相对小一些,恢复的时间自然要高效一些。
反过来说如果一周一备的话,首先binlog需要存储的至少是一周的数据(binlog如果小于一周的话否则故障发生时就无法恢复了)。所以我认为影响到的指标是expire_logs_days(可以通过 show variables like '%expire_logs_days%'来进行查看)

顺便分享一下林奇大师的课程,有兴趣的可以看看

在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章