前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Postgresql源码(23)Clog使用的Slru页面淘汰机制

Postgresql源码(23)Clog使用的Slru页面淘汰机制

作者头像
mingjie
发布2022-07-14 13:42:48
2000
发布2022-07-14 13:42:48
举报

SLRU页面选择函数SlruSelectLRUPage:选择一个空的或淘汰一个SLOT(可能触发IO),返回一个可用SLOT

代码语言:javascript
复制
static int
SlruSelectLRUPage(SlruCtl ctl, int pageno)
{
	SlruShared	shared = ctl->shared;

	/* Outer loop handles restart after I/O */
	for (;;)
	{
		int			slotno;
		int			cur_count;
		int			bestvalidslot = 0;	/* keep compiler quiet */
		int			best_valid_delta = -1;
		int			best_valid_page_number = 0; /* keep compiler quiet */
		int			bestinvalidslot = 0;	/* keep compiler quiet */
		int			best_invalid_delta = -1;
		int			best_invalid_page_number = 0;	/* keep compiler quiet */

    // 已经分配过了直接使用
		for (slotno = 0; slotno < shared->num_slots; slotno++)
		{
			if (shared->page_number[slotno] == pageno &&
				shared->page_status[slotno] != SLRU_PAGE_EMPTY)
				return slotno;
		}
    
    // 没有找到已经分配的SLOT,开始O(n)找SLOT
    // 总体原则:先找空的、再找用的少的&&不是last刚使用的&&没在IO的,返回
		cur_count = (shared->cur_lru_count)++;
		for (slotno = 0; slotno < shared->num_slots; slotno++)
		{
			int			this_delta;
			int			this_page_number;
      // 如果是空的直接使用
			if (shared->page_status[slotno] == SLRU_PAGE_EMPTY)
				return slotno;
      
      // 计算差值,差值最大的表示最旧没用到的
      // 每次使用都会把shared->page_lru_count[slotno]值刷到shared->cur_lru_count的最新值
			this_delta = cur_count - shared->page_lru_count[slotno];
			if (this_delta < 0)
			{
				shared->page_lru_count[slotno] = cur_count;
				this_delta = 0;
			}
			this_page_number = shared->page_number[slotno];
			if (this_page_number == shared->latest_page_number)
				continue;
      // 记录最大差值到best_valid_delta
      // 记录最大差值的页面到best_valid_page_number
			if (shared->page_status[slotno] == SLRU_PAGE_VALID)
			{
				if (this_delta > best_valid_delta ||
					(this_delta == best_valid_delta &&
					 ctl->PagePrecedes(this_page_number,
									   best_valid_page_number)))
				{
					bestvalidslot = slotno;
					best_valid_delta = this_delta;
					best_valid_page_number = this_page_number;
				}
			}
			else
			{
				if (this_delta > best_invalid_delta ||
					(this_delta == best_invalid_delta &&
					 ctl->PagePrecedes(this_page_number,
									   best_invalid_page_number)))
				{
					bestinvalidslot = slotno;
					best_invalid_delta = this_delta;
					best_invalid_page_number = this_page_number;
				}
			}
		}
    // 最大差值一直没有被赋值
    // 说明所有页面都是非FREE、非VALID状态,全部在IO中
    // 需要等IO
		if (best_valid_delta < 0)
		{
			SimpleLruWaitIO(ctl, bestinvalidslot);
			continue;
		}
    
    // 如果页面没有被修改过,直接使用
		if (!shared->page_dirty[bestvalidslot])
			return bestvalidslot;

    // 页面VALID、被修改过,需要IO到磁盘上
		SlruInternalWritePage(ctl, bestvalidslot, NULL);

	}
}

GDB脚本看下54页面刚用完,55页面开始使用的情况下,几个关键变量的变化

GDB

代码语言:javascript
复制
define lp9
set $total = shared->num_slots
set $i = 0
   while($i<$total)
     printf "(%2d) ", $i
     printf "(%2d) ", shared->page_number[$i]
     printf "(%d) ", shared->page_status[$i]
     printf "(%d)\n", shared->page_lru_count[$i]
     set $i = $i + 1
   end
end

结果

代码语言:javascript
复制
SlruSelectLRUPage(pageno=55)

