MySQL InnoDB Buffer Pool空间不足导致查询变慢

问题现象

前端调用后台服务查询接口响应很慢,查看 MySQL 的日志,有如下日志:

[Warning] InnoDB: Difficult to find free blocks in the buffer pool (13430 search iterations)! 13430 failed attempts to flush a page! Consider increasing the buffer pool size. It is also possible that in your Unix version fsync is very slow, or completely frozen inside the OS kernel. Then upgrading to a newer version of your operating system may help. Look at the number of fsyncs in diagnostic info below. Pending flushes (fsync) log: 0; buffer pool: 0. 2845050 OS file reads, 85165 OS file writes, 9180 OS fsyncs. Starting InnoDB Monitor to print further diagnostics to the standard output.

问题原因

MySQL InnoDB 存储引擎的 Buffer Pool (缓冲池)没有空闲块了,需要增大 Buffer Pool 的大小。

那 Buffer Pool 是什么?有什么作用?

对于使用MySQL InnoDB存储引擎的表来说,表数据是以页的形式存储在磁盘上,磁盘的访问速度相对于CPU来说很慢,为了调节磁盘和CPU的访问速度, InnoDB 存储引擎在处理客户端的请求时,如果需要访问某个页的数据,就会把完整的页的数据全部加载到内存中,然后通过内存进行读写访问,在读写访问之后并不着急把该页对应的内存空间释放掉,而是将其缓存起来,这样将来有请求再次访问该页面时,就可以省下磁盘 I/O 的开销了。

MySQL 服务器启动时向操作系统申请用来缓存表数据的内存,就叫 Buffer Pool(缓冲池)。

通过配置项 innodb_buffer_pool_size 配置 Buffer Pool 的大小,默认是 128M 。

Buffer Pool 的内存被划分为若干个页面,每个页面对应一个控制块。

Buffer Pool 相关的链表

  • free 链表:存储空闲的缓冲页信息。

  • flush 链表:存储脏页信息。脏页是Buffer Pool 中被修改的缓冲页,和磁盘上的数据不一致。

  • LRU (Least Recently Used)链表:管理当缓冲池不够用时,需要将哪些缓冲页从内存中移除。

Buffer Pool 实例及 chunk

为了提高Buffer Pool 的并发处理能力,可以通过配置项 innodb_buffer_pool_instances 配置多个 Buffer Pool 实例,每个实例是独立的(独立地申请内存空间,独立地管理各种链表)。

每个 Buffer Pool 实例以 chunk 为单位向操作系统申请内存空间,chunk 的大小默认值是 128MB,可以通过配置项 innodb_buffer_pool_chunk_size 修改。

