说起 buffer pool 相信各位也都耳熟能详,之前pdd面试,面试官提出过这样一个问题,buffer pool 主要是针对查询的优化还是写入的优化?
说这个问题之前,我们先来看一看 innodb 内存和磁盘结构,
从图中可见,innodb 是由内存结构和磁盘结构组成。其中内存结构主要由buffer pool,change buffer,自适应哈希,log buffer 四个部分组成。
buffer pool 都包含什么?
Innodb 引擎数据存储在磁盘上,为了加速数据访问,MySQL会把最常使用的数据,放进缓存里面,避免每次都去访问磁盘,这块内存区域就是缓冲池 buffer pool。它用于减少对磁盘的访问次数,提高数据库操作的效率。buffer pool 包含以下几个主要部分:
1.数据页(data pages): 这是 buffer pool 最主要的部分,用于缓存表的数据页。当从表中读取数据时,数据页首先被加载到 buffer pool 中,之后的读取操作可以直接从内存中进行,而不需要再次访问磁盘。
2.索引页(index pages): 除了数据页外,innodb 的索引页也会被缓存在 buffer pool 中。这包括主键索引(聚集索引)和二级索引页。缓存索引页可以加快查询速度,因为访问内存比访问磁盘要快得多。
3.插入缓冲(insert buffer,即change buffer): change buffer 是 buffer pool 的一部分,它专门用于缓存对非唯一二级索引的更改。这允许数据库合并多个索引更改操作,减少磁盘i/o。
4.自适应哈希索引(adaptive hash index): innodb 会根据表的访问模式构建哈希索引,以加速对 buffer pool 中数据的访问。如果 innodb 检测到对某些索引的查询非常频繁,它会在内存中创建这些索引的哈希版本,以提供更快的查找速度。
5.锁信息(lock information): innodb 的行级锁信息也存储在 buffer pool 中,这样当访问数据页时,可以快速检查和实施锁。
6.数据字典信息(data dictionary information): innodb 存储元数据信息,如表结构定义、索引信息等,这些信息也被缓存在 buffer pool 中。
7.脏页(dirty pages): 当 buffer pool 中的数据页被修改(如更新操作)但还没有写回磁盘时,这些页被标记为"脏页"。后台进程会定期将脏页刷新到磁盘中。
8.双写缓冲区(doublewrite buffer): 用于恢复机制的一部分,保证了数据页写入磁盘的原子性。在写入数据页之前,先将其复制到双写缓冲区,然后再写入数据文件。如果发生崩溃,双写缓冲区可以用来恢复损坏的页。
buffer pool 与 change buffer
先来看看查询和更新的简易流程。
在 mysql 中,change buffer 是一个特殊的数据结构,它是 buffer pool 的一部分,用于缓存对非唯一二级索引(secondary index)的更改。这些更改可能包括插入、删除和更新操作。change buffer 和 buffer pool 之间的关系可以看作是包含关系,即 change buffer 是 buffer pool 的组成部分。
这里是详细的解释:
• buffer pool:buffer pool 是 innodb 存储引擎中的一个关键组件,用于缓存数据和索引页,以减少磁盘i/o操作。当访问表的数据或索引时,innodb 首先检查所需的数据是否已经在 buffer pool 中。如果是,就可以直接从内存中读取,避免了磁盘读取的延迟和损耗。如果不是,innodb 将从磁盘读取数据页并将其放入 buffer pool。
• change buffer:change buffer 是 buffer pool 中的一个区域,专门用于缓存对非普通唯一索引页(non-unique secondary index page)的更改。当对表进行修改操作且索引页不在 buffer pool 中时,innodb 会将更改记录到 change buffer 中,而不是立即将更改写入磁盘上的索引页。这样可以减少随机i/o操作,因为多个更改可以合并在一起,然后一次性写入磁盘。这对于大量的插入、更新和删除操作特别有效。
change buffer 最终会被合并到 buffer pool 中相应的索引页中,这个过程称为 change buffer 合并(change buffer merge)。merge 操作可以在系统空闲时进行,或者当需要访问特定的索引页,数据库关闭和 redo 写满时触发。
对于 change buffer 俩个比较重要的参数
innodb_change_buffer_max_size :配置 change buffer 的大小,占整个 buffer pool 的比例,默认值是25%,最大值是50%。
innodb_change_buffering:具体配置哪些写操作启用写缓冲,可以设置成all/none/inserts/deletes。
如果数据库大都是非唯一索引,业务是写多读少,且不会对写后的数据立即读取,则可以考虑使用并调整对应的值。
buffer pool 是 innodb 性能优化的关键,因为它直接影响到数据库操作的速度。通过调整 buffer pool 的大小和行为,可以显著提高数据库的性能。在配置服务器时,通常会尽可能地分配更多的内存给 buffer pool,前提是不影响系统的其他部分。
总结来说
change buffer 是 buffer pool 的一部分,专门用于缓存索引的更改,以优化写入操作和减少磁盘i/o。这两者之间的关系是包含关系,changebuffer 是 buffer pool 的一个组成部分。
再回到问题,应该来说 buffer pool 主要是指对查询的优化,对写入优化具体是指 change buffer 。
- 欢迎关注微信公众号,交流探讨。
- 原文地址