После отключения электроэнергии в нашем центре обработки данных подчиненные базы данных MySQL находятся в затруднительном положении.
Это в журналах одного из ведомых устройств:
100118 10:05:56 [Note] Slave I/O thread: connected to master 'repl@db1:3306', replication started in log 'bin-log.004712' at position 724207814
100118 10:05:56 [ERROR] Error reading packet from server: Client requested master to start replication from impossible position ( server_errno=1236)
100118 10:05:56 [ERROR] Got fatal error 1236: 'Client requested master to start replication from impossible position' from master when reading data from binary log
100118 10:05:56 [Note] Slave I/O thread exiting, read up to log 'bin-log.004712', position 724207814
И консоль показывает чуть подробнее:
mysql> show slave status \G;
*************************** 1. row ***************************
Slave_IO_State:
Master_Host: db1
Master_User: repl
Master_Port: 3306
Connect_Retry: 10
Master_Log_File: bin-log.004712
Read_Master_Log_Pos: 724207814
Relay_Log_File: mysqld-relay-bin.000105
Relay_Log_Pos: 98
Relay_Master_Log_File: bin-log.004712
Slave_IO_Running: No
Slave_SQL_Running: Yes
Replicate_Do_DB: mmplive1,mmpjcr,fui
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 724207814
Relay_Log_Space: 98
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
1 row in set (0.00 sec)
ERROR:
No query specified
Глядя на журналы бункера на мастере, мы имеем:
-rw-rw---- 1 mysql mysql 724200412 Jan 18 09:22 bin-log.004712
-rw-rw---- 1 mysql mysql 1904 Jan 18 09:27 bin-log.index
-rw-rw---- 1 mysql mysql 5046830 Jan 18 11:22 slow-log
-rw-rw---- 1 mysql mysql 198249613 Jan 18 11:24 bin-log.004713
Как лучше всего починить рабов?
Варианты, которые я рассматриваю:
ОБНОВИТЬ:
Я пропустил еще один вариант: немного вернуть каждую позицию выполнения ведомого, чтобы он попытался воспроизвести команды, которые он уже обработал из bin-log.004712.
Я выбрал первый вариант.
Это работало до того момента, когда ведомое устройство начало пытаться делать вставки, конфликтующие с первичными ключами. Подчиненное устройство выполнило больше работы, чем сохранялось в главном журнале бункера, как упоминалось ранее. Один аспект, который я не ожидал, заключался в том, что подчиненное устройство содержало данные, которых не было в главном устройстве; то есть ведомое устройство сохранило некоторые транзакции до отключения электроэнергии, которое ведущее устройство НЕ ИМЕЛ настаивал.
Поскольку в моем случае эти транзакции не были связаны с платежами или аналогичными, я решил удалить данные с ведомого устройства (тем самым потеряв некоторые данные, которые произошли, но не существовали на ведущем устройстве), а затем снова запустил репликацию. . Это полностью обновило рабов. Если бы данные были более важными, у нас есть смещения с автоматическим приращением, достаточные для того, чтобы дать нам некоторое пространство для маневра для ручного анализа данных и обеспечения целостности ссылок. К счастью, в этом случае нам не пришлось этого делать.
Для машины в (пассивной) конфигурации мастер-мастер, которая оказалась в этой затруднительной ситуации, я выбрал аналогичный подход. Под пассивным мастером-мастером я подразумеваю, что у нас есть активный мастер (serverA), на который идут все записи, и пассивный мастер (serverB), который позволяет обновлять схему с нулевым временем простоя. Данные на активном главном сервере (serverA) были выбраны в качестве истинных значений, несмотря на то, что мы знали, что это означало, что мы потеряли пару сохраненных транзакций, которые не были сочтены важными.
Поменял лог файл и положение на раб.
CHANGE MASTER MASTER_LOG_FILE='bin-log.004713', MASTER_LOG_POS=0; -- on serverB
Перезапущена репликация подчиненного устройства на пассивном главном устройстве (serverB) до тех пор, пока не произойдет сбой с нарушением ограничений первичного ключа, как и в случае с другими подчиненными устройствами.
START SLAVE; -- on serverB
Остановлена репликация ведомого устройства от пассивного ведущего (serverB) к активному ведущему (serverA).
STOP SLAVE; -- on serverA
УДАЛИТЕ строки на подчиненном сервере (serverB), которых не было в главном устройстве на serverA.
DELETE FROM SOME_TABLE WHERE ID IN (???,????); -- on serverB
SHOW MASTER STATUS\G; -- get the new master log position on serverB
Переместите позицию exec активного ведущего (serverA) ведомого, чтобы пропустить эти удаления с пассивного ведущего (serverB).
CHANGE MASTER TO MASTER_LOG_POS=???; --on serverA; use the value just obtained from serverB
Перезапустите репликацию как на активном мастере (serverA), так и на пассивном мастере.
START SLAVE; -- on both machines. serverA does nothing and serverB starts catching up.
Это будет зависеть от того, насколько важно, чтобы ведомое устройство было точной копией ведущего. Ваш первый вариант будет работать в определенной степени, но ведомые устройства вполне могут терять информацию от ведущего. Если вы можете смириться с этим, потому что данные временные или что-то в этом роде, сделайте это. Если важно, чтобы подчиненные устройства были точными копиями, то второй вариант, вероятно, ваш единственный выбор. К сожалению, репликация MySQL не приемлет никаких неожиданных прерываний, я обнаружил, что подобные проблемы возникают гораздо чаще, чем мне хотелось бы, в моей архитектуре репликации.