2013年11月22日金曜日

MySQL 5.6のクラッシュセーフなレプリケーションの仕組み

ちょこちょこ思うこと。

MySQL 5.6のnutshellを読むと、`クラッシュセーフなレプリケーションを実現するためにはmaster_info_repositoryとrelay_log_info_repositoryをTABLEに設定しな! おっと、relay_log_recoveryも1にしておくんだぜ'みたいことが書いてある。

で、このバグレポートを見た時からずっと、sync_master_infoの暗黙のデフォルト10000のまんまじゃクラッシュセーフじゃなくね? sync_master_info= 1必須? それはパフォーマンス的に死ねる。という感じでモヤモヤしていたのだが、やっと合点がいったのでメモしときます。

まず、出てくるパラメータの説明。
  • master_info_repository
    • FILEの場合、従来どおりmaster.infoファイルに書く。
      • ファイル名はmaster_info_fileにより可変。
      • 更新があるたび(バイナリーログを受信するたび)にファイルにwrite、sync_master_info回イベントを受信するとfdatasync。5.5までの暗黙のデフォルトは0なのでfsyncはしない。5.6.6以降の暗黙のデフォルトは10000。
    • TABLEの場合、mysql.slave_master_infoテーブルに書く。
      • コイツはmysqlスキーマ初のInnoDBテーブル。
      • sync_master_info回イベントを受信するたびにUPDATE。
      • sync_master_info= 0にすると、mysql.slave_master_infoは *アップデートされない*
        • SHOW SLAVE STATUSはこのテーブルの情報を読んでいる訳ではないので、ちゃんと更新される。
  • relay_log_info_repository
    • master_info_repositoryのrelay-log.info版っぽいが、TABLEを指定した場合は少し振る舞いが異なる(俺的混乱のもとその1)
    • FILEの場合はいっしょなので割愛。
    • TABLEの場合、mysql.slave_relay_log_infoテーブルに書く。
      • SQLスレッドがリレーログから読み出したステートメントを実行する時に、同じトランザクションの中でmysql.slave_relay_log_infoを更新するようになる。
      • sync_relay_log_infoの値に依存せず、毎回テーブルは更新される。
        • mysql.slave_relay_log_infoを非トランザクションテーブルにすると、master_info_repository= TABLEの時と同じ動作(sync_relay_log_info回に1回更新)
        • 【2013/12/11 11:35】
          mysql.slave_relay_log_infoがトランザクション対応か非対応化は *関係なく* マスター側の更新されたテーブルとスレーブ側で更新が適用されるテーブルが共にトランザクション対応であるかどうか、で更新頻度が変わる。
          • Master MyISAM-> Slave MyISAM: depends on sync_relay_log_info
          • Master MyISAM-> Slave InnoDB: depends on sync_relay_log_info
          • Master InnoDB-> Slave MyISAM: depends on sync_relay_log_info
          • Master InnoDB-> Slave InnoDB: updated after each transaction
          • http://bugs.mysql.com/bug.php?id=71083
  • relay_log_recovery
    • 実は5.5からあるオプション
    • 起動した時に、持っているリレーログとrelay-log.infoを比較して、まだ適用していない(Exec_Master_Log_Pos以降の)リレーログを破棄する。
という訳で、relay_log_recovery= ONであれば、「Exec_Master_Log_Posの情報が正しくrelay-log.info(or mysql.slave_relay_log)に反映されている限り、バイナリーログの二重取りや欠損は発生しない(はず)」、かつ、relay_log_info_repository= TABLEであれば、「SQLスレッドが変更を反映するタイミングでmysql.slave_relay_log_infoも同じトランザクションで更新されるため、All or Nothingで片方だけが失われる(不整合が起こる)ことはない(はず)」になり、

relay_log_recovery && relay_log_info_repository= TABLEならクラッシュセーフになる、という理屈らしい。

………master_info_repository関係なくない? 関係ないよね?

0 件のコメント :

コメントを投稿