web-dev-qa-db-ja.com

「OLDEST_PAGE」により、データベースのトランザクションログがいっぱいです

Azureでホストされているデータベースがあります。 Azureエラスティックプールの一部です。昨日から、すべてのデータベース操作が一貫して次のエラーで失敗しています。

「OLDEST_PAGE」により、データベースのトランザクションログがいっぱいです

データベースですべてのアクティブなトランザクションを確認しましたが、現在アクティブなトランザクションはありませんが、ログファイルが100%の領域を使用しています。

db_log_file

次のドキュメントページを確認しましたが、問題を完全には理解できませんでした。

誰かがこの問題を理解するのを手伝ってくれませんか?



更新

このDBを新しいプールに移動すると、ログサイズが自動的に減少しました。移転後も問題は発生していません。

3
Ketan

これは、Azure SQLデータベースで見るべきものではありません。あなたはこれについてサポートをするべきです。

必要に応じて、自分でできることがいくつかあります。まず、データベースをチェックポイントしてみてください。次に、アクティブなトランザクションがないことが確実な場合は、データベースのSLOを変更します。エラスティックプールから取り出して、元に戻します。

注:これはAzure SQL DBにあることに気づく前にこの回答を書きました( Davidの回答 これは、Azureでの正当なバグのある動作を示しているようです)。

OPがそのエラーの意味についての説明も探していたため、ここを離れました。おそらく、このエラーのあるオンプレミスセットアップの他のユーザーにとって役立つでしょう。


トランザクションログがいっぱいです。共有したスクリーンショットを見ると、わずか59 MBです。かなり小さいです。より多くのトランザクションに対応するために、それは成長し続けると考えるでしょう。しかし、それは何らかの理由でできません。

SQL Serverは、ログファイルの再利用を開始しようとしています。しかし、その厄介なOLDEST_PAGE起こっていること。これは、ディスク上のデータファイルに保持されていない変更された日付ページがメモリに存在することを意味します。したがって、SQL Serverは、永続化されない可能性のあるトランザクションを記録するトランザクションログの一部を再利用できなくなります。

一時的な修正は、サーバーでCHECKPOINTコマンドを手動で実行して、バッファーされたページをディスクに強制的にフラッシュすることです。コマンドを複数回実行する必要がある場合がありますが、これにより、トランザクションログファイルを再利用できるようになります。

より大きな問題は、トランザクションログにあります。このクエリを実行する必要があります:

select max_size, growth from sys.master_files where [name] = 'YourLogFileName';

その後:

チェックmax_sizeログファイルの拡大を妨げる明示的な最大値があるかどうかを確認します

この場合は、max_sizeより大きな数値にして、実際のトランザクション負荷に対応します。この数は、通常のトランザクション数と、使用している復旧モデルによって異なります。

growthをチェックして、自動拡張が無効になっているかどうかを確認します(拡張= 0)

無効になっている場合は、有効にすることができます。

それができず、完全復旧モデルを使用している場合は、より頻繁なログバックアップをスケジュールできます。

それができず、SIMPLE復旧モデルを使用している場合は、自動または間接チェックポイント間のトランザクションを処理するのに十分な大きさになるまで、ログファイルのサイズを手動で増やす必要があります。

おそらく、Azureストレージのディスクがいっぱいであり、それがファイルの拡大を妨げている原因である可能性があります(ただし、別のエラーメッセージが予想されます)。

1
Josh Darnell

私のデータベースでは、これは間接チェックポイント機能が原因でした。アプリケーションにダーティページはそれほど多くないが、トランザクションログが多い場合、ログは増加し続けます。たとえば、Citrixは同じ列を繰り返し更新します。これはダーティページ数を増やしません。間接チェックポイントは、ダーティページの数に依存して、チェックポイントを実行するタイミングを認識します。

間接チェックポイント機能をオフにします。

ALTER DATABASE DBName SET TARGET_RECOVERY_TIME = 0 SECONDS WITH NO_WAIT

これは理由ではないかもしれませんが、それが私のデータベースにそれを引き起こしたものです。

0
PianoDan