web-dev-qa-db-ja.com

トランザクションログに正確に何が書き込まれますか?

ここにシナリオがあります:

  1. Simple復旧モデルのDB、

  2. 約14 GBのデータ(約8000万行)、

  3. INSERT ... SELECTステートメントを空のテーブルに挿入し、7つの非クラスター化、非一意、単一列のインデックスと、インデックスのないテーブルからの1つのクラスター化単一列の主キー、

  4. トランザクションログは、Autogrowthが2 GBオンの無制限のスペースを持つように設定されています

クエリは3時間実行されており、トランザクションログファイルは約45 GB

私の質問は単純です-なぜですか?このシナリオでは、実際にトランザクションログに何が書き込まれますか?私は この記事このtechnetリソース および このMSDN記事 を読みましたが、特にSimple回復モード-この操作は最小限に記録する必要があります...

テーブルは複製されません。ようやくクエリをキャンセルして、代わりに新しいテーブルにキー/インデックス/制約を作成し、古いテーブルを削除して名前を変更しました。速くなりますよね?

4
maialithar

しかし、なぜログが非常に大きいのか、特に単純復旧モードの場合はまだ理解できません。この操作は最小限のログに記録されます...

いいえ、単純復旧モードでは、 最小限のログに記録できる操作 を残して、他のすべての操作は完全にログに記録されます。単純な復旧モデルでは、チェックポイントが発生するタイミングが異なります。チェックポイントは、トランザクションのコミット後、およびログファイルがサイズの70%に達すると発生します。他のすべてのシナリオでは、単純復旧でのロギングは完全復旧と同じです。

最小限のロギングでは、特定の要件を満たすために ターゲットテーブルも必要です

約14 GBのデータ(約8000万行)、

あなたはinsert into select * fromクエリのタイプ?その場合、大量のデータの読み取りと移動を行っていたため、トランザクションログファイルには、クエリに応じて、新しいテーブルに割り当てられた各ページが記録されます。トランザクションログには、行われたすべての変更をロールバックするためのスペースも保持されます。これらすべてを念頭に置いて、必要なスペースは本物だと思います。実行したクエリとSQL Serverの構成はわかりませんが、それに応じて、答えが変わる可能性があります。

トランザクションログに記録されるイベントについて、同様の質問がありました 。それを読み取るための文書化されたコマンドはありませんが、文書化されていないコマンドを使用してトランザクションログを読み取ることができます。 Remus Rusanuによる Analyzing Transaction Log をお読みください。

RedGateとApexで利用できるサードパーティのツールがあり、トランザクションログの読み取りに役立ちます。あなたはそれらについてオンラインで検索することができます。

4
Shanky

すべてがトランザクションログに書き込まれます。これは、文字通り、データベースで発生したすべてのトランザクションのログです。

トランザクションログから何かを削除するには、トランザクションが次の条件を満たしている必要があります。

  1. コンプリート
  2. ディスクに書き込まれました
  3. 完全復旧モードの場合、バックアップ

トランザクションが完了していない場合、トランザクションをディスクに書き込むことができません。メモリ内のデータが現在読み込まれているトランザクションの初期に変更される可能性があるため、それ以降のすべてのトランザクションはこの結果に依存する可能性があります。

したがって、単一の長時間実行クエリの開始以降に実行されたトランザクションは(フルモードで)バックアップできず、ディスクに書き込むことができないため、トランザクションログから削除して領域を解放することはできません。

これには、ramに格納されている変更されたデータは、トランザクションがディスクにコミットされたことを示すチェックポイントに達していないため、削除できないという追加の効果もあります。

これを回避するには、クエリを小さなチャンクにバッチ化して、1つの大きなトランザクションではなく複数の個別のトランザクションを作成します。

サイズに関しては、トランザクションログは文字通りデータを変更するすべての単一のトランザクションであり、したがって、更新/挿入の多い環境では、通常、予想よりも多くのデータがいっぱいになる可能性があります。 (たとえば、カウンターを1から1000まで1ずつインクリメントすることは、トランザクションログのテーブル(4バイト)のintフィールドである1行であり、このテーブルがこの「クラスター化インデックスの場所」をこの列に変更することを示す1000エントリです。この値です。急速に成長する可能性があります。

1
Ste Bov