ディザスタリカバリ計画を作成しようとしています。1つのマスター(A)と3つのスレーブ(B、C、D)を使用した一方向レプリケーションがあります。
A
/|\
/ | \
B C D
マスターがクラッシュし、そのサーバー上のすべてのデータが失われ、まだ3つのスレーブがあり、最新のマスターになるように昇格するとします。たとえば、スレーブBが最新で、CとDはそうではありません。私がBを昇格させてスレーブをマスターした時点で、SHOW SLAVE STATUS\G
の結果は次のようになります。
slaveB> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Relay_Master_Log_File: master-bin.000002
Exec_Master_Log_Pos: 1476884
slaveC> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Relay_Master_Log_File: master-bin.000002
Exec_Master_Log_Pos: 78684
slaveD> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Relay_Master_Log_File: master-bin.000001
Exec_Master_Log_Pos: 746848
Bをマスターに昇格させるために、不足しているすべてのトランザクションをCとDに適用したいので、Bが新しいマスターになり、アプリケーションからのクエリの受信を開始する前に、すべてのスレーブが一貫した状態になっています。 BからのバイナリログでCとDからのトランザクションを逃しました(すべてのサーバーで--log-slave-updates
オプションを有効にしました)。
従来の問題の場合、環境はMySQL5.0を使用します
変更するために必要なこと、私が呼ぶもの、レプリケーションの参照ポイント。
サーバーB、C、およびDではbinlogが有効になっているため、これは便利です。
あなたが与えた
slaveB> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Relay_Master_Log_File: master-bin.000002
Exec_Master_Log_Pos: 1476884
slaveC> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Relay_Master_Log_File: master-bin.000002
Exec_Master_Log_Pos: 78684
ServerCをServerBのスレーブになるように同期させましょう
ステップ01:ServerCへのすべての書き込みを停止します
STOP SLAVE;
ステップ02:ServerCで、SHOW MASTER STATUS;
を実行します
出力がmaster-bin.000003位置12345678だったとしましょう
ステップ03:ServerCで、実行
mysqlbinlog master-bin.000003 > latest-binlog.sql
ステップ04:STEP 03
から位置を特定し、前後に3行を表示します
grep -C 3 12345678 latest-binlog.sql
タイムスタンプが「2013-09-0301:23:45」だったとしましょう
ステップ05:ServerBのバイナリログでその位置のタイムスタンプを検索します
ServerBのバイナリログがmaster-bin.000004であるとしましょう
ステップ06:ServerBのバイナリログマスター内のタイムスタンプに一致するダンプ位置-bin.000004
SQLFILE=dumpstuff.sql
BINLOG="master-bin.000004"
DT2="2013-09-03 01:23:45"
DT1="2013-09-03 01:00:00"
mysqlbinlog --start-datetime="${DT1}" --stop-datetime="${DT2}" > ${SQLFILE}
ステップ07:SQLFILE
内のタイムスタンプを見つけ、位置を見つけます
位置が87654321だとしましょう
ステップ08:SlaveCをSlaveBに接続します
SlaveCで、これを実行します
STOP SLAVE;
CHANGE MASTER TO master_log_file='master-bin.000004',master_log_pos=87654321;
START SLAVE;
それだけです!!!
これらすべての同じ手順を繰り返して、ServerDをServerBに同期します
これらの手順を実行してもデータが信頼できない場合は、Percona Toolsをダウンロードし、 pt-table-checksum を使用して各スレーブを新しいマスターと照合してください。違いがある場合は、 pt-table-sync を実行してSQLを生成し、違いを修復できます。
あなたはこのコメントをしました
ステップ2、3、4では、マスターbinlogにアクセスできません。slaveCで最新の適用済みトランザクションを取得する方法は、slaveCリレーログから(show slave statusのRelay_Master_Log_FileとExec_Master_Log_Posを使用して)抽出することだと思います。私は正しいですか?手順5から8は正しいようです。
mysqlbinlog をリモートで使用できます -read-from-リモートサーバー 。その上、あなたは古いマスター、ServerAに戻らない。あなたはスレーブ間でこれらのことを行っており、ServerBを新しいマスターにしています。管理されたホスティング会社を使用している場合は、それらの管理者がこのプロセスに関与する必要があります。少なくとも、Linuxボックスと必要なすべてのフォルダーのアクセス許可にアクセスできるようにするためのSSHトンネルアクセスを提供できます。 MySQL認証は必要ありません。
データフォルダ同期(rsync
)ではなくバイナリログから検索する必要がある理由があるかどうかを教えてください。アプリケーションがBへの書き込みを開始していないので、MySQLサーバーを停止してクリーンなrsync
を実行する余裕があると思います(データが大きすぎるのではないでしょうか?)。私はこの方法を直接体験しましたが、それは魅力のように機能しました。 binlogを読み取る(位置を数える際の人間の介入を読み取る)と、間違った位置になってしまう可能性があり、最悪の場合、重複したエントリを処理することになります。