Я реализовал решение высокой доступности для mysql на основе репликации мастер-мастер. В передней части есть механизм, который гарантирует, что только один db будет считываться / записываться в данный момент времени (т.е. мы используем репликацию только для HA).
Я подтвердил, что репликация работает должным образом, но меня интересует сценарий отказа и восстановление. В частности, меня беспокоит, что происходит, когда один мастер выходит из строя в неустранимом состоянии, и его нужно воссоздать из другого мастера:
mysqldump
(наши базы данных умеренно большие, и mysqldump
может легко занять несколько часов после нескольких месяцев использования).Простое решение первой проблемы - использовать третью базу данных, действующую как резервную копию, из которой я могу делать mysqldump
. Но тогда как мне убедиться, что воссозданный мастер может последовательно запускать репликацию с работающего мастера?
Я знаю два основных подхода к этой проблеме. Во-первых, если вы используете InnoDB вместо Myisam, вы можете сделать резервную копию в транзакции (--single-transaction --lock-tables = FALSE), которая в сочетании с --flush-logs (необязательно, но приятно) и --master-data предоставит вам согласованную резервную копию с информацией о положении репликации. Очистка журналов сбрасывает журналы перед созданием дампа, что означает, что позиция всегда будет 106, а --master-data поместит имя и позицию файла журнала прямо в файл дампа. Конечно, вы должны запустить это на мастере, чтобы --master-data работала.
Второй способ, о котором вы упомянули, - это использование третьего хоста для создания резервных копий. В этом случае вам нужно остановить репликацию, убедиться, что база данных доступна только для чтения (хотя на самом деле все ваши реплики должны быть доступны только для чтения, поскольку это не влияет на запись из репликации), а затем создать резервную копию и записать позицию репликации. В этом случае вы не можете использовать --master-data. Вместо этого вы можете сделать что-то вроде этого:
echo 'stop slave' | mysql {options)
mysqldump {your options} > DB.sql
echo 'show slave status\G' > DB.replication
echo 'start slave' | mysql {options)
Если вам когда-либо понадобится восстановление из этой резервной копии, вы должны запустить восстановление, а затем настроить репликацию, где два параметра master_log_file и master_log_pos взяты из файла DB.replication:
master_log_file = value of Master_Log_File
master_log_pos = value of Exec_Master_Log_Pos
Примечание: вы можете И СЛЕДУЕТ проверить это на другой реплике.
Дополнительное примечание: если у вас есть пул реплик (например, если вы разделили чтение и запись для веб-приложения), возможно, что реплики не синхронизированы с новым мастером; это может произойти, если переключение происходит в период интенсивного ввода-вывода при записи, поскольку реплики передаются асинхронно, и нет гарантии, что ваш резервный сервер находится в том же положении, что и другие реплики, при переключении на другой ресурс. Однако со мной этого еще не случилось ...