De hecho, no hay una forma útil de hacer esto hasta donde puedo ver.
La otra respuesta menciona DBCC PAGE
y deja al lector que descifre los detalles. Por experimentación supongo que significan bUse1
.
Esto no tiene en cuenta que DBCC PAGE
es 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-K
de K=2
acuerdo con el libro interno. ¿No debería haber un bUse2
? Si es así, ¿dónde es eso?
Sin bUse1
embargo, 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 0x00000002FE1F1440
arriba).
Hice esto inmediatamente después de ejecutar el script anterior y vi lo siguiente.
(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 PAGE
sí 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 DBCC
comando 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 PAGE
ninguna manera y utilizando ambos cambios, ¡el valor que estamos tratando de inspeccionar!