凭什么让日志先写?

运维 数据库运维
为了工作更好做,你会有几个选择,提前打印个名单,一个个来领,领的人在名单上打勾,东西拿走。或者大家都来拿,你看一眼,记在脑海里,但可能中途打个岔就记错了。也可以记住是谁,找个纸记下来,每次记一下或者隔一会记几下。

[[338681]]

 在生活中,你一定有过类似这样的经历:

比如部门发礼品、或者说学校发课本。如果在发放的时候,大家一窝蜂的涌了过来,毕竟双拳双敌四手,渐渐你就招架不过来。

为了工作更好做,你会有几个选择,提前打印个名单,一个个来领,领的人在名单上打勾,东西拿走。或者大家都来拿,你看一眼,记在脑海里,但可能中途打个岔就记错了。也可以记住是谁,找个纸记下来,每次记一下或者隔一会记几下。

对比上面的场景,你没有发现,不同的方式,效率上也存在的差别。比如在名单上找到打勾,那就会完全串行,每个人来都得在定位到自己那条信息上,找的过程费时间。

找一张纸,每隔一段时间记一次,这样效率也还挺高,问题就在于别人打岔的频率。

在计算机科学领域也存在这样的时候,比如我们常用的数据库系统里。数据库为了不喝娃哈哈AD钙奶,就能保证ACID中的A和D,使用了一种被称做「WAL」的机制。全称是write-ahead logging。数据库中所有的变更,会先写到日志里,最后才会写到持久存储的数据文件中。像MySQL 里的 redo log 和undo log 就是这种机制。

像你在纸上记录一样,一直不停的向后写,顺序写,速度就会快,时不时的回过头去检查一下,改一下速度就降下来了。

如果大量记录到白纸上的内容,没有及时的汇总记录到一个表格上,那等最后全部汇总也比较费力气。就像数据库里一直写WAL之后就应用到内存数据修改,速度很快,但如果出现故障的时候,就需要重新回放大量的redo log,恢复时间也无法接受。

就像行政急着要结果的时候,你才开始「回放」白纸上的内容,就会慢很多。如果是在发放的过程中,可以过一段时间汇总一下,然后在白纸上加个「标记」,用于一会提示自己上次算到什么位置了。这种就是数据库里的 checkpoint,下次恢复的时候,就直接从checkpoint 开始向后恢复就行,前面的已经持久化到了磁盘,不用再费事了。

此外,计算机里,许多时候,都是一个根据自己的场景权衡的过程。比如对于使用WAL的时候,MySQL 提供了不同的配置来支持什么时机,多长时间将 log 应用到数据文件,毕竟log 写到磁盘也还是要花点儿时间的。每次都刷盘,会影响效率,但间隔时间太长,就会在机器故障的时候丢失数据。

MySQL 默认将log 刷到磁盘的时机有三个:

  • 提交一个事务的时候
  • 固定大小的 log buffer 满了的时候
  • 无论 log buffer 是否满,每秒会刷一次

redo log 写磁盘的过程

redo log buffer和page cache都是在内存中,所以写入这两者都比较快,而fsync则需要消耗磁盘IO。Mysql的后台每隔1秒也会自动将redo log buffer中的内容刷到磁盘中去。

借用MySQL 官方博客的几张图来说明下

那有了redo log,就保证了故障时安全了吗?是的。

机器在故障的时候,内存中包含数据的内容,也就是所谓的「脏页」一般就会丢了,怎么样恢复丢失的数据呢?咱们前面看到,redo log 先刷盘,之后真正的数据库变更才刷盘,所以我们丢失的数据已经保存在磁盘中的redo log里了。重放redolog 就可以。但这里有例外的情况是MySQL 里包含一个 innodb_flush_log_at_trx_commit 的配置,默认是1,即严格的D,非1的情况下会丢失redo log buffer和page cache中的数据。

本文转载自微信公众号「 Tomcat那些事儿」,可以通过以下二维码关注。转载本文请联系 Tomcat那些事儿公众号。

 

责任编辑:武晓燕 来源: Tomcat那些事儿
相关推荐

2023-09-26 07:22:20

2009-08-11 08:54:53

用户升级Windows 7

2020-09-07 10:23:01

MySQL索引查询

2017-06-06 16:30:55

戴尔交付保障

2021-09-24 18:37:33

华为

2021-03-16 10:07:51

自动驾驶特斯拉人工智能

2018-09-07 18:56:03

2020-10-28 08:32:18

EDRNTAXDR

2019-09-23 13:45:48

2015-07-02 11:46:21

亚马逊云计算估值

2017-05-10 11:30:28

人工智能

2017-09-04 13:02:00

程序员

2013-05-16 09:58:01

写代码创业想法创业者

2021-10-21 11:45:00

SD-WAN

2016-01-04 11:39:15

OpenStack初创企业开源云市场

2012-07-13 09:02:07

2011-02-24 09:30:56

VMware微软Hyper-V

2021-08-30 10:49:39

Go语言编译器

2021-03-01 08:57:41

CTO代码架构师

2014-06-20 14:27:49

盈世Coremail电子邮箱
点赞
收藏

51CTO技术栈公众号