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

前端之家收集整理的这篇文章主要介绍了sql-server – 是否可以在SQL Server中查看LRU-K值?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
sql Server的sys.dm_os_memory_cache_entries中,可以查看缓存中条目的原始开销以及缓存条目的当前开销(分别为original_cost和current_cost). DMV sys.dm_os_buffer_descriptors包含当前在内存中的页面的记录以及有关页面的一些元数据. DVM中没有的一个有趣的信息块是数据页的LRU-K值.

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

解决方法

事实上,就我所见,实际上没有有用的方法可以做到这一点.

另一个答案提到了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使用K = 2的LRU-K.不应该有bUse2吗?如果是这样的话呢?

有一种观察bUse1值而不改变它的方法虽然我知道,这里是demonstrated by Bob Ward.

将调试器附加到sql Server进程并显示缓冲区结构的内存地址的引用内存(上面显示为0x00000002FE1F1440).

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

(从之前的实验中我发现突出显示的字节是在运行之间唯一改变的字节,所以这些肯定是正确的).

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

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

我相信这是尝试通过调用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的情况下获取页面的缓冲区地址,并且使用这两个更改我们要检查的值!

猜你在找的MsSQL相关文章