在 SQL Server 的 中sys.dm_os_memory_cache_entries,既可以查看缓存中条目的原始成本,也可以查看缓存条目的当前成本(original_cost和current_cost)。DMVsys.dm_os_buffer_descriptors包含当前内存中页面的记录以及有关页面的一些元数据。DVM 中没有的一大块有趣的信息是数据页的 LRU-K 值。
是否可以获取 SQL Server 缓冲池中数据页的 LRU-K 值?如果是这样,如何?
Mar*_*ith 23
事实上,据我所知,没有任何有用的方法可以做到这一点。
另一个答案提到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
Run Code Online (Sandbox Code Playgroud)
典型的结果是
+----+--------------+-------------------------+-------+-------------+
| ID | ParentObject | Object | Field | ObjectValue |
+----+--------------+-------------------------+-------+-------------+
| 8 | BUFFER: | BUF @0x00000002FE1F1440 | bUse1 | 54938 |
| 49 | BUFFER: | BUF @0x00000002FE1F1440 | bUse1 | 54945 |
| 90 | BUFFER: | BUF @0x00000002FE1F1440 | bUse1 | 54950 |
+----+--------------+-------------------------+-------+-------------+
Run Code Online (Sandbox Code Playgroud)
第二个结果是
+---------+-------------------------+--------------+--------------------+
| 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 |
+---------+-------------------------+--------------+--------------------+
Run Code Online (Sandbox Code Playgroud)
7 秒延迟后的输出增加 7,5 秒延迟后的输出增加 5。
所以很明显,这些 LRU 值是自某个纪元以来的秒数。重新启动 SQL Server 服务不会改变时代,但重新启动机器会改变。
该值每 65,536 秒滚动一次,所以我认为它只是使用类似 system_up_time mod 65536
这确实在我的脑海中留下了一个悬而未决的问题(任何接受者?)。SQL Server使用LRU-K与K=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
Run Code Online (Sandbox Code Playgroud)
内存中显示的值符合预期。
该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
Run Code Online (Sandbox Code Playgroud)
使用更高的值然后再次在
sqlmin.dll!LatchedBuf::FreeAndUnlatch() + 0x71 bytes
sqlmin.dll!UtilDbccDumpPage() + 0x545 bytes
sqlmin.dll!DbccPage() + 0xfa bytes
sqllang.dll!DbccCommand::Execute() + 0x153 bytes
Run Code Online (Sandbox Code Playgroud)
与较低的。
我不知道有什么方法可以在不使用DBCC BUFFER/DBCC PAGE任何方式的情况下获取页面的缓冲区地址,但使用这两种方法都会更改我们试图检查的值!
| 归档时间: |
|
| 查看次数: |
940 次 |
| 最近记录: |