undoログとは
undoログは、1つの読み書きトランザクションに紐づくundoレコードの集まりです。undoレコードは、クラスタ化インデックスの行に対する最新の変更を打ち消す情報が1件分入ったものです。行を1回変更するたびにundoレコードが1件増え、それらはundoログにまとめて置かれます。
InnoDBでは主に2つの用途があります。
1つはROLLBACK時の取り消しです。トランザクションがコミットされずに終わった場合、そのトランザクションが行った変更をundoログに基づいて打ち消し、データを変更前の状態へ戻します。
もう1つはMVCC(Multi-Version Concurrency Control)です。ある時点のスナップショットを見ている読み取りからは、他のトランザクションがすでにコミットした最新の行がまだ見えてはいけないことがあります。そのとき、undoログに残された古いバージョンをたどって、その読み取りから見えるべきバージョンを復元します。
undoログの場所
通常テーブル向けのundoログはundoテーブルスペースのrollback segmentに、一時テーブル向けはグローバル一時テーブルスペースのrollback segmentに割り当てられます。
rollback segmentはundoスロットの配列を持ち、スロットには先頭undoページの番号が入ります。undoページとundoレコードは同じテーブルスペース上の別領域にあります。undoレコードはundoページに複数件載ります。1ページに収まらなくなると、同じundoログに次のページをつなぎます。
undoログの種類と寿命
1つのトランザクションには、必要になった種類だけundoログが割り当てられます。通常テーブルのINSERTだけなら1本です。通常テーブルと一時テーブルの両方で、INSERTとUPDATE(またはDELETE)を行うと4本になります。
通常テーブル向けのundoログはundoテーブルスペースに置かれ、ROLLBACKとMVCCの両方に使われます。一時テーブル向けのundoログはグローバル一時テーブルスペースに置かれます。一時テーブルは作ったセッションからしか見えないので、他のトランザクションが古い値を読む必要はなく、ROLLBACKにだけ使われます。
通常テーブルでは、INSERTとUPDATEでコミット後にundoログを残すかが異なります。
INSERT用のundoログは、コミット完了時に破棄または再利用されます。コミット後に他のトランザクションが読む可能性がある古い値が存在しないからです。UPDATE用(DELETEを含む)のundoログは、コミット後も残します。他のトランザクションがまだ更新前の値を読んでいることがあるからです。他のトランザクションから読まれなくなったら回収されます。