De fato, não há maneira útil de fazer isso, tanto quanto eu possa ver.
A outra resposta menciona DBCC PAGE
e deixa ao leitor descobrir os detalhes. Por experimentação, presumo que eles significam bUse1
.
Isso não leva em conta o DBCC PAGE
uso da página e o valor é atualizado antes de ser mostrado para nós.
Um script demonstrando isso está abaixo (leva 12 segundos para ser executado).
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
Resultados típicos são
+----+--------------+-------------------------+-------+-------------+
| ID | ParentObject | Object | Field | ObjectValue |
+----+--------------+-------------------------+-------+-------------+
| 8 | BUFFER: | BUF @0x00000002FE1F1440 | bUse1 | 54938 |
| 49 | BUFFER: | BUF @0x00000002FE1F1440 | bUse1 | 54945 |
| 90 | BUFFER: | BUF @0x00000002FE1F1440 | bUse1 | 54950 |
+----+--------------+-------------------------+-------+-------------+
Com o segundo resultado sendo
+---------+-------------------------+--------------+--------------------+
| 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 |
+---------+-------------------------+--------------+--------------------+
A saída após o atraso de 7 segundos é incrementada em 7 e após o atraso de 5 segundos em 5.
Portanto, parece claro que esses valores de LRU são segundos desde alguma época. Reiniciar o serviço SQL Server não altera a época, mas reiniciar a máquina.
O valor passa a cada 65.536 segundos, então presumo que ele use algo como system_up_time mod 65536
Isso deixa uma pergunta sem resposta em minha mente (alguém que faz perguntas?). O SQL Server usa LRU-K
com de K=2
acordo com o livro interno. Não deveria haver um bUse2
? Se sim, onde é isso?
Há uma maneira de observar o bUse1
valor sem alterá-lo que eu conheço e que é demonstrado por Bob Ward aqui.
Anexe um depurador ao processo do SQL Server e exiba a memória referenciada para o endereço de memória da estrutura do buffer (mostrado 0x00000002FE1F1440
acima).
Fiz isso imediatamente após executar o script acima e vi o seguinte.
(De experiências anteriores, eu achei que os bytes destacados eram os únicos que mudavam entre as execuções, então esses são definitivamente os corretos).
Um aspecto surpreendente é que SELECT CAST(0xc896 as int)
= 51350
.
Isso é exatamente 3600 (uma hora) menos que o relatado por DBCC PAGE
.
Acredito que essa seja uma tentativa de desfavorecer as páginas mantidas em cache, chamando a DBCC PAGE
si mesma. Para uma página "normal", selecione este ajuste de uma hora não ocorre. Depois de correr
SELECT *
FROM T
SELECT ((ms_ticks) % 65536000) / 1000 AS [Roughly Expected Value]
FROM sys.dm_os_sys_info
O valor mostrado na memória é como esperado.
O DBCC
comando atualiza esse valor duas vezes. Uma vez em
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
Com o valor mais alto, novamente em
sqlmin.dll!LatchedBuf::FreeAndUnlatch() + 0x71 bytes
sqlmin.dll!UtilDbccDumpPage() + 0x545 bytes
sqlmin.dll!DbccPage() + 0xfa bytes
sqllang.dll!DbccCommand::Execute() + 0x153 bytes
Com o inferior.
Não conheço nenhuma maneira de obter endereços de buffer para páginas sem usar DBCC BUFFER
/ de DBCC PAGE
nenhuma maneira e usar essas duas alterações no valor que estamos tentando inspecionar!