Czy można wyświetlić wartości LRU-K w programie SQL Server?

21

W SQL Server sys.dm_os_memory_cache_entriesmożna wyświetlić zarówno oryginalny koszt wpisu w pamięci podręcznej, jak i bieżący koszt wpisu w pamięci podręcznej ( original_costi current_costodpowiednio). DMV sys.dm_os_buffer_descriptorszawiera zapis stron, które są obecnie w pamięci, a także niektóre metadane dotyczące stron. Jednym z interesujących fragmentów informacji niedostępnych w DVM są wartości LRU-K dla stron danych.

Czy można uzyskać wartości LRU-K dla stron danych w puli buforów w SQL Server? Jeśli tak to jak?

Jeremiasz Peschka
źródło
Czy ta wersja jest specyficzna?
JNK,
1
@JNK - W idealnym świecie nie, ale dopóki działa na SQL Server 2012, tak naprawdę nie martwię się.
Jeremiah Peschka,

Odpowiedzi:

21

Tak naprawdę, jak widzę, nie ma użytecznego sposobu na zrobienie tego.

Druga odpowiedź wspomina DBCC PAGEi pozostawia czytelnikowi ustalenie szczegółów. Z eksperymentów zakładam, że mają na myśli bUse1.

Nie bierze się pod uwagę, że DBCC PAGEsamo 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-Księ K=2według książki wewnętrzne. Czy nie powinno być bUse2? Jeśli tak to gdzie to jest?

Jest jeden sposób na obserwowanie bUse1wartoś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 0x00000002FE1F1440powyżej).

Zrobiłem to natychmiast po uruchomieniu powyższego skryptu i zobaczyłem następujące.

wprowadź opis zdjęcia tutaj

(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 PAGEsiebie. 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.

DBCCKomenda 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ć!

Martin Smith
źródło
3
To jeden ze sposobów na spędzenie świąt. :-)
RBarryYoung
3
@RBarryYoung Beats grając w Trivial Pursuit!
Martin Smith
Gdybym mógł dać punkty bonusowe za właściwe użycie debuggera, zrobiłbym to.
Jeremiasz Peschka,
1
Dobra robota! (I świetne umiejętności debugowania!)
DBArgenis
@DBArgenis - Dzięki! Szkoda, że ​​nie ma praktycznego rozwiązania. Może to być bardzo pouczające, jeśli możemy to łatwo zobaczyć.
Martin Smith
8

Jak wspomniałem panu Peschce na Twitterze, ta informacja jest przechowywana w strukturze BUF, która utrzymuje stronę w pamięci. DBCC PAGE podaje tę informację jako część jej nagłówka.

DBArgenis
źródło
3
Niechętnie udzielam ci „odpowiedzi”, @DBArgenis. Nadal uważam, że DBCC PAGEto okropny sposób na znalezienie czegokolwiek, ale wydaje się, że masz rację. Szkoda, że ​​dane z tego DBCC PAGEsą faktycznie bełkotliwe i nie odnoszą się do żadnego rzeczywistego czasu systemowego.
Jeremiah Peschka,
8
Przykład byłby przydatnym dodatkiem do tej odpowiedzi.
Mark Storey-Smith
3
@ MarkStorey-Smith - Zgadzam się. Chyba że DBArgenis ma jakąś sztuczkę w rękawie, nie widzę, jak to jest przydatne.
Martin Smith,
2
Żadne odniesienie do strony DBCC nigdy nie jest przydatne.
Jeremiasz Peschka,