缓冲池💡
缓冲,典型的缓存思想,通过缓存来获取更高的速度
池, 典型的 池化思想技术,本质上是提供复用率,较少资源的创建、删除。如线程池等
通过预读和局部性原理,mysql每次都是按页(4K)读取。每页读取后。会放在bufferpool中。把bufferpool当成一个缓存,就有个很重要的问题,即失效策略。
过期算法
把入缓冲池的页放到LRU的头部,作为最近访问的元素,从而最晚被淘汰
问题:
- 预读失效(预读数据可能没被使用):由于预读(Read-Ahead),提前把页放入了缓冲池,但最终MySQL并没有从页中读取数据,称为预读失效。
- [缓冲池污染]
当某一个SQL语句,要批量扫描大量数据时,可能导致把缓冲池的所有页都替换出去,导致大量热数据被换出,MySQL性能急剧下降,这种情况叫缓冲池污染。
那如果解决这个问题呢?本质上就是进行冷热数据分离思想。这里和垃圾回收中的分代收集算法思想是一样的。
mysqlLRU
- 区分热数据和冷数据。
- 设置放到热数据区的条件,来使得冷数据切换到热数据(都要达到,避免缓冲池污染,即短时间内扫描大量数据,导致热点数据被替换出来)
- 被访问的次数达标
- 在冷数据区停留时间大于T
参数
- innodb_buffer_pool_size(大小):配置缓冲池的大小,在内存允许的情况下,DBA往往会建议调大这个参数,越多数据和索引放到内存里,数据库的性能会越好
- innodb_old_blocks_pct:老生代占整个LRU链长度的比例,默认是37,即整个LRU中新生代与老生代长度比例是63:37。画外音:如果把这个参数设为100,就退化为普通LRU了
- innodb_old_blocks_time(在老生代停留时间):老生代停留时间窗口,单位是毫秒,默认是1000,即同时满足“被访问”与“在老生代停留时间超过1秒”两个条件,才会被插入到新生代头部。