写点什么

InnoDB 体系架构

作者:龙空白白
  • 2022 年 6 月 13 日
  • 本文字数:2350 字

    阅读完需:约 8 分钟

InnoDB体系架构

1、InnoDB 体系架构

下图简单显示了 InnoDB 的存储引擎的体系架构,可以认为这些内存块组成了一个大的内存池,负责如下工作



<center>InnoDB 存储引擎体系架构</center>


  • 维护所有进程/线程需要访问的多个内部数据结构

  • 存储磁盘上的数据,方便快速地读取,同时在对磁盘文件的数据修改之前在这里缓存

  • 重做日志(redo log)缓冲

  • 后台线程的主要作用是负责刷新内存池中的数据,保证缓冲池中的内存缓存的是最近的数据,此外将已修改的数据文件刷新到磁盘文件,同时保证在数据库发生异常的情况下 InnoDB 能恢复到正常运行状态

  • 1、后台线程

  • InnoDB 存储引擎是多线程的模型,因此其后台有多个不同的线程,负责处理不同的任务

  • 1、Master Thread


  • Master Thread 是一个非常核心的后台线程,主要负责将缓存池中的数据异步刷新到磁盘,保证数据的一致性,包括脏页的刷新、合并插入缓冲(Insert Buffer)、undo 页的回收

  • 2、IO Thread


  • 在 InnoDB 存储引擎中大量使用了 AIO(Async IO)来处理写 IO 请求,这样可以提高数据库的性能,而 IO Thread 的工作主要是负责 IO 请求的回调处理


  mysql> show variables like 'innodb_%_threads';  +-------------------------+-------+  | Variable_name           | Value |  +-------------------------+-------+  | innodb_purge_threads    | 1     |  | innodb_read_io_threads  | 1     |  | innodb_write_io_threads | 1     |  +-------------------------+-------+
复制代码


3、Purge Thread


当事务被提交之后,其使用的 undolog 可能不再需要,因此需要使用 Purge Thread 来回收已经使用的并分配的 undo 页,用户可以在 MySQL 数据库的配置文件中添加命令来启动独立的 Purge Thread


  mysql> show variables like 'innodb_purge_threads';  +----------------------+-------+  | Variable_name        | Value |  +----------------------+-------+  | innodb_purge_threads | 1     |  +----------------------+-------+  1 row in set (0.00 sec)
复制代码


4、Page Cleaner Thread


Page Cleaner Thread 是将之前版本中脏页的刷新操作都放入到独立的单线程中来完成,目的是为了减轻原 Master Thread 的工作对于用户查询线程的阻塞进一步提高 InnoDB 存储引擎的性能

2、内存

1、缓存池


InnoDB 存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理,缓存池简单来说就是一块内存区域,通过内存的速度来弥补磁盘速度较慢对数据库性能的影响,在数据库进行读取页的操作时,首先将从磁盘读到的页存放在缓存池中,下一次再读相同的页时,首先判断该页是否在缓冲池中,若在缓冲池中,称该页在缓冲池中被命中,直接读取该页。否则,读取磁盘上的页。


对于数据库中的页的修改操作,则首先修改在缓冲池中的页,然后在以一定的效率刷新到磁盘上,页从缓冲池中刷新回磁盘的操作并不是在每次页发生更新时触发,而是通过 Checkpoint 的机制刷新回磁盘,也是为了提高数据库的整体性能。而缓冲池的大小为


  mysql> show variables like 'innodb_buffer_pool_size';  +-------------------------+-----------+  | Variable_name           | Value     |  +-------------------------+-----------+  | innodb_buffer_pool_size | 134217728 |  +-------------------------+-----------+  1 row in set (0.00 sec)
复制代码


缓冲池中缓存的数据页类型有:索引页、数据页、undo 页、插入缓冲(insert buffer)、自适应哈希索引、InnoDB 存储的锁信息(lock info)、数据字典信息等、缓冲池中缓存索引页和数据页只是占了缓冲池中的很大一部分而已,如下图所示



<center>InnoDB 内存数据对象</center>


2、LRU List、Free List 和 Flush List


我们知道缓冲池是一个很大的内存结构,其中存放各种类型的页,那么 InnoDB 存储引擎是如何管理这些内存区域的呢?


数据库中的缓冲池是通过 LRU(Latest Recent Used,最近最少使用)算法来管理的,即最频繁使用的页在 LRU 列表的前端,而最少使用的页在 LRU 列表的尾端,当缓冲池不能存放读取到最新的页时,将首先释放 LRU 列表中尾端的页。


在 InnoDB 储存引擎中,缓冲池中页的大小默认为 16KB,同样使用 LRU 算法对缓冲池进行管理,不同的是 InnoDB 存储引擎对传统的 LRU 算法做了一些优化,在 InnoDB 的存储引擎中,LR 列表中还加入了 midpoint 位置,新读取到的页,虽然是最新访问的页,但并不是直接放入到 LRU 列表的首部,而是放入到 LRU 列表中的 midpoint 位置


3、重做日志缓冲


InnoDB 存储引擎的内存区域除了有缓冲池外,还有重做日志缓冲(redo log buffer),InnoDB 存储引擎首先将重做日志信息放入到缓冲区,然后按一定频率将其刷新到重做日志文件,该值可有配置参数 innodb_log_buffer_size 控制


mysql> show variables like 'innodb_log_buffer_size';+------------------------+----------+| Variable_name          | Value    |+------------------------+----------+| innodb_log_buffer_size | 16777216 |+------------------------+----------+1 row in set (0.00 sec)
复制代码


重做日志在以下情况下会将重做日志缓冲中的内容刷新到外部磁盘的重做日志文件中去


  • Master Thread 每一秒将重做日志缓冲刷新到重做日志文件

  • 每个事务提交时将重做日志缓冲刷新到重做日志文件

  • 当重做日志缓冲池剩余空间小于 1/2 时,重做日志缓冲刷新到重做日志文件


4、额外的内存池


在 InnoDB 存储引擎中,对内存的管理是通过一种称之为内存堆(heap)的方式进行的,在对一些数据结构本身的内存进行分配时,需要从额外的内存池中进行申请,当该区域的内存不够时,会从缓冲池中进行申请,例如,分配了缓冲池(innodb_buffer_pool),但是每个缓冲池中的帧缓冲(frame buffer)还有对应的缓冲控制对象(buffer control block),这些对象记录了一些诸如 LRU、锁、等待等信息,而这个对象的内存需要从额外内存池中申请。

2、Checkpoint 技术

发布于: 刚刚阅读数: 3
用户头像

龙空白白

关注

还未添加个人签名 2021.04.12 加入

IT行业 后端开发

评论

发布
暂无评论
InnoDB体系架构_MySQL InnoDB_龙空白白_InfoQ写作社区