目录

MySQL InnoDB 缓冲策略相关知识

MySQL5.6

问题和概念?

1. Innodb 缓冲池缓冲的是什么?

缓存表数据和索引数据。

2. 什么是预读?

读写磁盘,并不是按需读取,而是一次至少读取一页数据(一半是4k)。

3. 预读为什么有效?

局部性原理

4. 按页(预读4k)读取,和Innodb的关系是什么?

  1. 磁盘访问数据按页读取能够提高性能,所以缓冲池也是按页缓冲数据。

  2. 根据预读嗯的机制,按页读取能够提高我们缓冲的命中率。

5. Innodb 是基于什么算法做的缓冲?

LRU(Least recently used)

6. 传统的 LRU 算法在 Innodb 中会存在什么问题?

  1. 预读失效(MySql最终没有从缓冲中读取预读的内容)

  2. 缓冲池污染(全表扫描的查询,会造成真真的热点数据从缓冲中移除)

7. 如何避免预读失效

  1. 让预读失效的页停留在缓冲池LRU里的时间尽可能短。

  2. 让真正被读取的页,才挪到缓冲池LRU的头部。

将LRU分为两部分,新生代(new sublist)和老生代(old sublist),新老生代首尾相连,新页加入缓冲池中的时候,只加入到老生代头部。只有真正被读取的页加入到新生代。

8. 如何避免缓冲池污染

MySQL 缓冲池加入一个“老生代停留时间窗口”的机制: 1. T = 老生代停留时间窗口 2. 插入老生代头部的页,即使被立即访问,也不会直接插入到新生代头部 3. 只有满足“被访问”并且“在老生代停留时间”大于T,才会被插入到新生代头部

相关数据库配置参数

  • innodb_buffer_pool_size

    • 配置缓冲池的大小,内存允许的情况下越大越好。
  • innodb_old_blocks_pct

    • 老生代占整个LRU链长度的比例,默认为37.
  • innodb_old_blocks_time

    • 老生代停留时间窗口,单位是毫秒,默认是1000,即同时满足 被访问 与 在老生代停留时间超过1秒 两个条件,才会被插入到新生代头部。