前面我们提到了MySQL5.7的几个崩溃恢复产生的性能退化 为了解决崩溃恢复的效率问题, MySQL8.0对crash recovery的逻辑进行了进一步的优化。 在之前的版本中,InnoDB通过向redo log中写入日志来追踪在一次checkpoint后修改过的表空间信息,这样就无需在crash recovery时打开所有的表空间,只需搜集哪些被影响到的表空间。而到了8.0新版本里,采用了一种全新的方式:单独创建了系统映射文件, 将space id及路径信息轮换着写到两个指定的系统文件tablespaces.open.1 and tablespaces.open.2中(ref Fil_Open::write)
实现的思路其实不复杂,就是将所有的表空间ID和对应的路径信息存储到系统文件中,在崩溃恢复时再按需打开。
系统文件更新
那么如何保证所有的表空间信息都一个不漏的存储到系统文件了呢 ? 实际上他跟踪了所有的表空间文件操作,并更新内存cache中(Fil_Open::m_spaces), 如下:
a. fil_node_open_file
fil_system->m_open.enter();
fil_system->m_open.log(node->space->id, node->name);
fil_system->m_open.exit();
打开表空间文件后,写一条日志MLOG_FILE_OPEN, 并将表空间状态 Nodes::OPEN以及日志end lsn在内存中进行更新(Fil_Open::Nodes::load)
b. fil_node_close_file
fil_system->m_open.enter();
fil_system->m_