MySQL buffer pool里的三种链表和三种page

mysql buffer pool里的三种链表和三种page


buffer pool是通过三种list来管理的
1) free list
2) lru list
3) flush list

 

buffer pool中的最小单位是page,在innodb中定义三种page
1) free page :此page未被使用,此种类型page位于free链表中
2) clean page:此page被使用,对应数据文件中的一个页面,但是页面没有被修改,此种类型page位于lru链表中
3) dirty page:此page被使用,对应数据文件中的一个页面,但是页面被修改过,此种类型page位于lru链表和flush链表中

 

buffer pool flush list的工作原理

 

dirty page如何存在flush链表中?


在flush list中存在的page只能是dirty page,flush list中存在的dirty page是按着oldest_modification时间排序的,当页面访问/修改都被封装为一个mini-transaction,mini-transactin提交的时候,则mini-transaction涉及到的页面就进入了flush链表中,oldest_modification的值越大,说明page越晚被修改过,就排在flush链表的头部,oldest_modification的值越小,说明page越早被修改过,就排在flush链表的尾部,这样当flush链表做flush动作时,从flush链表的尾部开始scan,写出一定数量的dirty page到磁盘,推荐checkpoint点,使恢复的时间尽可能的短。除了flush链表本身的flush操作可以把dirty page从flush链表删除外,lru链表的flush操作也会让dirty page从flush链表删除。


buffer pool lru list的工作原理

总的来说每当一个新页面被读取buffer pool之后,MySQL数据库InnoDB存储引擎都会判断当前buffer pool的free page是否足够,若不足,则尝试flush LRU链表。

在MySQL 5.6.2之前,用户线程在读入一个page (buf_read_page)、新建一个page(buf_page_create)、预读page(buf_read_ahead_linear) 等等操作时,都会在操作成功之后,调用buf_flush_free_margin函数,判断当前buffer pool是否有足够的free pages,若free pages不足,则进行LRU list flush,释放出足够的free pages,保证系统的可用性。


通过判断当前buf pool中需要flush多少dirty pages,才能够预留出足够的可被替换的页面(free pages or clean pages in LRU list tail)。

 

说明:
可用pages由以下两部分组成:
1. buf pool free list中的所有page,都是可以立即使用的。
2. buf pool LRU list尾部(5+2*BUF_READ_AHEAD_AREA)所有的clean pages。
其中:BUF_READ_AHEAD_AREA为64,是一个linear read ahead读取的大小,1 extent

 

由于buf_flush_free_margin函数是在用户线程中调用执行的,若需要flush LRU list,那么对于用户的响应时间有较大的影响。因此,在MySQL 5.6.2之后,InnoDB专门开辟了一个page cleaner线程,处理dirty page的flush动作(包括LRU list flush与flush list flush),降低page flush对于用户的影响。

在MySQL 5.6.2前后的版本中,LRU list flush的不同之处在于是由用户线程发起,还是有后台page cleaner线程发起。但是,无论是用户线程,还是后台page cleaner线程,再决定需要进行LRU list flush之后,都会调用buf_flush_LRU函数进行真正的flush操作。

 
不同之处在于,MySQL 5.6.2之前,用户线程调用的buf_flush_free_margin函数,在判断是否真正需要进行LRU list flush时,将LRU list tail部分的clean pages也归为可以被replace的pages,不需要flush。而在page cleaner线程中,每隔1s,无论如何都会进行一次LRU list flush调用,无论LRU list tail中的page是否clean。这也可以理解,用户线程,需要尽量降低flush的概率,提高用户响应;而后台线程,尽量进行flush尝试,释放足够的free pages,保证用户线程不会堵塞。

 

Buffer Pool LRU/Flush List flush对比

1).LRU list flush,由用户线程触发(MySQL 5.6.2之前);而Flush list flush由MySQL数据库InnoDB存储引擎后台srv_master线程处理。(在MySQL 5.6.2之后,都被迁移到page cleaner线程中)
 
2).LRU list flush,其目的是为了写出LRU 链表尾部的dirty page,释放足够的free pages,当buf pool满的时候,用户可以立即获得空闲页面,而不需要长时间等待;Flush list flush,其目的是推进Checkpoint LSN,使得InnoDB系统崩溃之后能够快速的恢复。
 
3).LRU list flush,其写出的dirty page,需要移动到LRU链表的尾部(MySQL 5.6.2之前版本);或者是直接从LRU链表中删除,移动到free list(MySQL 5.6.2之后版本)。Flush list flush,不需要移动page在LRU链表中的位置。
 
4).LRU list flush,由于可能是用户线程发起,已经持有其他的page latch,因此在LRU list flush中,不允许等待持有新的page latch,导致latch死锁;而Flush list flush由后台线程发起,未持有任何其他page latch,因此可以在flush时等待page latch。
 
5).LRU list flush,每次flush的dirty pages数量较少,基本固定,只要释放一定的free pages即可;Flush list flush,根据当前系统的更新繁忙程度,动态调整一次flush的dirty pages数量,量很大。

 

buffer pool free list工作原理
free链表里存放的是空闲页面,初始化的时候申请一定数量的page,在使用的过程中,每次成功load页面到内存后,都会判断free page是否够用,如果不够用的话,就flush lru链表和flush链表来释放free page,这就可以满足其他进程在申请页面,使系统可用。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值