210_mysql_innodb_5_Innodb_online_ddl
580
2022-05-29
innodb 对 Bufffer Pool 的 LRU 算法做了优化,即:第一次从磁盘读入内存的数据页,会先放在 old 区域。如果 1 秒之后这个数据页不再被访问了,就不会被移动到 LRU 链表头部,这样对 Buffer Pool 的命中率影响就不大。
LRU:淘汰最久未使用的数据。
在 InnoDB 实现上,按照 5:3 的比例把整个 LRU 链表分成了 young 区域和 old 区域。
LRU_old 指向的就是 old 区域的第一个位置,是整个链表的 5/8 处。
靠近链表头部的 5/8 是 young 区域,靠近链表尾部的 3/8 是 old 区域。
//在 young 区域,因此和优化前的 LRU 算法一样。
//新插入的数据放入到LRU_OLD处,Old list 存储那些低频使用的数据(默认占整个BUFFER的3/8)
//Old list内的任何一个块数据被再次访问,innodb都会把它加入到Young list的头部。
-- innodb_old_blocks_time 控制的
这个参数用来表示 页读取到mid位置后,需要等待多久才会被加入到LRU列表的热端。
使LRU列表中的热点数据不被刷出:
set global innodb_old_blocks_time=1000;
1
放在冷热数据交界处,默认1000ms,过了这1s,还能存活下去,就调到热数据区了。
若存在时间超过了1秒,移动到链表头部。
#######################
扫描 200G 的历史数据表为例:
扫描过程中,需要新插入的数据页,都被放到 old 区域 ;
一个数据页里面有多条记录,这个数据页会被多次访问到,但由于是顺序扫描,这个数据页第一次被访问和最后一次被访问的时间间隔不会超过 1 秒,因此还是会被保留在 old 区域;
再继续扫描后续的数据,之前的这个数据页之后也不会再被访问到,于是始终没有机会移到链表头部(也就是 young 区域),很快就会被淘汰出去。可以看到,这个策略最大的收益,就是在扫描这个大表的过程中,虽然也用到了 Buffer Pool,但是对 young 区域完全没有影响,从而保证了 Buffer Pool 响应正常业务的查询命中率。
MySQL
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。