次の方法で共有


Azure SQL Databaseを使用したトランザクション ログ エラーのトラブルシューティング

Applies to:Azure SQL Database

トランザクション ログがいっぱいで、新しいトランザクションを受け入れることができない場合、エラー 9002 または 40552 が表示されることがあります。 これらのエラーは、Azure SQL Databaseによって管理されるデータベース トランザクション ログが領域のしきい値を超え、トランザクションを引き続き受け入れることができない場合に発生します。 これらのエラーは、SQL Serverの完全なトランザクション ログに関する問題に似ていますが、SQL Server、Azure SQL Database、およびAzure SQL Managed Instanceで解決が異なります。

この記事では、Azure SQL Databaseに焦点を当てています。 Azure SQL Databaseは、Microsoft SQL Server データベース エンジンの最新の安定したバージョンに基づいているため、多くのコンテンツは似ていますが、トラブルシューティングオプションやツールはSQL Serverとは異なる場合があります。

Azure SQL Managed Instanceでのトランザクション ログのトラブルシューティングの詳細については、「トランザクション ログエラーをAzure SQL Managed Instanceでトラブルシューティングする」を参照してください。

SQL Serverでのトランザクション ログのトラブルシューティングの詳細については、「完全なトランザクション ログ (SQL Server エラー 9002)を参照してください。

自動バックアップとトランザクション ログ

Azure SQL Databaseでは、トランザクション ログのバックアップが自動的に作成されます。 頻度、リテンション期間、詳細については、「 自動バックアップ」を参照してください。

空きディスク領域、データベース ファイルの拡張、ファイルの場所も管理されるため、トランザクション ログの問題の一般的な原因と解決策はSQL Serverとは異なります。

SQL Serverと同様に、各データベースのトランザクション ログは、ログ バックアップが正常に完了するたびに切り捨てられます。 切り捨てにより、ログ ファイルに空き領域ができて、新しいトランザクションに使用できるようになります。 ログ ファイルをログのバックアップで切り捨てることができない場合、ログ ファイルは新しいトランザクションを収容するために拡張されます。 ログ ファイルがAzure SQL Databaseの上限に達すると、新しい書き込みトランザクションは失敗します。

トランザクション ログのサイズについては、次のページを参照してください。

トランザクション ログの切り捨ての防止

特定のケースでログの切り捨てを妨げているものを検出するには、log_reuse_wait_descsys.databasesを参照してください。 「ログ再利用の待機」によって、通常のログバックアップによるトランザクションログの切り捨てを妨げている条件や原因が示されます。 詳細については、「sys.databases (Transact-SQL)を参照してください。

SELECT [name], log_reuse_wait_desc FROM sys.databases;

Azure SQL Databaseの場合、このクエリを実行するには、master データベースではなく、特定のユーザー データベースに接続することをお勧めします。

log_reuse_wait_descsys.databasesの次の値は、データベースのトランザクション ログの切り捨てが禁止されている理由を示している可能性があります。

log_reuse_wait_desc 診断 対応が必要
NOTHING 通常の状態。 ログの切り捨てをブロックしているものはありません。 いいえ。
CHECKPOINT ログの切り捨てを行うには、チェックポイントが必要です。 まれ。 継続しない限り、対応は必要ありません。 サポートが維持される場合は、Azure サポートでサポートリクエストを提出します。
LOG BACKUP ログ バックアップが必要です。 継続しない限り、対応は必要ありません。 サポートが維持される場合は、Azure サポートでサポートリクエストを提出します。
ACTIVE BACKUP OR RESTORE データベースのバックアップが実行されています。 継続しない限り、対応は必要ありません。 サポートが維持される場合は、Azure サポートでサポートリクエストを提出します。
ACTIVE TRANSACTION 進行中のトランザクションにより、ログの切り捨てが妨げられています。 アクティブなトランザクションまたはコミットされていないトランザクションがあるため、ログ ファイルを切り捨てることができません。 次のセクションをご覧ください。
REPLICATION Azure SQL Databaseでは、change データ キャプチャ (CDC) が有効になっている場合に発生する可能性があります。 sys.dm_cdc_errorsクエリを 実行 し、エラーを解決します。 解決できない場合は、Azure サポートでサポートリクエストを提出してください。
AVAILABILITY_REPLICA セカンダリ レプリカへの同期が進行中です。 継続しない限り、対応は必要ありません。 サポートが維持される場合は、Azure サポートでサポートリクエストを提出します。

