Tak naprawdę, jak widzę, nie ma użytecznego sposobu na zrobienie tego.
Druga odpowiedź wspomina DBCC PAGE
i pozostawia czytelnikowi ustalenie szczegółów. Z eksperymentów zakładam, że mają na myśli bUse1
.
Nie bierze się pod uwagę, że DBCC PAGE
samo jest to użytkowanie strony, a wartość jest aktualizowana, zanim zostanie nam pokazana.
Skrypt demonstrujący to jest poniżej (uruchomienie zajmuje 12 sekund).
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
Typowe wyniki to
+----+--------------+-------------------------+-------+-------------+
| ID | ParentObject | Object | Field | ObjectValue |
+----+--------------+-------------------------+-------+-------------+
| 8 | BUFFER: | BUF @0x00000002FE1F1440 | bUse1 | 54938 |
| 49 | BUFFER: | BUF @0x00000002FE1F1440 | bUse1 | 54945 |
| 90 | BUFFER: | BUF @0x00000002FE1F1440 | bUse1 | 54950 |
+----+--------------+-------------------------+-------+-------------+
Z drugim rezultatem
+---------+-------------------------+--------------+--------------------+
| 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 |
+---------+-------------------------+--------------+--------------------+
Wyjście po 7-sekundowym opóźnieniu jest zwiększane o 7, a po 5-sekundowym opóźnieniu o 5.
Wydaje się więc jasne, że te wartości LRU to sekundy od pewnej epoki. Ponowne uruchomienie usługi SQL Server nie zmienia epoki, ale powoduje to ponowne uruchomienie komputera.
Wartość zmienia się co 65 536 sekund, więc zakładam, że po prostu używa czegoś takiego system_up_time mod 65536
Pozostawia to w pamięci jedno pytanie bez odpowiedzi (któryś z uczestników?). SQL Server używa LRU-K
się K=2
według książki wewnętrzne. Czy nie powinno być bUse2
? Jeśli tak to gdzie to jest?
Jest jeden sposób na obserwowanie bUse1
wartości bez jej zmiany, o którym wiem, o czym świadczy tutaj Bob Ward .
Dołącz debugger do procesu SQL Server i wyświetl pamięć odniesienia dla adresu pamięci struktury bufora (pokazano 0x00000002FE1F1440
powyżej).
Zrobiłem to natychmiast po uruchomieniu powyższego skryptu i zobaczyłem następujące.
(Z wcześniejszych eksperymentów odkryłem, że wyróżnione bajty były jedynymi, które zmieniły się między przebiegami, więc są zdecydowanie właściwe).
Jednym zaskakującym aspektem jest to, że SELECT CAST(0xc896 as int)
= 51350
.
To dokładnie 3600 (jedna godzina) mniej niż zgłaszane przez DBCC PAGE
.
Uważam, że jest to próba zniechęcenia stron do przechowywania w pamięci podręcznej przez wywołanie DBCC PAGE
siebie. W przypadku strony „normalnej” wybierz tę jednogodzinną regulację. Po bieganiu
SELECT *
FROM T
SELECT ((ms_ticks) % 65536000) / 1000 AS [Roughly Expected Value]
FROM sys.dm_os_sys_info
Wartość wyświetlana w pamięci jest zgodna z oczekiwaniami.
DBCC
Komenda faktycznie aktualizuje tę wartość dwukrotnie. Raz o
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
Z wyższą wartością to ponownie przy
sqlmin.dll!LatchedBuf::FreeAndUnlatch() + 0x71 bytes
sqlmin.dll!UtilDbccDumpPage() + 0x545 bytes
sqlmin.dll!DbccPage() + 0xfa bytes
sqllang.dll!DbccCommand::Execute() + 0x153 bytes
Z dolnym.
Nie znam żadnego sposobu na uzyskanie adresów buforów dla stron bez użycia DBCC BUFFER
/ DBCC PAGE
żadnego sposobu i przy użyciu obu tych zmian wartość, którą próbujemy sprawdzić!