まずはSemi-Synchronous Replicationの機能説明から。そもそもSemi-Synchrounousってナニ?どうして完全な同期でもなく非同期でもなくSemi-Synchronousなの?という疑問をまずは解消したいと思う。さっそく次の図を見て欲しい。
これはSemi-Synchronous Replicationの動作を図で表したものである。図だけではなんだかよく分からないと思うので、以下に各ステップの詳細を説明する。
- アプリケーション(クライアント)からトランザクションをCOMMIT要求を出す。
- バイナリログを更新する。
- ストレージエンジン(テーブル)を更新する。
- それと同時にバイナリログの内容がスレーブへ送信される。
- スレーブがログの更新を受け取ったらマスターへackを返す。
- ストレージエンジンの更新とスレーブからのackを確認したらクライアントへ応答を返す。
- スレーブ側でログを適用する。(非同期)
万が一マスターがクラッシュした場合でも、COMMITが完了した全てのクエリはスレーブ側に存在する。スレーブ側にフェイルオーバーしても更新が失われることは一切無い。このフェイルオーバーはとても高速である。その理由を以下に順次説明しよう。
通常のHAでは稼働系のクラッシュが発生すると次のような手順でフェイルオーバーが実行される。
- スレーブがファイルシステムをマウントする。
- MySQLサーバを起動する。
- InnoDBのログを調べてクラッシュリカバリ(Redo/Undo)を行う。
ちなみに、スレーブにおいて全てのリレーログの適用が完了したかどうかは、SHOW SLAVE STATUSでExec_Master_Log_PosとRead_Master_Log_Posが同じになること、またはSHOW PROCESSLISTでSQLスレッドのステータスが「Has read all relay log; waiting for the slave I/O thread to update it」になることで確認することができる。HAの皮を被せるときはこれらの情報を参照されたい。
マスターがクラッシュした場合には、スタンドアロンで利用している場合や他のHAを利用している場合と同様に、アプリケーション側でのクラッシュリカバリ処理も必要になる。クラッシュリカバリの詳細については、過去に投稿した「もしもデータベースサーバがクラッシュしたら」を参照のこと。
また、Semi-Synchronous Replicationを利用してHAを行った場合、フェイルバックにも注意が必要である。マスター側でのストレージエンジンへの更新と、スレーブへの更新の転送は並列(非同期)で行われる。そのため、マスターにだけ存在するデータやスレーブにだけ存在するデータが発生してしまうという不整合な状況がまれに生じてしまう。そのような状況が想定されるため、一度フェイルオーバーが発生したときはマスターへデータをコピーし直す必要が生じるだろう。コピーをし直すとはつまり、スレーブからフルバックアップを取得してマスタへリストアするということである。バックアップの方法はLVMスナップショット、InnoDB Hot Backup、mysqldumpなどを利用すれば良い。負荷が少ないときを見計らって作業を実施するといいだろう。
ちなみに、スレーブ側にさらにスレーブ(孫スレーブ)をつけておけば、その孫スレーブからマスターへリストアを行うことが可能になる。孫スレーブをつけておけば2重障害にも対応できるというメリットがあるため、Semi-Synchronous ReplicationによるHAを運用する場合には孫スレーブの設置を検討しよう。(孫スレーブを設置するにはスレーブにおいて--log-slave-updatesオプションを利用するため、スレーブへのフェイルオーバー時にはFLUSH LOGSをする必要があるだろう。)
Semi-Synchronous Replicationは、MySQL 6.0から搭載される予定の機能なので、現行バージョンのMySQL 5.1では利用できない。そんなの待てないよ!という人はぜひPreview版を利用しよう。Preview版は下記のページに入手方法が載っている。
https://code.launchpad.net/~hezx/mysql-server/semi-sync-replication
Semi-Synchronous Replicationは元々GoogleのMark Callaghan氏とWei Li氏の手によって開発された。MySQL 6.0では、その機能をプラグイン化して提供する予定である。素晴らしい機能を提供してくれたGoogleの諸氏に感謝したい。
参考資料:
http://dev.mysql.com/doc/refman/6.0/en/replication-semisync.html
http://forge.mysql.com/wiki/ReplicationFeatures/SemiSyncReplication
http://code.google.com/p/google-mysql-tools/wiki/SemiSyncReplication
0 件のコメント:
コメントを投稿