アクティブなトランザクションによってログの切り捨てが妨げられている

トランザクション ログで新しいトランザクションが受け入れられない場合の最も一般的なシナリオは、実行時間の長いトランザクションまたはブロックされているトランザクションです。

次のサンプル クエリを実行して、コミットされていないトランザクションまたはアクティブなトランザクションとそのプロパティを確認します。

  • トランザクションプロパティに関する情報 をsys.dm_tran_active_transactionsから返します。
  • sys.dm_exec_sessionsからセッション接続情報 返します。
  • sys.dm_exec_requestsから要求情報 (アクティブな要求の場合) 返します。 このクエリを使用して、ブロックされているセッションを特定し、 request_blocked_byを探すこともできます。 詳細については、「 ブロック情報の収集」を参照してください。
  • sys.dm_exec_sql_textまたは sys.dm_exec_input_buffer DMV を使用して、現在の要求のテキストまたは入力バッファー テキスト返します。 textsys.dm_exec_sql_text フィールドによって返されるデータが NULL の場合、要求はアクティブではありませんが、未処理のトランザクションがあります。 その場合、event_infosys.dm_exec_input_buffer フィールドには、データベース エンジンに渡された最後のステートメントが含まれます。
SELECT [database_name] = db_name(s.database_id)
, tat.transaction_id, tat.transaction_begin_time, tst.session_id 
, session_open_transaction_count = tst.open_transaction_count
, transaction_duration_s = datediff(s, tat.transaction_begin_time, sysdatetime())
, input_buffer = ib.event_info
, request_text = CASE  WHEN r.statement_start_offset = 0 and r.statement_end_offset= 0 THEN left(est.text, 4000)
                       ELSE    SUBSTRING ( est.[text],    r.statement_start_offset/2 + 1, 
                                           CASE WHEN r.statement_end_offset = -1 THEN LEN (CONVERT(nvarchar(max), est.[text])) 
                                                ELSE r.statement_end_offset/2 - r.statement_start_offset/2 + 1
                                           END  )  END
, request_status = r.status
, request_blocked_by = r.blocking_session_id
, transaction_state = CASE tat.transaction_state    
                     WHEN 0 THEN 'The transaction has not been completely initialized yet.'
                     WHEN 1 THEN 'The transaction has been initialized but has not started.'
                     WHEN 2 THEN 'The transaction is active - has not been committed or rolled back.'
                     WHEN 3 THEN 'The transaction has ended. This is used for read-only transactions.'
                     WHEN 4 THEN 'The commit process has been initiated on the distributed transaction. This is for distributed transactions only. The distributed transaction is still active but further processing cannot take place.'
                     WHEN 5 THEN 'The transaction is in a prepared state and waiting resolution.'
                     WHEN 6 THEN 'The transaction has been committed.'
                     WHEN 7 THEN 'The transaction is being rolled back.'
                     WHEN 8 THEN 'The transaction has been rolled back.' END 
, transaction_name = tat.name
, azure_dtc_state    --Applies to: Azure SQL Database only
             =    CASE tat.dtc_state 
                 WHEN 1 THEN 'ACTIVE'
                 WHEN 2 THEN 'PREPARED'
                 WHEN 3 THEN 'COMMITTED'
                 WHEN 4 THEN 'ABORTED'
                 WHEN 5 THEN 'RECOVERED' END
, transaction_type = CASE tat.transaction_type    WHEN 1 THEN 'Read/write transaction'
                                             WHEN 2 THEN 'Read-only transaction'
                                             WHEN 3 THEN 'System transaction'
                                             WHEN 4 THEN 'Distributed transaction' END
