CLFS ログ シーケンス番号
共通ログ ファイル システム (CLFS) では、特定のストリーム内の各ログ レコードは、ログ シーケンス番号 (LSN) によって一意に識別されます。 ストリームにレコードを書き込むと、後で参照できるようにそのレコードを識別する LSN が返されます。
特定のストリームに対して作成された LSN は、厳密に増加するシーケンスを形成します。 つまり、特定のストリーム内のログ レコードに割り当てられた LSN は、同じストリームに以前に書き込まれたログ レコードに割り当てられた LSN よりも常に大きくなります。 次の関数は、特定のストリーム内のログ レコードの LSN を比較するために使用できます。
定数 CLFS_LSN_NULL と CLFS_LSN_INVALID は、すべての有効な LSN の下限と上限です。 有効な LSN は CLFS_LSN_NULL 以上です。 また、有効な LSN は厳密にCLFS_LSN_INVALID未満です。 CLFS_LSN_NULL は有効な LSN ですが、CLFS_LSN_INVALID は有効な LSN ではないことに注意してください。 それでも、前の一覧の関数を使用して、CLFS_LSN_INVALIDを他の LSN と比較できます。
CLFS は、ストリームごとに、ベース LSN と最後の LSN という 2 つの特殊な LSN を追跡します。 また、個々のログ レコードには 2 つの特別な LSN (前の LSN と次の元に戻す LSN) があり、これを使用して関連するログ レコードのチェーンを作成できます。 次のセクションでは、これらの特別な LSN について詳しく説明します。
ベース LSN
クライアントがストリームの最初のレコードを書き込むとき、CLFS は基本 LSN を最初のレコードの LSN に設定します。 ベース LSN は、クライアントが変更するまで変更されません。 ストリームのクライアントがストリーム内の特定のポイントより前にレコードを必要としなくなった場合は、ClfsAdvanceLogBaseまたはClfsWriteRestartAreaを呼び出すことで、ベース LSN を更新できます。 たとえば、クライアントが最初の 5 つのログ レコードを必要としなくなった場合は、ベース LSN を 6 番目のレコードの LSN に設定できます。
最後の LSN
クライアントがストリームにレコードを書き込むと、CLFS は最後の LSN を調整して、常に最後に書き込まれたレコードの LSN になるようにします。 ストリーム内の特定のポイントの後にクライアントがレコードを必要としなくなった場合は、ClfsSetEndOfLogを呼び出すことで、最後の LSN を更新できます。 たとえば、クライアントが 10 番目のレコードの後に書き込まれたレコードが不要になった場合、最後の LSN を 10 番目のレコードの LSN に設定することでストリームを切り捨てることができます。
ストリームのアクティブな部分
ストリームの アクティブ部分は、ベース LSN が指すレコードで始まり、最後の LSN が指すレコードで終わるストリームの部分です。 次の図は、ベース LSN と最後の LSN がストリームのアクティブな部分をどのように示しているかを示しています。
ストリーム にアーカイブ 末尾がある場合、ストリームのアクティブな部分は、ベース LSN またはアーカイブ 末尾が指すレコードのいずれか小さい方から始まります。 アーカイブの詳細については、CLFS によるアーカイブのサポートを参照してください。
前の LSN
2 つのアクティブなデータベース トランザクション (トランザクション A とトランザクション B) が、同じストリームに同時にレコードを書き込んでいるとします。 トランザクション A は、レコードを書き込むたびに、レコードの前の LSN を、トランザクション A によって書き込まれた前のログ レコードの LSN に設定します。これは、トランザクション A に属するログ レコードのチェーンを形成し、逆の順序で走査できます。 チェーンは、トランザクション A によって書き込まれた最初のログ レコードで終わり、前の LSN が CLFS_LSN_INVALID に設定されています。 同様に、トランザクション B は、書き込む各ログ レコードの前の LSN を設定することで、独自のログ レコード チェーンを作成します。
次の図の矢印は、ログ レコードの前の LSN が、特定のトランザクションに属するチェーン内の前のレコードをどのように指しているかを示しています。
Undo-next LSN
トランザクションが揮発性メモリ内のデータ オブジェクトに対して 5 回の更新を行い、4 回目と 5 回目の更新をロールバックし、6 回目の更新を行うとします。 トランザクションが更新を行うと、ログ レコード 1、2、3、4、5、5'、4'、6 が書き込まれます。 ログ レコード 1 から 5 は、更新プログラム 1 から 5 によって行われた変更を表します。 レコード 5' は更新プログラム 5 のロールバック中に行われた変更を記述し、レコード 4' は更新プログラム 4 のロールバック中に行われた変更を記述します。 最後に、レコード 6 では、更新プログラム 6 によって行われた変更について説明します。 数値 1、2、3、4、5、5'、4'、6 はログ レコードの LSN ではないことに注意してください。これらは、この説明の目的でログ レコードの名前を付けるために使用される数字にすぎません。
ロールバックを記述するログ レコード 5' と 4' は、補正ログ レコード (CLR) と呼ばれます。 このトランザクションは、各 CLR の元に戻す次の LSN を、更新がロールバックされた (元に戻した) ログ レコードの先行レコード (トランザクションによって書き込まれたレコードの中) に設定します。 この例では、レコード 5' の元に戻す次の LSN はレコード 4 の LSN、レコード 4' の元に戻す次の LSN はレコード 3 の LSN です。
通常のログ レコード (CLR ではないレコード) には、元に戻す次の LSN が、トランザクションによって書き込まれた以前のログ レコードに設定されます。 つまり、通常のレコードの場合、元に戻す次の LSN と前の LSN は同じです。
ここで、システム障害が発生し、再始動リカバリー中にトランザクション全体をロールバックする必要があるとします。 リカバリー コードはログ レコード 6 を読み取ります。 レコード 6 のデータは、レコード 6 が通常のレコード (CLR ではない) であることを示しているため、回復コードは更新プログラム 6 をロールバックします。 次に、リカバリー コードはレコード 6 の元に戻す次の LSN を検査し、レコード 4' を指していることを検出します。 レコード 4' のデータは CLR であることを示しているため、回復コードは更新プログラム 4' をロールバックしません。 代わりに、レコード 4' の元に戻す次の LSN を検査し、レコード 3 を指していることがわかります。 レコード 3 は CLR ではないため、回復コードは更新プログラム 3 をロールバックします。 更新 5 と 4 は、通常の順方向処理中に既にロールバックされているため、復旧中にロールバックされません。 最後に、リカバリー コードは更新プログラム 2 と 1 をロールバックします。
次の LSN を元に戻す方法は、次の LSN の矢印を使用して、更新プログラムが既にロールバックされているレコードをスキップリカバリー コード方法を示しています。