Sifr

日本語

Home » Study » Detail

Semi Synchronous Replication on MySQL 5.5

How to build Semi-Syncronous-Replication of MySQL 5.5.

Basic Knowledge

Let me goude you about basic knowledge about elements of replication, how it works and kinds of replication.

What replication is

Replication of MySQL is a function to get data redundant through copying data of master server to slave.

You can load balance and improve availability and reliability as replication puts database copies on multiple spots.

You can configure easily, read data from any servers, but update queary is available only on the master server. That is, you can't scaleout writing by replication. So I recommend you to use replication only when you don't need load balancing of update query. Or check clustering or another solution.

The difference of normal/semi

There are 2 kinds of replication. normal replication and semi synchronous replication.

The work of normal replication

It's important point of normal replication that the master server is independent from slave server. You can understand this as one-sided love of slave server.

Tasks for each roles|normal replication

It's simple that the task of master server. It's just to output binary log when it executes update query.

Slave servers have a bit comprecated task.

  1. Sign into the master server by an account which has replication authority.
  2. Take binary log and execute it if it has been modifired.
  3. Sign out from the master server.

Slave server repeats the 2nd task. So slave server doesn't sign out immediately after executing binary log.

Tasks while commiting|normal replication

The progress of actual commit:

  1. Write binary log when the master executes update query
  2. The master transfers binary log if it detects modification
  3. Slave executes update query

Recent commit might be dropped if the master crashed before completion of the 2nd progress.

The work of semi-synchronous replication

Semi-synchronous replication has the same elements to normal replication. This work is the same to synchronous replication of PostgreSQL. The master takes care of slaves like a childhood friend girl wakes up you every morning for the sake of going to school together.

Tasks for each roles|normal replication|semi-synchronous replication

The master server in this mode has more tasks than normal one.

  1. The master receives update query from client then transfer the binary log to slave.
  2. Receive `I got the binary log` acknowledge from slave then commit.

Slave server works simple.

  1. Sign into the master server as an account with replication authority.
  2. Return `I got the binary log` acknowledge to the master then commit
  3. Sign out from the master server

Slave server repeats the 2nd task until sign out.

The master will commit binary log ignoring slave server if the master doesn't receive acknowledge for configured time from slave.

Tasks while commiting|semi-synchronous replication

The progress of actual commit:

  1. Transfer binary log from the master to server before the master executes update query
  2. Slave returns acknowledge to the master
  3. Both the master and slave executes the update binary log respectively

Semi-synchronous replication doesn't cause rollback of recent commit when the master crashes.

Difference of redundancy

According to The work of normal replication and The work of semi-synchronous replication so far, there's a little difference of work though the elements are the same.

I recommend you to use semi-synchronous replication only if you need perfect integrity.

Response Speed

Semi-synchronous takes more time to reply response because it awaits acknowledge from slave until commit.

Integrity

Semi-synchronous replication doesn't lose commited data though normal one does, and slave server of normal replication remains old data longer after the master's commiting. So normal replication has problem of integrity. You must not use it for strict service like online bank.

Serviceability

Normal replication is greater than semi-synchronous one in serviceability because the master server is independent from slave server, the master doesn't owe latency even when slave server down and the configuration is a bit simpler.

Building

You will build one master - one slave environment. It'll be the same progress anyway even if you need multiple servers.

  • 「同じ方法で再構築出来る」をモットーに構築します。
  • 通常のレプリケーションも準同期レプリケーションも構築方法はほとんど同じです。異なる点では適宜記述します。
  • この構築例のOSはマスター・スレーブ共にSSH, MySQL-Serverインストール済みのCentOSを想定していますが、他の構成でも流用できます。

手順

  1. 構成の設計とMySQLサーバ設定の確認
  2. マスターのレプリケーション設定・データベースのコピー
  3. マスターのバックアップデータをスレーブに転送
  4. スレーブのレプリケーション設定
  5. 動作確認

構成の設計とMySQLサーバ設定の確認

下記の構成でレプリケーション構成を行います。分かる変数を各自の環境に合わせたら次に進みましょう。

構築するレプリケーションの種類

不明 通常レプリケーション 準同期レプリケーション

マスター ネットワーク情報

ホスト(IP/DN):

MySQL ポート:

MySQL サーバID:

MySQLレプリケーション ユーザ:

MySQLレプリケーション パスワード:

MySQL現在のバイナリログファイル名:

MySQL現在のバイナリログ位置:

スレーブ ネットワーク情報

ホスト(IP/DN):

MySQL サーバID:

SSH ポート:

SSH ユーザ:

SSH パスワード:

コンソール操作

SSHなどを用いて実際にサーバ機を操作します。

マスターサーバの操作

マスターの MySQLサーバーが使用するポートを解放

レプリケーションを行うには、マスター側のMySQLサーバの使用するポートが外部に公開されている必要があります。MASTERでファイアーウォールを利用している場合、TCP 3306 番ポートを開放して下さい。また、アウトバウンドのサーバとレプリケーションを行う場合は、ルータのネットワークアドレス変換を設定してください。

