MySQL InnoDB ストレージエンジンでは、データはページ単位で管理され、各レコードにはメタ情報を格納する「レコードヘッダ」が含まれる。特に Compact 行フォーマットにおいて、このヘッダは5バイト(40ビット)で構成され、トランザクション制御や物理レイアウトに不可欠な情報を保持している。本稿では、その構成要素である delete_mask、min_rec_flag、n_owned、heap_no、record_type、next_record の役割を詳細に解説する。
Compact 行フォーマットの概要
Compact は InnoDB のデフォルト行フォーマットであり、以下の構造を持つ:
- レコードヘッダ:5バイト。制御フラグとポインタ情報を格納。
- NULL ビットマップ:各カラムの NULL 状態を1ビットで表現。
- 可変長フィールド長リスト:VARCHAR などの長さ情報を格納。
- システムカラム:6バイト(DB_TRX_ID: 6B + DB_ROLL_PTR: 7B、ただし実際は圧縮されて格納)。
- ユーザーデータ:実際のカラム値。
検証用テーブルの作成
CREATE TABLE demo (
c1 INT,
c2 INT,
c3 VARCHAR(10000),
PRIMARY KEY (c1)
) CHARSET=ascii ROW_FORMAT=COMPACT;
主キー c1 を指定することで、InnoDB は暗黙の row_id を生成しない。以下4件のデータを挿入:
INSERT INTO demo VALUES
(1, 100, 'aaaa'),
(2, 200, 'bbbb'),
(3, 300, 'cccc'),
(4, 400, 'dddd');
レコードヘッダの構成要素
delete_mask(1ビット)
レコードが論理削除されたかどうかを示すフラグ。
0:有効なレコード1:削除済み(物理削除は遅延される)
削除時に即座にディスクから消去せず、後続の INSERT 操作で再利用可能な「ゴミ領域」として管理される。これにより I/O 負荷を軽減し、空間効率を向上させる。
min_rec_flag(1ビット)
B+木の非リーフノードにおいて、そのノード内の最小キーを持つレコードにのみ設定されるフラグ(1)。リーフノードのレコードでは常に 0。ノード分割・マージ時の最適化に利用される。
n_owned(4ビット)
現在のスロット(slot)が「所有」するレコード数を示す。InnoDB はページ内のレコードをグループ化し、各グループの先頭レコード(スロット)にこの値を設定する。最大15(2⁴−1)まで表現可能。
例:スロットAが n_owned=3 → A自身と次の2件のレコードをカバー。これはページ内バイナリサーチを高速化するための設計。
heap_no(13ビット)
ページ内でのレコードの物理位置を示すインデックス(0~8191)。特殊な2つの仮想レコードが存在:
Infimum:最小境界レコード(heap_no = 0)Supremum:最大境界レコード(heap_no = 1)
ユーザーレコードは heap_no = 2 から割り当てられる。この値はページ内の相対順序を維持するために使用される。
record_type(3ビット)
レコードの種別を識別:
0:通常のユーザーレコード1:Infimum(最小境界)2:Supremum(最大境界)3:B+木の非リーフノードレコード(インデックスノード)
上記 demo テーブルの実データはすべて record_type = 0 となる。
next_record(16ビット)
現在のレコードから次のレコードまでの相対オフセット(バイト単位)を格納。これにより、ページ内の全レコードが主キー順に単方向リンクリストとして接続される。
リンクリストの動的更新
以下の操作で next_record は動的に調整される:
- INSERT:主キー順で適切な位置に挿入し、前後の
next_recordを再リンク。 - DELETE:レコードを論理削除(
delete_mask=1)し、前のレコードのnext_recordを削除対象の次へジャンプさせる。 - UPDATE(主キー変更):旧レコードを削除マークし、新レコードを再挿入。
例:主キー2のレコードを削除後、再度同じキーで挿入すると、InnoDB は削除済み領域を再利用し、リンクリストを元の状態に復元する。これによりフラグメンテーションを抑制しつつ、順序性を保つ。
設計思想の要約
- 空間効率:論理削除と再利用により、頻繁な物理書き込みを回避。
- 順序維持:
next_recordと仮想境界レコードで、常にソート順を保証。 - 検索最適化:
n_ownedとスロット構造により、ページ内検索を O(log n) に近づける。
これらのメカニズムは、InnoDB が高スループットとACID特性を両立する基盤となっている。