初识 InnoDB存储引擎

一、InnoDB存储引擎概述

  • InnoDB 是事务安全的 MySQL存储引擎。
  • 支持行锁、MVCC、外键
  • 提供一致性非锁定读

InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。

因此可将其视为基于磁盘的数据库系统(Disk-base Database)。

二、体系架构

InnoDB 存储引擎有多个内存块,可以认为这些内存组成了一个大的内存池,负责如下工作:

  • 维护所有进程 / 线程 需要访问的多个内部数据结构;
  • 缓存磁盘上的数据,方便快速地读取,同时在对磁盘文件的数据修改之前在这里缓存;
  • 重做(redo log)缓冲。
图1 InnoDB 存储引擎体系架构

后台线程

后台线程主要作用是负责刷新内存池中的数据,保证缓冲池中的内存缓存的是最近的数据。

此外,将已修改的数据文件刷新到磁盘文件,同时保证在数据库发生异常的情况下 InnoDB 能恢复到正常的运行状态。

图2 后台线程

内存

图3 InnoDB存储引擎内存结构

缓冲池

缓冲池是一块内存区域,存放各种类型的页。
使用缓冲池技术来通过内存的速度去弥补磁盘速度较慢对数据库性能的影响。

配置参数:innodb_buffer_pool_size

可以允许多个缓冲池实例,每个页根据哈希值平均分配到不同的缓冲池实例中。
作用:减少数据库内部资源竞争,提高并发处理能力。
配置参数:innodb_buffer_pool_instances

在数据库中进行读取页的操作,首先会从磁盘中读取的页放到缓冲池中,下次读取相同页时,看缓冲池是否能命中,能就直接读取,查询操作和修改操作的流程如图3 和图4所示。

图4 查询操作
图5 修改操作

LRU列表、Free列表、Flush列表

LRU(Lastest Recent Used,最近最少使用)

通常,数据库的缓冲池用 LRU 算法来管理。

概念:频繁使用的页放在 LRU列表 的前端,最少使用的页放在尾端。
作用:LRU列表用来管理已读取的页。

较传统的 LRU 做出相应优化

  1. LRU列表 加入 midpoint 位置(默认在LRU列表长度的 5/8 处),新读的页放在该位置。
    midpoint 之后称 old列表(新读取的页放这),midpoint 之前称 new列表热点数据)。
    配置参数innodb_old_blocks_pct ,默认值37,即 old列表的长度为 37%(约 3/8)。

  2. 加入 innodb_old_blocks_time 参数
    当页读取到 midpoint 位置后,需要等待多久时间才加入到 LRU列表的热端(new列表),默认值1000,即1秒。

当页从 LRU 列表 的 old 部分加入到 new 部分时,此时操作称 page made young
innodb_old_blocks_time 参数的设置而导致页无法 old -> new,则称 page not made young

注意:插入缓冲、锁信息、自适应哈希索引 等页不存在 LRU列表中。

Free列表

空闲列表。下图6,当需要从缓存池中分页时,分页的过程。

图6 分页过程

需要注意的是,当 Free列表中还有空闲页,则说明 LRU列表中页数未固定,还可以从 Free列表中取。
所以此时 midpoint 是动态变化的(如上文提到的,因为 midpoint 位置是按 LRU列表长度百分比进行设置的)。

反之,当 Free列表用完,LRU列表页数固定,则 midpoint 也会固定下来。

Flush列表

Flush列表即脏页列表

LRU列表中页被修改后,称该页为脏页,即缓冲池和磁盘上的页的数据产生了不一致,缓冲池中的页的版本比磁盘的新。
这时数据库会通过 checkpoint 机制将脏页刷回磁盘。

LRU列表用来管理缓冲池中页的可用性
Flush列表用来管理将页刷回磁盘

注意:脏页存在于 LRU列表中,也存在于 Flush列表中。

重做日志缓冲

如上图3所示,InnoDB存储引擎的内存区域除了有缓冲池外,还有重做日志缓冲(redo_log_buffer)和 额外的内存池(innodb_additional_mem_pool_size)。

InnoDB存储引擎首先会把重做日志信息先放到这个缓冲区中,然后再按一定的频率刷到重做日志文件
刷新频率一般为一秒,所以该区一般不用设置太大,用户只需保证每秒产生的事务量在这个缓冲大小之内即可。

配置参数:innodb_log_buffer_size,默认8MB。

重做日志缓冲中的内容 刷新到 外部磁盘的重做日志文件,有三种情况会触发。

  • Master Thread 每秒将重做日志缓冲刷新到重做日志文件;
  • 每个事务提交时会将重做日志缓冲刷新到重做日志文件;
  • 当重做日志缓冲池剩余空间小于 1/2 时,重做日志缓冲刷新到重做日志文件。

额外的内存池

在 InnoDB 存储引擎中,对内存的管理是通过一种成为内存堆(heap)的方式进行的。

在对一些数据结构本身的内存进行分配时,需要从额外的内存池中进行申请,当该区域的内存不够时,会从缓冲池中进行申请。

每个缓冲池中的帧缓冲(frame buffer)和对应的缓冲控制对象(buffer control block),这些对象记录了一些诸如 LRU、锁、等待等信息,这些对象的内存需要从额外的内存池中进行申请。

因此,在申请了很大的 InnoDB 缓冲池时,也应考虑相应地增加这个值。

参考资料

[1] MySQL技术内幕 InnoDB存储引擎 第2版

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值