深入浅出InnoDB MLOG CHECKPOINT

提示:公众号展示代码会自动折行,建议横屏阅读

1 MLOG CHECKPOINT是什么

在MySQL 5.7存储引擎InnoDB崩溃恢复中,我们一定看到过MLOG_CHECKPOIN的身影。从上一个检查点(LOG CHECKPOINT)开始,进行第一次redo日志扫描(参考函数recv_group_scan_log_recs() ),就是要找到MLOG_CHECKPOINT。那么MLOG_CHECKPOINT是用来做什么的?

大家都知道在InnoDB恢复的过程,是先应用redo日志,再执行undo操作。Redo日志从日志文件中读取之后,会按照(space_id, page_no)存入到哈希表中,然后再批量地把日志应用到数据页中。而数据页的读取需要根据space_id来打开对应的数据文件。为此我们写入如下以MLOG_FILE开头的类型日志来记录文件操作:

1) MLOG_FILE_CREATE2:文件创建时写入,格式为(type, space_id, first_page_no, flags, path)

2) MLOG_FILE_RENAME2:重命名文件时写入,格式为(type, space_id, first_page_no, path, newpath)

3) MLOG_FILED_ELETE:文件删除时写入,格式为(type, space_id, first_page_no, path)

4) MLOG_FILE_NAME(MFN):文件在上一个检查点之后第一次被修改时写入,格式为(type, space_id, first_page_no, path)。Space初始的max_lsn为0,在mtr开始的时候,多了一次函数调用:set_named_space()。在mtr提交的时候,检查如果max_lsn为0,则表示该表第一次被修改,写入MLOG_FILE_NAME日志。同时,修改max_lsn为当前日志系统的lsn。

我们有了这些对应的日志记录,因此在恢复时,只需要扫描一遍日志文件,就可以建立起space id到文件路径的的映射。这里存在一个问题,当系统做检查点的时候,并不能保证,所有修改的数据页对应的MLOG_FILE_NAME日志记录在检查点之后都存在。也就是说检查点可能正好位于某个数据文件对应的MLOG_FILE_NAME日志之后,在该数据文件对应的数据页修改日志记录之前。

如上图所示,检查点-1之后,space_id为100第一次修改,记录了MFN(MLOG_FILE_NAME)日志。新生成的检查点-2之后,有该文件的页面修改日志。如果系统恢复从检查点-2开始,则没有MLOG_FILE_NAME记录,我们就无从得到该数据文件对应的文件路径,对应的数据页日志记录就无法正常应用。

为了弥补这种缺失MLOG_FILE_NAME记录的情况,MLOG_CHECKPOINT应运而生。其基本原理是补充写入MLOG_FILE_NAME,并记录MLOG_CHECKPOINT标记。如下图所示:

在系统做检查点时(参见函数log_checkpoint()),对当前活动的所有数据文件做一个检查点(参见函数fil_names_clear())。扫描所有内存中的space,如果max_lsn大于检查点lsn,那么再次写入对应的MLOG_FILE_NAME日志,并重置max_lsn为0。当这些日志写完之后,写入MLOG_CHECKPOINT,即表示补充的MLOG_FILE_NAME日志结束。因此当系统恢复时,扫描碰到MLOG_CHECKPOINT日志,则意味着,在它之前,检查点之后的所有日志对应的space映射已经完全建立起来了。在它之后,就不存在MLOG_FILE_NAME记录缺失的情况了。

当映射关系建立起来之后,应用日志之前,要对存在哈希表中的日志记录进行预处理(参见函数recv_init_crash_recovery_spaces())。对于文件是删除状态的日志记录,则可以丢弃;对于文件是缺失状态的日志记录,则可以告警或者报错。

这里还有一点需要指出,从检查点开始日志扫描,有可能会扫描到不止一条MLOG_CHECKPOINT日志。每条MLOG_CHECKPOINT日志都记录了对应的检查点LSN,因此必然能找到起始检查点对应的MLOG_CHECKPOINT日志(参见函数recv_parse_log_recs()和变量recv_sys->mlog_checkpoint_lsn),在它之后,最多可能存在一条MLOG_CHECKPOINT日志,即为下一个未完成的检查点写入的。

上图中,如果从检查点-2开始恢复,MLOG_CHECKPOINT-2和其对应的MLOG_FILE_NAME日志是恢复所必须的。MLOG_CHECKPOINT-1和MLOG_CHECKPOINT-3则不是,但也没有副作用。检查点和MLOG_CHECKPOINT之间相互交错,极大地增加了系统恢复的复杂度。

2 MLOG CHECKPOINT的前世今生

在5.6中,是通过扫描所有数据文件,读取第一个数据页获取ID,以此建立space和文件路径的映射关系。

在5.7中,MLOG_CHECKPOINT是在WL#7142: InnoDB: Simplify tablespace discovery during crash recovery中引入。相对于5.6的方案,好处是,不用扫描额外的数据文件(比如孤儿文件等),另外对于没有对应数据文件的日志是否应该丢弃更准确。但是新的方案也引入了新的问题,比如系统检查点逻辑和恢复逻辑变得更复杂,导致了很多新的bug。系统恢复时重复扫描,也导致恢复时间变长。后一个问题其实可以通过将MLOG_CHECKPOINT写入到单独的日志文件中解决。

