Чем GTID отличается от классической репликации по координатам
В классической схеме репликации реплика запоминает файл и позицию в бинлоге мастера, откуда продолжать чтение — это пара MASTER_LOG_FILE и MASTER_LOG_POS. После смены мастера эти координаты приходится искать вручную, сверяя логи, и ошибка на пару байт портит всю репликацию.
GTID (Global Transaction Identifier) присваивает каждой транзакции уникальный идентификатор вида server_uuid:номер. Реплика хранит набор уже применённых GTID и при переключении сама вычисляет, с какой транзакции продолжать — без ручного поиска файла и позиции.
Как включить GTID на мастере и репликах
Режим включается одинаковыми параметрами на всех узлах:
[mysqld]
gtid_mode = ON
enforce_gtid_consistency = ON
log_bin = /var/lib/mysql/binlog
server_id = 10Параметр enforce_gtid_consistency запрещает конструкции, которые нельзя однозначно привязать к одной транзакции — например, смешение временных и обычных таблиц в одном запросе. Включать его нужно до перевода репликации на GTID, иначе сервер откажется запускаться с существующими проблемными запросами в логах.
Настройка реплики через MASTER_AUTO_POSITION
Вместо файла и позиции реплика указывает лишь адрес мастера:
CHANGE MASTER TO
MASTER_HOST='10.0.0.10',
MASTER_USER='repl',
MASTER_PASSWORD='strong-pass',
MASTER_AUTO_POSITION=1;
START SLAVE;Флаг MASTER_AUTO_POSITION=1 говорит серверу сверить набор GTID на реплике с набором на мастере и запросить именно недостающие транзакции. Базовые шаги настройки пользователя для репликации и самого канала описаны в статье про Master-Slave репликацию.
Переключение на новый мастер без потери позиции
Главное преимущество GTID проявляется при аварии мастера. Порядок действий:
| Шаг | Действие |
|---|---|
| 1 | Остановить запись на старом мастере или подтвердить его недоступность |
| 2 | Выбрать реплику с самым полным набором GTID через SHOW SLAVE STATUS |
| 3 | Выполнить CHANGE MASTER TO с адресом новой реплики-мастера |
| 4 | Запустить START SLAVE на остальных репликах |
| 5 | Проверить Seconds_Behind_Master и Executed_Gtid_Set на каждом узле |
Поскольку GTID глобально уникален для всего кластера, реплики не запросят повторно уже применённые транзакции и не потеряют события между старым и новым мастером, если они переключались на актуальную копию.
Диагностика: разрыв в наборе GTID
Самая частая проблема — errant transaction, транзакция, выполненная прямо на реплике в обход мастера. Она портит набор GTID и останавливает репликацию с ошибкой дубликата. Найти её помогает сравнение множеств:
SELECT GTID_SUBTRACT(
@@GLOBAL.gtid_executed,
'source-uuid:1-500'
) AS extra_transactions;Если результат не пустой, на реплике есть транзакции, которых нет на мастере, — их нужно либо пропустить через GTID_NEXT, либо полностью перезалить реплику из свежего бэкапа.
Частые ошибки при переходе на GTID
Перед включением GTID на проде стоит проверить:
- На всех узлах binlog в формате ROW, а не STATEMENT.
- server_id уникален для каждого узла кластера, включая резервные реплики.
- Нет прямых записей на реплики в обход мастера, которые создают errant transactions.
- Проверена процедура переключения на тестовом стенде, а не только в теории.
Чек-лист перед вводом GTID в продакшен
Финальная проверка перед переключением рабочей репликации:
- gtid_mode = ON и enforce_gtid_consistency = ON на мастере и всех репликах.
- CHANGE MASTER TO использует MASTER_AUTO_POSITION=1 везде.
- Executed_Gtid_Set сверен между узлами и не показывает расхождений.
- Есть свежий полный бэкап на случай, если переключение пойдёт не по плану.
- Мониторинг Seconds_Behind_Master настроен и присылает алерт при отставании.