Microsoft内およびコンサルタントとしてのデータ専門家としてのキャリアを通じて、SQLServerデータベースの最も誤解されている部分の1つがトランザクションログであることに気づきました。トランザクションログがどのように機能し、管理する必要があるかについての知識の欠如、または単なる誤解は、次のようなあらゆる種類の本番環境の問題につながる可能性があります。
- トランザクションログが制御不能になり、スペースが不足する可能性があります
- トランザクションログの繰り返し縮小によるパフォーマンスの問題
- VLFフラグメンテーションと呼ばれる問題によるパフォーマンスの問題 、この投稿で説明しました
- トランザクションログのバックアップを使用して目的の時点に回復できない
- ディザスタリカバリ中にテールログバックアップを実行できない(テールログバックアップの説明については、ここを参照してください)
- フェイルオーバーとパフォーマンスの復元に関するさまざまな問題
この投稿では、トランザクションログと、それがどのように機能し、管理する必要があるかについて、時折シリーズを開始します。その過程で、上記のすべての問題に触れます。この投稿では、ロギングとは何か、なぜロギングが必要なのかを説明します。
ロギングに関する基本的な用語
SQL Serverのメカニズムについて話していると、説明する前に単語やフレーズを使用する必要がある鶏が先か卵が先かという問題があります。このシリーズでこの問題を回避するために、ロギングについて説明するときに使用する必要のあるいくつかの用語を説明することから始めます。シリーズが進むにつれて、これらの用語の多くを拡張していきます。
トランザクション、コミット、ロールバック
トランザクションには、データベースに対する変更または一連の変更が含まれます。開始と終了が定義されています。開始は、BEGIN TRANSACTIONステートメントが使用されるとき、またはSQLServerが自動的にトランザクションを開始するときです。終わりは次の4つのうちの1つです。
- COMMITTRANSACTIONステートメントが実行されるとトランザクションがコミットされます
- 自動コミットトランザクションの場合、SQLServerがトランザクションを自動的にコミットするとトランザクションはコミットされます
- ROLLBACK TRANSACTIONステートメントが実行された後、トランザクションはロールバックを終了します
- 問題が発生した後、トランザクションはロールバックを終了し、SQLServerはトランザクションを自動的にロールバックします
トランザクションがコミットされると、トランザクションに加えられた変更はデータベースで確定され、ディスク上のSQLServerトランザクションログで永続的になります。 「トランザクションログで」と言ったことに注意してください。メモリ内のデータファイルページへの実際の変更は、トランザクションがコミットされたときにディスクに書き込まれません。変更はトランザクションログですでに永続的であるため、データファイルで永続化する必要はありません。最終的に、データファイルページはチェックポイント操作によってディスクに書き込まれます。
逆に、トランザクションがロールバックすると、トランザクションで行われたデータ変更はデータベースに存在しなくなります。トランザクションのロールバックはより多くの変更を実行することを意味するため、データベースにはまだ物理的な変更がありますが、ロールバックされたトランザクションはデータベース内のデータに影響を与えていないと考えることができます。
チェックポイントとロールバック操作は、独自の投稿に値するトピックであるため、シリーズの後半で説明します。
これらの3つの用語については、チュートリアルSQLServerトランザクションの概要でさらに詳しく説明します。 SentryOneブログで。
ログ、ログレコード、およびSQLServerトランザクションログ
ロギングとは、ほとんどの場合、トランザクションのコンテキストで、データベースへの変更の永続的な説明を作成することを意味します。変更が行われると、その変更はログレコードに記録されます。ログレコードには通常、変更をデータベースで再生したり、必要に応じてデータベースでロールバックしたりするのに十分な情報が含まれています。
このログレコードは最初はメモリにあり、トランザクションがコミットする前にディスクに書き込むことができますが、前に必ずディスクに書き込む必要があります。 トランザクションはコミットを終了できます。そうでない場合、トランザクションは永続的ではありません。この規則の例外は、耐久性の遅延の場合です。 この投稿でAaronBertrandが説明している機能が有効になっています。
ログレコードはトランザクションログ(ディスク上の1つ以上のログファイル)に保存されます。これはやや複雑な内部アーキテクチャを備えています。これについては、シリーズの次の投稿でログレコードについて詳しく説明します。
クラッシュリカバリ
クラッシュとは、SQL Serverが予期せずシャットダウンし、変更されたさまざまなデータベースを正しくシャットダウンできなかった場合です(変更されたすべてのデータファイルページがディスクに書き込まれ、データベースが正常にシャットダウンされたとマークされていることを確認してください)。
>SQL Serverは起動時に、すべてのデータベースをチェックして、正常にシャットダウンされたものとしてマークされていないデータベースがあるかどうかを確認します。見つかった場合、そのデータベースはクラッシュリカバリを実行する必要があります。これにより、次のことが保証されます。
- クラッシュ前にコミットされたトランザクションについては、トランザクションのすべての変更がデータベースに反映されていることを確認してください(つまり、トランザクションを再生します)
- クラッシュ前にコミットされなかったトランザクションについては、トランザクションの変更がデータベースに反映されていないことを確認してください(つまり、トランザクションをロールバックします)
つまり、クラッシュリカバリにより、データベースはトランザクション的に一貫性のあるになります。 クラッシュが発生した時点で。クラッシュリカバリが使用されます:
- SQL Serverが起動し、回復する必要のあるデータベースを見つけたとき
- データベースのセカンダリコピーへのフェイルオーバー中
- バックアップを含む復元シーケンスの最後(ここを参照)
クラッシュリカバリは複雑なプロセスであり、詳細に説明する前に、シリーズの別のいくつかの投稿が必要です。
ロギングが必要な理由
ロギングの最も基本的な理由は、SQL Serverデータベースでトランザクションを永続化できるようにすることです。これにより、クラッシュリカバリ中にリカバリしたり、通常のデータベース操作中に必要に応じてロールバックしたりできます。ロギングがなかった場合、データベースはトランザクションに一貫性がなく、クラッシュ後に構造的に破損する可能性があります。
ただし、ログを記録しないと、次のようなSQLServerの他の機能のホストは使用できません。
- 一貫してリカバリできるデータバックアップ
- 復元操作中に使用でき、ログ配布を実装できるSQLServerトランザクションログのバックアップ
- レプリケーション。トランザクションログからトランザクションを収集できることに依存しています
- トランザクションログから変更を収集するためにトランザクションレプリケーションログリーダーエージェントを使用する変更データキャプチャ
- データベースのミラーリングおよび可用性グループ。再生のためにデータベースのセカンダリコピーにログレコードを送信することに依存しています
SQL Server(および同様のすべてのデータベースサーバー)は、先行書き込みロギングと呼ばれるものを使用します。 。これは、データベースを適切にクラッシュリカバリする機能を保証するために、変更自体の前に変更の説明をディスクに書き込む必要があることを意味します。ログレコードがそれを説明する前に変更がデータファイルに書き込まれ、SQL Serverがクラッシュした場合、何をロールバックするかを知る方法がなく、データベースに一貫性がなくなります。この順序は、分離レベル、トランザクションのタイプ、または遅延耐久性機能が使用されているかどうかに関係なく、不変です。最初にレコードをログに記録し、後でデータページをログに記録します。
氷山の一角
この紹介記事からわかるように、トランザクションログとSQL Serverデータベースへのログ記録には膨大な量が含まれます。これまでに行ったのは、高レベルの用語を定義し、ログ記録が必要な理由を説明することだけです。シリーズが進むにつれて、私が分岐してさらに深くなるときに、あなたが私に加わってくれることを願っています!