¿Es posible ver los valores de LRU-K en SQL Server?


21

En SQL Server sys.dm_os_memory_cache_entries, es posible ver tanto el costo original de una entrada en la memoria caché como el costo actual de la entrada de la memoria caché ( original_costy current_costrespectivamente). El DMV sys.dm_os_buffer_descriptorscontiene un registro de las páginas que están actualmente en la memoria, así como algunos metadatos sobre las páginas. Una porción interesante de información no disponible en el DVM son los valores LRU-K para las páginas de datos.

¿Es posible obtener los valores de LRU-K para páginas de datos en el grupo de búferes en SQL Server? ¿Si es así, cómo?


¿Es esta versión específica?
JNK

1
@JNK: en un mundo perfecto, no, pero mientras funcione en SQL Server 2012, realmente no me preocupo.
Jeremiah Peschka

Respuestas:


21

De hecho, no hay una forma útil de hacer esto hasta donde puedo ver.

La otra respuesta menciona DBCC PAGEy deja al lector que descifre los detalles. Por experimentación supongo que significan bUse1.

Esto no tiene en cuenta que DBCC PAGEes en sí un uso de la página y el valor se actualiza antes de que se nos muestre.

A continuación se muestra un script que demuestra esto (tarda 12 segundos en ejecutarse).

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

Los resultados típicos son

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

Con el segundo resultado siendo

+---------+-------------------------+--------------+--------------------+
| 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 salida después del retraso de 7 segundos se incrementa en 7 y después del retraso de 5 segundos en 5.

Por lo tanto, parece claro que estos valores de LRU son segundos desde alguna época. Reiniciar el servicio de SQL Server no altera la época, pero reiniciar la máquina sí.

El valor se transfiere cada 65.536 segundos, por lo que supongo que solo usa algo como system_up_time mod 65536

Esto deja una pregunta sin respuesta en mi mente (¿hay personas que respondan?). SQL Server utiliza LRU-Kde K=2acuerdo con el libro interno. ¿No debería haber un bUse2? Si es así, ¿dónde es eso?

Sin bUse1embargo, sé que hay una manera de observar el valor sin cambiarlo y que Bob Ward lo demuestra aquí.

Adjunte un depurador al proceso de SQL Server y muestre la memoria referenciada para la dirección de memoria de la estructura del búfer (que se muestra 0x00000002FE1F1440arriba).

Hice esto inmediatamente después de ejecutar el script anterior y vi lo siguiente.

ingrese la descripción de la imagen aquí

(De la experimentación anterior, descubrí que los bytes resaltados fueron los únicos que cambiaron entre ejecuciones, por lo que estos son definitivamente los correctos).

Un aspecto sorprendente es que SELECT CAST(0xc896 as int)= 51350.

Esto es exactamente 3600 (una hora) menos de lo informado por DBCC PAGE.

Creo que esto es un intento de desfavorecer las páginas que se mantienen en caché llamándose a DBCC PAGEsí mismas. Para una página "normal", seleccione este ajuste de una hora. despues de correr

SELECT *
FROM T

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

El valor que se muestra en la memoria es el esperado.

El DBCCcomando realmente actualiza ese valor dos veces. Una vez en

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 el valor más alto, nuevamente en

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

Con el inferior.

Sin embargo, no conozco ninguna forma de obtener direcciones de búfer para las páginas sin usar DBCC BUFFER/ de DBCC PAGEninguna manera y utilizando ambos cambios, ¡el valor que estamos tratando de inspeccionar!


3
Bueno, esta es una forma de pasar tu Navidad. :-)
RBarryYoung

3
¡@RBarryYoung Beats jugando Trivial Pursuit!
Martin Smith

Si pudiera dar puntos de bonificación por el uso apropiado de un depurador, lo haría.
Jeremiah Peschka

1
¡Bien hecho! (¡Y excelentes habilidades de depuración!)
DBArgenis

@DBArgenis - ¡Gracias! Es una pena que no parezca haber una solución práctica. Podría ser bastante informativo si pudiéramos ver esto fácilmente.
Martin Smith

8

Como le mencioné al Sr. Peschka en Twitter, esta información se mantiene en la estructura BUF que guarda la página en la memoria. DBCC PAGE le brinda esta información como parte de su encabezado.


3
De mala gana, te concedo "la respuesta", @DBArgenis. Sigo manteniendo que DBCC PAGEes una forma terrible de encontrar algo, pero parece que estás en lo correcto. Es una pena que los datos DBCC PAGEsean, efectivamente, galimatías y no se relacionen con ningún tiempo real del sistema.
Jeremiah Peschka

8
Un ejemplo sería una adición útil a esta respuesta.
Mark Storey-Smith

3
@ MarkStorey-Smith - Estoy de acuerdo. A menos que DBArgenis tenga algún truco bajo la manga, no puedo ver cómo esto es útil.
Martin Smith

2
Ninguna referencia a DBCC PAGE equivale a algo útil.
Jeremiah Peschka
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.