È possibile visualizzare i valori LRU-K in SQL Server?


21

In SQL Server sys.dm_os_memory_cache_entries, è possibile visualizzare sia il costo originale di una voce nella cache sia il costo corrente della voce cache ( original_coste current_costrispettivamente). Il DMV sys.dm_os_buffer_descriptorscontiene un record delle pagine attualmente in memoria e alcuni metadati relativi alle pagine. Una parte interessante di informazioni non disponibili nel DVM sono i valori LRU-K per le pagine di dati.

È possibile ottenere i valori LRU-K per le pagine di dati nel pool di buffer in SQL Server? Se é cosi, come?


Questa versione è specifica?
JNK,

1
@JNK - In un mondo perfetto, no, ma finché funziona su SQL Server 2012 non mi preoccupo davvero.
Jeremiah Peschka,

Risposte:


21

In realtà non c'è modo utile per farlo per quanto posso vedere.

L'altra risposta menziona DBCC PAGEe lascia al lettore capire i dettagli. Per sperimentazione presumo che significhino bUse1.

Questo non tiene conto che DBCC PAGEè esso stesso un uso della pagina e il valore viene aggiornato prima che ci venga mostrato.

Uno script che dimostra questo è di seguito (l'esecuzione di 12 secondi).

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

I risultati tipici sono

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

Con il secondo risultato essere

+---------+-------------------------+--------------+--------------------+
| 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 |
+---------+-------------------------+--------------+--------------------+

L'uscita dopo il ritardo di 7 secondi viene incrementata di 7 e dopo il ritardo di 5 secondi di 5.

Quindi sembra chiaro che questi valori LRU sono secondi dall'epoca. Il riavvio del servizio SQL Server non modifica l'epoca ma il riavvio della macchina lo fa.

Il valore passa ogni 65.536 secondi quindi presumo che usi solo qualcosa di simile system_up_time mod 65536

Questo lascia nella mia mente una domanda senza risposta (qualche acquirente?). SQL Server utilizza LRU-Kcon K=2secondo il libro interno. Non dovrebbe esserci un bUse2? Se è così dov'è?

C'è un modo di osservare il bUse1valore senza cambiarlo che io conosco e che è dimostrato da Bob Ward qui.

Collegare un debugger al processo di SQL Server e visualizzare la memoria di riferimento per l'indirizzo di memoria della struttura del buffer (mostrato 0x00000002FE1F1440sopra).

L'ho fatto immediatamente dopo aver eseguito lo script sopra e ho visto quanto segue.

inserisci qui la descrizione dell'immagine

(Da precedenti sperimentazioni avevo scoperto che i byte evidenziati erano gli unici che cambiavano tra le esecuzioni, quindi sono sicuramente quelli giusti).

Un aspetto sorprendente è che SELECT CAST(0xc896 as int)= 51350.

Questo è esattamente 3600 (un'ora) in meno rispetto a quanto riportato da DBCC PAGE.

Credo che questo sia un tentativo di sfatare le pagine mantenute nella cache chiamando DBCC PAGEse stesse. Per una pagina "normale" selezionare questa regolazione di un'ora non si verifica. Dopo aver corso

SELECT *
FROM T

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

Il valore mostrato in memoria è come previsto.

Il DBCCcomando aggiorna effettivamente quel valore due volte. Una volta a

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

Con il valore più alto, quindi di nuovo a

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

Con quello inferiore.

Non sono a conoscenza di alcun modo per ottenere gli indirizzi buffer per le pagine senza usare DBCC BUFFER/ in DBCC PAGEalcun modo e usando entrambe queste modifiche il valore che stiamo cercando di ispezionare!


3
Bene, questo è un modo per passare il tuo Natale. :-)
RBarryYoung il

3
@RBarryYoung Beats giocando a Trivial Pursuit!
Martin Smith,

Se potessi dare punti bonus per l'uso appropriato di un debugger, lo farei.
Jeremiah Peschka,

1
Molto bene! (E grandi capacità di debug!)
DBArgenis,

@DBArgenis - Grazie! Peccato che non sembra esserci una soluzione pratica. Potrebbe essere abbastanza informativo se potessimo vederlo facilmente.
Martin Smith,

8

Come ho già detto a Peschka su Twitter, queste informazioni sono conservate nella struttura della BUF che contiene la pagina in memoria. DBCC PAGE fornisce queste informazioni come parte dell'intestazione.


3
A malincuore, ti concedo "la risposta", @DBArgenis. Continuo a sostenere che DBCC PAGEè un modo terribile di trovare qualcosa, ma tu sembri avere ragione. È un peccato che i dati DBCC PAGEsiano, effettivamente, incomprensibili e non si riferiscano a nessun tempo reale del sistema.
Jeremiah Peschka il

8
Un esempio sarebbe un'utile aggiunta a questa risposta.
Mark Storey-Smith il

3
@ MarkStorey-Smith - Sono d'accordo. A meno che DBArgenis non abbia qualche asso nella manica, non vedo come sia utile.
Martin Smith,

2
Nessun riferimento alla PAGINA DBCC equivale mai a qualcosa di utile.
Jeremiah Peschka,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.