バベルの図書館は完成しない

Extended outer memory module
for my poor native memory.

Posts:
2020/09/28 gendoc という YAML からドキュメントを生成するコマンドを作った
2020/09/13 ISUCON10 の予選を 7 位で通過した
2019/12/01 Puma の内部構造やアーキテクチャを追う
2019/05/27 Golang の正規表現ライブラリの処理の流れをざっくり掴む
2019/04/29 InnoDB の B+Tree Index について
2019/04/29 InnoDB における index page のデータ構造
2019/04/28 InnoDB はどうやってファイルにデータを保持するのか
2019/01/06 Designing Data-Intensive Applications を読んでいる
2019/01/03 年末年始に読んだ本について、など
2019/01/01 Ruby から ffi を使って Rust を呼ぶ
2018/11/10 ブラウザにおける状態の持ち方
2018/07/01 Rust で web アプリ、 或いは Rust における並列処理
2018/05/14 なぜテストを書くのか
2018/05/13 Rust で wasm 使って lifegame 書いた時のメモ
2018/03/12 qemu で raspbian のエミュレート(環境構築メモ)
2018/03/12 qemu で xv6 のエミュレート(環境構築メモ)
2018/03/03 Ruby の eval をちゃんと知る
2018/02/11 Web のコンセプト
2018/02/03 Rspec のまとめ
2018/02/03 Ruby を関数型っぽく扱う

InnoDB はどうやってファイルにデータを保持するのか

今日は MySQL のストレージエンジンとして有名な InnoDB がデータをどうやってディスク上に保持しているのかについて。

半分くらいは翻訳記事と言えなくもない。

基本的な構造

space

InnoDB は内部的に space という仮想的なデータの単位を持つ。 これは MySQL のリファレンスとかだと tablespace と呼ばれることもある。 space はファイルシステム上では複数のファイルに分かれていることもあるが、論理的には一つのファイルとして扱われる。

space は 32-bit integer の ID を持つ。

InnoDB は必ず system space と呼ばれる space を持っており、これは ID 0 で表現される。

MySQL では一つのテーブルが一つの space を持つという構造になっている。(だから多分 InnoDB をストレージエンジンにしていると、テーブルは使える ID の個数に対応して 16383(=16384 - 1) 個くらいしか作れないんだと思う)

page

spacepage という単位で構成される。

これは基本的に 16KB のサイズを持っていて、それぞれの page は 32-bit integer の ID を持つ(これを offset と呼んでいる)。

なので 64 TB までしかデータを保持することができない(16KB * 32-bit)。

space の内部構造

実際には space という論理的な単位だとサイズが不定で色々と都合が悪い。そこで spacepage の中間単位として extent というものがある。(extent はデフォルトで page が 64 個分、つまり 1 MB になっている)

すごくざっくりと説明すると space の内部構造は、 extent が 256 個ごとにその先頭 page にメタ情報を保持するヘッダ page がやってくる、という連続的な構造になっている。ただし space の 0 番目の page のみ space 全体に対するメタ情報も持つ。

このメタ情報を持つ page のうち、 space の先頭のものを FSP_HDR (file space header) と呼び、それに続く 256 の extent の先頭のものを XDES (extent descriptor) と呼ぶ。

FSP_HDRXDES の次には必ず IBUF_BITMAP と呼ばれる insert buffering に関わる page が置かれる。

また FSP_HDR に続く IBUF_BITMAP の後には INODE と呼ばれる index に関わる page が置かれる。

以下、 system spaceper-table space の場合に分けて詳しく見ていく。

system space の場合

先頭の FSP_HDR, IBUF_BITMAP, INODE page に続いて以下の type を持つ page が置かれる。

また 64 - 127 番目と 128 - 191 番目の page には double write buffer に使われる。

per-table space の場合

先頭の 3 つの page に続いて定義順に index の root の page が配置される。つまり 4 番目 の page にクラスタインデックスの root が来ることになる。

page の内部構造

page はそれぞれ FIL Header, FIL Trailer と呼ばれる 38 byte のヘッダと 8 byte のトレイラを持つ。残りは肝心の中身。

ヘッダの構成

トレイラの構成

参考

2019/04/28 23:17
tags: mysql - db - innodb
This site is maintained by furuhama yusuke.
from 2018.02 -