前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深入浅出InnoDB MLOG CHECKPOINT

深入浅出InnoDB MLOG CHECKPOINT

作者头像
腾讯数据库技术
发布2019-09-16 11:11:00
1.9K0
发布2019-09-16 11:11:00
举报

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

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等。腾讯数据库技术团队专注于持续优化数据库内核和架构能力,提升数据库性能和稳定性,为腾讯自研业务和腾讯云客户提供“省心、放心”的数据库服务。此公众号和广大数据库技术爱好者一起,推广和分享数据库领域专业知识,希望对大家有所帮助

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-09-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 腾讯数据库技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 提示:公众号展示代码会自动折行,建议横屏阅读
  • 1 MLOG CHECKPOINT是什么
  • 2 MLOG CHECKPOINT的前世今生
相关产品与服务
云数据库 SQL Server
腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档