バッファ管理。チェックポイント。トランザクションが未確定のデータのフラッシュについて
昨日の宿題への回答。
CHECKPOINTの処理でトランザクションが未確定の変更がフラッシュされるのか?
答え
される。
タプルを追加し、まだトランザクションをコミットもロールバックもしていない時に、CHECKPOINTを実行して確かめた。フラッシュされたかどうかは、ファイルをpg_filedumpして確認した。pg_filedumpすると次のように表示された。
Item 1 -- Length: 32 Offset: 8160 (0x1fe0) Flags: NORMAL XMIN: 589 XMAX: 0 CID|XVAC: 0 Block Id: 0 linp Index: 1 Attributes: 2 Size: 24 infomask: 0x0802 (HASVARWIDTH|XMAX_INVALID)
空のテーブルだったところにタプルが追加されたのでフラッシュされたと判断できる。
ロールバックされるデータがディスクや共有バッファ上のページに記録されるとしたらその可視性はどのように禁止されるのか?
答え
MVCCの可視性チェック(たとえばHeapTupleSatisfiesMVCC関数で)で、CLOG(コミットログ)を使って可視性がOKかどうか判断される(キャッシュが有効な場合など必ずしもCLOGをみないけど)。
CLOGには、トランザクションがコミットされたかロールバックされたかといった情報がチェックポイント時に書き込まれる。タプルはどのトランザクションにより追加されたかを示す情報であるトランザクションIDをもっている(上のpg_filedumpの例だとXMINの589がトランザクションID)。このトランザクションIDを使ってCLOGを見るとそのタプルがコミットされたかロールバックされたかわかる。今回の場合は、ロールバックされたと記録されている。
可視性チェックの処理では、ついでにタプルの情報を書き換えロールバックされていたとマークする。さらに、すでにディスクにフラッシュされてしまっている場合は、ページをダーティにして次のフラッシュでディスクが更新されるようにする。ディスクに書き込まれたものをpg_filedumpしてみると次のようになっている。
Item 1 -- Length: 32 Offset: 8160 (0x1fe0) Flags: NORMAL
XMIN: 589 XMAX: 0 CID|XVAC: 0
Block Id: 0 linp Index: 1 Attributes: 2 Size: 24
infomask: 0x0a02 (HASVARWIDTH|XMIN_INVALID|XMAX_INVALID)
infomaskにロールバックされたことを示すXMIN_INVALIDのビットが加えられてたことがわかる。次のMVCCの可視性チェックからは、CLOGをみなくてもこのフラグで可視性を判断できる。XMIN_INVALIDのタプルはいずれVACUMMにより除去される。
ちなみに、CLOGからコミットされたと判断できた場合のpg_filedumpの結果は次のようになる。
Item 1 -- Length: 32 Offset: 8160 (0x1fe0) Flags: NORMAL
XMIN: 589 XMAX: 0 CID|XVAC: 0
Block Id: 0 linp Index: 1 Attributes: 2 Size: 24
infomask: 0x0902 (HASVARWIDTH|XMIN_COMMITTED|XMAX_INVALID)
infomaskにコミットされたことを示すXMIN_COMMITTEDのビットが立つ。当然、このデータはMVCCの可視性チェックで見えるデータとして扱われる。