トランザクション ログのアーキテクチャと管理

すべての SQL Server データベースにはトランザクション ログがあり、データベース内のすべてのトランザクションとそれらのトランザクションによって加えられた変更が記録されます。 トランザクション ログはデータベースの重要なコンポーネントの 1 つであり、システム障害が発生すると、データベースを一貫性のある状態にするために求められる場合があります。 このガイドでは、トランザクション ログの物理アーキテクチャおよび論理アーキテクチャについて説明します。 アーキテクチャを理解することで、トランザクション ログを効率的に管理できるようになります。

適用対象: 別途記載がなければ SQL Server 2005 から SQL Server 2012。

このガイドの内容

トランザクション ログの論理アーキテクチャ

トランザクション ログの物理アーキテクチャ

先行書き込みトランザクション ログ

トランザクション ログのバックアップ

トランザクション ログの論理アーキテクチャ

SQL Server のトランザクション ログは、論理的にはトランザクション ログが一続きのログ レコードから構成されているものとして機能します。 それぞれのログ レコードは、LSN (ログ シーケンス番号) によって識別されます。 新しい各ログ レコードは、ログの論理上の末尾に前レコードの LSN より大きな LSN を付けて書き込まれます。 ログ レコードは、作成された順で連続して保管されます。 各ログ レコードにはトランザクション ID が含まれ、どのトランザクションについてのレコードかを示します。 各トランザクションに関連付けられているログ レコードはすべて、逆方向のポインターを使用して連鎖的にリンクされており、これによってトランザクションのロールバックをスピードアップできます。

データ変更のログ レコードには、実行した論理操作の記録または変更したデータの前後のイメージの記録が行われます。 前イメージは、操作が実行される前のデータのコピーです。後イメージは、操作を実行した後のデータのコピーです。

操作を復旧する手順は、ログ レコードの種類によって異なります。

  • 論理操作が記録されている場合

    • 論理操作をロールフォワードするには、その操作を再実行します。

    • 論理操作をロールバックするには、逆の論理操作を実行します。

  • 前後イメージが記録されている場合

    • 操作をロールフォワードするには、後イメージを適用します。

    • 操作をロールバックするには、前イメージを適用します。

トランザクション ログには各種の操作が記録されます。 記録される操作には次のようなものがあります。

  • 各トランザクションの開始および終了。

  • あらゆるデータ変更 (挿入、更新、または削除)。 これには、システム ストアド プロシージャまたは DDL (データ定義言語) ステートメントによって、システム テーブルなどのテーブルに加えられた変更が含まれます。

  • エクステントおよびページのすべての割り当てと割り当て解除。

  • テーブルまたはインデックスの作成と削除。

ロールバック操作も記録されます。 トランザクションごとにトランザクション ログの領域が予約されるので、明示的にロールバック ステートメントを実行したときやエラーが発生したときのロールバックに備え、十分なログ領域が確保されます。 予約領域のサイズは、トランザクションで実行される操作によって変わりますが、一般には各操作を記録するために使用される領域のサイズと同じです。 この予約領域は、トランザクションが完了したときに解放されます。

ログ ファイルの中で、データベース全体を正常にロールバックするために必要な最初のログ レコードから最後に書き込まれたログ レコードまでの部分を、ログのアクティブな部分、またはアクティブ ログといいます。 これは、データベースの完全復旧を実行するために必要なログのセクションです。 アクティブなログはどの部分も切り捨てることができません。 この先頭ログ レコードのログ シーケンス番号 (LSN) は、最小復旧 LSN (MinLSN) として知られています。

トランザクション ログの物理アーキテクチャ

データベースのトランザクション ログは、1 つ以上の物理ファイルにマップされます。 概念的には、ログ ファイルは一続きのログ レコードです。 物理的には、一連のログ レコードは、トランザクション ログを実装する一連の物理ファイルに効率的に格納されます。 1 つのデータベースにトランザクション ログ ファイルが少なくとも 1 つ必要です。

