MySQL
InnoDB

InnoDB の DoubleWrite 技術をみる

doublewrite とは?

InnoDB が備わっている「データ二重書き込み」によるデータ保護機能。最初から有効になっている。1 この機能はトランザクションログとは別なので混同しないように。

どういう仕組みなのか?

  • テーブルスペースの doublewrite buffer 領域と呼ばれる場所に書き込む
    • 当該領域は 最低でも 100 ページ分が確保2 されており、連続追記に適した設計になっている
    • 使われなくなった領域は実データ書き込み後解放(再利用)される
  • fsync 関数を呼び出し
  • テーブルスペースのデータを書き込むページに書き込む
  • fsync 関数を呼び出し

二重にデータを書き込む形だが、Percona の説明 によると

  • 基本的には 5% 未満に収まる
  • ただしバッファプールに適合しない場合 30% の劣化が出る
    • ランダムアクセスが多発するため
  • 書き込み多発して doublewrite buffer が一杯の場合も解放待ちのため劣化幅が大きくなる

仕組み的に巨大な BLOB とは相性がとても悪いように思われる

なんのために使われるのか?

瞬断等により中途半端にデータが書き込まれた状態になった場合 (half-write) に修復のために利用される

  • 本来書き込まれるはずのデータが破損していた場合は doublewrite buffer 領域から修復
    • doublewrite buffer 領域が先に書き込まれてるため
  • doublewrite buffer 領域のデータが破損していた場合当該データは無視
    • トランザクションログである redo ログから修復する

ソースコード上はどこに存在するのか?

storage/innobase/buf/buf0dblwr.cc にある

無効にしてよいのか?

基本的には無効にすべきではない。が、以下に該当する場合は無効に出来る

  • Fusion-IO を使用している場合
    • Fusion-IO が備わっている Atomic Writes で代替可能
    • そもそも Fusion-IO を使っている場合 MySQL では自動的に無効化される3
  • ファイルシステムに ZFS を使っている場合45
    • Atomic Writes に対応しているため