为了解决这些问题,8.0抛弃了MLOG_CHECKPOINT解决方案。WL#9499 - InnoDB: Replace MLOG_FILE_NAME with MLOG_FILE_OPEN。在新的解决方案中,space到文件路径的映射关系写入到了两个文件tablespaces.open.1和tablespaces.open.2中,同时支持--innodb-scan-directories进行数据文件扫描(如5.6的方式)。新增的两个文件也类似于记录补偿的文件映射补偿日志。笔者当时作为WL#9499的代码审查人之一,深切感受到要把这个看似简单的功能写的稳定可靠,的确要耗费不少心血。

那么除了以上三种方案之外,是否还有其他选择?当然有。通过InnoDB数据字典里space和datafile系统表,就可以建立space到文件的完整映射关系。但是这种方案更加复杂:我们需要在系统恢复之前,先恢复数据字典表。为了先恢复字典表,则需要先扫描日志文件,获取数据字典表的日志信息,优先应用,然后还要进行相应的undo操作。由于字典表的undo记录可能和数据的undo记录在同一事务中,又给字典表单独undo增加了难度。不管是从性能和复杂度来说,都未必比前面三种更优。

综上所述,MLOG_CHECKPOINT已经完成了其在MySQL版本迭代中的历史使命。相比较三种解决方案,5.6的解决方案更简单更可靠。8.0则对5.6和5.7的解决方案进行了综合,也不失为一个好的选择。

参考文档:WL#7142: InnoDB: Simplify tablespace discovery during crash recovery


腾讯数据库技术团队对内支持QQ空间、微信红包、腾讯广告、腾讯音乐、腾讯新闻等公司自研业务,对外在腾讯云上支持TencentDB相关产品,如CynosDB、CDB、CTSDB、CMongo等。腾讯数据库技术团队专注于持续优化数据库内核和架构能力,提升数据库性能和稳定性,为腾讯自研业务和腾讯云客户提供“省心、放心”的数据库服务。此公众号和广大数据库技术爱好者一起,推广和分享数据库领域专业知识,希望对大家有所帮助

本文分享自微信公众号 - 腾讯数据库技术(gh_83eebc796d5d)

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-09-14

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏软件开发-青出于蓝

Sqoop导入数据之提供密码别名

    最近遇到sqoop密码导入的问题,记录下。Sqoop从关系型数据库导入到hdfs中时,需要关系型数据库的密码,但是密码明文展示不安全,所以在hadoop...

10820
来自专栏运维经验分享

mongodb.conf配置文件详解 

启动MongoDB有2种方式,一是直接指定配置参数,二是指定配置文件。这里先介绍配置文件,启动方式如下:

15620
来自专栏架构专题

这句简单的sql,如何加索引?颠覆了我多年的认知

不啰嗦,直接入正题。问题是这样的。请问下面的sql语句,要想加快查询速度,该怎么创建索引?以下,以mysql数据库为准。

10440
来自专栏热爱IT

Elasticsearch数据库

1、什么是Elasticsearch 1、概念以及特点          1、Elasticsearch和MongoDB/Redis/Memcache一样,...

9020
来自专栏运维经验分享

mongodb的internalQueryExecMaxBlockingSortBytes异常修复

查询该错误,未找到具体原因。然后在mongodb\cursor.js 854行,增加打印result。得到具体错误信息如下: Overflow sort st...

16130
来自专栏腾讯云TVP

5G风起,未来数据库有哪些关键词?

在自己工作的领域中,发现快乐是我坚持做技术的动力。而技术域其实就是一个画圆的过程,当你发现你的圈圈画得越大,需要求知的东西也就越多。每天必须保持一种持续学习,和...

2.1K3750
来自专栏业余草

微服务不是架构演变的终点!

本文将介绍微服务架构和相关的组件,介绍他们是什么以及为什么要使用微服务架构和这些组件。本文侧重于简明地表达微服务架构的全局图景,因此不会涉及具体如何使用组件等细...

56350
来自专栏金融级分布式数据库TDSQL

现场直击 | 腾讯TDSQL带你走进VLDB 2019

VLDB 2019(Very Large Data Bases)于2019.8.26 – 2019.8.30在洛杉矶召开,腾讯TDSQL分布式数据库团队带来现场...

752320
来自专栏运维经验分享

技术分享 | MongoDB 一次排序超过内存限制的排查 setParameter:

某次在客户现场处理一起APP业务中页面访问异常的问题,该页面直接是返回一行行硕大的报错代码,错误大概如下所示:

18430
来自专栏生信宝典

深入对比数据科学工具箱:Python和R之争

在真实的数据科学世界里,我们会有两个极端,一个是业务,一个是工程。偏向业务的数据科学被称为数据分析(Data Analysis),也就是A型数据科学。偏向工程的...

15940

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励