SE の雑記

SQL Server の情報をメインに Microsoft 製品の勉強内容を日々投稿

ロックリソースを取得する仮想列

leave a comment

The Curious Case of the Dubious Deadlock and the Not So Logical Lock  や Undocumented Virtual Column: %%lockres% を見て初めて知りました。

SQL Server ではテーブル内の情報を取得する際にはロックを取得します。
DMV では sys.dm_tran_locks、SQL Server Profiler では、lock::acquire のイベント、拡張イベントでは lock_acquired を使用することで、取得されているロックや要求したロックの情報を取得することができます。

今まで知らなかったのですが、 %%lockeres%% を使用することで、ロックのリソースを確認することができるようです。
この手のアンドキュメントの仮想列 (Virtual Column) としてはページの情報を取得するために使用していた %%physloc%% は知っていたのですがロックのパターンは知りませんでした。

以下のようなクエリを実行すると行ごとにロックのリソースを取得することができます。

SELECT TOP 10  *,%%lockres%% AS LockResource FROM LockTest
SELECT TOP 10  *,%%lockres%% FROM LockTest

image

リソースだけですと情報がわかりませんのでロックの DMV と結合をしてみます。

そうすると以下のように行単位にどのようなロックが取得されたのかを確認することができました。

SELECT TOP 10 
Tbl.*,
tl.resource_type,
tl.request_mode,
tl.request_type,
tl.request_status,
%%lockres%% AS LockResource
FROM LockTest Tbl
LEFT JOIN
sys.dm_tran_locks tl ON
Tbl.%%lockres%%  = resource_description

image

 

実際にはインテントロックやデータベースの共有ロックもかかっているはずなのですべてのロックの情報が取得されているというわけではありませんが、動作を確認する上では便利そうですね。
ロックのモードを変更すると、行の情報も変わっていました。
image

以下のクエリはカバードインデックスのみで検索した場合の結果になるのですが、この場合はうまくリソースの情報を割り当てることができませんでした。
KEY ロック
image

また、行バージョニングによる読み取り制御 (READ COMMITTED SNAPSHOT) を使用した場合も同様にリソースの情報とロックの情報を割り当てることができませんでした。
# こちらは動作としてロック取得でないのでまぁそうなのかなと。
image
使いこなすためにはまだまだ勉強しないといけませんがなかなか面白そうな情報ですね。
書籍としては MicrosoftR SQL ServerR 2008 Internals (Pro – Developer) / Professional SQL Server 2008 Internals and Troubleshooting / Professional SQL Server 2012 Internals and Troubleshooting に少し記載がされているのですが今まで気づきませんでした。
# 日本語の書籍ではまだ紹介されていなさそうですね。

Share

Written by Masayuki.Ozawa

7月 14th, 2013 at 7:54 pm

Posted in SQL Server

Tagged with

Leave a Reply