4.10. Репликация в MySQL
4.10.8. Поиск неисправностей репликации
Если вы следовали инструкциям, но установленный механизм репликации не работает, прежде всего следует искать пользовательские ошибки. Выполните следующие проверки:
Производит ли головной сервер записи в двоичный журнал? Проверьте это при помощи команды SHOW MASTER STATUS. Если да, значение Position будет отличным от нуля. Если нет, проверьте, запущен ли головной сервер с опцией log-bin и установлен ли server-id.
Запущен ли подчиненный сервер? Проверьте это при помощи команды SHOW SLAVE STATUS. Ответ находится в столбце Slave_running. Если нет, проверьте опции подчиненного сервера и просмотрите сообщения в журнале ошибок.
Если подчиненный сервер запущен, установил ли он соединение с головным сервером? Выполните команду SHOW PROCESSLIST, найдите поток, которому соответствует значение system user в столбце User и none в столбце Host, и проверьте столбец State. Если в нем находится значение connecting to master, проверьте привилегии для пользователя репликации на головном сервере, имя хоста головного сервера, установку DNS, посмотрите, запущен ли головной сервер в текущее время, доступен ли он для подчиненного сервера. После этого, если все окажется в порядке, просмотрите журналы ошибок.
Если подчиненный сервер был запущен, но затем остановился, посмотрите на вывод команды SHOW SLAVE STATUS и проверьте журналы ошибок. Такое обычно случается, когда некоторый запрос, успешно выполняющийся на головном сервере, не выполняется на подчиненном. Если создан корректный образ головного сервера и данные на подчиненном сервере обновлялись только через поток подчиненного сервера, этого происходить не должно. Но если все же такое случилось - значит, имеет место ошибка; как сообщить о ней, читайте ниже.
Если запрос, успешно выполняемый на головном сервере, не выполняется на подчиненном, и нельзя выполнить полную ресинхронизацию базы данных (ее стоит выполнить), попробуйте сделать следующее:
Сначала проверьте: возможно где-либо случайно оказалась ненужная запись. Разберитесь, как она оказалась там, затем удалите ее, и выполните команду SLAVE START.
Если вы проделали все, о чем написано выше, и ничего не помогло или этого сделать нельзя, попытайтесь понять, будет ли безопасно выполнить обновления вручную (если необходимо) и после этого игнорировать следующий запрос от головного сервера.
Если вы решили пропустить следующий запрос, выполните команды SET GLOBAL SQL_SLAVE_SKIP_COUNTER=1; SLAVE START; чтобы пропустить запрос, не использующий функции AUTO_INCREMENT или LAST_INSERT_ID(). В противном случае выполните команды SET GLOBAL SQL_SLAVE_SKIP_COUNTER=2; SLAVE START. Причина того, что запросы, использующие функции AUTO_INCREMENT или LAST_INSERT_ID(), обрабатываются по-другому, заключается в том, что они создают два события в двоичном журнале головного сервера.
Если вы уверены, что подчиненный сервер был успешно запущен и синхронизирован с головным сервером, а также что обновления таблиц не производились вне потока подчиненного сервера, пришлите нам отчет об ошибке, и вам не потребуется опять повторять описанные выше уловки.
Удостоверьтесь, что вы не внесли старой ошибки при апгрейде MySQL до более новой версии.
Если ничего не помогает, просмотрите журналы ошибок. Если журналы большие, выполните команду grep -i slave /path/to/your-log.err на подчиненном сервере. Искать ошибку на головном сервере - не лучшая идея, поскольку в его журналах находятся лишь системные ошибки общего характера; если это возможно, он посылает ошибку на подчиненный сервер, когда что-либо происходит не так, как надо.
Если вы убедились, что пользовательская ошибка здесь ни при чем, однако механизм репликации по-прежнему не работает или работает нестабильно, пришло время начать работу над отчетом об ошибке. Вы должны предоставить нам столько информации, сколько нужно, чтобы отследить ошибку. Пожалуйста, уделите отчету об ошибке нужное количество времени и усилий, чтобы сделать его хорошо. В идеале мы хотели бы иметь контрольный пример в формате, который находится в каталоге mysql-test/t/rpl* исходного дерева. Отослав такой контрольный пример, в большинстве случаев можно рассчитывать на получение патча в течение одного-двух дней, хотя, конечно, это время может варьироваться в зависимости от множества факторов.
Еще один хороший способ проинформировать нас об ошибке - написать простую программу с легко конфигурируемыми параметрами соединения для головного и подчиненного серверов, в которой будет продемонстрирована проблема наших систем. Программа может быть написана на Perl или на C, в зависимости от того, какой язык вы знаете лучше.
Подготовив информацию об ошибке одним из двух способов, используйте утилиту mysqlbug, чтобы создать отчет об ошибке, и пошлите его по адресу <bugs@lists.mysql.com>. Если же вы имеете дело с фантомом - проблемой, которая имеет место, но вы по какой-либо причине не можете ее воспроизвести по желанию:
Убедитесь, что эта проблема не вызвана пользовательской ошибкой. Например, при обновлении подчиненного сервера вне потока подчиненного сервера данные будут не синхронизированы, и могут быть нарушения уникальных ключей при обновлениях. В этом случае поток подчиненного сервера остановится и будет ждать, пока таблицы не будут очищены вручную, для приведения их в синхронизированный режим.
Запустите подчиненный сервер с опциями log-slave-updates и log-bin - при этом в журнал будет заноситься информация обо всех обновлениях, происходящих на подчиненном сервере.
Сохраните все доказательства наличия ошибки перед сбросом репликации. Если у нас нет информации о проблеме, или имеется только отрывочная информация, потребуется время, чтобы найти источник проблемы. Вы должны собрать следующие "свидетельства":
Все двоичные журналы головного сервера
Весь двоичный журнал подчиненного сервера
Вывод команды SHOW MASTER STATUS на головном сервере во время обнаружения проблемы
Вывод команды SHOW SLAVE STATUS на головном сервере во время обнаружения проблемы
Журналы ошибок головного сервера и подчиненного сервера
Для изучения двоичных журналов используйте утилиту mysqlbinlog. Таким образом можно находить проблемные запросы, например:
mysqlbinlog -j pos_from_slave_status /path/to/log_from_slave_status | head
Собрав "свидетельства" о проблеме-фантоме, попробуйте сначала организовать их в отдельный контрольный пример. После этого сообщите о проблеме по адресу <bugs@lists.mysql.com>, описав эту проблему во всех подробностях.