slotno  page_number[slotno]  shared->page_status[slotno]  shared->page_lru_count[slotno]    shared->page_lru_count[slotno] (newpage55)
( 0)    ( 4)                 (2)                          (1770127)                         (1770127)
( 1)    ( 1)                 (2)                          (     11)                         (     11)                        
( 2)    ( 0)                 (2)                          (      6)                         (      6)                        
( 3)    ( 5)                 (2)                          ( 894332)                         ( 894332)                        
( 4)    ( 6)                 (2)                          ( 911112)                         ( 911112)                        
( 5)    ( 7)                 (2)                          (1755207)                         (1755207)                        
( 6)    ( 8)                 (2)                          (1448227)                         (1448227)                        
( 7)    ( 9)                 (2)                          (1633175)                         (1633175)                        
( 8)    (10)                 (2)                          (1455242)                         (1455242)                        
( 9)    (11)                 (2)                          (1633187)                         (1633187)                        
(10)    (12)                 (2)                          (1633177)                         (1633177)                        
(11)    (13)                 (2)                          (1278375)                         (1278375)                        
(12)    (14)                 (2)                          (1657380)                         (1657380)                        
(13)    (15)                 (2)                          (1126074)                         (1126074)                        
(14)    (16)                 (2)                          (1669976)                         (1669976)                        
(15)    (17)                 (2)                          (1721254)                         (1721254)                        
(16)    (18)                 (2)                          (1207329)                         (1207329)                        
(17)    (19)                 (2)                          (1606693)                         (1606693)                        
(18)    (20)                 (2)                          (1705478)                         (1705478)                        
(19)    (21)                 (2)                          (1379095)                         (1379095)                        
(20)    (22)                 (2)                          (1633183)                         (1633183)                        
(21)    (23)                 (2)                          (1768703)                         (1768703)                        
(22)    (24)                 (2)                          (1769738)                         (1769738)                        
(23)    (25)                 (2)                          (1769806)                         (1769806)                        
(24)    (26)                 (2)                          (1769982)                         (1769982)                        
(25)    (27)                 (2)                          (1769271)                         (1769271)                        
(26)    (28)                 (2)                          (1770066)                         (1770066)                        
(27)    (29)                 (2)                          (1768997)                         (1768997)      
(28)    (30)                 (2)                          (1769748)                         (1769748)                                                
(29)    (31)                 (2)                          (1769408)                         (1769408)                        
(30)    (32)                 (2)                          (1769880)                         (1769880)                        
(31)    (33)                 (2)                          (1769997)                         (1769997)                        
(32)    (34)                 (2)                          (1769818)                         (1769818)                        
(33)    (35)                 (2)                          (1769992)                         (1769992)                        
(34)    (36)                 (2)                          (1769564)                         (1769564)                        
(35)    (37)                 (2)                          (1770077)                         (1770077)                        
(36)    (38)                 (2)                          (1770097)                         (1770097)                        
(37)    (39)                 (2)                          (1770111)                         (1770111)                        
(38)    (40)                 (2)                          (1770075)                         (1770075)                        
(39)    (41)                 (2)                          (1770067)                         (1770067)                        
(40)    (42)                 (2)                          (1770098)                         (1770098)                        
(41)    (43)                 (2)                          (1770072)                         (1770072)                        
(42)    (44)                 (2)                          (1770065)                         (1770065)                        
(43)    (45)                 (2)                          (1770119)                         (1770119)                        
(44)    (46)                 (2)                          (1770070)                         (1770070)                        
(45)    (47)                 (2)                          (1770123)                         (1770123)                        
(46)    (48)                 (2)                          (1770088)                         (1770088)                        
(47)    (49)                 (2)                          (1770117)                         (1770117)                        
(48)    (50)                 (2)                          (1770120)                         (1770120)                        
(49)    (51)                 (2)                          (1770122)                         (1770122)                        
(50)    (52)                 (2)                          (1770107)                         (1770107)                        
(51)    (53)                 (2)                          (1770121)                         (1770121)                        
(52)    (54)                 (2)                          (1770128)                         (1770128)                        
(53)    ( 0) -> (55)         (0) -> (2)                   (      0) -> (1770130)            (1770130)                        
(54)    ( 0)                 (0)                          (      0)                         (      0)                        
(55)    ( 0)                 (0)                          (      0)                         (      0)                        
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2021-12-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档