Можно ли просмотреть значения LRU-K в SQL Server?

21

В SQL Server sys.dm_os_memory_cache_entriesможно просматривать как первоначальную стоимость записи в кэше, так и текущую стоимость записи в кэше ( original_costи current_costсоответственно). DMV sys.dm_os_buffer_descriptorsсодержит запись страниц, которые в настоящее время находятся в памяти, а также некоторые метаданные о страницах. Одна интересная порция информации, которой нет в DVM, это значения LRU-K для страниц данных.

Можно ли получить значения LRU-K для страниц данных в пуле буферов в SQL Server? Если да, то как?

Иеремия Пешка
источник
Эта версия зависит от конкретной версии?
JNK
1
@JNK - В идеальном мире нет, но пока он работает на SQL Server 2012, я не очень беспокоюсь.
Иеремия Пешка

Ответы:

21

На самом деле, насколько я понимаю, нет никакого полезного способа сделать это.

В другом ответе упоминается, DBCC PAGEи читатель может выяснить детали. Из экспериментов я предполагаю, что они имеют в виду bUse1.

При этом не учитывается, что DBCC PAGEэто само использование страницы, и значение обновляется, прежде чем оно будет показано нам.

Сценарий, демонстрирующий это ниже (занимает 12 секунд).

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

Типичные результаты

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

Со вторым результатом

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

Выход после 7-секундной задержки увеличивается на 7, а после 5-секундной задержки на 5.

Таким образом, кажется очевидным, что эти значения LRU являются секундами с некоторой эпохи. Перезапуск службы SQL Server не меняет эпоху, но перезапускает машину.

Значение переворачивается каждые 65 536 секунд, поэтому я предполагаю, что оно просто использует что-то вроде system_up_time mod 65536

Это оставляет один вопрос без ответа в моем уме (любые берущие?). SQL Server использует LRU-Kс K=2согласно внутренним книгам. Там не должно быть bUse2? Если так, то где это?

bUse1Хотя есть один способ наблюдать значение, не меняя его, о котором я знаю, и это продемонстрировал Боб Уорд здесь.

Присоедините отладчик к процессу SQL Server и отобразите в памяти ссылки для адреса памяти структуры буфера (показано 0x00000002FE1F1440выше).

Я сделал это сразу после запуска сценария выше и увидел следующее.

введите описание изображения здесь

(Из предыдущих экспериментов я обнаружил, что выделенные байты были единственными, которые менялись между прогонами, так что они определенно правильные).

Одним удивительным аспектом является то, что SELECT CAST(0xc896 as int)= 51350.

Это ровно на 3600 (один час) меньше, чем сообщалось DBCC PAGE.

Я считаю, что это попытка отрицать страницы, хранящиеся в кеше, вызывая DBCC PAGEсебя. Для «нормальной» страницы выбора эта часовая корректировка не происходит. После запуска

SELECT *
FROM T

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

Показанное в памяти значение соответствует ожидаемому.

Команда DBCCфактически обновляет это значение дважды. Однажды в

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

С более высоким значением, то снова при

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

С нижним.

Я не знаю ни одного способа получить адреса буферов для страниц, не используя DBCC BUFFER/ DBCC PAGEкаким-либо образом, и используя оба эти изменения, значение, которое мы пытаемся проверить!

Мартин Смит
источник
3
Ну, это один из способов провести Рождество. :-)
RBarryYoung
3
@RBarryYoung Beats играет в Trivial Pursuit!
Мартин Смит
Если бы я мог дать бонусные баллы за надлежащее использование отладчика, я бы сделал.
Иеремия Пешка
1
Отлично сработано! (И отличные навыки отладки!)
DBArgenis
@DBArgenis - Спасибо! Позор, что, кажется, нет практического решения, хотя. Это может быть довольно информативно, если бы мы могли это легко увидеть.
Мартин Смит
8

Как я упоминал г-ну Пешке в твиттере, эта информация хранится в структуре BUF, которая хранит страницу в памяти. DBCC PAGE предоставляет вам эту информацию как часть своего заголовка.

DBArgenis
источник
3
Неохотно, я даю вам «ответ», @DBArgenis. Я все еще утверждаю, что DBCC PAGEэто ужасный способ найти что-нибудь, но вы, похоже, правы. Жаль, что данные DBCC PAGE, по сути, являются бессмысленными и не относятся к какому-либо реальному системному времени.
Иеремия Пешка
8
Пример будет полезным дополнением к этому ответу.
Марк Стори-Смит
3
@ MarkStorey-Smith - я согласен. Если у Д.Б.Арджениса не будет уловки, я не могу понять, насколько это полезно.
Мартин Смит
2
Никакая ссылка на DBCC PAGE никогда не приводит к чему-либо полезному.
Иеремия Пешка