MySQLをチューニング、そしてスケールアップ/スケールアウトへ

第8回MySQLのレプリケーション構成

第8回はMySQLの代表的なスケールアウト構成であるレプリケーション機能について解説します。

レプリケーションとは

データベースでのレプリケーションは、多くの場合データを複数のサーバで保持することで、処理性能の拡張性や耐障害性の向上を狙いとしています。レプリケーションによってデータの複製が作成されることにより、1台のサーバに障害が発生した場合でもデータを失うリスクが削減できるほか、システムを継続利用できる可能性が高まります。さらに複数のサーバにデータが複製されている場合は、データ参照処理を分散できる利点があります。

MySQLサーバのレプリケーション機能は2000年5月にリリースされたMySQL 3.23.15から実装されており、MySQLサーバの中でも初期から含まれている機能の一つとなっています。

参考URL
C.3.46 Changes in Release 3.23.15 (08 May 2000)

MySQLサーバのレプリケーション機能は、データの変更を1台で行い、複数のサーバにその複製を展開するマスタースレーブ型と呼ばれる構成となっています。

同期型レプリケーションと非同期型レプリケーション

レプリケーションにはデータの複製のタイミングによって同期型と非同期型に分類することができます。同期型の場合は、データの変更から全ての複製先への展開が一連の処理で(同期的に)行われます。非同期型の場合は、データの変更と複製先への展開が同一のタイミングであるという保証がない点(非同期的)が違いとなります。

同期型では全ての複製先にデータが反映されたことを待つ必要がありますが、アプリケーションがデータベースからの応答を得た時点で全てのサーバが同じデータを持っていることがメリットです。一方で非同期型は応答を待たなければならないのは、基本的に1台のサーバで起きたデータの変更のため、同期型に比べて高い応答性能が期待できます。ただしアプリケーションが応答を得た時点では他のサーバに変更が反映されていない可能性があることに注意が必要となります。

MySQLのレプリケーションでは、デフォルトでは非同期型となっています。MySQL 5.5以降では、プラグインをインストールすることで同期型と非同期型の中間に当たる準同期型をサポートしています。それぞれの挙動の詳細はアーキテクチャの解説の中で説明していきます。

MySQLのレプリケーションのアーキテクチャ

MySQLのレプリケーション構成では、⁠コミットされたトランザクションログの内容をコピーする」というのがアーキテクチャを非常におおまかに説明した言葉となります。特にポイントになるのがデータではなく、コミットされたトランザクションを記録しているバイナリログ(Binlog)の内容をコピーしている点です。

また、データの変更を行ったマスターが変更点をスレーブに渡す「プッシュ型」ではなく、最初にスレーブ内のIOスレッドがマスターに接続し、そのIOスレッドがログの内容を受け取る「プル型」になっているのも特徴です。IOスレッドはリレーログにコピーすると再びマスターに接続して次のバイナリログの変更を待ちます。

MySQLのデフォルトの非同期レプリケーションでは、以下の流れとなっています。

  • 0) スレーブのIOスレッドがマスターに接続
  • 1) アプリケーションがトランザクションをコミット
  • 2) データとバイナリログ(Binlog)が同時に変更
  • 3) MySQLサーバがアプリケーションにコミット完了の応答
  • 4) IOスレッドがバイナリログの内容を受け取りスレーブのリレーログにコピー
  • 5) スレーブのSQLスレッドがリレーログにコピーされた内容をデータに反映
図1 非同期レプリケーションの流れ
図1 非同期レプリケーションの流れ

非同期レプリケーションの設定方法

MySQLのレプリケーションを利用するうえで、最低限必要となるのは以下の設定です。

  • マスターと各スレーブがそれぞれ異なるserver-idを持っていること
  • [マスター]バイナリログが有効となっていること
  • [マスター]スレーブのIOスレッドが接続するためのREPLICATION SLAVE権限を持つユーザが存在すること
  • [スレーブ]IOスレッドがCHANGE MASTER TOコマンドで指定するマスターに接続可能であること

MySQL 5.6以降ではトランザクションを一意に識別するGTID(Global Transaction Identifiers)が利用可能となっているため、CHANGE MASTER TOコマンドでMASTER_AUTO_POSITION = 1に指定すると自動的にスレーブ側にコピーしていないトランザクションのみを抽出してレプリケーションを開始できます。GTIDを有効にしていない環境では、レプリケーションを開始するマスターのバイナリログのポジションを明示的に指定する必要があります。

GTIDを利用することで、マスターとスレーブ間やスレーブ同士でのレプリケーションの進み具合を簡単に比較できるようになったため、オープンソースのMySQL運用支援ツールMySQL Utilitiesにも自動フェールオーバーツールのmysqlfailoverコマンドが用意されています。

参考URL
5.12. mysqlfailover — Automatic replication health monitoring and failover

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

準同期レプリケーションでは、バイナリログの内容がスレーブに渡りリレーログに書き込まれてからアプリケーションにコミットの応答を返します。このため仮にアプリケーションがコミットの応答を受け取った直後にマスターに障害が発生したとしても、コミットが成功したトランザクション内容を失うことはありません。一方でマスターとスレーブが別のデータセンターに置かれている構成などでネットワークのレイテンシが大きい場合などには、コミット時のレスポンスタイムに大きな影響が出ます。

準同期レプリケーションを利用するためには、マスターおよびスレーブのそれぞれに準同期レプリケーションのプラグインをインストールする必要があります。

