是否可以在SQL Server中查看LRU-K值?


21

在SQL Server中sys.dm_os_memory_cache_entries,可以查看缓存中条目的原始成本以及缓存条目的当前成本(original_costcurrent_cost)。DMV sys.dm_os_buffer_descriptors包含当前内存中页面的记录以及有关页面的一些元数据。DVM中没有的一个有趣的信息块是数据页的LRU-K值。

是否可以获取SQL Server缓冲池中数据页的LRU-K值?如果是这样,怎么办?


此版本特定吗?
JNK 2013年

1
@JNK-完美的世界,没有,但是只要它在SQL Server 2012上有效,我就不用担心。
Jeremiah Peschka

Answers:


21

据我所知,实际上没有任何有用的方法可以做到这一点。

另一个答案提到DBCC PAGE并留给读者自己找出细节。通过实验,我认为它们的意思是bUse1

这没有考虑到DBCC PAGE页面本身的用途,并且值在显示给我们之前已更新。

演示此操作的脚本如下(运行需要12秒)。

USE tempdb;

CREATE TABLE T(X INT);

INSERT INTO T VALUES(1);

DECLARE @DBCCPAGE NVARCHAR(100);

SELECT @DBCCPAGE = 'DBCC PAGE(0,' + CAST(file_id AS VARCHAR) + ',' + CAST(page_id AS VARCHAR) + ',0) WITH TABLERESULTS;'
FROM   T CROSS APPLY  sys.fn_PhysLocCracker (%%physloc%%)

DECLARE @DbccResults TABLE 
(
      ID INT IDENTITY,
      ParentObject VARCHAR(1000)NULL,
      Object VARCHAR(4000)NULL,
      Field VARCHAR(1000)NULL,
      ObjectValue VARCHAR(MAX)NULL
)    
INSERT INTO @DbccResults EXEC(@DBCCPAGE)  
WAITFOR DELAY '00:00:07'
INSERT INTO @DbccResults EXEC(@DBCCPAGE)  
WAITFOR DELAY '00:00:05'
INSERT INTO @DbccResults EXEC(@DBCCPAGE)             

SELECT *
FROM @DbccResults   
WHERE Field = 'bUse1'    
ORDER BY ID

EXEC(@DBCCPAGE) 

DROP TABLE T

典型结果是

+----+--------------+-------------------------+-------+-------------+
| ID | ParentObject |         Object          | Field | ObjectValue |
+----+--------------+-------------------------+-------+-------------+
|  8 | BUFFER:      | BUF @0x00000002FE1F1440 | bUse1 |       54938 |
| 49 | BUFFER:      | BUF @0x00000002FE1F1440 | bUse1 |       54945 |
| 90 | BUFFER:      | BUF @0x00000002FE1F1440 | bUse1 |       54950 |
+----+--------------+-------------------------+-------+-------------+

第二个结果是

+---------+-------------------------+--------------+--------------------+
| BUFFER: | BUF @0x00000002FE1F1440 | bpage        | 0x00000002F4968000 |
| BUFFER: | BUF @0x00000002FE1F1440 | bhash        | 0x0000000000000000 |
| BUFFER: | BUF @0x00000002FE1F1440 | bpageno      | (1:120)            |
| BUFFER: | BUF @0x00000002FE1F1440 | bdbid        | 8                  |
| BUFFER: | BUF @0x00000002FE1F1440 | breferences  | 0                  |
| BUFFER: | BUF @0x00000002FE1F1440 | bcputicks    | 0                  |
| BUFFER: | BUF @0x00000002FE1F1440 | bsampleCount | 0                  |
| BUFFER: | BUF @0x00000002FE1F1440 | bUse1        | 54950              |
| BUFFER: | BUF @0x00000002FE1F1440 | bstat        | 0x9                |
| BUFFER: | BUF @0x00000002FE1F1440 | blog         | 0x1c9a             |
| BUFFER: | BUF @0x00000002FE1F1440 | bnext        | 0x0000000000000000 |
+---------+-------------------------+--------------+--------------------+

