--innodb-log-file-size

提供:MySQL Practice Wiki

移動: 案内, 検索
innodb-log-file-size
ファイル my.cnf, my.ini
セクション [mysqld]
データ型 整数 (K、M、Gで修飾可)
デフォルト値 5MB
値の範囲 1MB 〜 (32ビットコンピュータではファイルの合計4GB)
効果 記事を参照
効果の有効範囲 mysqld/innodb
使用頻度

説明

InnoDBのログファイルは、別名WAL - Write Ahead Logと呼ばれるもので、名前を日本語に直すと「前もって書き込んでおくためのログ」とでも呼べるだろうか。InnoDBのテーブルに対して行われた更新は、全ていったんログに書き込まれるのである。トランザクションがコミットされると、innodb_flush_log_at_trx_commit=1 が設定されていればログファイルに書き込みが行われる。0または2の場合には、ログバッファと呼ばれる領域にデータが保持される。その後、時間をおいてからテーブルスペースへ更新が反映されるのである。

なぜこのような仕組みになっているのだろうか?

コミットと同時にテーブルスペースを反映すればいいじゃないか?と思われるかも知れない。しかし、テーブルスペースへの更新には時間がかかるのである。なぜか?簡単に言うと、更新するべき箇所がたくさんあるからである。テーブルスペースに含まれているのはデータだけではなく、インデックス情報も含まれている。インデックスはBツリー構造になっているため、場合に因ってはインデックスを辿ったり、ページが分かれる場合にはリーフノード以外にも1つ以上のノンリーフノードを更新しなければいけない。そして、大抵の場合一つのテーブルに定義されているインデックスは複数あり、インデックスが増えればそれだけ更新するべきページも増えてしまう。さらに、一つのトランザクションにおいて更新するテーブルが複数ある場合も多い。更新するページはテーブルスペース内に離散して格納されているので、ディスクに対するランダムアクセスが発生してしまう。

つまり、テーブルスペースの更新はとてもコストが高いので、コミット時にこれら全ての更新を行っていたのでは書き込み性能が出ないのである。

そこで、まずはコミット時に全ての更新をWALに書き込み、時間が経ってからテーブルスペースを更新するという方法が採られている。この方法にはさらに次のメリットがある。

  • WALに対する書き込みはシーケンシャルなので、シーク時間がなくとても速い。
  • 急激にたくさんの書き込み要求が来た場合に耐えることができる。
  • 複数のトランザクションが同じページを更新した場合、書き込み回数を減らすことができる。

即ち、WALにはテーブルスペースにまだ反映されていないデータが含まれていることになる。つまり、InnoDBのデータは、テーブルスペースとログを合わせて初めて、完全な情報を含んでいるのである。なのでみだりにログを削除してはいけない。

MySQL サーバを普通にシャットダウンした場合でも、WALにはテーブルスペースに反映されていないデータが残っている。シャットダウンと同時にテーブルスペースへデータを反映させるには、innodb_fast_shutdown=0を設定すれば良い。このオプションはMySQLサーバ稼働中に変更できるので、以下のようにしてからシャットダウンすると、WALを削除しても安全な状態になる。

mysql> SET GLOBAL innodb_fast_shutdown=0;

MySQL サーバ稼働中、WALにだけ書き込まれたデータはどこにあるのだろうか?答えは、InnoDBバッファプールである。バッファプールはテーブルスペースに対するキャッシュ+その他のデータを保持する領域であるが、対応するページがバッファプール内でだけ更新され、テーブルスペースは更新されていないという状態になる。このとき、そのページは「ダーティ」な状態であるという。

ダーティなページをテーブルスペースへ書き込む動作は、チェックポイント処理と呼ばれる。チェックポイントが行われると、「このページのチェックポイントしたよ!」という情報が、WALに書き込まれる。

また、InnoDBのログファイルは、クラッシュリカバリ時にRedoログとして使用される。最後のチェックポイント以降におこなわれた更新を、データファイルへ再適用するのである。ログファイルは全てスキャンされるため、ログファイルが大きいとクラッシュリカバリに時間がかかるようになる。


デフォルトの5MBは小さすぎるので、とりあえず特にサイジングしていなくても100MBぐらいに増やしておくといいだろう。ディスクに余裕がある時、または非常に更新が多いサービスを展開するときは、ログファイルをデータディスクとは別のディスクにするといい。

性能向上のためにInnoDBログファイルのディスク領域としてSSDが有用なのではないかと思うのだが、ハードウェアがないため検証はしていない。

参考

MySQL Performance Blogの投稿が参考になる。

http://www.mysqlperformanceblog.com/2006/07/03/choosing-proper-innodb_log_file_size/
個人用ツール