Est-il possible d'afficher les valeurs LRU-K dans SQL Server?

21

Dans SQL Server sys.dm_os_memory_cache_entries, il est possible d'afficher à la fois le coût d'origine d'une entrée dans le cache ainsi que le coût actuel de l'entrée du cache ( original_costet current_costrespectivement). Le DMV sys.dm_os_buffer_descriptorscontient un enregistrement des pages actuellement en mémoire ainsi que des métadonnées sur les pages. Un morceau intéressant d'informations non disponibles dans le DVM sont les valeurs LRU-K pour les pages de données.

Est-il possible d'obtenir les valeurs LRU-K pour les pages de données dans le pool de tampons dans SQL Server? Si c'est le cas, comment?

Jeremiah Peschka
la source
Cette version est-elle spécifique?
JNK
1
@JNK - Dans un monde parfait, non, mais tant qu'il fonctionne sur SQL Server 2012, je ne m'inquiète pas vraiment.
Jeremiah Peschka

Réponses:

21

Il n'y a en fait aucun moyen utile de le faire pour autant que je puisse voir.

L'autre réponse mentionne DBCC PAGEet laisse au lecteur le soin de comprendre les détails. D'après l'expérimentation, je suppose qu'ils signifient bUse1.

Cela ne prend pas en compte qui DBCC PAGEest en soi une utilisation de la page et la valeur est mise à jour avant qu'elle ne nous soit montrée.

Un script démontrant ceci est ci-dessous (prend 12 secondes pour s'exécuter).

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

Les résultats typiques sont

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

Le deuxième résultat étant

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

La sortie après le délai de 7 secondes est incrémentée de 7 et après le délai de 5 secondes de 5.

Il semble donc clair que ces valeurs LRU sont des secondes depuis une certaine époque. Le redémarrage du service SQL Server ne modifie pas l'époque mais le redémarrage de la machine le fait.

La valeur est reportée toutes les 65 536 secondes, donc je suppose qu'elle utilise simplement quelque chose comme system_up_time mod 65536

Cela laisse une question sans réponse dans mon esprit (des preneurs?). SQL Server utilise LRU-Kavec K=2selon le livre interne. Ne devrait-il pas y en avoir bUse2? Si oui, où est-ce?

Il y a une façon d'observer la bUse1valeur sans la changer que je sache et c'est Bob Ward démontre ici.

Attachez un débogueur au processus SQL Server et affichez la mémoire référencée pour l'adresse mémoire de la structure de la mémoire tampon (affichée comme étant 0x00000002FE1F1440 ci-dessus).

J'ai fait cela immédiatement après avoir exécuté le script ci-dessus et j'ai vu ce qui suit.

entrez la description de l'image ici

(D'après une expérimentation précédente, j'avais trouvé que les octets en surbrillance étaient les seuls à avoir changé entre les exécutions, ce sont donc certainement les bons).

Un aspect surprenant est que SELECT CAST(0xc896 as int)=51350 .

C'est exactement 3600 (une heure) de moins que ce qui est rapporté par DBCC PAGE .

Je pense que c'est une tentative de défavoriser les pages gardées en cache en s'appelant DBCC PAGE. Pour une page "normale" sélectionnez ce réglage d'une heure ne se produit pas. Après avoir couru

SELECT *
FROM T

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

La valeur affichée en mémoire est celle attendue.

La DBCCcommande met à jour cette valeur deux fois. Une fois à

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

Avec la valeur plus élevée, puis à nouveau à

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

Avec le plus bas.

Je ne connais aucun moyen d'obtenir des adresses de tampon pour les pages sans utiliser DBCC BUFFER/ de DBCC PAGEtoute façon et en utilisant ces deux changements la valeur que nous essayons d'inspecter!

Martin Smith
la source
3
Eh bien, c'est une façon de passer Noël. :-)
RBarryYoung
3
@RBarryYoung Beats joue Trivial Pursuit!
Martin Smith
Si je pouvais donner des points bonus pour une utilisation appropriée d'un débogueur, je le ferais.
Jeremiah Peschka
1
Bien joué! (Et d'excellentes compétences de débogage!)
DBArgenis
@DBArgenis - Merci! Dommage qu'il ne semble pas y avoir de solution pratique. Il pourrait être très instructif si nous pouvions voir cela facilement.
Martin Smith
8

Comme je l'ai mentionné à M. Peschka sur Twitter, ces informations sont conservées dans la structure BUF qui conserve la page en mémoire. DBCC PAGE vous donne ces informations dans le cadre de son en-tête.

DBArgenis
la source
3
À contrecœur, je vous accorde "la réponse", @DBArgenis. Je maintiens toujours que DBCC PAGEc'est une façon terrible de trouver quoi que ce soit, mais vous semblez avoir raison. Il est dommage que les données proviennent DBCC PAGE, effectivement, de charabia et ne se rapportent à aucune heure système réelle.
Jeremiah Peschka
8
Un exemple serait un ajout utile à cette réponse.
Mark Storey-Smith
3
@ MarkStorey-Smith - Je suis d'accord. À moins que DBArgenis n'ait un truc dans sa manche, je ne vois pas comment cela est utile.
Martin Smith
2
Aucune référence à DBCC PAGE n'équivaut à quelque chose d'utile.
Jeremiah Peschka