参考URL
17.3.8.2 Semisynchronous Replication Installation and Configuration

MySQLの準同期レプリケーションでは、以下の流れとなっています。

  • 0) スレーブのIOスレッドがマスターに接続
  • 1) アプリケーションがトランザクションをコミット
  • 2) データとバイナリログ(Binlog)が同時に変更
  • 3) IOスレッドがバイナリログの内容を受け取りスレーブのリレーログにコピー
  • 4) スレーブがマスターにコピー完了の応答
  • 5) MySQLサーバがアプリケーションにコミット完了の応答
  • 6) スレーブのSQLスレッドがリレーログにコピーされた内容をデータに反映
図2 準同期レプリケーションの流れ
図2 準同期レプリケーションの流れ

準同期の流れの4)、5)の各応答と6)のスレーブでのデータ変更は一連の処理になっておらず、実行されるのはこの順番とは限らず応答中にデータ変更が進むこともあります。

MySQL 5.6の準同期レプリケーションでは、全てのスレーブが応答するか、いずれかのスレーブから応答がない場合はサーバパラメタrpl_semi_sync_master_timeoutで指定したタイムアウトになってから、アプリケーションに応答します。MySQL 5.7では、上記のタイムアウト以外に新しいパラメタのrpl_semi_sync_master_wait_for_slave_countで指定した台数(デフォルトでは1)のスレーブから応答があった時点でアプリケーションが応答する仕組みが加わっています。

表1 MySQLのレプリケーションの方式による特色
非同期型 準同期型
応答性能 マスターでの処理のみを待つ マスターでの処理とスレーブへのコピーを待つ
耐障害性 低い。スレーブへのコピー前にマスターに障害が発生するとコミットが成功したトランザクションを失う 非同期型よりも高い
用途 耐障害性はクラスタリングなど他の方法で担保されている場合のスケールアウト構成
ディザスタリカバリ構成
簡易的な高可用性構成

非同期レプリケーションと準同期レプリケーションは同一のレプリケーション構成の中で混在させることができるため、データを保護するためにスレーブのうち1台を準同期レプリケーションとし、他のスレーブは非同期レプリケーションで参照処理の負荷分散を行うという構成を構築することが可能です。これによって応答性能への影響を最小限に抑えながら、耐障害性を持った構成とすることができます。

レプリケーションのフォーマット

実際にはレプリケーションのフォーマットではなく、バイナリログをどの形式で記録するかによって、レプリケーションでコピーされるものが変わって来ます。

参考URL
17.1.2 Replication Formats
表2 MySQLのレプリケーションのフォーマットによる特色
文ベース 行ベース ミックス
binlog_formatの値 STATEMENT ROW MIXED
バイナリログ内容 データおよびスキーマ定義を変更したSQL文 変更後のデータ[1] 基本は文ベース、特定の関数や変数の利用があった場合は行ベース[2]
データ量 [3]
主な制約 非決定性の(nondeterministic)関数は不整合の可能性あり[4] トリガーの利用不可 N/A

SUPER権限を持っているユーザは、SETコマンドにてサーバ全体または接続中のセッションのバイナリログフォーマットを一時的に変更可能です。

参考URL
5.2.4.2 Setting The Binary Log Format

MySQL 5.7のレプリケーション新機能

2015年5月現在開発中のMySQL 5.7でもレプリケーション関連の改善が数多く行われています。マスターからスレーブにログを送受信するスレッドを並列処理可能にしてスループットの向上を図っているほか、パフォーマンススキーマでのレプリケーション関連性能統計情報を追加してより詳細な稼働状況のチェックを可能にしています。

より効率的な運用を可能にするため、MySQLサーバを再起動することなくレプリケーションのフィルタリング設定を動的に変更可能にしています。MySQL 5.6でGTIDを有効にするためにはレプリケーション構成全体を一時的に停止する必要があり、既存環境への導入の障壁となっていましたが、MySQL 5.7ではサーバを停止することなく動的に設定可能になっています。

スレーブの遅延を最小化するためにMySQL 5.6でマルチスレッドスレーブが導入されました。ただし並列処理されるのは変更対象のテーブルが別々のスキーマの場合のみでした。MySQL 5.7では同一スキーマ内のテーブルに対する変更も並列で実行されるようになったため、従来と比較して5倍以上のスループットが出ているベンチマークもあります。

マルチソースレプリケーション

従来のMySQLのレプリケーションは、スレーブは1台のマスターしか利用することができませんでした。1台のマスターから複数台のスレーブにデータを展開することはできても、その逆に1台のスレーブに複数のマスターに分割されたデータの変更点を集約することはツールを利用する必要がありました。ツールの例としては、do_akiさんによる開発のSwitchMasterやMySQL Utilitiesの中のmysqlrplmsなどがあります。いずれも一定間隔でスレーブの接続するマスターを切り替えていく仕組みになっています。

参考URL

SwitchMaster - master n : slave 1 replication for mysql

5.19. mysqlrplms — Set Up and Start Replication Among a Slave and Multiple Masters

MySQL 5.7ではスレーブからマスターへの接続にチャンネルという機能を追加し、1台のスレーブから複数のマスターに接続して変更点を集約する、マルチソースレプリケーション機能が追加となりました。

図3 マルチソースレプリケーション[5]
図3 マルチソースレプリケーション(注5)

次回は

次回は高い可用性と更新処理性能の拡張性を両立したMySQL Clusterのアーキテクチャを解説いたします。

おすすめ記事

記事・ニュース一覧