查看 Buffer Pool的信息

  • 查看 Buffer Pool 大小:show variables like 'innodb_buffer_pool_size';

  • 查看 Buffer Pool 实例个数:show variables like 'innodb_buffer_pool_instances';

  • 查看 chunk 大小:show variables like 'innodb_buffer_pool_chunk_size';

  • 查看 Buffer Pool 状态:show engine innodb status\G

    mysql> show engine innodb status\G
    ...
    ----------------------
    BUFFER POOL AND MEMORY
    ----------------------
    Total large memory allocated 2198863872
    Dictionary memory allocated 1889983
    Buffer pool size   131072
    Free buffers       8685
    Database pages     121738
    Old database pages 44777
    Modified db pages  25340
    Pending reads      0
    Pending writes: LRU 0, flush list 1, single page 0
    Pages made young 57648, not young 454686
    0.00 youngs/s, 0.00 non-youngs/s
    Pages read 49231, created 86169, written 1538233
    0.00 reads/s, 0.00 creates/s, 0.00 writes/s
    Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
    Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
    LRU len: 121738, unzip_LRU len: 0
    I/O sum[0]:cur[0], unzip sum[0]:cur[0]
    ----------------------
    INDIVIDUAL BUFFER POOL INFO
    ----------------------
    ---BUFFER POOL 0
    Buffer pool size   16384
    Free buffers       1077
    Database pages     15216
    Old database pages 5596
    Modified db pages  3136
    Pending reads      0
    Pending writes: LRU 0, flush list 0, single page 0
    Pages made young 6486, not young 52789
    0.00 youngs/s, 0.00 non-youngs/s
    Pages read 5894, created 11149, written 196015
    0.00 reads/s, 0.00 creates/s, 0.00 writes/s
    No buffer pool page gets since the last printout
    Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
    LRU len: 15216, unzip_LRU len: 0
    I/O sum[0]:cur[0], unzip sum[0]:cur[0]
    ---BUFFER POOL 1
    Buffer pool size   16384
    Free buffers       1088
    Database pages     15215
    Old database pages 5596
    Modified db pages  3136
    Pending reads      0
    Pending writes: LRU 0, flush list 1, single page 0
    Pages made young 6933, not young 5973
    0.00 youngs/s, 0.00 non-youngs/s
    Pages read 6033, created 10759, written 184737
    0.00 reads/s, 0.00 creates/s, 0.00 writes/s
    Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
    Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
    LRU len: 15215, unzip_LRU len: 0
    I/O sum[0]:cur[0], unzip sum[0]:cur[0]
    ---BUFFER POOL 2
    Buffer pool size   16384
    Free buffers       1077
    Database pages     15228
    Old database pages 5601
    Modified db pages  3132
    Pending reads      0
    Pending writes: LRU 0, flush list 0, single page 0
    Pages made young 7429, not young 81168
    0.00 youngs/s, 0.00 non-youngs/s
    Pages read 6002, created 10761, written 209768
    0.00 reads/s, 0.00 creates/s, 0.00 writes/s
    Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
    Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
    LRU len: 15228, unzip_LRU len: 0
    I/O sum[0]:cur[0], unzip sum[0]:cur[0]
    ---BUFFER POOL 3
    Buffer pool size   16384
    Free buffers       1093
    Database pages     15212
    Old database pages 5595
    Modified db pages  3136
    Pending reads      0
    Pending writes: LRU 0, flush list 0, single page 0
    Pages made young 7077, not young 65129
    0.00 youngs/s, 0.00 non-youngs/s
    Pages read 6317, created 10330, written 208418
    0.00 reads/s, 0.00 creates/s, 0.00 writes/s
    Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
    Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
    LRU len: 15212, unzip_LRU len: 0
    I/O sum[0]:cur[0], unzip sum[0]:cur[0]
    ---BUFFER POOL 4
    Buffer pool size   16384
    Free buffers       1080
    Database pages     15223
    Old database pages 5599
    Modified db pages  3200
    Pending reads      0
    Pending writes: LRU 0, flush list 0, single page 0
    Pages made young 7127, not young 72730
    0.00 youngs/s, 0.00 non-youngs/s
    Pages read 6272, created 10750, written 187345
    0.00 reads/s, 0.00 creates/s, 0.00 writes/s
    No buffer pool page gets since the last printout
    Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
    LRU len: 15223, unzip_LRU len: 0
    I/O sum[0]:cur[0], unzip sum[0]:cur[0]
    ---BUFFER POOL 5
    Buffer pool size   16384
    Free buffers       1094
    Database pages     15215
    Old database pages 5598
    Modified db pages  3200
    Pending reads      0
    Pending writes: LRU 0, flush list 0, single page 0
    Pages made young 7117, not young 14164
    0.00 youngs/s, 0.00 non-youngs/s
    Pages read 6171, created 10595, written 174556
    0.00 reads/s, 0.00 creates/s, 0.00 writes/s
    Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
    Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
    LRU len: 15215, unzip_LRU len: 0
    I/O sum[0]:cur[0], unzip sum[0]:cur[0]
    ---BUFFER POOL 6
    Buffer pool size   16384
    Free buffers       1091
    Database pages     15209
    Old database pages 5594
    Modified db pages  3200
    Pending reads      0
    Pending writes: LRU 0, flush list 0, single page 0
    Pages made young 7012, not young 97165
    0.00 youngs/s, 0.00 non-youngs/s
    Pages read 6141, created 10860, written 179494
    0.00 reads/s, 0.00 creates/s, 0.00 writes/s
    No buffer pool page gets since the last printout
    Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
    LRU len: 15209, unzip_LRU len: 0
    I/O sum[0]:cur[0], unzip sum[0]:cur[0]
    ---BUFFER POOL 7
    Buffer pool size   16384
    Free buffers       1085
    Database pages     15220
    Old database pages 5598
    Modified db pages  3200
    Pending reads      0
    Pending writes: LRU 0, flush list 0, single page 0
    Pages made young 8467, not young 65568
    0.00 youngs/s, 0.00 non-youngs/s
    Pages read 6401, created 10965, written 197900
    0.00 reads/s, 0.00 creates/s, 0.00 writes/s
    Buffer pool hit rate 1000 / 1000, young-making rate 0 / 1000 not 0 / 1000
    Pages read ahead 0.00/s, evicted without access 0.00/s, Random read ahead 0.00/s
    LRU len: 15220, unzip_LRU len: 0
    I/O sum[0]:cur[0], unzip sum[0]:cur[0]
    ...
    

    其中一些字段的含义如下:

    • Total large memory allocated:代表 Buffer Pool 向操作系统申请的连续内存空间大小,包括全部控制块、缓冲页、以及碎片。
    • Buffer pool size:代表该 Buffer Pool 可以容纳多少缓冲页,单位是页。
    • Free buffers:代表当前 Buffer Pool 还有多少空闲缓冲页,也就是 free 链表中还有多少个节点。
    • Database pages:代表 LRU 链表中页的数量。
    • Modified db pages:代表脏页数量,也就是 flush 链表中节点的数量。
    • Buffer pool hit rate:表示在过去某段时间内,平均访问 1000 次页面时,该页面有多少次已经被缓存到 Buffer Pool中。

参考资料

  • 《MySQL 是怎样运行的 —— 从根上理解 MySQL》 第 17章 小孩子 1949 著
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值