これはほとんどのフォーラムやWebでよくある質問のようですが、通常は次のように聞こえる多くの形式でここで尋ねられます。
SQL Serverの場合-
- トランザクションログが大きくなる理由は何ですか?
- なぜ私のログファイルはとても大きいのですか?
- この問題の発生を防ぐ方法は何ですか?
- 根本的な原因を理解し、トランザクションログファイルを適切なサイズにしたい場合はどうすればよいですか?
より短い回答:
おそらく、長時間実行されているトランザクションが実行されている(インデックスのメンテナンス?大きなバッチ削除または更新?)か、「デフォルト」(デフォルトの意味については以下を参照)リカバリモードでFull
になっていて、ログバックアップを取得しました(または、十分な頻度で取得していません)。
それが復旧モデルの問題である場合、簡単な答えは、特定の時点の復旧と定期的なログバックアップが必要ない場合は、[Simple
復旧モードに切り替える]です。しかし、多くの人々は、復旧モデルを理解せずに答えを出します。それが重要である理由を理解するために読んで、それからあなたが何をするかを決定してください。また、ログのバックアップを取り始めて、Full
の回復を続けることもできます。
他の理由も考えられますが、これらが最も一般的です。この回答は、最も一般的な2つの理由について詳しく説明し始め、理由とその背後にある理由に関する背景情報を提供するとともに、他のいくつかの理由を探ります。
より長い答え:どのシナリオがログを成長させ続ける可能性がありますか?多くの理由がありますが、通常、これらの理由は次の2つのパターンにあります。復旧モデルについて誤解があるか、トランザクションが長時間実行されている。詳細については以下をお読みください。
(完全復旧モードで、ログバックアップを行わない-これが最も一般的な理由です-この問題が発生している人の大多数がそうです。 )
この答えはSQL Serverの復旧モデルの詳細ではありませんが、復旧モデルのトピックはこの問題にとって重要です。
SQL Serverには、3つの リカバリモデル があります。
Full
、Bulk-Logged
およびSimple
。Bulk-Logged
は今のところ無視します。これはハイブリッドモデルであり、このモデルに参加しているほとんどの人が理由と復旧モデルを理解していると言います。
私たちが気にかけている2つとその混乱が、この問題を抱えている人々の大多数のケースの原因ですSimple
とFull
。
復旧モデルについて説明する前に、一般的な復旧について説明しましょう。このトピックをさらに詳しく知りたい場合は、 Paul Randalのブログ と、必要なだけ投稿してください。ただし、この質問の場合:
クラッシュ/リカバリの再開
トランザクションログファイルの目的の1つは、crash/restart recoveryです。クラッシュまたは再起動の前に行われた(ロールフォワード/やり直し)作業のロールフォワードおよびロールバック、およびクラッシュまたは再起動(ロールバック/元に戻す)の後に開始されたが終了しなかった作業。トランザクションが開始されたが終了しなかったことを確認するのはトランザクションログの役割です(トランザクションがコミットされる前にロールバックまたはクラッシュ/再起動が発生しました)。そのような状況では、ログの役目は「ねえ、これは本当に終わっていないので、ロールバックしましょう」と回復することです。また、何かを終了したこと、およびクライアントアプリケーションに終了が通知されていることを確認し(まだデータファイルに強化されていない場合でも)、「ねえ、これは本当に起こったのです。それをロールフォワードしてみましょう。アプリケーションがそれをそうであると考えるようにしましょう」再起動後。今はもっとありますが、それが主な目的です。
ポイントインタイムリカバリ
トランザクションログファイルのもう1つの目的は、データベースの「エラー」による時点へのリカバリ、またはリカバリポイントの保証を可能にすることですデータベースのデータやログファイルに関連するハードウェア障害が発生した場合。このトランザクションログに、回復のために開始および終了したトランザクションのレコードが含まれている場合、SQL Serverはこの情報を使用して、問題が発生する前のデータベースを取得できます。しかし、それが常に利用可能なオプションであるとは限りません。そのためには、データベースを正しい復旧モデルに置き、ログバックアップを作成する必要があります。
復旧モデルについて:
単純復旧モデル
そのため、上記の紹介では、最初にSimple Recovery
モデルについて説明するのが最も簡単です。このモデルでは、SQL Serverに次のように伝えています。「クラッシュとトランザクションの再開にトランザクションログファイルを使用しても問題ありません...」(本当に選択肢はありません。調べてください ACIDプロパティ およびそれはすぐに理にかなっているはずです。)"...しかし、クラッシュ/再起動のリカバリ目的でそれが不要になったら、ログファイルを再利用してください。"
SQL Serverはシンプルリカバリでこのリクエストをリッスンし、クラッシュ/リカバリを再開するために必要な情報のみを保持します。データがデータファイルに(多かれ少なかれ)強化されているため、SQL Serverが回復できることが確認されると、強化されたデータはログで不要になり、切り捨てのマークが付けられます。つまり、再利用されます。
完全復旧モデル
_Full Recovery
を使用すると、ログファイルが利用可能であるか、またはカバーされている特定の時点まで、特定の時点まで回復できるようにすることをSQL Serverに指示しています。ログバックアップ。この場合、SQL Serverは、Simple Recovery Modelでログファイルを切り捨てても安全な状態になると、それを行いません。代わりにこれにより、ログファイルは継続的に増加し、継続的に増加します通常の状況では、ログバックアップ(またはログファイルドライブのスペースが不足します)。
ここにはルールと例外があります。長期実行トランザクションについては、以下で詳しく説明します。
ただし、完全復旧モードで注意すべき点は次のとおりです。Full Recovery
モードに切り替えただけで、最初の完全バックアップを行わない場合、SQL ServerはしないFull Recovery
モデルになるというリクエストを尊重します。トランザクションログは、フルリカバリモデルに切り替えて最初のFull Backup
を取得するまで、Simple
と同じように動作し続けます。
では、制御されないログの増加の最も一般的な理由は何ですか?回答:完全復旧モードであり、ログバックアップはありません。
これは人に時間をall発生します。
なぜそれがいつも起こるのですか?新しいデータベースはそれぞれ、モデルデータベースを調べることで初期復旧モデル設定を取得するためです。
モデルの初期復旧モデル設定は、誰かが変更しない限り、常にFull Recovery Model
です。したがって、「デフォルトの復旧モデル」はFull
と言えます。多くの人はこれに気づいておらず、データベースをFull Recovery Model
で実行していて、ログバックアップがないため、トランザクションログファイルが必要以上に大きくなっています。これが、組織とそのニーズに対応できない場合にデフォルトを変更することが重要である理由です)
また、ログのバックアップを頻繁に取らないと、ここで問題が発生する可能性があります。
1日にログバックアップを行うと正常に聞こえる場合があります。これにより、復元に必要な復元コマンドが少なくなりますが、上記の説明に留意すると、ログバックアップを作成するまで、ログファイルは増加し続けます。
ログバックアップの頻度は、次の2つの点を考慮して検討する必要があります。
( "私の復旧モデルは問題ありません。ログはまだ増え続けています!)
これは、制御されずに抑制されていないログの増加の原因にもなります。復旧モデルは関係ありませんが、と表示されることがよくあります。「しかし、私は単純復旧モデルを使用しています。なぜログがまだ増えているのですか?」
ここでの理由は簡単です。SQLがこのトランザクションログを上記のリカバリ目的で使用している場合、トランザクションの開始までさかのぼる必要があります。
長時間かかるトランザクションや多くの変更を行うトランザクションがある場合、ログは、まだ開いているトランザクション内にある、またはそのトランザクションの開始以降に開始された変更のチェックポイントで切り捨てることはできません。
これは、1回の削除ステートメントで数百万行を削除する大きな削除は1つのトランザクションであり、その削除全体が完了するまで、ログは切り捨てを実行できないことを意味します。 Full Recovery Model
では、この削除がログに記録され、大量のログレコードになる可能性があります。メンテナンスウィンドウ中のインデックス最適化の動作と同じです。また、トランザクション管理が不十分で、開いているトランザクションを監視およびクローズしないと、ユーザーとログファイルに深刻な影響を与える可能性があります。
あなたはここで自分を救うことができます:
UPDATE TableName Set Col1 = 'New Value'
はトランザクションです。 BEGIN TRAN
をそこに配置しなかったので、その必要はありません。これは、完了時に自動的にコミットされる1つのトランザクションです。したがって、多数の行で操作を行う場合は、それらの操作をより管理しやすいチャンクにバッチ処理し、ログを回復する時間を与えることを検討してください。または、それに対処するための適切なサイズを検討してください。または、バルクロードウィンドウでの復旧モデルの変更を検討してください。短い答え:はい。以下でより長い答え。
質問:「ログ配布を使用しているため、ログのバックアップが自動化されています...なぜトランザクションログの増加が見られるのですか?」
回答:読んでください。
ログ配布はまさにそのようなものです。トランザクションログのバックアップをDRの目的で別のサーバーに配布しています。いくつかの初期化がありますが、その後のプロセスはかなり簡単です:
NORECOVERY
またはSTANDBY
)。また、計画どおりに進行しない場合に監視および警告するジョブもあります。
場合によっては、ログ配布の復元を1日に1回、3日ごと、または週に1回だけ実行することもできます。それは結構です。ただし、すべてのジョブ(ログバックアップおよびコピージョブを含む)でこの変更を行うと、ログバックアップを取るまでその間ずっと待機することになります。これは、ログが大幅に増大することを意味します(ログバックアップのないフルリカバリモードでであるため-おそらく、コピーする大きなログファイルも意味します)。復元ジョブのスケジュールを変更するだけで、ログのバックアップとコピーがより頻繁に行われるようにする必要があります。そうしないと、この回答で説明されている最初の問題が発生します。
この2つ以外にも理由はありますが、これらが最も一般的です。原因に関係なく:この原因不明のログの増加/切り捨ての欠如の理由を分析し、それらが何であるかを確認する方法があります。
sys.databases
カタログビューにクエリを実行すると、ログファイルが切り捨て/再利用を待機している理由を説明する情報を確認できます。
理由コードのルックアップIDを含むlog_reuse_wait
という列と、待機理由の説明を含むlog_reuse_wait_desc
列があります。参照された本のオンライン記事から、主な理由(表示される可能性が高い理由と、その理由を説明できる理由です。欠落しているものは、使用されていないか内部で使用されています)と待機中のメモがいくつかありますイタリック:
0 =なし
それがどのように聞こえるか..待つべきではない
1 =チェックポイント
チェックポイントが発生するのを待っています。これは起こり、あなたは大丈夫です-しかし、後で答えや編集をするためにここを探す必要がある場合があります。
2 =ログのバックアップ
ログのバックアップが行われるのを待っています。あなたはそれらをスケジュールしていてそれがすぐに起こるか、またはここで説明されている最初の問題があり、それを修正する方法を知っている
3 =アクティブバックアップまたは復元
バックアップまたは復元操作がデータベースで実行されています
4 =アクティブなトランザクション
ログをバックアップする前に完了する必要があるアクティブなトランザクションがあります(いずれかの方法-ROLLBACK
またはCOMMIT
)。これが、この回答で説明されている2番目の理由です。
5 =データベースミラーリング
高性能ミラーリングの状況でミラーが遅れているか、遅延が発生しているか、ミラーリングが何らかの理由で一時停止しています
6 =レプリケーション
これが原因となるレプリケーションの問題がある可能性があります-ログリーダーエージェントが実行されていない、データベースがレプリケーション用にマークされていると考えているなどの理由でデータベースがその他の理由で。この理由も確認できます。トランザクションがログリーダーによって消費されているのと同じように、適切なタイミングで調べているため、これは完全に正常です
7 =データベーススナップショットの作成
データベースのスナップショットを作成しています。スナップショットが作成されているときにちょうどいい瞬間を見ると、これがわかります
8 =ログスキャン
私はこれが永遠に実行される問題にまだ遭遇していません。十分に長く、頻繁に見れば、これが発生していることがわかりますが、それがトランザクションログの過度の増大の原因ではないはずです。
9 = AlwaysOn可用性グループのセカンダリレプリカは、このデータベースのトランザクションログレコードを対応するセカンダリデータベースに適用しています。まだ最も明確な説明について..
私は実際にはどの回答にも満足していません スタックオーバーフローについて (最も高く投票されている提案を含む)、そしてマイクの回答がすることについて対処したいことがいくつかあるのでいいえ、私もここに私の入力を提供すると思いました。私もこの回答のコピーをそこに置いた。
ログファイルを小さくすることは、実際には予期しない増加が発生し、再び発生することはないと思われるシナリオのために予約する必要があります。ログファイルが再び同じサイズに拡大する場合、一時的に縮小してもあまり効果はありません。ここで、データベースのリカバリ目標に応じて、これらのアクションを実行する必要があります。
何か問題が発生した場合に復元できることを確認せずに、データベースを変更しないでください。
(そして、ポイントインタイムリカバリとは、完全バックアップまたは差分バックアップ以外に復元できることを気にかけていることを意味します。)
おそらくデータベースはFULL
リカバリモードです。そうでない場合は、次の点を確認してください。
ALTER DATABASE yourdb SET RECOVERY FULL;
定期的なフルバックアップを実行している場合でも、ログファイルはlogバックアップを実行するまで大きくなります。これは保護のためであり、ディスクスペースを無駄に消費しないようにするためです。リカバリの目的に応じて、これらのログバックアップを頻繁に実行する必要があります。たとえば、災害発生時に15分以上のデータを失うことを許容できるというビジネスルールがある場合、15分ごとにログをバックアップするジョブが必要です。現在の時刻に基づいてタイムスタンプ付きのファイル名を生成するスクリプトは次のとおりです(ただし、メンテナンスプランなどでもこれを行うことができます。メンテナンスプランで縮小オプションを選択しないでください。ひどいです)。
DECLARE @path NVARCHAR(255) = N'\\backup_share\log\yourdb_'
+ CONVERT(CHAR(8), GETDATE(), 112) + '_'
+ REPLACE(CONVERT(CHAR(8), GETDATE(), 108),':','')
+ '.trn';
BACKUP LOG foo TO DISK = @path WITH INIT, COMPRESSION;
\\backup_share\
は、基礎となる別のストレージデバイスを表す別のマシン上にある必要があることに注意してください。これらを同じマシン(または同じ基礎ディスクを使用する別のマシン、または別のVM))にバックアップしても、実際には役に立ちません。爆破すると、データベースが失われましたandそのバックアップ。ネットワークインフラストラクチャによっては、ローカルでバックアップし、バックグラウンドで別の場所に転送する方が理にかなっている場合があります。どちらの場合でも、それらをプライマリデータベースマシンからできるだけ早く削除したい。
さて、定期的なログバックアップを実行したら、ログファイルを今までに爆発したものよりも合理的なものに縮小するのが妥当です。これはnotは、ログファイルが1 MBになるまでSHRINKFILE
を繰り返し実行することを意味します-ログを頻繁にバックアップしている場合でも、同時実行の合計に対応する必要があります発生する可能性のあるトランザクション。 SQL Serverはファイルをゼロ設定する必要があるため(インスタントファイル初期化が有効になっている場合のデータファイルとは異なり)、ログファイルの自動拡張イベントはコストがかかり、ユーザートランザクションはこれが発生するまで待機する必要があります。この拡大縮小縮小拡大ルーチンをできるだけ少なくしたいので、ユーザーに料金を支払わせたくないのは確かです。
縮小が可能になる前に、ログを2回バックアップする必要がある場合があることに注意してください(Robertに感謝)。
したがって、ログファイルの実用的なサイズを考え出す必要があります。ここで誰もあなたのシステムについて多くのことを知らずにそれが何であるかを知ることはできませんが、ログファイルを頻繁に圧縮していて、それが再び成長している場合、適切な透かしはおそらく最大のものよりも10-50%高いです。それが200 MBになり、その後の自動拡張イベントを50 MBにしたい場合、ログファイルのサイズを次のように調整できます。
USE [master];
GO
ALTER DATABASE Test1
MODIFY FILE
(NAME = yourdb_log, SIZE = 200MB, FILEGROWTH = 50MB);
GO
ログファイルが現在200 MBを超える場合は、最初にこれを実行する必要がある場合があります。
USE yourdb;
GO
DBCC SHRINKFILE(yourdb_log, 200);
GO
これがテストデータベースで、Point-in-Timeリカバリを気にしない場合は、データベースがSIMPLE
リカバリモードであることを確認する必要があります。
ALTER DATABASE yourdb SET RECOVERY SIMPLE;
データベースをSIMPLE
リカバリモードにすると、SQL Serverはallトランザクションの記録を保持するために大きくなるのではなく、ログファイルの一部を再利用します(基本的に非アクティブなトランザクションを段階的に廃止します)。 (FULL
のように、ログをバックアップするまで回復します)。 CHECKPOINT
イベントはログを制御するのに役立ち、CHECKPOINT
sの間に大量のt-logアクティビティを生成しない限り、ログが成長する必要がないことを確認します。
次に、このログの増加が異常なイベント(たとえば、毎年の春の大掃除または最大のインデックスの再構築)によるものであり、通常の日常的な使用によるものではないことを確認する必要があります。ログファイルを途方もなく小さいサイズに圧縮し、SQL Serverが通常のアクティビティに対応するためにログファイルを再度拡張する必要がある場合、何が得られましたか。一時的に解放したディスク領域を利用できましたか?すぐに修正が必要な場合は、次のコマンドを実行できます。
USE yourdb;
GO
CHECKPOINT;
GO
CHECKPOINT; -- run twice to ensure file wrap-around
GO
-- 200 MB
DBCC SHRINKFILE(yourdb_log, 200);
GO
それ以外の場合は、適切なサイズと成長率を設定します。ポイントインタイムリカバリの例のように、同じコードとロジックを使用して、適切なファイルサイズを決定し、適切な自動拡張パラメータを設定できます。
TRUNCATE_ONLY
オプションを使用してログをバックアップしてから、SHRINKFILE
を使用します。まず、このTRUNCATE_ONLY
オプションは非推奨になり、現在のバージョンのSQL Serverでは使用できなくなりました。次に、FULL
復旧モデルを使用している場合、これによりログチェーンが破壊され、新しい完全バックアップが必要になります。
データベースをデタッチし、ログファイルを削除して、再アタッチします。これがどれほど危険かを強調することはできません。データベースが復旧しない可能性があります。疑わしいものとして復旧する可能性があります。バックアップがある場合は、バックアップに戻す必要がある場合もあります。
「データベースの縮小」オプションを使用します。 DBCC SHRINKDATABASE
と同じことを行う保守計画オプションは、特にログの問題の問題を本当に解決する必要があるだけの場合は、悪い考えです。調整するファイルをターゲットにして、DBCC SHRINKFILE
またはALTER DATABASE ... MODIFY FILE
(上記の例)を使用して個別に調整します。
ログファイルを1 MBに圧縮します。 SQL Serverでは特定のシナリオでそれを実行でき、解放されたすべての領域を確認できるため、これは魅力的に見えます。データベースが読み取り専用でない限り(そして、それがそうである場合は、ALTER DATABASE
を使用してそのようにマークする必要があります)、ログは復旧モデルに関係なく現在のトランザクションに対応する必要があるため、多くの不要な増加イベントが発生します。 SQL Serverがゆっくりと苦痛に取り戻すことができるように、そのスペースを一時的に解放する目的は何ですか?
2番目のログファイルを作成します。これは、ディスクがいっぱいになったドライブを一時的に軽減しますが、これは、パンクした肺をバンドエイドで固定しようとするようなものです。別の潜在的な問題を追加するのではなく、問題のあるログファイルを直接処理する必要があります。一部のトランザクションログアクティビティを別のドライブにリダイレクトする以外は、2番目のログファイルは(2番目のデータファイルとは異なり)実際には何もしません。 Paul Randalは、複数のログファイルが後であなたに噛まれる理由も説明しています 。
ログファイルを少しだけ小さくして、それ自体が常に小さな速度で自動拡張できるようにする代わりに、ある程度大きなサイズ(最大の同時トランザクションセットの合計に対応できるサイズ)に設定し、適切な自動拡張を設定します。フォールバックとして設定することで、単一のトランザクションを満たすために複数回拡張する必要がなくなり、通常のビジネスオペレーション中に拡張が必要になることは比較的まれです。
ここで考えられる最悪の設定は、1 MBの増加または10%の増加です。おかしなことに、これらはSQL Serverのデフォルトです(私は不満を言っています 変更を要求しない )-データファイル用に1 MB、ログファイル用に10%。前者はこの日と年齢では非常に小さすぎ、後者は毎回イベントが長くなります(たとえば、ログファイルは500 MB、最初の増加は50 MB、次の増加は55 MB、次の増加は60.5 MBです) 、等々-そして遅いI/Oでは、私を信じてください、あなたは本当にこの曲線に気づくでしょう)。
ここで止めないでください。ログファイルの圧縮に関するアドバイスの多くは本質的に悪いものであり、破滅的なものになる可能性さえありますが、ディスク領域を解放するよりもデータの整合性を重視する人もいます。
ログファイルの内容も確認できます。これを行うには、文書化されていないfn_dblog
、または ApexSQL Log などのトランザクションログリーダー。
インデックスの再編成は表示されませんが、すべてのDMLイベントとさまざまなDDLイベントが表示されます:ALTER
、CREATE
、DROP
、トリガーの有効化/無効化、権限の付与/取り消し、オブジェクトリネーム。
免責事項:私はApexSQLでサポートエンジニアとして働いています
これは、ログが増大してディスクがいっぱいになるほとんどすべてのDBAにとって最も頻繁に直面する問題です。
•トランザクションログが非常に大きくなる理由は何ですか?
•ログファイルが非常に大きいのはなぜですか。
log_reuse_wait_des
cの列sys.databases
テーブルは、ログが切り捨てられないように保持しているものを確認します。
select name, log_reuse_wait_desc
from sys.databases
•この問題の発生を防ぐ方法は何ですか?
ログのバックアップは、ログの再利用を妨げているものがない限り、ログの増大を制御するのに役立ちます。
•根本的な原因を理解し、トランザクションログファイルを適切なサイズにしたい場合はどうすればよいですか?
実際に原因を特定している場合は、以下のページで説明されているように、それを修正してみてください。
https://www.brentozar.com/archive/2016/03/my-favorite-system-column-log_reuse_wait_desc/
異常な状況でない限り、適切なログバックアップをスケジュールすることは、ログの増大に対処する最良の方法です。