SQL Server データベース エンジンにより、各物理ログ ファイルは内部的に多くの仮想ログ ファイルに分割されています。 仮想ログ ファイルのサイズは固定されておらず、1 つの物理ログ ファイルに対する仮想ログ ファイルの数も決まっていません。 仮想ログ ファイルのサイズは、ログ ファイルの作成時や拡張時にデータベース エンジンにより動的に選択されます。 データベース エンジンでは、管理する仮想ファイルの数を少なく保とうとします。 ログ ファイルを拡張した後の仮想ファイルのサイズは、既存のログのサイズと増加した新しいファイルのサイズの合計になります。 管理者が仮想ログ ファイルのサイズや数を構成または設定することはできません。

仮想ログ ファイルがシステムのパフォーマンスに影響を与えるのは、小さな size 値と growth_increment 値で物理ログ ファイルを定義した場合のみです。 size 値はログ ファイルの初期サイズであり、growth_increment 値は新しい領域が必要になるたびにファイルに追加される容量を示します。 小さな増加が繰り返されることにより、これらのログ ファイルが大きいサイズに拡張された場合、多くの仮想ログ ファイルが生成されます。 このような状況では、データベースの起動、ログのバックアップ操作、およびログの復元操作の速度が低下する場合があります。 ログ ファイルの size には最終的に必要なサイズに近い値を割り当て、growth_increment には比較的大きい値を割り当てることをお勧めします。 これらのパラメーターの詳細については、「ALTER DATABASE の File および Filegroup オプション (Transact-SQL)」を参照してください。

トランザクション ログは、循環して使用されるファイルです。 たとえば、4 つの仮想ログ ファイルに分割された 1 つの物理ログ ファイルが格納されたデータベースがあるとします。 このデータベースの作成時、論理ログ ファイルは物理ログ ファイルの先頭から始まります。 新しいログ レコードは論理ログの末尾に追加され、物理ログの末尾に向かって拡張されます。 ログの切り捨てにより、最小復旧ログ シーケンス番号 (MinLSN) より前にあるすべての仮想ログ レコードが解放されます。 MinLSN は、データベース全体を正常にロールバックするために必要な最も古いログ レコードのログ シーケンス番号です。 例として挙げたデータベースのトランザクション ログは、次の図のようになります。

4 つの仮想ログ ファイルに分割されたログ ファイル

論理ログの末尾が物理ログ ファイルの末尾に達すると、新しいログ レコードはまた物理ログ ファイルの先頭から記録されていきます。

ログ ファイルの先頭に循環されるログ レコード

このサイクルは、論理ログの末尾が論理ログの先頭に達しない限り、無限に繰り返されます。 古いログ レコードが頻繁に切り捨てられ、次のチェックポイントで作成されるすべての新規ログ レコードを格納するのに必要な領域が常に確保されている場合、論理ログがいっぱいになることはありません。 ただし、論理ログの末尾が論理ログの先頭に達した場合には、次のいずれかの処理が発生します。

  • ログで FILEGROWTH の設定が有効になっていて、ディスクの領域が使用できる場合、ファイルは growth_increment パラメーターで指定した量だけ拡張され、新規ログ レコードがその拡張部分に追加されます。 FILEGROWTH の設定の詳細については、「ALTER DATABASE の File および Filegroup オプション (Transact-SQL)」を参照してください。

  • ログで FILEGROWTH の設定が有効になっていない場合、またはログ ファイルを保持しているディスクの空き領域が growth_increment で指定した量よりも少ない場合は、エラー 9002 が生成されます。

ログに複数の物理ログ ファイルが含まれている場合、論理ログは、すべての物理ログ ファイルの領域を使用し終えてから、最初の物理ログ ファイルの先頭に戻ります。

ログの切り捨て

ログの切り捨ては、ログがいっぱいにならないようにするために不可欠です。 ログの切り捨てでは、SQL Server データベースの論理トランザクション ログから非アクティブな仮想ログ ファイルが削除されます。これにより、論理ログの領域が解放され、物理トランザクション ログで再利用できるようになります。 トランザクション ログが切り捨てられなければ、物理ログ ファイルに割り当てられているディスク上の領域がいっぱいになってしまいます。 ただし、ログの切り捨て前に、チェックポイント操作が必要です。 チェックポイントでは、現在メモリにある修正ページ (ダーティ ページ) とトランザクション ログ情報がメモリからディスクに書き込まれます。 チェックポイントが実行されると、トランザクション ログの非アクティブな部分は再利用できるようにマークが付けられます。 その後、ログの切り捨てにより、非アクティブな部分を解放できます。 チェックポイントの詳細については、「データベース チェックポイント (SQL Server)」を参照してください。

