MySQL Buffer Pool 简述
# 一、基本介绍
Buffer Pool 是MySQL的缓存池,即在 MySQL 启动的时候为 Buffer Pool 申请一片连续的内存空间,InnoDB 会把存储的数据划分为若干个「页」,以页作为磁盘和内存交互的基本单位,一个页的默认大小为 16KB。可以在服务启动时,配置innodb_buffer_pool_size
参数来设定缓存池的大小。
InnoDB 用于缓存从磁盘加载到内存中和将要从内存写入磁盘中的数据,如果没有缓存,每次需要读取某条记录时,就需要将该记录所在的页上的数据全部加载到内存中,读写完毕后,又需要将整页数据全部写回磁盘。即使当前操作的记录占用的存储非常小,不足一整页,也需要读写整页的数据。每次读写数据,都需要与磁盘进行 I/O 交互,这将极大的影响MySQL的性能。
在程序的数据处理是在内存中进行的,数据的读写是与磁盘进行交互的,在这两者中间加入一个中间层 Buffer Pool,就能够有效地降低每次读写数据直接与磁盘进行交互的次数,显著提高MySQL的性能。当读取数据时,如果数据存在于 Buffer Pool 中,客户端就会直接读取 Buffer Pool 中的数据,否则再去磁盘中读取。当修改数据时,如果数据存在于 Buffer Pool 中,那直接修改 Buffer Pool 中数据所在的页,然后将其页设置为脏页,为了减少磁盘I/O,不会立即将脏页写入磁盘,后续由后台线程选择一个合适的时机将脏页写入到磁盘。
# 二、基本构成
# 1,控制块与缓存页
Buffer Pool中默认的缓存⻚大小和在磁盘上默认的⻚大小是一样的,都是16KB。为了更好的管理Buffer Pool中的缓存⻚,每一个缓存⻚都创建了一些控制信息,这些控制信息包括该⻚所属的表空间编号、⻚号、缓存⻚在Buffer Pool中的地址、链表节点信息、锁信息等。每个缓存⻚对应的控制信息占用的内存大小是相同的,我们就把每个⻚对应的控制信息占用的一块内存称为一个控制块吧,控制块和缓存⻚是一一对应的,它们都被存放到BufferPool中,其中控制块被存放到BufferPool的前边,缓存⻚被存放到BufferPool后边,所以整个Buffer Pool对应的内存空间看起来就是这样的:
# 2,LRU 链表
# 3,free 链表
# 4,flush 链表
# 5,哈希表
脏页刷盘、实例、配置
# 1,作用
# 3,持久化
- 为了防止断电导致数据丢失的问题,当有一条记录需要更新的时候,InnoDB 引擎就会先更新内存(同时标记为脏页),然后将本次对这个页的修改以 redo log 的形式记录下来,这个时候更新就算完成了;
- InnoDB 引擎会在适当的时候,由后台线程将缓存在 Buffer Pool 的脏页刷新到磁盘里;
- Buffer Pool 除了缓存**「索引页」和「数据页」,还包括了 Undo 页,插入缓存、自适应哈希索引、锁信息**等等。
- undo log 和数据页的刷盘策略是一样的,都需要通过 redo log 保证持久化。
- buffer pool 中有 undo 页,对 undo 页的修改也都会记录到 redo log。
- redo log 会每秒刷盘,提交事务时也会刷盘,数据页和 undo 页都是靠这个机制保证持久化的。