web-dev-qa-db-ja.com

SQL Serverのログ操作を最小限に抑えて、「ログがいっぱい」のエラーを回避する方法

私は本番環境にデータベースを保持しており、ログファイルが常にいっぱいになり、そのデータウェアハウスがあり、多くのジョブ/クエリが実行されています。以下は私が得ているエラーです

Msg 9002, Level 17, State 4, Line 7
The transaction log for database  is full due to 'ACTIVE_TRANSACTION'. 

これは理にかなっており、SQLがアクションを実行できないため、ログファイルがいっぱいになることを理解しています。 2つのログファイルがあります

  • 無制限の拡張と自動拡張が有効なDドライブ[Dドライブサイズ180 GB]
  • 静的サイズのEドライブ[Eドライブ120 GB、ログファイルサイズ:20 GB]

私はこの問題についていくつかの調査を行い、それに対する可能な解決策を見つけました: 出典

  • ログのバックアップ。
  • ログが自動的に大きくなるようにディスク領域を解放します。
  • ログファイルを十分な容量のあるディスクドライブに移動します。
  • ログファイルのサイズを増やします。
  • 別のディスクにログファイルを追加する。
  • 長期実行トランザクションを完了または強制終了します。

ここで、スペースが限られていると仮定すると(つまり、180 GB + 20 GB)、SIMPLE RECOVERYモードのデータベースには十分であると考えています。 この問題を特定して、それが発生する前に修正を行うにはどうすればよいですか?

レプリケーション

以下の設定で新しいサンプルデータベースを作成して、このシナリオを複製しようとしました enter image description here

以下のクエリでは、100万行を取得してテーブルに挿入します

SET NOCOUNT ON;
DECLARE @SET_SIZE INT = 500000000;

CREATE TABLE dbo.Test500Million (N INT  PRIMARY KEY CLUSTERED NOT NULL);

;WITH T(N) AS (SELECT N FROM (VALUES (NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL),(NULL)) AS X(N))
,NUMS(N) AS (SELECT TOP(@SET_SIZE) ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS N FROM T T1, T T2, T T3, T T4, T T5, T T6, T T7, T T8, T T9)
INSERT INTO dbo.Test500Million(N)
SELECT N FROM NUMS;

DROP TABLE dbo.Test500Million 

今、sys.databasesを検証し、エラーメッセージを調べているときに、両方のCHECKPOINTS & ACTIVE_TRANSACTION

私の質問

  • 私の観察では、これはselectではなくinsertステートメントでのみ発生していることがわかりました。したがって、ログエントリはINSERT/UPDATEのみであり、いずれの場合もSELECTステートメントではないと想定します。私は正しいですか?
  • 更新レコードを挿入するときにログを最小限に抑えるにはどうすればよいですか?私はすでにシンプルリカバリモードを持っています。
  • この期間の平均スループットは約25 MBから上がっていることがわかりました。 1.2 MBまで。どういう意味ですか?
  • ディスク領域を増やす以外に、この問題をトラブルシューティングする方法はありますか?
  • オプションだけがファイルを縮小することである場合、いつそれを行うべきですか?アクティブなトランザクションがONのときに実行できますか? [本番環境]

収集できる統計情報がさらに必要かどうかをお知らせください。

6
Zerotoinfinity

•私の観察では、これはselectでではなくinsertステートメントでのみ発生していることがわかりました。したがって、ログエントリはINSERT/UPDATEのみであり、いずれの場合もSELECTステートメントではないと想定します。私は正しいですか?

Selectステートメント自体は、insert、update、deleteなどのDMLステートメントと比較してログに記録されません。 selectステートメントのfn_dblogの出力が表示される場合は、エントリがありません。ただし、DMLステートメントのエントリは多数あります。 ご注意ください。トランザクションログが維持され、トランザクションに関連する情報がそこに書き込まれるため、クラッシュリカバリまたはリカバリ中に、SQL Serverはコミットされたトランザクションとコミットされていないトランザクションを認識し、これを読み取ることでデータベースを一貫した状態にすることができますISなぜログが非常に必要なのかトランザクションログがないと回復は不可能です

すべての実際的な目的のために、すべてのトランザクションはSQL Serverに記録されます。したがって、トランザクションを実行しても、トランザクションログに何も記録されないというシナリオはありません。 SQL Serverでログを無効にするオプションはありません。 SQL Serverのログとリカバリ をお読みになることをお勧めします。

•更新レコードを挿入するときに、ログを最小限に抑えるにはどうすればよいですか?シンプルリカバリモードをすでに持っています

単純な復旧モデルではロギングは行われないが、トランザクションがコミットするとすぐにトランザクションログが切り捨てられ、トランザクション用に生成されたログによって使用されるスペースが再利用されると誤解されています。事実、単純復旧でのロギングはほとんど完全復旧と同じであり、ログの切り捨てが発生した場合の違いがあります。はい、 特定のコマンド のみの一括ログ復旧モデルで最小限のログを記録できます。一括ログでも、残りのコマンドの場合、復旧モデルのログはいっぱいになります。

•この期間の平均スループットは約25 MBから上がっていることがわかりました。 1.2 MBまで。どういう意味ですか?

理解できません。説明してください。

•この問題のトラブルシューティングを行うには、ディスク容量を増やす以外の方法はありますか?

すでに示唆されているように、@ SET_SIZE INT = 500000000(ダミーであっても)を維持すると、このような上限が高い理由で問題が発生する可能性が高くなります。 500000に減らして、ログファイルの動作を確認できますか。ログファイルの自動拡張がMB単位であり、適切な値に設定されていることを確認してください。バッチでトランザクションを実行します。最後に、 トランザクションログが増加し続ける、または領域が不足する理由を読んだ場合 すると、良いアイデアが得られます。

•ファイルを縮小するオプションしかない場合は、いつ行うべきですか?アクティブなトランザクションがONのときに実行できますか? 【制作環境】案内用ですが、スペースを空ける必要があります。毎日何百万ものデータを処理する大規模なデータウェアハウスがあります。

データファイルやログファイルは圧縮しないでください。私はそれをお勧めしません。本当にONCEを縮小してスペースを再利用したい場合で、縮小する以外に選択肢がない場合は、それを試してみてください。ただし、縮小が完了したら、断片化されたすべてのインデックスを再構築する必要があることを忘れないでください。 This Article でPaulによって指定された方法を試すことができます。これは、縮小しないことを示し、縮小の代替手段を提供します。

ログファイルを縮小できるのは1回だけですが、ログファイルが大きくなったのはトランザクションを実行したためにログファイルが大きくなったため、基本的にはトランザクションログファイルではなく、間違いであることに注意してください。自動拡張イベントを回避できるように、ログファイルにある程度のスペースを事前に割り当てて、拡大および縮小するこのプロセス全体の代わりに、

別物

enter image description here

上記の設定は非常に悪いです。データファイルの1 MBの自動拡張は、問題を引き起こす可能性があります。正しい値を設定するには、記事 Autogrowth settings をお読みください。これは、正しい自動拡張設定を計算するのに役立ちます。

5
Shanky

可能であれば、トランザクションごとに変更されるデータの量を減らす必要があります。より少ないデータでより頻繁にコミットします。それ以外の場合は、ログサイズをさらに増やします。スペースが不足している場合は、増やす必要があります。

0
leancz