次の図は、切り捨てを行う前と後のトランザクション ログを示しています。 最初の図は、切り捨てが行われていないトランザクション ログを示しています。 現在、4 つの仮想ログ ファイルが論理ログで使用されています。 この論理ログは最初の仮想ログ ファイルの先頭から始まり、仮想ログ 4 で終了します。 MinLSN レコードは仮想ログ 3 にあります。 仮想ログ 1 および仮想ログ 2 には、非アクティブなログ レコードのみが含まれています。 これらのレコードは切り捨てることができます。 仮想ログ 5 はまだ使用されていないので、現在の論理ログには含まれていません。

4 つの仮想ログがあるトランザクション ログ

2 番目の図は、切り捨て後のログの状態を示しています。 仮想ログ 1 および仮想ログ 2 は再利用のために解放されています。 この時点で、論理ログは仮想ログ 3 の先頭から始まっています。 仮想ログ 5 はまだ使用されていないので、現在の論理ログには含まれていません。

4 つの仮想ログ ファイルに分割されたログ ファイル

何かの理由で遅延が発生している場合を除いて、ログの切り捨ては、次のイベントの後に自動的に発生します。

  • 単純復旧モデルでは、チェックポイントの後。

  • 完全復旧モデルまたは一括ログ復旧モデルで、前回のバックアップ後にチェックポイントが発生している場合は、ログ バックアップの後。

ログの切り捨ては、さまざまな要因で遅延が発生する場合があります。 ログの切り捨てで長時間の遅延が発生すると、トランザクション ログがいっぱいになる可能性があります。 詳細については、「ログの切り捨てが遅れる原因となる要因」および「満杯になったトランザクション ログのトラブルシューティング (SQL Server エラー 9002)」を参照してください。

先行書き込みトランザクション ログ

このセクションでは、データの変更をディスクに記録するときの先行書き込みトランザクション ログの役割について説明します。 SQL Server では、先行書き込みログ (WAL) を使用します。これにより、関連付けられているログ レコードより前にデータ変更がディスクに書き込まれることがなくなります。 これにより、トランザクションの ACID プロパティが維持されます。

先行書き込みログがどのように機能するのかを理解するには、変更されたデータがディスクに書き込まれるしくみを把握しておくことが重要です。 SQL Server はバッファー キャッシュを保持し、データを取得する必要がある場合は、そのキャッシュの中へデータ ページを読み取ります。 ページがバッファー キャッシュ内で変更されたとき、その変更が直ちにディスクに書き戻されるわけではありません。代わりに、そのページはダーティとマークされます。 データ ページが物理的にディスクに書き込まれる前には、複数回の論理書き込みが行われる可能性があります。 論理書き込みを行うたびに、トランザクション ログ レコードが、変更を記録するログ キャッシュに挿入されます。 ログ レコードは、関連付けられているダーティ ページがバッファー キャッシュから削除されディスクに書き込まれる前に、ディスクに書き込まれる必要があります。 チェックポイント プロセスでは、指定されたデータベースからのページを含むバッファーのバッファー キャッシュを定期的にスキャンし、ダーティ ページをすべてディスクに書き込みます。 チェックポイントは、すべてのダーティ ページがディスクに書き込まれたことを確認するために作成されるポイントで、その後の復旧の時間を短縮します。

変更されたデータ ページをバッファー キャッシュからディスクに書き込むことを "ページのフラッシュ" といいます。 SQL Server には、関連付けられているログ レコードの書き込み前にダーティ ページをフラッシュしないためのロジックが用意されています。 ログ レコードは、トランザクションがコミットされるときにディスクに書き込まれます。

トランザクション ログのバックアップ

このセクションでは、トランザクション ログのバックアップと復元 (適用) の方法について説明します。 完全復旧モデルと一括ログ復旧モデルでは、データを復旧するためにトランザクション ログを定期的にバックアップすること (ログ バックアップ) が必要不可欠です。 ログのバックアップは、完全バックアップの実行中でも行うことができます。 復旧モデルの詳細については、「SQL Server データベースのバックアップと復元」を参照してください。

