SQL Server에서 LRU-K 값을 볼 수 있습니까?


21

SQL Server에서는 sys.dm_os_memory_cache_entries캐시에있는 항목의 원래 비용과 현재 캐시 항목에 대한 비용 ( original_costcurrent_cost각각)을 모두 볼 수 있습니다. DMV sys.dm_os_buffer_descriptors에는 현재 메모리에있는 페이지 레코드와 페이지에 대한 일부 메타 데이터가 포함됩니다. DVM에서 사용할 수없는 흥미로운 정보는 데이터 페이지의 LRU-K 값입니다.

SQL Server의 버퍼 풀에서 데이터 페이지에 대한 LRU-K 값을 얻을 수 있습니까? 그렇다면 어떻게?


이 버전에만 해당됩니까?
JNK

1
@JNK-완벽한 세상에서 아닙니다. 그러나 SQL Server 2012에서 작동하는 한 걱정하지 않습니다.
Jeremiah Peschka

답변:


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내가 아는 값을 바꾸지 않고 값 을 관찰하는 한 가지 방법이 있으며 여기에서 Bob Ward시연 합니다.

디버거를 SQL Server 프로세스에 연결하고 버퍼 구조의 메모리 주소에 대한 참조 메모리를 표시하십시오 ( 0x00000002FE1F1440위 그림 참조).

위의 스크립트를 실행 한 직후이 작업을 수행하여 다음을 확인했습니다.

여기에 이미지 설명을 입력하십시오

(이전 실험에서 강조 표시된 바이트가 실행간에 변경된 유일한 바이트이므로 확실히 올바른 바이트임을 알았습니다.)

놀라운 측면 중 하나는 SELECT CAST(0xc896 as int)= 51350입니다.

이보고 한 것보다 정확히 3600 (1 시간) 짧습니다 DBCC PAGE.

나는 이것이 DBCC PAGE자신 을 호출하여 캐시에 보관되는 페이지를 싫어하는 일부 시도라고 생각 합니다. "일반"페이지의 경우이 1 시간 조정이 발생하지 않습니다를 선택하십시오. 실행 후

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를 플레이!
Martin Smith

디버거를 적절하게 사용하기 위해 보너스 포인트를 줄 수 있다면 그렇게 할 것입니다.
Jeremiah Peschka

1
잘 했어! (그리고 훌륭한 디버깅 기술!)
DBArgenis

@DBArgenis-감사합니다! 실용적인 해결책이없는 것 같습니다. 우리가 이것을 쉽게 볼 수 있다면 상당히 유익 할 것입니다.
Martin Smith

8

트위터에서 Peschka 씨에게 언급했듯이이 정보는 페이지를 메모리에 저장하는 BUF 구조에 보관됩니다. DBCC PAGE는이 정보를 헤더의 일부로 제공합니다.


3
그런 다음, @DBArgenis에 "답변"을 부여합니다. 나는 여전히 DBCC PAGE아무것도 찾을 수있는 끔찍한 방법이지만, 당신은 옳은 것처럼 보입니다. 데이터 DBCC PAGE가 효과적으로 횡설수설하고 실제 시스템 시간과 관련이없는 것은 유감입니다 .
Jeremiah Peschka

8
이 답변에 유용한 추가 예가 있습니다.
Mark Storey-Smith 1

3
@ MarkStorey-Smith-동의합니다. DBArgenis가 자신의 소매를 비틀 지 않으면 이것이 어떻게 유용한 지 알 수 없습니다.
Martin Smith

2
DBCC PAGE에 대한 언급은 유용한 것이 아닙니다.
Jeremiah Peschka
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.