MySQL InnoDB 缓冲策略相关知识
目录
MySQL5.6
问题和概念?
1. Innodb 缓冲池缓冲的是什么?
缓存表数据和索引数据。
2. 什么是预读?
读写磁盘,并不是按需读取,而是一次至少读取一页数据(一半是4k)。
3. 预读为什么有效?
局部性原理
4. 按页(预读4k)读取,和Innodb的关系是什么?
-
磁盘访问数据按页读取能够提高性能,所以缓冲池也是按页缓冲数据。
-
根据预读嗯的机制,按页读取能够提高我们缓冲的命中率。
5. Innodb 是基于什么算法做的缓冲?
LRU(Least recently used)
6. 传统的 LRU 算法在 Innodb 中会存在什么问题?
-
预读失效(MySql最终没有从缓冲中读取预读的内容)
-
缓冲池污染(全表扫描的查询,会造成真真的热点数据从缓冲中移除)
7. 如何避免预读失效
-
让预读失效的页停留在缓冲池LRU里的时间尽可能短。
-
让真正被读取的页,才挪到缓冲池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秒 两个条件,才会被插入到新生代头部。