SQL Serverの専門家からのアドバイスが必要です。私はDBAではなく単なる開発者なので、私の無知を許してください。
私の環境は、SQL Server 2008 R2 x64(10.50.4339.0)の2つの等しいインスタンス(Node1とNode2)で構成されています。私は2つのデータベースを持っています:DB1とDB2、Full
復旧モデル。両方のデータベースは、単一のSQLインスタンス内の相互間のレプリケーションに参加し、両方ともNode1からNode2にミラーリングされます。これらは本番データベースではなく、変更を行う前に完全なDBバックアップを作成しました。
ただし、問題が発生しました。プリンシパルのDB1とDB2の両方でログファイルが大きくならず、次のように実行されます。
select log_reuse_wait_desc, name, * from sys.databases where name='DB1' or name='DB2'
は、ログバックアップを手動で実行したにもかかわらず、DB1とDB2の両方に `log_reuse_wait_desc = 'LOG_BACKUP'があることを示しています。
これが、現在の状態を引き起こした一連のイベントです:
log file full...
メッセージが表示されます。そこで、DB1とDB2の両方のログファイルを停止して0Mbに縮小し、データ/構造の更新タスクを完了するためにディスク領域を解放しました。メッセージ9002、レベル17、状態2、行1データベース 'DB2'のトランザクションログがいっぱいです。ログの領域を再利用できない理由を確認するには、sys.databasesのlog_reuse_wait_desc列を参照してください
データ/構造変更スクリプトの実行中に、関連するパーティションの空きディスク領域が数KBに減少し、SQL Serverから警告メールが送信されました。
log_reuse_wait_desc
列を表示してNOTHING
を表示する方法を調査しました。ただし、提案された解決策では、DB1とDB2をシンプルリカバリモードにするか、それらをデタッチ/再アタッチする必要がありました。これは、レプリケーションとミラーリングのために実行できないことです。
Paul S. Randal からのアドバイスにも従い、ログバックアップを手動で実行しました。
BACKUP LOG DB2 TO DISK = 'z:\DB2.TRN'
これは正常に完了しましたが、log_reuse_wait_desc
には引き続きLOG_BACKUP
が表示され、ログファイルは増加していません。
DBCC LOGINFO出力:
DB1:次のような421レコード:
DB2:次のような381レコード:
DB2の初期loginfoレコード: https://i.stack.imgur.com/TTsVu.png
DB1のField
列には値2と4が含まれているが、DB2のField
列には値2のみが含まれていることに注意してください。ファイルサイズとオフセットフィールドは恐ろしく見えます:54GB +?空き容量が少ないかもしれません。現在、ドライブには26GBの空き容量があり、減少していません。 SQL Serverがハングしたようです。
レプリケーション/ミラーリングを無効にせずにバックアップから復元することなく、現在のDB1およびDB2を修正する方法はありますか?
どんな助けでも大歓迎です。
操作によってトランザクションログにギャップが生じ、仮想ログファイルが物理ログファイルの前にループバックするのを妨げているのではないでしょうか。概念的には、これは物理ファイルの終わりに達したときにすべきデータベース内で発生 です:
DBCC LOGINFO
は、物理ログファイルの先頭のVLFのステータスが2であることを示すレコードを返します。これらのVLFはクリアする必要があります。これは、完全復旧モードでは、TLogバックアップをとる必要があることを意味します。この状況はlog_reuse_wait_desc
表示する列LOG BACKUP
同じように。これを修正するには、論理ヘッダーを物理ファイルの先頭に向かって強制的に戻し、これらのステータス2 VLFをクリアする必要があります(そして、うまくいけばlog_reuse_wait_desc
列はNOTHING
の表示に戻ります)。これを行うには、次の手順を実行します(DB1データベースとDB2データベースの両方で実行する必要がある場合があります)。
BACKUP LOG [DBNAME]...
)データベースに対してここで何が起こっているのですか?
プロセスに関する最後のメモ。 tlogが非常にアクティブな場合は、これを数回、またはアクティビティが少ない時間帯に実行する必要がある場合があります。アクティビティが多いと、2番目のログバックアップを実行する前に、別の誤った自動拡張イベントが発生する可能性があります。これにより、基本的にはステップ3と考えていたものがステップ1に戻ります。通常、ステップ1と2はすぐに実行され、ステップ3の完了には最も時間がかかります。手順4と5を必ず実行してください。
あなたの状況は正常なものであり、あなたはそれを「修正」するために何もすべきではありません。
これがPaul Randaleの記事です log_reuse_wait_descがログバックアップの実行後にLOG_BACKUPと言うのはなぜですか?
これを理解するための重要な瞬間:
成長していないトランザクションログがあり、定期的なログバックアップを行っているが、log_reuse_wait_descはLOG_BACKUPのままである場合これは、前のログバックアップが実行されたときにVLFがゼロにクリアされたためです。
それはどうして起こりますか?
挿入/更新/削除/ DDLアクティビティがほとんどないデータベースを想像してください。通常のログバックアップの間に生成されるログレコードはほんのわずかで、それらはすべて同じVLFにあります。次のログバックアップが実行され、これらのいくつかのログレコードがバックアップされますが、現在のVLFをクリアできないため、log_reuse_wait_descをクリアできません。データベースに十分な変更があり、現在のVLFがいっぱいになり、次のVLFがアクティブになると、次のログバックアップがクリアできるはずです。以前のVLFの場合、log_reuse_wait_descはNOTHINGに戻ります。次のログバックアップが発生し、現在のVLFをクリアできない場合、その場合は再度LOG_BACKUPに戻ります。
[LOG_BACKUPは、「ログのバックアップを取る必要があるか、バックアップされたログレコードがすべて現在のVLFにあるため、消去できなかったためです。」
あなたの状況と写真に戻ります。
最初のデータベースでは表示されませんが、2番目では正しい行が表示されました。そのログには381のVLFがあり、そのうちの1つだけがログのアクティブな部分を含んでいます。 VLFは57Mbです。
したがって、ログバックアップを実行したときに、バックアップするログ行は57Mb未満でした。すべての行は最後からのものでしたVLF(FSeqNo = 97737)、0 VLFがクリアされました。
しかし、これは問題ではありません。次のVLF=に到達し、ログバックアップを実行したら、log_reuse_wait_desc
変更されます。
SQL Serverログファイルは、トランザクションを実行するために実行されたすべての手順の記録を作成します。トランザクションがロールバックされた場合、これらの手順を逆にする必要があります。
SIMPLE
復旧モデルでは、トランザクションがコミットされると、ログの一部とその手順が解放され、再利用できます。
FULL
復旧モデルでは、トランザクションログバックアップが実行されるまで、トランザクション情報がログに保持されます。データベースのすべての変更の手順をバックアップすることにより、トランザクションログのバックアップを(完全バックアップと組み合わせて)使用して、データベースを特定の時点に復元できます。
同じコマンドが他のサーバーに送信され、そこで同じ変更が行われるため、レプリケーションによってデータがログファイルに保持されることもあります。
新しいトランザクションが発生していても、ログファイルが他のトランザクションでいっぱいになっている場合、ログファイルが自動的に大きくなるように設定されていると(通常はデフォルトである)、データベースサーバーはログファイルを大きくしようとします。
ログファイルは自動的に縮小することもできます。ただし、これはnotがデフォルト設定です。なぜなら….
通常の操作条件下では、ログファイルを圧縮したくないです。通常のワークロードに対応するために、現在のサイズに成長しました。縮小すると、ほぼ確実に再び成長する必要があります。
これで、ログを再利用できない理由として_'LOG_BACKUP'
_が表示されます。トランザクションログを手動で取得することに問題はありません。ただし、それがログがいっぱいであるという通常の理由である場合は、スケジュールされたジョブ(理想的には共有ファイルサーバー)を使用して、ログのバックアップを定期的に作成する必要があります。データベースがアクティブな場合、手動のログバックアップを実行した直後に新しいログアクティビティが発生します。最後のログバックアップ以降にCHECKPOINT
があった場合、_LOG_BACKUP
_が表示されることがあります(ただし、ログがいっぱいではありません)。
大きなINSERT
sが原因でログがいっぱいになる場合は、それらを小さなチャンクに分割し、各INSERT
コマンドの間にログファイルのバックアップジョブが実行されることを確認してください。
注:コマンドDBCC SQLPERF (LOGSPACE)
;を使用して、ログファイルがどの程度いっぱいであるかを確認できます。これにより、ログファイルのサイズと、使用中のその領域の割合の両方が表示されます。