7秒延迟后的输出增加7,5秒延迟后的输出增加5。

因此,很明显,这些LRU值距离某个纪元仅几秒钟。重新启动SQL Server服务不会更改纪元,但重新启动计算机会更改纪元。

该值每65,536秒滚动一次,因此我认为它只使用类似 system_up_time mod 65536

这确实在我的脑海中留下了一个未解决的问题(任何参与者?)。SQL Server使用LRU-KK=2根据内部书。不应该有bUse2吗?如果是这样,那在哪里?

bUse1我知道,有一种观察值而不更改它的方法,Bob Ward在此演示了这一点。

将调试器附加到SQL Server进程,并显示引用的内存以获取缓冲区结构的内存地址(如上所示0x00000002FE1F1440)。

运行上面的脚本后,我立即执行了此操作,然后看到了以下内容。

在此处输入图片说明

(从以前的实验中,我发现突出显示的字节是运行之间唯一改变的字节,因此这些绝对是正确的)。

一个令人惊讶的方面是SELECT CAST(0xc896 as int)= 51350

比的报告少3600(一小时)DBCC PAGE

我相信这是一种尝试通过调用DBCC PAGE自身来使保留在缓存中的页面不受欢迎的尝试。对于“正常”页面,请选择此一小时的调整。跑步后

SELECT *
FROM T

SELECT ((ms_ticks) % 65536000) / 1000 AS [Roughly Expected Value]
FROM sys.dm_os_sys_info

内存中显示的值符合预期。

DBCC命令实际上将该值更新两次。一次

sqlmin.dll!BPool::Touch()  + 0x3bfe bytes   
sqlmin.dll!BPool::Get()  + 0x12e bytes  
sqlmin.dll!LatchedBuf::ReadLatch()  + 0x14f bytes   
sqlmin.dll!UtilDbccDumpPage()  + 0x364 bytes    
sqlmin.dll!DbccPage()  + 0xfa bytes 
sqllang.dll!DbccCommand::Execute()  + 0x153 bytes

具有较高的值,然后再次位于

sqlmin.dll!LatchedBuf::FreeAndUnlatch()  + 0x71 bytes   
sqlmin.dll!UtilDbccDumpPage()  + 0x545 bytes    
sqlmin.dll!DbccPage()  + 0xfa bytes 
sqllang.dll!DbccCommand::Execute()  + 0x153 bytes   

与较低的。

我不知道有什么方法可以在不使用DBCC BUFFER/的情况下获取页面的缓冲区地址,DBCC PAGE但是同时使用这两种更改,我们正在尝试检查的值!


3
好吧,这是度过圣诞节的一种方式。:-)
RBarryYoung 2013年

3
@RBarryYoung Beats玩琐碎的追求!
马丁·史密斯

如果我可以给适当使用调试器的奖励积分,我会的。
Jeremiah Peschka

1
做得好!(以及出色的调试技巧!)
DBArgenis

@DBArgenis-谢谢!遗憾的是,似乎没有可行的解决方案。如果我们可以轻松地看到这一点,可能会提供很多信息。
马丁·史密斯

8

正如我在推特上向Peschka先生提到的那样,此信息保留在将页面保存在内存中的BUF结构中。DBCC PAGE将此信息作为标题提供给您。


3
奇怪的是,我给你“答案”,@ DBArgenis。我仍然认为这DBCC PAGE是找到任何东西的可怕方法,但是您似乎是正确的。很遗憾,来自的数据DBCC PAGE实际上是乱码,并且与任何实际系统时间都不相关。
Jeremiah Peschka

8
一个示例将是对该答案的有用补充。
Mark Storey-Smith

3
@ MarkStorey-Smith-我同意。除非DBArgenis袖手旁观,否则我看不出这有什么用。
马丁·史密斯

2
从未提及DBCC PAGE会有用。
Jeremiah Peschka 2013年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.