NOLOCKテーブルヒントを付与しているのにロック待ちが発生した(処理遅延トラブル):SQL Serverトラブルシューティング(63)(1/2 ページ)
本連載では、「Microsoft SQL Server(以下、SQL Server)」で発生するトラブルについて、「なぜ起こったか」の理由とともに具体的な対処方法を紹介していきます。今回は「NOLOCKテーブルヒントを付与しているのにロック待ちが発生した」場合の解決方法を解説します。
本連載では、「Microsoft SQL Server(以下、SQL Server)」で発生するトラブルについて、「なぜ起こったか」の理由とともに具体的な対処方法を紹介していきます。
トラブル 52(カテゴリー:処理遅延トラブル):NOLOCKテーブルヒントを付与しているのにロック待ちが発生した
「Windows Server 2012 R2」上に「SQL Server 2016 RTM」をインストールした環境を想定して解説します(本トラブルシューティングの対応バージョン:SQL Server 全バージョン)。
トラブルの実例:トラブル39で発生したロック待ちを防ぐため、NOLOCKテーブルヒント(*1、*2)を付与したクエリを実行した。他のトランザクションが更新中の不確定な行でも、NOLOCKテーブルヒントを付与したクエリの結果を読み取ることができるため、もうロック待ちに悩むことはないと考えていた。ところが、ある時、処理遅延が発生した。dm_exec_requestsを実行して状況を確認してみると、statusはsuspendedになっており、wait_typeがLCK_M_SCH_Sと表示された(図1)。
トラブルの原因を探る
wait_typeではLCKから始まるLCK_M_SCH_Sと表示されていたため、動的管理ビューのdm_tran_locksを使用して、ロックの状況を確認します(図2)。
通常であればOBJECT_SCHEMA_NAME関数やOBJECT_NAME関数を使用して対象のオブジェクト名を特定できます。しかし今回のような状況では、オブジェクト名を確認するクエリさえもロック待ちになる場合があるため、注意してください。
事前に対象のデータベースまで特定できている場合には、sys.schemasやsys.objectsにNOLOCKテーブルヒントを付与して結合することで、オブジェクト名まで特定できます。対象のデータベースが特定できていない場合にはdm_exec_connectionsなどの動的管理ビューを使用して対象セッションが実行しているクエリを確認し、オブジェクトを推測することもできます(図3)。
LCK_M_SCH_Sの待ちは、スキーマ共有ロック取得の待機中であることを示しています。NOLOCKテーブルヒントを使用したクエリを実行した場合、修正中のデータによるロック待ちは発生しませんが、テーブルに対して列を追加するなど、スキーマを修正するような処理が実行されている場合には、ロック待ちが発生してしまいます。
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- 「SQL Server 2016」に搭載される新たなセキュリティ対策を追う
パブリックプレビューが公開されているマイクロソフトのRDB次期版「SQL Server 2016」。特徴の1つとするセキュリティ対策機能のポイントと目指すところをキーパーソンに聞いた。 - そもそも、リレーショナルデータベースとは何か?
データベースを基礎から勉強し理解を深めていくことは簡単なことではありません。本連載では、データベースに対するハードルを少しでも低くするために、初心者の方に必要なデータベースの基本から、障害対策やチューニングといった実践に即した内容までを幅広く解説していきます。今回は、データベースの役割と、それを管理するソフトウェアであるDBMSの基本機能について解説します。【更新】 - データの登録を行うINSERT文
- 複数の条件を指定してSELECT文を実行する
前回は、SELECT文の初歩の初歩を解説しました。今回は、複数の条件を指定して、目的のデータを取り出す方法を解説します(編集部) - Oracle運用の基本「ログ」を理解しよう
本連載では、Oracle Database運用の鍵となるトラブル対処法について紹介していきます。第1回、第2回では情報収集の要となるログについて見ていきます。ログの出力情報は10gと11gとでは大きく異なる点がありますので、それぞれについても確認しておきましょう。