適用対象:✅ Warehouse in Microsoft Fabric
Warehouse のクエリの実行に異常に時間がかかる場合や、スタックしているように見える場合、考えられる原因の 1 つはロックです。 ロックは、セッションがロックを保持し、他のクエリが続行できないようにするときに発生します。
この記事では、ロックがワークロードに影響を与えるかどうかを判断する方法と、実行できるアクションについて説明します。
Tip
Warehouse では 、テーブル レベルのロックが使用されます。 DML 操作では、影響を受ける行の数に関係なく、テーブル全体のロックが取得されます。 この動作は、行レベルおよびページ レベルのロックをサポートするSQL Serverとは異なります。
前提条件
- アクティブなワークロードがあるウェアハウス。
- ビューアー ワークスペース ロールのメンバーシップは、この記事の動的管理ビュー (DMV) に対してクエリを実行するための最小限のアクセス許可です。
- DMV を使用したトラブルシューティングの詳細については、「DMV を 使用した接続、セッション、および要求の監視」を参照してください。
手順 1: クエリがロック待ちになっているかどうかを確認する
まず、現在ロック待ちになっているクエリがあるかどうかを確認します。
次のクエリを実行します。
SELECT
request_session_id,
resource_type,
resource_description,
request_mode,
request_status
FROM sys.dm_tran_locks
WHERE request_status = 'WAIT';
クエリが行を返す場合、一部のセッションは他のセッションに保持されているリソースの解放を待機しています。 各行は、現在許可できないロック要求を示します。
Tip
sys.dm_tran_locks ビューは、許可されたロックに対して多数の行を返すことができます。
request_status = 'WAIT'によるフィルター処理は、ブロックされているセッションに焦点を当てています。
手順 2: ブロックされたクエリを特定する
次に、ブロックされているクエリと、ブロックしているセッションを確認します。
SELECT
session_id,
status,
blocking_session_id,
wait_type,
total_elapsed_time,
open_transaction_count
FROM sys.dm_exec_requests
WHERE blocking_session_id <> 0;
このクエリは次の結果を返します。
- ブロックされたクエリを実行しているセッション (
session_id) - 現在ブロックされているセッション (
blocking_session_id) - 待機している時間 (
total_elapsed_time、ミリ秒単位) - ブロック セッションに開いているトランザクションがあるかどうか (
open_transaction_count)
クエリで blocking_session_id が 0 以外であり、open_transaction_count > 0 と表示される場合、そのクエリはロックを保持している別のセッションを待機しています。
手順 3: ブロック セッションを見つける
ロックされているリソースを理解するには、ブロック セッションによって現在保持されているロックを調べます。 前に特定した session_id を、次のサンプル クエリの <blocking_session_id> に置き換えます。
SELECT
request_session_id,
resource_type,
resource_associated_entity_id,
request_mode,
request_status
FROM sys.dm_tran_locks
WHERE
request_status = 'GRANT'
AND request_session_id = <blocking_session_id>;
このクエリを使用して、次の内容を確認します。
- ブロッキング セッションが現在どのリソースに対してロックを保持しているか。 たとえば、
resource_type = OBJECTであるresource_associated_entity_idを識別するために、sys.objectsを使用できます。 - ロックモード (例えば、排他 (
X)、スキーマ変更 (Sch-M)) - ロックが DDL 操作と統計更新のどちらに関連しているか (
UPDSTATS)
Note
統計関連のロック ( UPDSTATSのロックなど) も sys.dm_tran_locksに表示されます。 Schema-Modification (Sch-M) ロックと排他 (X) ロックが最も一般的なブロッカーですが、どの種類のロックでも、競合する要求をブロックする可能性があります (たとえば、Sch-S は Sch-M をブロックします)。
手順 4: ブロックしているトランザクション所有者を見つける
多くの場合、セッションを終了するのではなく、ブロックしているトランザクションの所有者に作業の COMMIT または ROLLBACK を依頼することをお望みになる場合があります。
TRYまたはCATCHでのエラー処理には、COMMITROLLBACK構造体を使用することを検討してください。 詳細については、「TRY...CATCH」を参照してください。
ブロッキング セッションに関連付けられている所有者とクエリを識別できます。 前に特定した session_id を、次のサンプル クエリの <blocking_session_id> に置き換えます。
SELECT
r.session_id,
s.login_name,
s.program_name,
r.status,
r.blocking_session_id,
r.command,
r.total_elapsed_time,
s.last_request_start_time,
s.last_request_end_time
FROM sys.dm_exec_requests r
JOIN sys.dm_exec_sessions s
ON r.session_id = s.session_id
WHERE r.session_id = <blocking_session_id>;
-
login_nameは、ブロッキング セッションの所有者です。 -
program_nameは、セッションを開始したアプリケーションです。DMS_user値は、Fabric ポータル クエリ エディターを示します。 -
commandは現在実行中のコマンドです。
その後、トランザクションの所有者に連絡して、必要に応じてコミットまたはロールバックすることができます。
手順 5: ブロック セッションがアイドル状態であるか、進行していないかどうかを確認する
ブロック セッションはアクティブに表示される可能性がありますが、実際には進行していません。
セッションがアイドル状態または停止していることを示す兆候は、次のとおりです。
-
status = 'sleeping'は、アクティブなクエリが実行されていないことを示します。 - 有効期間が長いオープン要求を示す、現在の時刻よりも大幅に早い
last_request_start_timeを探します。 - チェックの間に増加していない
total_elapsed_timeを探します。これは、セッションが停止していることを示します。
SELECT
session_id,
status,
last_request_start_time,
last_request_end_time,
open_transaction_count
FROM sys.dm_exec_sessions
WHERE session_id = <blocking_session_id>;
- セッションの状態が
sleepingでopen_transaction_count > 0場合、セッションにはアクティブなクエリのない開いているトランザクションがあります。これは、作業を行わずにロックを保持します。 - セッションが
sys.dm_exec_requestsに表示され、チェックの間にtotal_elapsed_timeが増加し続ける場合、セッションはアクティブに進行しています。 トランザクションを終了してロールバックを強制するのではなく、トランザクションが完了するのを待つ方が望ましい場合があります。
手順 6: ブロックを解決するためのアクションを実行する
Note
ブロック状態は、ブロック セッションがトランザクションを完了すると、多くの場合、単独で解決されます。 ワークロードが遅延を許容できる場合は、待機が最も安全なオプションです。
ダウンストリーム クエリのブロックを解除する必要がある場合は、ブロック セッションに次の特性があるかどうかを検討してください。
- 開いているトランザクションがある
- 停止しているように見える、または進行していない
- ブロッキングロックを保持している (たとえば、排他 (
X) またはSch-M)
その場合、管理者ワークスペース ロールのメンバーは、次を使用してセッションを終了できます。
KILL <session_id>;
KILL コマンドは次のコマンドを実行します。
- セッションを終了する
- そのセッションのアクティブなトランザクションで実行されたすべての作業をロールバックする
- ロックを解除する
- ダウンストリーム クエリの続行を許可する
注意事項
セッションを強制解除すると、そのセッションによって実行されたすべてのコミットされていない作業がロールバックされます。 この操作により、ユーザーまたはアプリケーションによって行われたデータ変更が元に戻される場合があります。 このオプションは、トランザクションの終了がワークロードに悪影響を与えないと確信している場合にのみ使用します。
手順 7: 今後のロックの問題を防ぐ
同様の問題を防ぐには、次の手順を実行します。
- 明示的なトランザクションを開いたままにしないでください (対応する
BEGIN TRANSACTIONやCOMMITなしでROLLBACK)。 - トランザクションの有効期間を短くします。 トランザクション内で必要な操作のみを実行します。
- 完了時には、必ずトランザクションを
COMMITまたはROLLBACKしてください。 - トラフィックの少ない時間帯に DDL 操作 (
ALTER TABLEなど) をスケジュールします。
次を使用して、開いているトランザクションを事前に監視します。
SELECT
session_id,
login_name,
open_transaction_count,
program_name,
status,
blocking_session_id,
last_request_start_time
FROM sys.dm_exec_sessions
WHERE open_transaction_count > 0;
オープン トランザクションを定期的に監視し、適切なタイミングで介入することで、チェーンの形成をブロックする可能性を減らすことができます。