InnoDB存储引擎(2)—— InnoDB 体系架构

InnoDB存储引擎(2)—— InnoDB 体系架构_第1张图片

 1. 内存池

    由多个内存块组成,负责的工作如下:

  • 维护所有进程 / 线程需要访问的多个内部数据结构
  • 缓存磁盘上的数据,方便快速读取,同时在对磁盘文件的数据修改之前在这里缓存
  • 重做日志(redo log)缓冲
  • ....

2. 后台线程

  • 作用
    • 负责刷新内存池中的数据,保证缓冲池中的内存缓存是最近的数据。
    • 将已修改的数据文件刷新到磁盘文件,同时保证在数据库发生异常的情况下InnoDB 能恢复到正常运行状态
  • 分类
    • Master Thread
      • 是一个非常核心的后台线程
      • 主要负责将缓冲池中的数据异步刷新到磁盘,保证数据的一致性
        • 脏页的刷新
        • 合并插入缓冲(INSERT BUFFER)
        • undo 页的回收
        • ...
    • IO Thread
      • InnoDB 存储引擎中大量使用了AIO(Async IO)来处理写请求,这样可以极大的提高数据的性能
      • IO Thread 的工作主要负责这些IO 请求的回调处理
      • 分类
        • write IO thread
        • read IO thread(读线程的ID 总是小于写线程)
        • insert buffer IO thread
        • log IO thread
    • Purge Thread
      • 主要负责回收已经使用并分配的undo页(事务提交后,其所使用的undo log 可能不再需要)
      • InnoDB 1.1 版本之前,purge 操作通过Master Thread 完成,InnoDB 1.1 开始使用单独的线程进行purge操作,而减轻Master Thread 的负荷,从而提高CPU 使用率以及提升存储引擎的性能
      • InnDB1.2 开始支持多个Purge Thread ,目的是为了进一步加快undo页的回收
    • Page Cleaner Thread
      • InnoDB 1.2.x 版本引入,作用是将之前版本中的脏页刷新操作都放入到单独的线程中来完成
      • 目的是减轻原Master Thread的工作及对于用户查询线程的阻塞
      • 进一步提高InnoDB 存储引擎的性能

3. 内存(内存池的组成单元)

InnoDB存储引擎(2)—— InnoDB 体系架构_第2张图片 InnoDB 数据引擎内存结构图
  • 缓冲池
    • 平衡磁盘速度和CPU 速度(就是一般的缓存的特点),从而提高数据库的整体性能
    • 将页“FIX”到缓冲池中
      • InnoDB 将表中的记录按照页的方式进行管理
      • FIX 到缓冲池是指,当一个页之前从未读取过时,首先从磁盘中读取出来并放入缓冲池的过程
    • 页在缓冲池中命中
      • 当需要读取一页时,判断该页是否在缓冲池中,在则称为页在缓冲池中命中,并直接返回该页
    • 页在缓冲池中未命中
      • 当需要读取一页时,判断该页是否在缓冲池中,不在则称为该页在缓冲池中未命中,需要将页“FIX”到缓冲池
    • 数据库中页的修改操作
      • 首先修改在缓冲池中的页,然后再以一定的频率刷新到磁盘上
      • 页从缓冲池刷新回磁盘的操作不是在每次页更新时触发,而实通过一种checkpoint的机制刷新回磁盘
    • 数据库缓冲池大小直接影响数据库的整体性能
    • 缓冲池中缓存的数据页类型
      • 索引页
      • 数据页
      • undo页
      • 插入缓存(insert buffer)
      • 自适应哈希索引(adaptive hash index)
      • InnoDB 存储的锁信息(lock info)
      • 数据字典信息(data dictionary)
    • 多个缓冲池实例
      • InnDB 1.0.x 版本开始,允许有多个缓冲池实例
      • 每个页根据哈希值平均分配到不同的缓冲池实例中
      • 目的是为了减少数据库内部的资源竞争,增加数据库并发处理能力
  • LRU List、Free List 和 Flush List
    • 缓冲池是通过LRU 算法管理的
      • 最频繁使用的页放在LRU List 的前端,而最少使用的页在LRU List的末尾
      • 当缓存池已经满时,首先释放LRU List 末尾的页
    • InnoDB 对LRU 算法的优化
      • 在LRU List 中加入midpoint 位置,新读取的页不直接放在List 的首部,而是先放入到List 的 midpoint 位置。这个算法称为——midpoint insertion strategy。目的是为了防止热点数据被挤出缓存,常见的操作为索引或数据的扫描操作。
      • InnoDB 进一步引入innodb_old_blocks_time 参数来管理LRU List,用于表示页读取到mid 位置后需要等待多久才会被加入到LRU List 的热端
    • LRU List 不对自适应哈希索引、Lock信息、Insert Buffer等页进行管理
    • 压缩页的管理——unzip_LRU
      • InnDB 1.0.x 开始支持压缩页的功能,对非16KB的页使用unzip_LRU进行管理
      • unzip_LRU List 对不同压缩页大小的页进行分别管理
      • 通过伙伴算法进行内存分配,以4KB 的页为例
        • 检查4KB 的unzip_LRU List,检查是否有可用的空闲页
        • 若有,则直接使用
        • 否则,检查8KB 的 unzip_LRU List
        • 若能得到空闲页,将页分成2 个4KB页,存放到4KB 的unzip_LRU列表
        • 若不能得到空闲也,从LRU 列表中申请一个16KB 的页,将页分为一个8KB的页和2个4 KB的页,分别存放到对应的unzip_LRU列表中
    • Free List 用于缓冲池的空闲空间管理
    • Flush List 用于脏页
      • 脏页既存在于LRU List 中,也存在于Flush List 中
      • LRU List 用来管理缓冲池中也的可用性,Flush List 用来管理将页刷新回磁盘,二者互不影响
  • redo 日志缓冲
    • redo 日志信息先放入这个缓冲区,然后按一定频率将其刷新到redo 日志文件
    • redo 日志缓冲的大小不用很大,只需保证每秒产生的事务量在这个缓冲大小之内即可
    • redo 日志缓冲刷新到磁盘中的redo 日志文件的时机
      • Master Thread 每一秒将redo 日志缓冲刷新到redo 日志文件
      • 每个事务提交时会将redo 日志缓冲刷新到redo 日志文件
      • 当redo 日志缓冲剩余空间小于1 / 2时,redo 日志缓冲刷新到redo 日志文件
  • 额外的内存池

你可能感兴趣的:(#,MySQL,技术内幕与InnoDB存储引擎,架构,innodb,mysql)