问题
随着 MySQL 使用的内存越来越大,我们建议使用多个 buffer pool instance。
那么我们的问题是: 一张表有多少在 buffer pool 中,一张表只能在一个 buffer pool instance 中么?
实验
这期的实验很短很简单,
先宽油起一个数据库:
接下来,我们建一个有数据的表,建表的方法参考实验 11:
反复执行 insert,让表里有更多数据:
我们查询一下 buffer pool 的分布:
这里会输出 196 行,我们将结果手工简化一下来分析(如果是 MySQL 8.0,可以用窗口函数来直接分析,此处偷个懒,手工简化一下):
我们可以看到其中的规律:
- 我们这张表的各个数据页,交替出现在两个 buffer pool instance中(POOL_ID 为 0 和 1,以下简称 POOL);
- 3-35 页出现在 POOL 1 中,36-63 空缺;
- 其后,每 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 的技术内容,你们还有什么想知道的吗?赶紧留言告诉小编吧!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。