innodbのレコードの構造
レコードのフォーマットはrem0rec.cに詳しい説明がある。
OLD STYLEとNEW STYLEの2種類がある。
(MySQL Internals Manualの説明はOLD STYLEのもの)
index->table->compが1だとNEW STYLE。
compはdict_mem_table_create()で設定している。
ha_innobase::create -> create_table_def -> dict_mem_table_create
create tableで、row_format=redundantのとき、compがFALSEになる。
それ以外(default, compressedなど)のときは、compはTRUEになる。
指定しなかったときもTRUEになる。
システムカタログ(SYS_TABLESなど)は、comp = FALSE。
MySQL 5.0.3 Release Notes --------------------------------------------------------------------- InnoDB: Introduced a compact record format that does not store the number of columns or the lengths of fixed-size columns. The old format can be requested by specifying ROW_FORMAT=REDUNDANT. The new format (ROW_FORMAT=COMPACT) is the default. ---------------------------------------------------------------------
OLD_STYLEのRecord Format
Record Formatは、大きくわけて3つのデータからなる。
(1)データへのオフセットリスト
最終フィールドから順に設定される。
(2)レコードの情報 (6bytes)
各種フラグや次のレコードへのポインタなど、レコードの情報が格納される。
(3)データ
データリスト。各フィールドのデータは、オフセットリストで指定された位置に存在する。
レコードの先頭アドレス(Origin of the record)は、データリストの先頭位置が使用される。オフセットリストに指定されるオフセットは、これが基点になるので、先頭フィールドのオフセットは0。
以下のようなレイアウトになる。
最終フィールドのデータ末尾のoffset ...... 2番目のフィールドのデータ末尾のoffset 先頭フィールドのデータ末尾のoffset レコード情報(6 bytes) <---- ここがOrigin of the recordのポインタ 先頭フィールドのデータ 2番目のフィールドのデータ ...... 最終フィールドのデータ
オフセットについて:オフセットの先頭ビットはNULLフラグとして使用される。レコード長(データの長さの合計値)が127byte未満のときは、各フィールドのオフセットは1byteで表現される。それ以上のときは2byte使う。オフセット長が1byteか2byteかどうかは、レコード情報のフラグに設定される。
また、2byteのときは、2番目のビットはデータが別ページに保存されたことを示すフラグとして使用される。
オフセットには各フィールドの末尾の位置が設定されるので、あるフィールドの先頭のオフセットを知りたいときは、1つ前のフィールドのオフセットを見る。
レコード情報のレイアウトは以下のとおり。
未使用 (2 bits) 削除フラグ (1 bit) min_rec_flag (1 bit) このレコードが保持しているレコード数 (4 bits) レコード番号 (13 bits) フィールドの数 (10 bits) 1byteオフセットフラグ (1 bit) 1だったらオフセットは1byte。0だったら2byte。 次のレコードへのポインタ (16 bits)
NEW_STYLEのRecord Format
NEW_STYLEはレコードサイズが小さくなるように、以下の工夫をしている
(1)各レコードにフィールド数をもたない
(2)オフセットではなく、データ長をもつ
(3)各レコードに固定長のデータ長はもたない
(4)NULLフィールドのデータ長はもたない
レコードのレイアウトは以下のようになる。
可変長でNULLではない最終フィールドの長さ ...... 可変長でNULLではない先頭フィールドの長さ NULLフラグ(NULLが許可されているフィールドにつき1bit。byte単位で確保される) レコード情報 (4 bytes) <-- Origin of the record 先頭レコードのデータ ...... 最終レコードのデータ フィールド長: テーブル定義のフィールド長が255bytes以内のときは、1byte(0〜255)。 フィールド長が256bytes以上のときは、以下のようになる データ長が127bytes以内のときは1byte。(0〜127) データ長が128以上のときは2byteが使用される。先頭ビットは常に1で、 2番目のビットはextern storage flagとして使用される。データ長として 使用できるのは14 bits(128〜16383)。 レコード情報: 未使用 (2 bits) 削除フラグ (1 bit) min_rec_flag (1 bit) このレコードが保持しているレコード数 (4 bits) レコード番号 (13 bits) レコードタイプ (3 bits) 次のレコードへのポインタ (16 bits) レコードタイプ: 000: conventional 001: node pointer (inside B-tree) 010: infimum 011: supremum 1xx: reserved
システムカラム
各レコードの先頭には、以下のシステム用のカラムが追加される。
(1)Row ID (6 bytes)
(2)Transaction ID (6 bytes)
(3)Rollback pointer (7 bytes)
ただし、Primary keyが定義されているときは、Row IDの代わりにPrimary keyが使用される。
Primary keyなし Row ID Transaction ID Rollback pointer ユーザー定義のカラム1 ユーザー定義のカラム2 ..... Primary keyあり Primary key (ユーザー定義のカラム1) Transaction ID Rollback pointer ユーザー定義のカラム2 .....