, tst.is_user_transaction
, local_or_distributed = CASE tst.is_local WHEN 1 THEN 'Local transaction, not distributed' WHEN 0 THEN 'Distributed transaction or an enlisted bound session transaction.' END
, transaction_uow    --for distributed transactions. 
, s.login_time, s.host_name, s.program_name, s.client_interface_name, s.login_name, s.is_user_process
, session_cpu_time = s.cpu_time, session_logical_reads = s.logical_reads, session_reads = s.reads, session_writes = s.writes
, observed = sysdatetimeoffset()
FROM sys.dm_tran_active_transactions AS tat 
INNER JOIN sys.dm_tran_session_transactions AS tst  on tat.transaction_id = tst.transaction_id
INNER JOIN Sys.dm_exec_sessions AS s on s.session_id = tst.session_id 
LEFT OUTER JOIN sys.dm_exec_requests AS r on r.session_id = s.session_id
CROSS APPLY sys.dm_exec_input_buffer(s.session_id, null) AS ib 
OUTER APPLY sys.dm_exec_sql_text (r.sql_handle) AS est;

さらに領域を解放するためのファイル管理

Azure SQL Databaseのエラスティック プールでトランザクションログの切り捨てが妨げられる場合、エラスティック プールに空き容量を確保することが解決策の一部となり得ます。 ただし、トランザクション ログ ファイルの切り捨てがブロックされている根本的な状況を解決することが重要です。 場合によっては、一時的により多くのディスク領域を作成すると、実行時間の長いトランザクションが完了できるため、通常のトランザクション ログのバックアップでトランザクション ログ ファイルの切り捨てがブロックされる状況を取り除くことができます。 ただし、領域を解放すると、トランザクション ログが再び大きくなるまで、一時的な解放のみが提供される場合があります。

データベースとエラスティック プールのファイル領域の管理の詳細については、「Azure SQL Database のデータベースのファイル領域管理」を参照してください。

エラー 40552:トランザクション ログの使用領域が多すぎるため、セッションを終了しました

40552: The session has been terminated because of excessive transaction log space usage. Try modifying fewer rows in a single transaction.

この問題を解決するには、次の方法を試してください。

  1. この問題は、挿入、更新、削除など、すべての DML 操作で発生する可能性があります。 不要な書き込みを避けるために、トランザクションを確認してください。 バッチ処理を実装したり、複数の小さなトランザクションに分割したりして、すぐに操作される行の数を減らしてみてください。 詳細については、「 バッチ処理を使用して SQL Database アプリケーションのパフォーマンスを向上させる方法」を参照してください。
  2. この問題は、インデックスの再構築操作によって発生する可能性があります。 この問題を回避するには、次の式が当てはまることを確認します。(テーブルの影響を受ける行の数) に 2 GB (バイト単位で更新されたフィールドの平均サイズ + 80) < 乗算します。 大きなテーブルの場合は、パーティションを作成し、テーブルの一部のパーティションでのみインデックスのメンテナンスを実行することを検討してください。 詳細については、「 パーティション テーブルとパーティション インデックスの作成」を参照してください。
  3. bcp.exe ユーティリティまたは System.Data.SqlClient.SqlBulkCopy クラスを使用して一括挿入を実行する場合は、1 回のトランザクションでサーバーにコピーされる行数を -b batchsize オプションまたは BatchSize オプションで制限してください。 詳細については、「 bcp Utility」を参照してください。
  4. ALTER INDEX ステートメントを使用してインデックスを再構築する場合は、SORT_IN_TEMPDB = ONONLINE = ON、およびRESUMABLE=ONオプションを使用します。 再開可能なインデックスでは、ログの切り捨てがさらに頻繁に行われます。 詳細については、「ALTER INDEX (Transact-SQL)を参照してください。

その他のリソース ガバナンス エラーの詳細については、「 リソース ガバナンス エラー」を参照してください。