MySQL 5.7 :新的日志类型MLOG_FILE_NAME来避免崩溃恢复时扫描全部ibd

前言

对应 Worklog:http://dev.mysql.com/worklog/task/?id=7142

对应change log entry:

Incompatible Change: A new log record type (MLOG_FILE_NAME) is used to identify file-per-table tablespaces that have been modified since the last checkpoint. This enhancement simplifies tablespace discovery during crash recovery and eliminates scans on the file system prior to redo log application. For more information about the benefits of this enhancement, see Tablespace Discovery During Crash Recovery.

This enhancement changes the redo log format, requiring that MySQL be shut down cleanly before upgrading to or downgrading from MySQL 5.7.5.

问题:

改进的主要目的是为了消除在crash recovery时对文件目录的扫描,因为在innodb层无法根据redo log中的space id直接找到对应的文件,因此需要打开每个ibd的第一个page来进行判定。

新的修改简化了上述逻辑,只有在一次checkpoint后被修改了的表才需要被读取,其他的干净的表空间无需扫描。 在WL#7142中也处理了类似RENAME这样的崩溃恢复逻辑,不在本文的讨论范围之内,后续单独开文讨论。

 

更改:

1.REDO LOG类型修改

MLOG_FILE_CREATE2、MLOG_FILE_CREATE:使用MLOG_FILE_NAME来代替

MLOG_FILE_RENAME:使用MLOG_FILE_RENAME2来代替

增加新类型:

MLOG_FILE_RENAME2:(space_id, first_page_number, filename, new_filename)

MLOG_FILE_CREATE:(space_id, name)

MLOG_CHECKPOINT

 

详细见:enum mlog_id_t 枚举类型中关于各个类型的注释

 

2.Mini Transaction事务提交时的修改

 

当需要修改数据页时,在开启一个mini transaction后,需要:

        mtr_start(&mtr);

mtr.set_named_space(index->space);

 

set_named_space 会将当前的space id保存到mtr_t::m_named_space中

 

mtr_commit时,如果对数据做了修改,那么在5.7中分为两步。

入口函数:mtr_t::Command::execute

a.mtr_t::Command::prepare_write()

#根据set_named_space 函数设定的space id,进行判断:

 

        fil_space_t*    space

= is_predefined_tablespace(m_impl->m_named_space)

? NULL

: fil_names_write(m_impl->m_named_space, m_impl->m_mtr);

 

如果是预定义的系统表空间(ibdata, undo space ,tmp space),space = NULL; 否则调用函数 fil_names_write(m_impl->m_named_space, m_impl->m_mtr)写入一个MLOG_FILE_NAME类型的REDO记录;

 

#如果该space是上次CHECKPOINT后第一次被修改(调用 fil_names_dirty(space)),需要append一个1字节的MLOG_MULTI_REC_END类型,因为当前mtr肯定大于1个log 记录了(一个mtr可能包含多个log rec)

 

在函数fil_names_dirty中,会判断space->max_lsn值是否为0,如果为0,表示第一次修改,加入到fil_system->named_spaces链表中;否则,设置space->max_lsn为当前的log_sys->lsn; (后面再说何时reset max_lsn为0)

 

#否则,需要忽略掉在fil_names_write写入的REDO记录。

 

b.mtr_t::Command::finish_write

将redo log从cache写入redo log 公共buffer

 

3. Redo checkpoint

对应函数log_checkpoint

这里会调用函数fil_names_clear,遍历fil_system->named_spaces链表,如果space->max_lsn的值小于当前做checkpoint的LSN(在该LSN之前的脏页已经刷盘),则将其中每个space->max_lsn设置为0,并从链表取出。同时写一个MLOG_FILE_NAME日志(所有named_spaces上的成员)。

然后写一个MLOG_CHECKPOINT日志,参考函数:mtr_t::commit_checkpoint。

 

因此这个mini transaction应该包含fil_system->named_spaces链表上每个成员的MLOG_FILE_NAME日志以及紧随其后的一个MLOG_CHECKPOINT日志

 

4.崩溃恢复

 

在crash recovery时,会有一个内存结构对象来维护space id和表名的映射关系:

typedef std::map<

ulint,

file_name_t,

std::less<ulint>,

ut_allocator<std::pair<const ulint, file_name_t> > >    recv_spaces_t;

static recv_spaces_t    recv_spaces;

 

参考函数:

recv_parse_or_apply_log_rec_body–>fil_name_parse –>fil_name_process

 

 

相关代码:

http://bazaar.launchpad.net/~mysql/mysql-server/5.7/revision/7825

http://bazaar.launchpad.net/~mysql/mysql-server/5.7/revision/7829

http://bazaar.launchpad.net/~mysql/mysql-server/5.7/revision/7888

http://bazaar.launchpad.net/~mysql/mysql-server/5.7/revision/7966

http://bazaar.launchpad.net/~mysql/mysql-server/5.7/revision/8152

http://bazaar.launchpad.net/~mysql/mysql-server/5.7/revision/8560

 

时间: 2025-01-23 17:56:31

MySQL 5.7 :新的日志类型MLOG_FILE_NAME来避免崩溃恢复时扫描全部ibd的相关文章

mysql中my.cnf 配置 日志类型及文件配置详解