マスターにレプリケーション用ユーザーを作成

まず、レプリケーション権限のみを持ったレプリケーション専用のユーザーを作成します。MASTERのMySQLコンソールで以下のSQLを実行します。

GRANT REPLICATION SLAVE ON *.* TO replication_user@'slave.example.com' IDENTIFIED BY 'password';

ユーザ作成に成功したら、設定を反映してください。

FLUSH PRIVILEGES;

マスターのレプリケーション設定とデータベースの複製

レプリケーション構築の勘所で、すべきことは下記2点です。

  1. マスター用の設定を行う
  2. スレーブ側にマスターのデータを転送するため現在状況を複製する

「1.」では設定読み込みのためにMySQLサーバを再起動する必要がありますし、「2.」ではデータコピー中にユーザがデータベースに書き込めなくする必要があります(バックアップ中にデータを更新されては困る)。途中で手を止めるとサーバ停止時間が伸びてしまうので、ひと通り手順をさらってから作業に進んでください。

マスター用の設定を行う

「マスター用の設定」とは、下記三点のことを指します。すでに設定済みの場合はスキップしてOKです。

  1. SQL実行時にクエリのバイナリログを出力する
  2. どのサーバか識別するためサーバIDを付与する
  3. 準同期レプリケーションを行う場合に準同期レプリケーションマスター用のモジュールを読む

これらの変更はvi /etc/my.cnf で [mysqld] 中に下記を追加して行います。

  1. server-id=20 # サーバー固有のIDを指定します
  2. rpl_semi_sync_master_enabled=1 # 準同期レプリケーションのみ追加 準同期レプリケーションマスター動作を有効にします
  3. rpl_semi_sync_master_timeout=1500 # 準同期レプリケーションのみ追加 更新時、SLAVEが応答しない時のタイムアウト時間を1.5秒に設定します
  4. log-bin # バイナリログを生成するようにします
  5. expire_logs_days = 14 # ログの保持を保証する期間(日数)です。0以外の値にすると、ログローテーション・サーバ再起動のタイミングで指定日数以上経過したログファイルは自動的に削除されます。

編集したら /etc/rc.d/mysqld restart でマスターを再起動し、設定を反映してください。

スレーブ側にマスターのデータを転送するため現在状況を複製する

下記役割を持つ、A,・B 2つのターミナルを用意します。

  • A:マスターのMySQLコンソール上でSQLクエリ実行する
  • B:マスターのシェルの操作を行う

ここからノンストップ作業

ターミナルAで下記SQLを実行し、 MySQLサーバの書き込みを禁止します。※ログアウトするとロックが解けてしまうため、コピーが完了までAはMySQLサーバからログアウトしてはいけません

FLUSH TABLES WITH READ LOCK;

下記SQLを実行し、現在のログ位置を取得します。FileとPositionの値をメモしておいてください。→上のフォームにメモってくる

SHOW MASTER STATUS;

mysql> SHOW MASTER STATUS;

FilePositionBinlog_...
mysqld-bin.000001805 

1 row in set (0.00 sec)

スレーブ側にデータを転送する前に圧縮します(データサイズや回線速度によっては圧縮せずに cp を使った方が速く終わる場合もあります。要はマスターのDBデータをスレーブにコピー出来れば良いので、適宜方法を選択してください)。

  • cd /var/lib/mysql
  • tar zcvf master-mysql-data.tar.gz *

ターミナルAで下記クエリを実行してロックを解除してください。

UNLOCK TABLES;

ここまでノンストップ作業

マスター→スレーブ データ転送

前項で作成したマスターデータベースの複製をスレーブに転送します。転送方法はSFTPでもFTPSでもSCPでもUSBメモリでもフロッピーディスクでも構いません。

下の例ではマスター側のコンソールでSFTPを使って転送します。

  • cd /var/lib/mysql
  • sftp -oPort=22 replication_user@slave.example.com
  • replication_user@slave.example.com's password: # パスワード応答
  • cd /var/lib/mysql
  • put master-mysql-data.tar.gz

スレーブサーバの操作

スレーブ 設定ファイル

スレーブとして動作するように設定ファイルを編集します。

vi /etc/my.cnf で [mysqld] 中に下記を追加してください。

  • server_id=20 # サーバー固有のIDを20に設定します
  • plugin-load=rpl_semi_sync_slave=semisync_slave.so # 準同期レプリケーションのみ追加 準同期レプリケーションスレーブ動作を有効にします

※旧ヴァージョンのMySQLサーバでレプリケーションを行っていた方へ…MySQLのヴァージョン5.5未満のレプリケーションで使用していた master_host, master_port, master_user, master_password の設定項目は、my.confに記述できなくなりました。これら変数を my.cnf に記述してMySQLサーバーを起動しようとすると、 /var/log/mysqld.log には [ERROR] /usr/libexec/mysqld: unknown variable 'master_host=master.example.com' とエラーメッセージが出力され、起動ができません。これらの変数はSLAVEで CHANGE MASTER TO ... クエリを実行した時に自動的に /var/lib/mysql/master.info に書き込まれるようになりました。

