LSN とは?

神谷 雅紀
Escalation Engineer

 

Do’s & Dont’s #16 で LSN (Log Sequence Number) について簡単に触れました。今回は LSN をもう少し詳しく見てみましょう。

 

LSN とは

LSN は、各トランザクションログレコードに割り当てられる番号です。トランザクションログレコードは、LSN によって一意に識別することができます。

データベースのデータファイルに対する変更は、すべてトランザクションログレコードとして、トランザクションログファイルに記録されます。例えば、あるデータを更新した場合、以下のような内容がトランザクションログに記録されます。これらひとつひとつに割り当てられる一意な番号が LSN です。

トランザクション T が開始された。
ページ A のスロット B の行が削除された。B の各列の値は C, D ,E …。
更新後の新しい行を格納するためにページが分割された。分割されたページは A, 追加されたページは F。
ページ分割に伴う行移動のために、ページ A のスロット H の行が削除された。H の各列の値は I, J, K …。
ページ分割に伴う行移動のために、ページ A のスロット L の行が削除された。L の各列の値は M, N, O …。
ページ分割に伴う行移動のために、ページ A のスロット P の行が削除された。P の各列の値は Q, R, S …。
ページ分割に伴う行移動のために、ページ F のスロット U の行が追加された。U の各列の値は I, J, K …。
ページ分割に伴う行移動のために、ページ F のスロット V の行が追加された。V の各列の値は M, N, O …。
ページ分割に伴う行移動のために、ページ F のスロット W の行が追加された。W の各列の値は Q, R, S …。
ページ A のスロット G に新しい行が追加された。追加された行の各列の値は C, D, Z …。
トランザクション T がコミットされた。

トランザクションログレコードは、そのデータベースにおけるすべてのトランザクションで直列です。例えば、トランザクション A のトランザクションが開始されて LSN 1 のトランザクションログレコードが生成された後、トランザクション B が開始されて LSN 2 が生成され、トランザクション A の行追加の LSN3 が生成されると、各 LSN の大小関係は LSN1 < LSN2 < LSN3 となり、トランザクションログファイルにも LSN1, LSN2, LSN3 の順に記録されます。

トランザクションログ A の Begin Transaction トランザクションログレコード LSN1 (例えば、10:1:1)
トランザクションログ B の Begin Transaction トランザクションログレコード LSN2 (例えば、10:1:2)
トランザクションログ A の Insert トランザクションログレコード LSN3 (例えば、10:1:3)

LSN の表記方法

LSN の表記方法にはいくつかのパターンがあります。

例えば、Do’s & Dont’s #16 のサンプルのように、エラーログに記録されるバックアップ実行に関するメッセージでは、43:3601:1 のように 3 つの 10 進数をコロンで区切っています。一方、RESTORE HEADERONLY の出力では、43000000360100001 のように区切りなしの 10 進数で表記されています。以下のように、16 進数で表記される場合もあります。

 

DBCC CHECKDB (DBNAME) WITH no_infomsgs executed by sa found 0 errors and repaired 0 errors. Elapsed time: 0 hours 0 minutes 9 seconds. Internal database snapshot has split point LSN = 0000002b:00000f01:0001 and first LSN = 0000002b:00000e11:0001.

 

上のメッセージ内の 16 進数表記を見ると、LSN が 4 バイト、4 バイト、2 バイトの 3 つの部分から構成されていることが推測できるでしょう。4 バイトの符号なし整数を 10 進数で表現した場合の最大桁数は 10 桁、2 バイトの場合は 5 桁なので、4 バイト、4 バイト、2 バイトを 10 進数で連続表記すると、10 桁、10 桁、5 桁の合計 25 桁の数になります。

つまり、

0000002b:00000e11:0001 (16 進数コロン区切り表記)
= 43:3601:1 (10 進数コロン区切り表記)
= 0000000043000000360100001 (10 進数区切りなし表記)
= 43000000360100001(先行する 0 を省略した 10 進数区切りなし表記)

となります。

10 進数区切りなし表記を用いると、LSN を直接比較することができ、簡単に大小関係を確認することができます。大きな値ほど新しい (最近の) トランザクションログレコードです。

例 : 43000000360100001 < 43000000360100005 < 43000000360200005 < 44000000360200005