mysql有以下几种日志: 错误日志:    log-err 查询日志:    log 慢查询日志:  log-slow-queries 更新日志:    log-update 二进制日志: log-bin     [client]   port = 3306 socket = /home/mysql/mysql/tmp/mysql.sock   [mysqld]   !include /home/mysql/mysql/etc/mysqld.cnf #包含的配置文件 ,把用户名,密码文件单独存

MySQL · 引擎特性 · InnoDB 崩溃恢复过程

在前面两篇文章中,我们详细介绍了 InnoDB redo log 和 undo log 的相关知识,本文将介绍 InnoDB 在崩溃恢复时的主要流程. 本文代码分析基于 MySQL 5.7.7-RC 版本,函数入口为 innobase_start_or_create_for_mysql,这是一个非常冗长的函数,本文只涉及和崩溃恢复相关的代码. 在阅读本文前,强烈建议翻阅下面两篇文章: 1. MySQL · 引擎特性 · InnoDB undo log 漫游 2. MySQL · 引擎特性 · I

IBM Accelerator for Machine Data Analytics(二)加快新日志类型的分析

开始之前 IBM Accelerator for Machine Data Analytics 的主要优点和长处之一是能够轻松地对工具进行配置和定制. 此 系列文章和教程面向那些希望初步了解加速器,进一步加快机器数据分析,同时还想获取自定义洞察的读者. 本教程是使用 IBM Accelerator for Machine Data Analytics 来分析一种全新类型的数据的一个具体示例.它为第 3部分建立了基础,第 3 部分将说明如何在索引和搜索中即插即用 地使用这种新的日志类型. 目标 在

MySQL · 引擎特性 · InnoDB崩溃恢复

前言 数据库系统与文件系统最大的区别在于数据库能保证操作的原子性,一个操作要么不做要么都做,即使在数据库宕机的情况下,也不会出现操作一半的情况,这个就需要数据库的日志和一套完善的崩溃恢复机制来保证.本文仔细剖析了InnoDB的崩溃恢复流程,代码基于5.6分支. 基础知识 lsn: 可以理解为数据库从创建以来产生的redo日志量,这个值越大,说明数据库的更新越多,也可以理解为更新的时刻.此外,每个数据页上也有一个lsn,表示最后被修改时的lsn,值越大表示越晚被修改.比如,数据页A的lsn为100

MySQL · 引擎特性 · MySQL5.7 崩溃恢复优化

在MySQL5.7之前的版本中, InnoDB每次做crash recovery之前都需要扫描数据目录,打开每个文件并创建内存对象.当目录下文件个数特别多时,会严重影响到崩溃恢复的速度. 为了解决这个问题,MySQL5.7通过结合checkpoint + 标注被修改的文件的方式,从一个checkpoint点开始,可以找到所有崩溃恢复需要打开的文件,从而避免扫描数据目录. 本文简单的记录了相关的代码,以及一个相关的优化点. 提交mini transaction 入口函数: mtr_commit -

Mysql日志文件和日志类型介绍_Mysql

日志文件类型 MySQL有几个不同的日志文件,可以帮助你找出mysqld内部发生的事情: 日志文件 记入文件中的信息类型 错误日志 记录启动.运行或停止mysqld时出现的问题. 查询日志 记录建立的客户端连接和执行的语句. 更新日志 记录更改数据的语句.不赞成使用该日志. 二进制日志 记录所有更改数据的语句.还用于复制. 慢日志 记录所有执行时间超过long_query_time秒的所有查询或不使用索引的查询. 默认情况下,所有日志创建于mysqld数据目录中.通过刷新日志,你可以强制 mys

Mysql数据库日志类型查询与配置详解

mysql常见的日志类型有五种:错误日志.二进制日志.查询日志.慢查日志和中继日志. 一.错误日志 错误日志包含四类信息: (1) 服务器启动和关闭进程过程中的信息: (2) 服务器运行过程中的错误信息: (3) 事件调度器运行一个事件时产生的信息: (4) 在从服务器上启动从服务器进程时产生的信息. 在mysql中查看错误日志的存放路径:  代码如下 复制代码 # mysql -u root -p 123456 mysql> SHOW VARIABLES LIKE '%err%'; 查看警告信

MySQL 5.7新特性

    关于MySQL5.7,现在据说也是蛮火的,此文主要参照官方文档整理的,时日有些长了,最新的特性可能没采集进来,各位看客朋友们随意就好~~勿喷 新的特性 1.安全性增强 1)mysql.user表.plugin字段要求非空:新增时间戳字段保存密码最后被修改时间:不再使用password字段,使用authentication_string替代 2)安装与服务.全新的安装方式mysqld --initialize:安装完毕后只创建一个本地root账户,即root@'localhost':无匿名

MySQL · 特性分析 · MySQL 5.7新特性系列一

1. 背景 MySQL 5.7在2015-10-21发布了GA版本,即5.7.9,目前小版本已经到了5.7.12.5.7新增了许多新的feature和优化,接下来一个系列,我们就一起来尝尝鲜.首先这次主要是预览feature的变化以及兼容性问题.后面的系列,会针对重要的feature展开来学习. 2 安全相关的特性 2.1 认证插件 mysql.user表中的plugin更改成not null,5.7开始不再支持mysql_old_password的认证插件,推荐全部使用mysql_native