マスターデータベースが障害を起こしたらスレーブはどうする?
レプリケーションのしくみ
- 備用スレーブ:マスターデータベースのbinlogを同期し、マスター障害時の切り替えに使用。通常は読み専用サービスを提供しない。
- 読み専用スレーブ:マスターデータベースのbinlogを同期し、読み専用サービスを提供する。
一主多からのレプリケーション同期方法
ベース同期の主からスレーブへの同期
スレーブを設定する際の基本的なコマンド例:
CHANGE MASTER TO
MASTER_HOST='master.example.com',
MASTER_PORT=3306,
MASTER_USER='repl_user',
MASTER_PASSWORD='securepass',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=123456;
FileSync位置の取得方法:
- 新マスターA’のリレーログ同期完了を待つ。
- show master statusを実行し、最新のFile名とPositionを取得する。
- 障害発生時刻Tを記録する。
- mysqlbinlogツールを用いてFileを解析し、時刻Tのログポジションを抽出する。
同期ポジションの特定方法:
mysqlbinlogコマンドの例:
mysqlbinlog --stop-datetime="2023-01-01 12:34:56" --start-datetime="2023-01-01 12:34:56" mysql-bin.000001
この方法の欠点:
- 正確な同期位置を特定できない場合がある。
- 手動でSQLスレープスキップコマンドを実行する必要がある。
スレープ同期エラー回避方法:
- トランザクションをスキップする場合:
- 特定のエラーコードをスキップする場合:
SET GLOBAL sql_slave_skip_counter = 1;
START SLAVE;
SET SLAVE_SKIP_ERRORS = '1032,1062';
START SLAVE;
注意事項:
- GTID同期後にSlave_skip_errorsを空に戻す必要がある。
GTID同期の仕組み
MySQL 5.6から導入されたGTID(Global Transaction Identifier)は、同期位置の特定を自動化する。
GTIDの構造:
GTID = server_uuid:gno
- server_uuid: インスタンスが最初に起動時に生成される、グローバルに一意な値。
- gno: トランザクションごとに配布される整数値。
GTID同期のメリット:
- 同期位置を手動で特定する必要がない。
- トランザクションの完全同期が保証される。
GTID同期を用いた主備切り替え
GTID同期の設定例:
CHANGE MASTER TO
MASTER_HOST='master.example.com',
MASTER_PORT=3306,
MASTER_USER='repl_user',
MASTER_PASSWORD='securepass',
MASTER_AUTO_POSITION=1;
同期の仕組み:
- 新スレーブがCHANGE MASTER TOを実行し、GTID同期をリクエスト。
- 新スレーブのGTID集合がマスターに送信される。
- マスターがGTID集合の差分を計算し、不足するGTIDがあれば同期を拒否。
- 差分があれば、最初のGTID位置から同期を開始。
GTID同期を用いた同期エラー回避
特定のGTIDをスキップする方法:
SET GTID_NEXT = '1234-5678-90AB-CDEF-1234567890AB:123';
START TRANSACTION;
COMMIT;
SET GTID_NEXT = 'AUTOMATIC';
START SLAVE;
この方法の効果:
- 指定したGTIDをスレーブのGTID集合に直接追加。
- 該当するトランザクションをスキップして同期を継続。
GTID同期での主備切り替えの課題とその解決方法
主備切り替え時、binlogに不足するGTIDがある場合の対応:
- 主からスレーブへの同期が不完全な場合:
- 主のGTID_PURGEDを確認。
- スレーブ側でRESET MASTERを実行。
- GTID_PURGEDを設定し、START SLAVEを実行。
- 完全同期を要求する場合:
- スレーブの再構築を行う。
- 他の完全同期済みスレーブを用いる場合:
- 新スレーブを完全同期済みスレーブに接続。
- 同期完了後、必要に応じて主に接続。
- binlogのバックアップがある場合:
- 不足するbinlogをスレーブに適用。
- START SLAVEを実行して同期を再開。