MySQLの準同期レプリケーション

MySQL 5.5での準同期レプリケーション

準同期レプリケーション自体はMySQL 5.5から導入されました。マスターー側およびスレーブ側にそれぞれ準同期レプリケーション用のプラグインをインストールし、マスターー側で rpl_semi_sync_master_enabled とスレーブ側で rpl_semi_sync_slave_enabled を有効にしておくと準同期レプリケーションが利用できるようになります。 rpl_semi_sync_master_enabled を有効にしたマスターに対して、非同期レプリケーションと準同期レプリケーションのスレーブを混在させることは可能です。

準同期レプリケーションの流れ
  1. アプリケーションからトランザクションをコミット
  2. バイナリログとストレージエンジンにトランザクション内容を記録
  3. マスターからスレーブにトランザクション内容を転送
  4. スレーブのリレーログにトランザクション内容を記録
  5. スレーブからマスターに応答
  6. マスターからアプリケーションに応答

上記の3の時点でスレーブに障害が発生しているかネットワークに問題があるなどで通信できない場合は、マスターの rpl_semi_sync_master_timeout で設定されたタイムアウトまで待ち、非同期レプリケーションと同様にスレーブの応答が無いままアプリケーションに応答を返します。この値のデフォルト値は10,000ミリ秒です。
rpl_semi_sync_master_wait_no_slave がデフォルトの ON の場合には、スレーブが一時的に切断されている場合などもタイムアウトまで待ちます。OFFに変更するとスレーブが接続されていない場合はすぐにアプリケーションに応答します。

MySQL 5.7で複数台の準同期スレーブを待つ設定

MySQLの準同期レプリケーションで何台のスレーブが応答した時点で以降の処理を継続するかはマスターの rpl_semi_sync_master_wait_for_slave_count で制御します(5.7.3以降)。 デフォルトでは1台のスレーブから応答があった段階でアプリケーションに応答します。

MySQL 5.7の"Lossless"準同期レプリケーション

従来の準同期レプリケーションでは、特定のタイミングでマスターに障害が発生した場合にデータの不整合が起こりえる課題が残っていました。上記の流れの2の時点で、別のクライアントからはコミットの内容を参照することができます。
上記の2の後でマスターに障害が発生すると、他のクライアントから見えていたコミット済みのトランザクションがスレーブには存在せず、データの整合性が取れていないように見えてしまいます。この問題を解決するのがMySQL 5.7の"Lossless"準同期レプリケーションです。
"Lossless"準同期レプリケーションMySQL 5.7から新たに加わったパラメタ rpl_semi_sync_master_wait_point のデフォルト値 AFTER_SYNC を利用することで実現できます。この値を AFTER_COMMIT に変更した場合はMySQL 5.6までの挙動になります。

"Lossless"準同期レプリケーションの流れ
  1. アプリケーションからトランザクションをコミット
  2. バイナリログのみにトランザクション内容を記録
  3. マスターからスレーブにトランザクション内容を転送
  4. スレーブのリレーログにトランザクション内容を記録
  5. スレーブからマスターに応答
  6. ストレージエンジンにトランザクション内容を記録
  7. マスターからアプリケーションに応答

MySQLレプリケーション構成の模式図
※非同期レプリケーションMySQL 5.6の準同期レプリケーションではバイナリログへの記録とストレージエンジンへの変更点の記録は逐次ではなく同時

準同期レプリケーション関連のパラメタ一覧

パラメタ名 設定箇所 デフォルト値
rpl_semi_sync_master_enabled マスター OFF
rpl_semi_sync_slave_enabled スレーブ OFF
rpl_semi_sync_master_timeout マスター 10000
rpl_semi_sync_master_wait_no_slave マスター ON
rpl_semi_sync_master_wait_for_slave_count マスター 1
rpl_semi_sync_master_wait_point マスター AFTER_SYNC