在MySQL5.7之前的版本中, InnoDB每次做crash recovery之前都需要扫描数据目录,打开每个文件并创建内存对象。当目录下文件个数特别多时,会严重影响到崩溃恢复的速度。
为了解决这个问题,MySQL5.7通过结合checkpoint + 标注被修改的文件的方式,从一个checkpoint点开始,可以找到所有崩溃恢复需要打开的文件,从而避免扫描数据目录。
本文简单的记录了相关的代码,以及一个相关的优化点。
提交mini transaction
入口函数:
mtr_commit -->
mtr_t::Command::execute
mtr_t::Command::prepare_write()
复制代码
// fil_names_write_if_was_clean
/// 如果space->max_lsn 等于0,表示从最近一次checkpoint开始至今,这是第一次被修改
/// fil_names_dirty_and_write:
1. 加入到链表fil_system->named_spaces的尾部
2. 更新fil_space_t::max_lsn为当前LSN
3. 写入一条MLOG_FILE_NAME,日志内容包括space id 及表空间文件路径
复制代码
// 如果是从上次checkpoint后第一次修改该tablespace, fil_names_dirty_and_write返回true,表示一条 MLOG_FILE_NAME已经追加到当前mtr了,因此在日志组的尾部增加"MLOG_MULTI_REC_END"
// 否则,如果从上次chec