私が見る限り、実際にこれを行う便利な方法はありません。
他の答えは言及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 |
+----+--------------+-------------------------+-------+-------------+
2番目の結果は
+---------+-------------------------+--------------+--------------------+
| 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
これにより、未回答の質問が1つ残ります(受験者はいますか?)。SQL Serverは、内部ブックに従ってLRU-K
withを使用しますK=2
。あるべきではないbUse2
?もしそうなら、それはどこですか?
bUse1
値を変更せずに監視する方法は1つありますが、これはボブワードがここで示しています。
デバッガーをSQL Serverプロセスに接続し、バッファー構造のメモリアドレスの参照先メモリを表示します(上図0x00000002FE1F1440
参照)。
上記のスクリプトを実行した直後にこれを行い、次のことを確認しました。
(以前の実験から、強調表示されたバイトが実行間で変更された唯一のものであることがわかったので、これらは間違いなく正しいものです)。
1つの驚くべき側面は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
が、これらの両方を使用すると、検査しようとしている値が変更されます!