问题

随着 MySQL 使用的内存越来越大,我们建议使用多个 buffer pool instance。

那么我们的问题是: 一张表有多少在 buffer pool 中,一张表只能在一个 buffer pool instance 中么?

实验

这期的实验很短很简单,先宽油起一个数据库:

接下来,我们建一个有数据的表,建表的方法参考 实验 11

反复执行 insert,让表里有更多数据,

我们查询一下 buffer pool 的分布,

这里会输出 196 行,我们将结果手工简化一下来分析(如果是 MySQL 8.0,可以用窗口函数来直接分析,此处偷个懒,手工简化一下),

我们可以看到其中的规律:

  1. 我们这张表的各个数据页,交替出现在两个 buffer pool instance中(POOL_ID 为 0 和 1,以下简称 POOL);

  2. 3-35 页出现在 POOL 1 中,36-63 空缺;

  3. 其后,每 64 页更换一个 POOL,两个 POOL 交替出现。

来整理一下思路:

为什么 buffer pool 需要使用多个 POOL?

  • 访问 buffer pool 时需要上锁,只是用一个 POOL,锁冲突比较严重。使用多个 POOL,可以分担锁的冲突压力。

一张表的各个页为什么交替出现在各个 POOL 中?

  • 为了让各个 POOL 中的数据量相对平衡。

那为什么不是一页一轮换,而是 64 页一轮换?

  • 我们访问数据,经常扫描连续的多个页。如果一页一轮换,那我们一次扫描就要涉及多个 POOL,那么锁的冲突压力就不得分担,迷失了最初的目标。

最后一个小技巧:

我们来看一下 buffer pool 里有这张表的多少数据?

我们可以大概评估 buffer pool 中有表 a 的多少数据,但行数并不完全相等,原理留给大家思考。(提示:InnoDB 的数据页中,不完全是行数据

小贴士

information_schema.INNODB_BUFFER_PAGE 的查询成本比较高,未经测试的情况下,大家尽量不要在生产环境直接使用。

关于 MySQL 的技术内容,你们还有什么想知道的吗?赶紧留言告诉小编吧!