Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

binary log と 2PC と Group Commit

802 views

Published on

http://marv-tech.connpass.com/event/36743/ でお話させていただいた内容です。

基本的には
http://www.slideshare.net/takanorisejima/mysql57-ga-multithreaded-slave
からの抜粋です。

Published in: Technology
  • Be the first to comment

binary log と 2PC と Group Commit

  1. 1. binary log と 2PC と Group Commit 瀬島 貴則瀬島 貴則
  2. 2. 免責事項 - 本資料は個人の見解であり、私が所属する組 織の見解とは必ずしも一致しません。 - 内容の一部に偏ったものがあるかもしれません が、各自オトナの判断でよろしくお願いします。
  3. 3. 自己紹介 - わりとMySQLでごはんたべてます - 一時期は Resource Monitoring もよくやってま した - Twitter: @ts4th
  4. 4. ちょっと宣伝 - 最近はわりとスライドを公開してますので - よろしかったら参考までに - http://www.slideshare.net/takanorisejima
  5. 5. 今日のお題 - 先日、 MySQL5.7 GA の Multi-threaded slave というお題目でお話させていただく機会があった のですが - Multi-Threaded Slave 以外の部分、 Two-Phase Commit と Group Commit の部分 は、 5.7 も MTS も使わない人でも、知っといて 損はない内容なので、今日はそのお話を改めて させていただきます。
  6. 6. では、 はじめます
  7. 7. はじめに - そもそも、 slave の SQL_Thread がシングルス レッドのとき、どのようにして replication で master と同じ状態が復元されるのか? - いたってシンプル - master が注意深く binlog 吐いてる
  8. 8. 例えば InnoDB の場合 1. master で更新処理実行中の各スレッドが、そ れぞれ transaction cache に更新内容をため ていく 2. InnoDB で PREPARE する(5.7.10 以降、 innodb_support_xa は常に true) 3. 1. の transaction cache から一連の更新処理 を BEGIN&COMMIT で挟んで binlogに書く 4. InnoDBで COMMIT する
  9. 9. Two-Phase Commit & Group Commit - MySQL の Replication 開発者であらせられる Dr. Mats Kindahl の blog この記事がわかりや すいですが - Binary Log Group Commit in MySQL 5.6 - (この後の話に関連して)大事なところを二つだ けかいつまんで解説すると
  10. 10. Two-Phase Commit(2PC) - 参考になるのは ha_commit_trans() や MYSQL_BIN_LOG::ordered_commit() あたり - Binary Log Group Commit in MySQL 5.6 の Figure.1 のとおり - storage engine(InnoDBなど)に prepare して - binlog に 書いて - binlog に COMMIT(fsync) してから - storage engineに COMMIT する
  11. 11. Transaction Coordinator Log - ソースコード中に tc_log ってのが出てきますが - Transaction の順序を管理するための Log の 抽象クラスが TC_LOG であって、その実装の ひとつが MYSQL_BIN_LOG - MYSQL_BIN_LOG::prepare() や MYSQL_BIN_LOG::commit() が、 Two-Phase COMMIT を実現するために必要 な関数を呼んでる
  12. 12. innodb_support_xa=true と 2PC - innodb_support_xa=true だと、 prepare のと き undo log に xid が書き込まれる(5.7.10以降 は常にそうなる) - undo log に xid 書き込まれた PREPARED な transaction は、 クラッシュ後の再起動時、 binlog から xid 読み込んだ後、その xid 使って innobase_commit_by_xid() で最終的に COMMIT される
  13. 13. なんかややこしいですが - クラッシュリカバリ時、xid のない PREPARED は rollback の 対象になるんですが、 xid つき の PREPARED は binlog からその xid が取得 できれば COMMIT にできるようです。詳しくは - innobase_xa_prepare() - MYSQL_BIN_LOG::recover() - innobase_xa_recover() - innobase_commit_by_xid()
  14. 14. というわけで、 MySQL の 2PC は - InnoDB のクラッシュリカバリ機能単体では実現 できず、 InnoDB のクラッシュリカバリ機能と binlog のクラッシュリカバリ機能とが組み合わ さって、実現されてるようです - binlog のヘッダには open するときに立てて close する ときにリセットするフラグがあるので、正常に close した か(クラッシュしてないか)は、フラグをみて判断してます
  15. 15. Group Commit - Binary Log Group Commit in MySQL 5.6 の Figure.5 を参照 - flush/sync/commit という stage がある - binlog へ書き出す のが flush stage - binlog に fsync() する のが sync stage - storage engine に commit するのが commit stage - flush stage に書きだした順序で、 commit stage で commit することが保証されている
  16. 16. ソースコード的にいうと - Group Commit はまさに MYSQL_BIN_LOG::ordered_commit() - flush/sync/commit の stage を queue で管理 することによって、 fsync() の回数を減らして、 binlog に event 書き出す順番と storage engine に commit する順番を担保している - そして、 binlog に書くとき、各 Transaction を BEGIN - COMMIT でシリアライズしてる
  17. 17. だから binary log は読みやすいし - そして slave の SQL_Thread は性能がでない - master は Transaction を並列実行しながらも、 それらをひとかたまりの BEGIN - COMMIT に まとめシリアライズして binlog に吐いている - master では並列実行してる Transaction が、 slave だと BEGIN - COMMIT のひとかたまり が、ひとつずつしか実行できない - まぁ SQL_Thread はシングルスレッドだしね
  18. 18. ではちょっとデモ 1. debug build した mysqld を用意します 2. お手元の gdb で attach します 3. MYSQL_BIN_LOG::sync_binlog_file() あたり に break point 張って continue します 4. 適当に INSERT などします 5. binlog を fsync() させたら gdb から kill します 6. innobase_commit_by_xid() 実行されます
  19. 19. 公式ドキュメントちょっと悩ましい - XA PREPARE なトランザクションはロールバッ クする とか sync_binlog=1 のときの挙動 を書 いてるんですが、現状の実装と噛み合ってない ところもある。 - このへんバグレポートしようかと思ったけど、い やーなんていうのがいいんだろうむずかしい
  20. 20. おわり

×