問題の説明
ApsaraDB RDS for SQL Serverインスタンスでリクエストがブロックされます。
原因
アプリケーションは、テーブルまたはリソースからデータを頻繁に読み取り、またはテーブルまたはリソースにデータを書き込みます。 多数のリクエストがブロックされると、ステートメントはアプリケーション上で低速で実行されます。
識別
RDSインスタンスのブロックの問題を特定するには、次の操作を実行することを推奨します。
次のステートメントを実行して、定期的に
sys.sysprocesses
を監視し、ブロッキング情報を取得します。1 = 1の
WHILE 1 = 1 BEGIN SELECT * FROM SYS.SYSPROCESSES WHERE BLOCKED <> 0; WAITFOR DELAY '00:00:01'; END;
説明監視間隔を指定できます。 この例では、
00:00:01
が使用されます。次の図は、サンプル出力を示しています。
説明blocked
列は、ブロックヘッダーのセッションID
を示します。waitresource
列は、ブロックされたセッションが待機するリソースを示します。 出力のパラメーターの詳細については、「sys.sysprocesses (Transact-SQL) 」をご参照ください。次のステートメントを実行して、
sys.dm_tran_locks
およびsys.dm_os_waiting_tasks
ビューを監視し、ブロック情報を取得します。1 = 1の
WHILE 1 = 1 Begin SELECT db.name DBName, tl.request_session_id, wt.blocking_session_id, OBJECT_NAME(p.OBJECT_ID) BlockedObjectName, tl.resource_type, h1.TEXT AS RequestingText, h2.TEXT AS BlockingText, tl.request_mode FROM sys.dm_tran_locks AS tl INNER JOIN sys.databases db ON db.database_id = tl.resource_database_id INNER JOIN sys.dm_os_waiting_tasks AS wt ON tl.lock_owner_address = wt.resource_address INNER JOIN sys.partitions AS p ON p.hobt_id = tl.resource_associated_entity_id INNER JOIN sys.dm_exec_connections ec1 ON ec1.session_id = tl.request_session_id INNER JOIN sys.dm_exec_connections ec2 ON ec2.session_id = wt.blocking_session_id CROSS APPLY sys.dm_exec_sql_text(ec1.most_recent_sql_handle) AS h1 CROSS APPLY sys.dm_exec_sql_text(ec2.most_recent_sql_handle) AS h2 WAITFOR DELAY '00:00:01'; END;
次の図は、サンプル出力を示しています。
次の表に、出力のパラメーターを示します。
パラメーター
説明
DBName
データベースの名前。
request_session_id
現在のリクエストのセッションのID。 セッションはブロックされたセッションです。
blocking_session_id
ブロックヘッダのセッションID。
BlockedObjectName
ブロックされたセッションによって管理されるオブジェクト。
resource_type
セッションが待機するリソースのタイプ。
RequestingText
セッションで実行されるステートメント。 ステートメントはブロックされたステートメントです。
BlockingText
ブロックヘッダーのセッションで実行されるステートメント。
request_mode
セッションによって要求されるロックモード。
最適化の提案
最適化のために次の操作を実行できます。
ブロックヘッダーのセッションを終了して、ブロックの問題を解決します。
長期間コミットされていないトランザクションが存在するかどうかを確認します。 トランザクションが存在する場合は、最も早い機会にトランザクションをコミットします。
共有ロックが原因でクエリがブロックされ、アプリケーションでダーティな読み取りが許可されている場合は、
WITH (NOLOCK)
クエリヒントを使用します。 たとえば、クエリに対してSELECT * FROMテーブルWITH (NOLOCK);
ステートメントを実行できます。 このように、クエリはブロックの問題を防ぐためにロックを適用しません。アプリケーションロジックをチェックして、リソースに順番にアクセスします。
関連ドキュメント
緊急時のブロッキングの問題を解決する方法の詳細については、ApsaraDB RDS for SQL Serverインスタンスでリクエストがブロックされた場合はどうすればよいですか。
ApsaraDB RDSコンソールでパフォーマンスメトリックを指定し、アラートルールを作成して、パフォーマンスの問題をできるだけ早く特定して解決できます。 詳細については、「モニタリングとアラート」をご参照ください。
インデックス最適化、クエリ最適化、ストレージ最適化などのパフォーマンス最適化ポリシーの詳細については、「パフォーマンスの最適化と診断」をご参照ください。