2013年04月26日

MySQL 5.6 では innodb_flush_log_at_trx_commit の意味が MySQL 5.5 と違う

はてなブックマークに登録

innodb_support_xa と binlog の危ない関係 で、 MySQL がトランザクションログのコミットをシングルスレッドでシーケンシャルに fsync していると書いたのですが、誤解だったのでその補足です。

タイトルの通り、 innodb_flush_log_at_trx_commit=1 の場合も、トランザクションログが fsync されません。トランザクションがディスクに書かれるシーケンスは次のようになります。

1. prepare (fsync)
2. write binlog (grouped, fsync)
3. commit

このうち 1 は従来通り各スレッドで並列に実行され、 2 と 3 が昨日紹介した sql/binlog.cc の MYSQL_BIN_LOG::ordered_commit() の中のでグループ化されてシーケンシャルに実行される処理です。 この ordered_commit() は先頭で

     thd->durability_property= HA_IGNORE_DURABILITY;
というようなフラグを立てています。このフラグは MySQL のソースコードの中で参照しているのは storage/innobase/trx/trx0trx.cc だけで、 HA_IGNORE_DURABILITY の時は flush_log_at_trx_commit=0 のように振る舞い、フラッシュ (fsync) を実行しません。

この場合、データの永続性は prepare されたトランザクションの内容と binlog で担保されます。 クラッシュリカバリの時は、 binlog を読み込んで、そこに書かれているprepare済みトランザクションをコミットしていきます。 (このため、クラッシュしたマシンからDBをコピーしてMySQLを再起動する場合など、binlogのコピーをサボるとコミットしたはずのトランザクションが消えてしまうので注意が必要です。今のところリカバリに読まれるのは最後の binlog だけで、 binlog のローテート時はトランザクションログにも fsync します)

最終的に、トランザクションごとの fsync の数は、 MySQL 5.5 の場合は (sync_binlog=0 の場合) 2回だったのに対して、 MySQL 5.6 では2回のうち1回は負荷が高くなるほどグループ化されて複数のコミットを1度で fsync されることになります。この点で MariaDB の方が速そうというのは勘違いでした。

この辺りはドキュメントが整ってなくて、 MySQL-internals に質問のスレッドが立っているのでそこが参考になります。


@methane
songofacandy at 18:27│Comments(0)TrackBack(0)mysql 

トラックバックURL

この記事にコメントする

名前:
URL:
  情報を記憶: 評価: 顔   
 
 
 
Blog内検索
Archives
このブログについて
DSASとは、KLab が構築し運用しているコンテンツサービス用のLinuxベースのインフラです。現在5ヶ所のデータセンタにて構築し、運用していますが、我々はDSASをより使いやすく、より安全に、そしてより省力で運用できることを目指して、日々改良に勤しんでいます。
このブログでは、そんな DSAS で使っている技術の紹介や、実験してみた結果の報告、トラブルに巻き込まれた時の経験談など、広く深く、色々な話題を織りまぜて紹介していきたいと思います。
最新コメント