mysqlのレプリケーションについて、

質問させてください。

MASTER、SLAVE1、SLAVE2、SLAVE3という構成で、
MASTERから各SLAVEにレプリケーションしている状態において、
MASTERに障害が発生し、
SLAVEのどれかをMASTERに昇格させる場合、
3つのSLAVEのポジションはどのように同期を取ったらよいのでしょうか。

MASTERには接続できないものとします。

よろしくお願いします。

回答の条件
  • 1人2回まで
  • 登録:2009/05/18 22:51:00
  • 終了:2009/05/25 22:55:02

回答(3件)

id:kn1967 No.1

kn1967回答回数2915ベストアンサー獲得回数3012009/05/18 23:48:19

ポイント27pt

作業としては、Slave1をマスターとして再起動した後

Slave2/Slave3でマスター情報を書き換えて再起動するだけで同期されます。


一応、マニュアルが基本になりますので下記参照のうえで

どのあたりが判り難いのかを明示されると理解が進むと思いますよ。

MySQL :: MySQL 5.1 リファレンスマニュアル :: 5.3.6 フェイルオーバでのマスタ切り替え

たとえば、Slave 1 を選択する場合、

すべての Web Clients を Slave 1 にリダイレクトして、

そこのバイナリ ログ にアップデートを記録します。

つまり、Slave 2 と Slave 3 は Slave 1 から複製することになります。

id:the_yakisoba

ご回答ありがとうございます。

> Slave 2 と Slave 3 は Slave 1 から複製することになります。

これはSlave1からDumpしてSlave2、3を作るという意味ではないですよね?

提示いただいたリンク先を読んだところ、

「STOP SLAVE IO_THREAD」をしてSlave1、2、3がその時点までのリレー ログを、

更新して同期しているようです。

しかし、

同期に関して気になる記述があり

「実情では、複数スレーブのリレー ログがマスタからそれほど遅れをとらないので、この方法が適用できるとの考えに基づいています。」

もしSlaveごとにリレーログの遅れに差分がある場合、

どのように同期を取ることができるのでしょうか。

2009/05/19 01:19:28
id:crazytaxi No.2

crazytaxi回答回数2ベストアンサー獲得回数02009/05/19 12:32:00

ポイント27pt

そのような状態になったときは、Slave1, Slave2, Slave3 で show slave status を実行し、ポジションに差異がないかどうかを見ます。

具体的には、Master_Log_File, Exec_Master_Log_Pos を見て、違いがないことを確認します。

ほとんどありえないですが、もし差異がある場合。

・3つバラバラ -> 一番進んでいるものをMasterに昇格させ、Slaveを新規で作る

・2つ一緒 -> どちらかをMasterに昇格させる

ということをやることになると思います。

昇格するサーバーは、バイナリログを出力するようにする必要があります。

また、kn1967さんもコメントでおっしゃっている通り、差異が発生することはありえます。

どうしても差異が発生してはいけないようなデータを取り扱っている場合、マルチマスタなりを検討した方がいいです。

自分はやったことないですが、Master の show master status を常時どこかに出力しておいたら、障害時に差分比較はできるかもしれないと思っています。

それが正しいという保証ができるかはわからないですが。

id:the_yakisoba

ご回答ありがとうございます。

> ・3つバラバラ -> 一番進んでいるものをMasterに昇格させ、Slaveを新規で作る

新規で作成ということは、

新MasterからDumpして作成ということでしょうか。

また、

新Masterとその他SlaveのExec_Master_Log_Posを比較して、

差分を手動で更新させ同期を取るといった手段は有効でしょうか。

2009/05/19 14:32:23
id:crazytaxi No.3

crazytaxi回答回数2ベストアンサー獲得回数02009/05/19 15:13:11

ポイント26pt

> ・3つバラバラ -> 一番進んでいるものをMasterに昇格させ、Slaveを新規で作る

新規で作成ということは、

新MasterからDumpして作成ということでしょうか。

そうですね。


また、

新Masterとその他SlaveのExec_Master_Log_Posを比較して、

差分を手動で更新させ同期を取るといった手段は有効でしょうか。

可能でしょうか?っていう質問だと思って回答します。

以下の状態であれば可能です。

  • 前述の回答の通り、新Masterの方が進んでいる
  • 新Masterで、バイナリログを出力してあった
  • 新Masterで、show slave status が確認できる

障害時、以下のようなステータスだったとします。

  • 新Masterの show master status の Position: 8000
  • 新Masterの show slave status の Exec_Master_Log_Pos: 20000
  • Slaveの show slave status の Exec_Master_Log_Pos: 19600

この状態の時、Slaveは、新Masterと比べて、20000 - 19600 = 400(byte)分、旧Masterのバイナリログが実行されてないことになります。

ですので、新Masterのバイナリログの position を400byteさかのぼったところからSQLを流すことで、同期が取れた状態になります。

8000 - 400 = 7600です。

mysqlbinlog -j 7600 mysqld-bin.000001 > diff.sql

この出力が差分になります。

id:the_yakisoba

ご回答ありがとうございます。

新Masterのバイナリログは、

新Masterのリレーログで代用できないでしょうか。

  • 新Masterの show slave status の Relay_Log_Pos: 9000

mysqlbinlog -j 8600 relay-bin.000001 > diff.sql

2009/05/19 18:53:51
  • id:kn1967
    マニュアル先頭のほうにて「スレーブはマスタのデータベースが
    スレーブとの互換性を保持しているかどうかを確認することができない。」
    マニュアル最後のほうにも「複数スレーブとマスタは同期していません。
    スレーブのいくつかは他のスレーブよりも前に出ていることがあります。」
    などと記述がありますように、ご心配されておられるような差異が
    発生する可能性は少なからずあります。

    基本動作としては同時に行われる”はず”のものであっても
    タイムラグは発生しますので、どこまでのものを要求するかによっては
    レプリケーションを(親→子→孫)にするとか
    マスターを冗長化するといった対処が必要になるかもしれません。
  • id:crazytaxi
    回答できないのでコメントで。
    その方法でも特に問題ないと思います。
    やったことないですが…

    新Masterとしたあとは、バイナリログを見るわけだし、バイナリログを見るという方針にしておいた方が間違いはないと思います。

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

絞り込み :
はてなココの「ともだち」を表示します。
回答リクエストを送信したユーザーはいません