GTID & 非GTID の混合レプリは無理
レプリケーション止まった時
ポジション形式のレプリケーションでは
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
が使えたけど GTID では無理
1. どこで止まったか確認する
mysql> show slave status \G; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: hasegawa-dbs01.luis.local Master_User: repl Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000001 Read_Master_Log_Pos: 972 Relay_Log_File: mysql-relay-bin.000005 Relay_Log_Pos: 602 Relay_Master_Log_File: mysql-bin.000001 Slave_IO_Running: Yes Slave_SQL_Running: No Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 1008 Last_Error: Error 'Can't drop database 'after'; database doesn't exist' on query. Default database: 'after'. Query: 'DROP DATABASE after' Skip_Counter: 0 Exec_Master_Log_Pos: 837 Relay_Log_Space: 1238 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: NULL Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 1008 Last_SQL_Error: Error 'Can't drop database 'after'; database doesn't exist' on query. Default database: 'after'. Query: 'DROP DATABASE after' Replicate_Ignore_Server_Ids: Master_Server_Id: 101921870 Master_UUID: c06c5e97-8117-11e9-8d70-fa163e3939ac Master_Info_File: /var/lib/mysql/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: 190604 16:31:15 Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: c06c5e97-8117-11e9-8d70-fa163e3939ac:1-5 Executed_Gtid_Set: c06c5e97-8117-11e9-8d70-fa163e3939ac:1-4 Auto_Position: 1
Retrieved_Gtid_Set: c06c5e97-8117-11e9-8d70-fa163e3939ac:1-5 Executed_Gtid_Set: c06c5e97-8117-11e9-8d70-fa163e3939ac:1-4
c06c5e97-8117-11e9-8d70-fa163e3939ac:1-4 まで実行だけど、
c06c5e97-8117-11e9-8d70-fa163e3939ac:1-5 を受け取ってエラーになったと推測できる。
2. エラーになった GTID をどうにかする
エラーになったとこを無視できるなら、エラーになったトランザクションを空コミットして実行したことにする。
作業する前にスレーブを止める。
STOP SLAVE; SET GTID_NEXT = c06c5e97-8117-11e9-8d70-fa163e3939ac:5 <-- ここ重要。失敗したとこ BEGIN; COMMIT; SET GTID_NEXT = AUTOMATIC <-- 元に戻す。エラーになった GTID 以降の GTID が入ってくる START SLAVE;
GTID なしのレプリケーションに戻す
MASTER_AUTO_POSITION = 0; をつければ OK
CHANGE MASTER TO MASTER_HOST = 'hasegawa-dbm01.luis.local', MASTER_USER = 'repl', MASTER_PASSWORD = 'repl', MASTER_LOG_FILE = 'mysql-bin.000001', MASTER_LOG_POS = 972, MASTER_AUTO_POSITION = 0;
バックアップとリストア
GTID レプリケーションでもやり方は今まで変わらない。
rarirure.rip
rarirure.rip
mysqldump でやるなら
$ mysqldump -uUser -pPassword --all-databases --single-transaction --master-data=2 --triggers --routines --events > dump.sql
--triggers --routines --events
をつけないと、エラーになって dump できない。
スレーブの追加
ここでも GTID 特有の問題が発生する。
Got fatal error 1236 from master when reading data from binary log: ‘The slave is connecting using CHANGE MASTER TO MASTER_AUTO_POSITION = 1, but the master has purged binary logs containing GTIDs that the slave requires.
例えば以下のような CHANGE MASTER 文を発行する。
CHANGE MASTER TO MASTER_HOST='', MASTER_USER='', MASTER_PASSWORD='', MASTER_AUTO_POSITION=1;
そうすると ↑ のエラーになってレプリが貼れない。
よくあるのはフェイルオーバーし、スレーブの向き先を元のマスターへ戻した時(本来はあんましないけど検証するときはよくする)とか
一時的にバックアップ用としてレプリケーションを長期間止めておいて、START SLAVE; したときとか。
エラーの内容は
スレーブがバイナリログを読んで次の GTID をマスターにを要求したが、マスターから「そんなものはないぞ!」が返ってきたエラー。
復旧方法1
無理やりの方法。なお、オススメしない。
GTID_PURGED にマスターの GTID_EXECUTED を入れる。
1. master で現時点の GTID_EXECUTED を確認する。
master> show global variables like 'GTID_EXECUTED'; +---------------+-------------------------------------------+ | Variable_name | Value | +---------------+-------------------------------------------+ | gtid_executed | df57c352-9bdd-11e9-9b3c-fa163eb7e9f7:1-19 | +---------------+-------------------------------------------+
2. マスターの情報をリセットして、GITD_PURGED に入れる。
slave> RESET MASTER; slave> SET GLOBAL GTID_PURGED="df57c352-9bdd-11e9-9b3c-fa163eb7e9f7:1-19";
GITD_PUREGED は GTID_EXECUTED が空のときでないと実行できない。
3. スレーブ再開
slave> START SLAVE;
がこれは
1. どこで止まったか確認する と同じように、スレーブで最後に実行した(GTID_EXECUTED)から、マスターの GTID_EXECUTED の間はレプリされないので
その間に存在しない DB とかテーブルに対してのクエリがあると普通に死ぬ。
スレーブが死んでいる間に、マスターで DB 作って START SLAVE; 後に、CREATE TABLE した結果。
Last_SQL_Error: Error 'Unknown database 'errornow'' on query. Default database: 'errornow'. Query: 'create table test(id int)'
復旧方法2
律儀にやる。
$ mysqldump -uUser -pPassword --all-databases --single-transaction --master-data=2 --triggers --routines --events > dump.sql
随時更新中