編集したら /etc/rc.d/mysqld restart でSLAVEを再起動し、設定を反映してください。

マスターを指定

スレーブサーバに「どのMySQLサーバをマスターとするのか」の情報を与える必要があります。スレーブのMySQLコンソールで下記SQLを実行してください。

CHANGE MASTER TO master_host='master.example.com', master_port=3306, master_user='20', master_password='password', master_log_file='mysqld-bin.000001', master_log_pos=805;

実行後 /var/lib/mysql/master.info が生成されるのが確認できます。

マスターと同期開始

スレーブのMySQLコンソールで下記SQLを実行してください。

START SLAVE;

Test

スレーブの状態を確認する

SLAVE側のMySQLコンソールで下記クエリを実行し、レプリケーションが構築できているか確認してください。エラー無くマスターと同じ位置までログが進んでいれば正常です。

SHOW SLAVE STAUS;

PCの再起動

スレーブサーバのPC再起動です。PCを再起動してもスレーブ状態は維持されます。レプリケーションの再設定(START SLAVE)が不要なのが分かりました。

マスターでコミット

マスターでの更新クエリ実行です。マスターにテーブルを作って、SLAVE側で反映されるかを確認してください。

CREATE DATABASE hoge;

SLAVE側でも同じ更新が行われるはずです。

スレーブでコミット

※レプリケーションが壊れる可能性があるので本番環境でこのテストを行わないでください。

スレーブ側で更新クエリを実行するとどうなるか。スレーブ側でも更新クエリは実行できてしまいます。マスターとデータの齟齬が生まれてしまうので、SLAVE側での更新は行わないようにしてください。スレーブ側でデータベースを更新出来なくするのもひとつの手ですが一長一短です。スレーブ側で更新できるなら、マスターが不慮に停止しても迅速にサービス復旧できるからです。

スレーブダウン時のコミット

準同期レプリケーション構築時、スレーブがダウンしている場合の動作です。スレーブのMySQLサーバーをストップしてからマスターで更新クエリを実行すると、 rpl_semi_sync_master_timeout で指定した時間 [ms] 待機してから更新クエリが実行されます。このクエリ実行後にスレーブのMySQLサーバーを立ち上げると同じ更新が行われました。スレーブがダウンしても expire_logs_days で示した日数以内に再起動出来れば問題ないようです。

Maintenance

レプリケーション構築後にどんなメンテナンスが必要かと言っても場合によりけりなのですが。個人的にチェックすべきと思った点を抑えます。

障害発生時

スレーブサーバが死んだ時はほぼ問題無しです。準同期レプリケーションであれば更新クエリ実行時に rpl_semi_sync_master_timeout で指定した時間待機するので多少パフォーマンスが低下しますが、これまでの手順どおりに再度レプリケーションを組み直せば良いだけです。

問題はマスターサーバが死んだ場合です。フェイルオーバーが必要になります。マスターサーバが息をしていない場合はスレーブサーバで下記クエリを実行してください。

RESET MASTER;

これでスレーブはマスターに昇格し、元マスタのバイナリログを読みに行かなくなります。なお、既存のバイナリログ関係ファイルはすべてリセットされます。

バイナリログのサイズ

データベースの更新頻度が低ければ2週間のバイナリログ自動削除で大丈夫ですが、更新頻度が高くなるとものすごい勢いでバイナリログが書き込まれることになります。「ハードディスクの中がログファイルでパンパンだぜ」という事態に陥る可能性があるわけです。時折ハードディスクの残量とバイナリログの増加速度を見てバイナリログの保持期間を調整してください。

バックアップ

レプリケーションを組むだけで安心してはいけません。RAIDを組んでもバックアップは別途必要と言われるように、レプリケーションを組んでもDBのバックアップは別途取得するようにしてください。

貴方の中の全どぢっ娘がうっかりデータ全削除をしてしまう可能性はゼロではないからです。

Others

後書き

MySQL5.5で準同期レプリケーションをしようとした時に、頭から尻尾まで解説したサイトが見つかりませんでした。大抵、通常のレプリケーションを組んであるのが前提だったり、細部がはしょってあったり。それで、MySQL5.5を用いた準同期レプリケーション設定の解説をしようと思いました。

しかしながら、なかなかうまくいかないもので。作ってから「僕の解説中途半端だお…」と気づきました。気付いたもののなかなか更新出来ず、半端な解説を掲載したまま一年近くが経過してしまいました。

数日ああでもないこうでもないと考えて作成したMySQL5.5+準同期レプリケーション構築の解説ドキュメント。多少なり役立てたのであれば幸いです。

とみんのブログ - 今更ながらMySQLのレプリケーション その1
準同期レプリケーションについての解説しています。
現場指向のレプリケーション詳説
運用しながらのレプリケーションの構築方法を解説しています。
半袖野郎 blog.hansode.org - 2009年05月08日
master.infoの構造・作り方を解説しています。
OpenGroove - レプリケーション時のRESET MASTERとRESET SLAVE
レプリケーション時のRESET MASTER・RESET SLAVEコマンドの動作を解説しています。

サイドメニュー