最初のログ バックアップを作成する前に、データベース バックアップや一連のファイル バックアップの最初のバックアップを行って、完全バックアップを作成する必要があります。 ファイル バックアップだけを使ったデータベースの復元は複雑になる可能性があります。 したがって、可能な時点でデータベースの完全バックアップを行うことから始めることをお勧めします。 その後、トランザクション ログを定期的にバックアップする必要があります。 その結果、作業損失の可能性が最小限に抑えられるだけでなく、トランザクション ログの切り捨ても可能になります。 一般に、トランザクション ログは、通常のログ バックアップ後に毎回切り捨てられます。

ログ バックアップは、ビジネス要件に対応するために十分な頻度で作成することをお勧めします。特に、ログ ドライブに障害が起こった場合に生じる作業損失に対する許容範囲を考慮してください。 ログ バックアップを行う適切な頻度は、作業損失に対する許容範囲と、ログ バックアップを保存、管理、復元できる量とのバランスによります。 15 分から 30 分間隔でログ バックアップを行えば十分でしょう。 業務上、作業損失の可能性を最小限に抑えることが求められる場合は、ログ バックアップの頻度を増やすことを検討します。 ログ バックアップの頻度を増やせば、ログ切り捨ての頻度も高くなり、ログ ファイルが小さくなる利点もあります。

復元する必要があるログ バックアップの数を制限するには、定期的なデータのバックアップが不可欠です。 たとえば、データベースの完全バックアップを毎週実行し、差分バックアップを毎日実行するようにスケジュールできます。

ログ チェーン

ログ バックアップの連続的なシーケンスを、ログ チェーンと呼びます。 ログ チェーンは、データベースの完全バックアップから始まります。 通常、新しいログ チェーンが開始されるのは、データベースが最初にバックアップされたとき、または復旧モデルを単純復旧から完全復旧または一括ログ復旧に変更したときだけです。 データベースの完全バックアップの作成時に既存のバックアップ セットを上書きしない限り、既存のログ チェーンはそのまま残ります。 ログ チェーンがそのまま残っている場合は、メディア セット内にあるデータベースの完全バックアップからデータベースを復元し、その後で復旧ポイントに達するまで後続のログ バックアップをすべて復元できます。 復旧ポイントは、最後のログ バックアップの末尾、または任意のログ バックアップの特定の復旧ポイントである場合があります。 詳細については、「トランザクション ログのバックアップ (SQL Server)」を参照してください。

データベースを障害の発生時点まで復元するには、ログ チェーンが途切れていないことが条件になります。 つまり、トランザクション ログ バックアップのシーケンスは、障害の発生時点まで途切れずに続いている必要があります。 ログのシーケンスの始まりは、復元するデータ バックアップの種類 (データベース バックアップ、部分バックアップ、ファイル バックアップ) によって異なります。 データベース バックアップまたは部分バックアップの場合、ログ バックアップのシーケンスはデータベース バックアップまたは部分バックアップの最後から始まっている必要があります。 一連のファイル バックアップの場合、ログ バックアップのシーケンスはファイル バックアップの完全なセットから始まっている必要があります。 詳細については、「トランザクション ログ バックアップの適用 (SQL Server)」を参照してください。

ログ バックアップの復元

ログ バックアップを復元すると、トランザクション ログに記録された変更がロールフォワードされ、ログ バックアップ操作が開始された時点のデータベースの正確な状態が再現されます。 データベースを復元するときは、復元するデータベースの完全バックアップ後に作成されたログ バックアップを復元するか、復元する最初のファイル バックアップの先頭からログ バックアップを復元する必要があります。 通常、最新のデータまたは差分バックアップを復元した後、復旧ポイントに到達するまで一連のログ バックアップを復元する必要があります。 その後、データベースを復旧します。 その結果、復旧を開始したときに不完全だったトランザクションがすべてロールバックされ、データベースがオンラインになります。 データベースが復旧された後は、それ以上バックアップを復元できません。 詳細については、「トランザクション ログ バックアップの適用 (SQL Server)」を参照してください。

その他の情報

トランザクション ログに関するその他の情報については、次の記事および書籍を参照することをお勧めします。

SQL Server のログ記録と復旧について (著者: Paul Randall)

SQL Server Transaction Log Management (SQL Server のトランザクション ログ管理) (著者: Tony Davis、Gail Shaw)