【MySQL】十九、MySQL数据库生产环境应用经验分享(三)

【MySQL】十九、MySQL数据库生产环境应用经验分享(三)

本文主要介绍MySQL数据库的在生产环境的使用经验分享

6 如何通过chunk来支持数据库运行期间的Buffer Pool动态调整?

6.1 buffer pool这种大块头,能在运行期间动态调整大小吗?

MySQL设计了一个chunk机制,也就是说buffer pool是由很多chunk组成的,他的大小是innodb_buffer_pool_chunk_size参数控制的,默认值就是28MB。

所以实际上我们可以来做一个假设,比如现在我们给buffer pool设置一个总大小是8GB,然后有4个buffer pool,那么每个buffer pool就是2GB,此时每个buffer pool是由一些列的128MB的chunk组成的,也就是说每个buffer pool会有16个chunk。

然后每个buffer pool里的每个chunk里就是一些列的描述数据块和缓存页,每个buffer pool里的多个chunk共享一套free、flush、lru链表,此时的话,看起来可能大致如下图所示:

image-20211006214606861

在上面的图里,可以清晰的看到,每个buffer pool里面已经有了多个chunk,每个chunk就是一系列的描述数据块和缓存页,这样的话,就是把buffer pool按照chunk为单位,拆分为了一系列的小数据块,但是每个buffer pool是公用一套free、flush、lru链表。

6.2 基于chunk机制是如何支持运行期间动态调整buffer pool大小的?

有了chunk机制,就可以支持动态调整buffer pool大小了。比如我们buffer pool现在总大小是8GB,现在需要动态加到16GB,那么此时只要申请一系列的128MB大小的chunk就可以了,只要每个chunk是连续的128MB没存就行了,然后把这些申请到的chunk内存分配给buffer pool就可以了。

有这个chunk机制,此时并不需要额外申请16GB连续的内存空间,然后还要把已有的数据进行拷贝。

7 如何基于机器配置来合理设置Buffer Pool?

7.1 生产环境中应该给buffer pool设置多少内存?

首先考虑一个问题,我们现在数据库部署在一台机器上,这台机器可能有8GB、16GB、32GB、64GB、128GB的内存大小,那么此时buffer pool应该设置多大呢?

通常来说,我们建议一个比较合理的、健康的比例,是给buffer pool设置你的机器内存的50%~60%左右。比如有32GB的机器,那么给buffer pool设置个20GB的内存,剩下的留给OS和其他人来用,这样比较合理一些。

假如机器有128GB的内存,那么buffer pool可以设置80GB左右。

7.2 buffer pool总大小=(chunk大小*buffer pool数量)的2倍数

确定了buffer pool的总大小之后,就得考虑一下设置多少个buffer pool,以及chunk的大小了。

有一个很关键的公式就是buffer pool总大小=(chunk大小*buffer pool数量)的倍数

比如默认的chunk大小是128MB,那么此时如果你机器的内存是32GB,打算给buffer pool总大小在20GB左右,那么得算一下,此时buffer pool的数量应该是多少个呢?

假设buffer pool的数量是16个,这是没问题的,此时chunk大小*buffer pool的数量 = 16 * 128MB = 2048MB,然后buffer pool总大小如果是20GB,此时buffer pool总大小就是2048MB的10倍,这就符合规则了。

当然如果buffer pool的数量设置成32,此时buffer pool总大小(20GB)就是(chunk大小128MB*32个buffer pool)的5倍,也是可以的。

那么此时你的buffer pool大小是20GB,然后buffer pool数量是32个,每个buffer pool大小是640MB,然后每个buffer pool包含5个128MB的chunk。

7.3 show engine innodb status

当数据库启动之后,可以通过show engine innodb status 查看当前innodb里的一些具体情况,此时可能看到如下信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Total memory allocated xxxx;
Dictionary memory allocated xxx
Buffer pool size xxxx
Free buffers xxx
Database pages xxx
Old database pages xxxx
Modified db pages xxxx
Pending reads 0
Pending writes: LRU 0, flush list 0, single page 0
Pages made young xxx, not young xxx
xx youngs/s, xx non-youngs/s
Pages read xxxx, created xxxx, written xxx
xx reads/s, xx creates/s, 1xx writes/s
Buffer pool hit rate xxx/1000, young-making rate xxx/1000 not xx/1000
Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
LRU len:xxxx, unzip_LRU len:xxx
I/O sum[xxx]:cur[xx],unzip sum[16xx:cur[0]]

(1) Total memory allocated, 这就是说buffer pool最终的总大小是多少

(2) Buffer pool size,这个就是说Buffer pool一共能容纳多少个缓存页

(3) Free buffers,这个就是说free链表中一共有多少个空闲的缓冲页是可用的

(4) Database pages 和Old database pages ,就是说lru链表中一共有多少个缓存页,以及冷数据区域里的缓存页数量

(5) Modified db pages,这就是flush链表中的缓存页数量

(6) Pending reads和Pending writes,等待从磁盘上加载进缓存页的数量,还有就是即将从lru链表中刷入磁盘的数量,即将从flush链表中刷入磁盘的数量。

(7) Pages made young 和not young,这就是说已经lru冷数据区域里访问之后转移到热数据区域的缓存页的数量,以及在lru冷数据区域里1s内被昂问了没进入热数据区域的缓存页的数量。

(8) youngs/s和not youngs/s,就是说每秒从冷数据区域进入热数据区域的缓存页的数量,以及每秒在冷数据区域里被访问了但是不能进入热数据区域的缓存页的数量。

(9) Page read xxx, created xxx, written xxx, xxreads/s, xx creates/s, 1xx writes/s,这里就是说已经读取、创建和写入了多少个缓存页,以及每秒钟读取、创建和写入的缓存页数量。

(10) Buffer pool hit rate xxx/1000,这就是说每1000次访问,有多少次是直接命中了buffer pool里的缓存的。

(11) young-making rate xxx/1000 not xx/1000,每1000次访问有多少次访问让缓存页从冷数据区域移动到了热数据区域,以及没移动的缓存页数量。

(12) LRU len:这就是lru链表里的缓存页的数量

(13) I/O sum:最近50s读取磁盘页的总数

(14) I/O cur:现在正在读取磁盘页的数量

【MySQL】十九、MySQL数据库生产环境应用经验分享(三)

https://www.shuiwh.com/posts/learn-mysql-019/

作者

水无痕

发布于

2025-07-27

更新于

2025-07-27

许可协议