Ch03-MySQL 之 内存结构

Ch03-MySQL 之 内存结构

October 30, 2021
MySQL
mysql

Buffer Pool

1. Buffer Pool #

Buffer Pool 是内存中比较重要的一块区域,主要用来缓存被访问的表和索引数据。Buffer Pool 允许直接从从内存中获取经常使用的数据,在专用的服务器上面,最高有 80% 的物理内存被分配给 Buffer Pool。

为了提高大容量读取操作的效率,Buffer Pool 被划分成了可以容纳多行的页。为了提高缓存管理的效率,Buffer Pool 采用链接页表的方式实现,对于较少使用的数据,采用 LRU 算法的变体进行淘汰。

Buffer Pool 不仅仅缓存索引,还会缓存行的数据,自适应哈希索引,插入缓冲 (Insert Buffer),锁,以及其他内部数据结构,InnoDB 还利用 Buffer Pool 来帮助实现延迟写入(合并多个写入操作,一起顺序写回)。因此选择合适的 Buffer Pool 可以有效提升 MySQL 的效率,当然,过大的 Buffer Pool 也会导致预热和关闭时间的延长 (比如有很多脏页在 Buffer Pool 中)。

条目 说明
LRU 链表 维护 Clean Page(此 Page 已被使用且未被修改)和 Dirty Page
Flush 链表 维护 Dirty Page(此 Page 已被使用且被修改)
Free 链表 维护 Free Page(此 Page 未被使用)

对于更多 Buffer Pool 的细节可以参考 Buffer Pool

2. Change Buffer #

Change Buffer 是一种特殊的数据结构,当修改的二级索引页不在 Buffer Pool 中时,那么 Change Buffer 会缓存二级索引页的变更部分(可能是由 INSERT, UPDATE, DELETE 等 DML 语句的操作导致)。当页面因为其他的读操作被载入 Buffer Pool 的时候,这些更改稍后也会被一起合并。

与 clustered index(InnoDB 的专业术语,指 primary key index) 不同,二级索引通常是非唯一的,而且插入顺序也相对比较随机,比如删除和更新影响的二级索引页可能在索引树上面并不相邻。当影响到的页因为其他操作而被读入 Buffer Pool 时,便会合并更改的缓存。

当系统处于空闲时间,或者在关机前的时间,清理操作会将更改的索引页写入到磁盘。与每次将修改的值立即写入磁盘相比,清理操作可能会更有效率。对于更多 Change Buffer 的细节可以参考 Change Buffer

innodb-change-buffer

3. Adaptive Hash Index #

InnoDB 存储引擎会监控对表上索引的查找,如果观察到建立 Hash Index 可以带来速度的提升,则建立 Hash Index,所以被称为自适应 (Adaptive) 的。Adaptive Hash Index 通过 Buffer Pool 的 B+树构造而来,因此建立的速度非常快,而且也不需要将整张表都建立 Hash Index,InnoDB 存储引擎会自动根据访问的频率和模式来为某些页建立 Hash Index。

对于更多 Adaptive Hash Index 的细节可以参考 Adaptive Hash Index

4. Log Buffer #

Log Buffer 是内存中的一块区域,该区域主要暂存将被写入到的磁盘的 Log File。一个比较大的 Log Buffer 可以使得比较大的事务在提交之间不需要将 Redo Log 写入到磁盘,因此,如果有 UPDATE, INSERT, DELETE 等大体量的事务操作,可以考虑适当的增加 Log Buffer以节约磁盘I/O。

对于更多 Log Buffer 的细节可以参考 Log Buffer

5. 参考文献 #