浅析 InnoDB 存储引擎的工作流程

InnoDB
InnoDB 是由 Innobase Oy 公司开发,该存储引擎是第一个完整支持 ACID 事务的 MySQL 存储引擎 。具有插入缓存、两次写、自适应哈希索引等关键特性,是一个高性能、高可用的存储引擎 。
整体架构
InnoDB 有多个内存块,这些内存块组合在一起组成了一个大的内存池 。而 InnoDB 的内存池中会有多个后台线程,这些后台线程负责刷新内存池中的数据,和将脏页(已修改的数据页)刷新到磁盘文件 。
后台线程
默认情况下,InnoDB 存储引擎有 13 个后台线程:

  • 一个 master 线程
  • 一个锁监控线程
  • 一个错误监控线程
  • 十个 IO 线程
    • 插入缓存线程
    • 日志线程
    • 读线程(默认 4 个)
    • 写线程(默认 4 个)
下面是我本机上的十个 IO 线程
内存池
InnoDB 存储引擎的内存池包含:缓冲池、日志缓存池、额外内存池 。这些内存的大小分别由配置文件中的参数决定 。其中占比最大的是缓冲池,里面包含了数据缓存页、索引、插入缓存、自适应哈希索引、锁信息和数据字典 。InnoDB 会在读取数据库数据的时候,将数据缓存到缓冲池中,而在修改数据的时候,会先把缓冲池中的数据修改掉,一旦修改过的数据页就会被标记为脏页,而脏页则会被 master 线程按照一定的频率刷新到磁盘中 。日志缓存则是缓存了redo-log 信息,然后再刷新到 redo-log 文件中 。额外内存池则是在对一些数据结构本身分配内存时会从额外内存池中申请内存,当该区域内存不足则会到缓冲池中申请 。
浅析 InnoDB 存储引擎的工作流程

文章插图
 
Master Thread
InnoDB 存储引擎的主要工作都在一个单独的 Master Thread 中完成,其内部由四个循环体构成:主循环( loop )、后台循环( background loop )、刷新循环( flush loop )、暂停循环( suspend loop ) 。具体工作流程如下图所示:
浅析 InnoDB 存储引擎的工作流程

文章插图
 
主循环
主要负责将缓冲池中的日志文件刷新到磁盘中、合并插入缓存、刷新缓冲池中的脏页数据到磁盘中、删除无用的 Undo 页、产生一个 checkpoint。在主循环中会多次将脏页刷新到磁盘中,但是有一些刷新任务总会执行,有一些则根据参数来判断当前是否需要刷新 。而这个参数 innodb_max_dirty_pages_pct 最大脏页比例是通过配置文件决定的,你可以根据实际情况来调整你自己的最大脏页比例,来达到最好的性能 。
伪代码如下:
后台循环
在后台循环中 InnoDB 会做这些事:删除无用的Undo页、合并插入缓存 。如果当前 InnoDB 处于空闲状态,则跳转到刷新循环,否则跳转到主循环继续处理数据 。
伪代码如下:
刷新循环
一旦执行到刷新循环,InnoDB 会一直处理脏页数据,直到脏页数据达到最大脏页比例以下 。这时候会跳转到暂停循环中(所有数据都处理完毕) 。
伪代码如下:
暂停循环
在本循环中,InnoDB会将 Master Thread 挂起,减少内存资源使用,一直处于 waiting 状态,等待事件来唤醒 。一旦有新的事件过来,就跳转到主循环中 。
【浅析 InnoDB 存储引擎的工作流程】伪代码如下:


    推荐阅读