Выберите продукт

MySQL replication lag на VDS: диагностика и лечение (GTID, relay log, parallel replication)

Replication lag в MySQL — не всегда «медленный slave»: показатель Seconds_Behind_Master часто врёт. Покажу, как отличить проблему чтения binlog от применения relay log, проверить GTID-наборы, включить parallel replication и найти узкие места диска/flush на VDS.
MySQL replication lag на VDS: диагностика и лечение (GTID, relay log, parallel replication)

Что такое replication lag и почему на VDS он всплывает чаще

Replication lag в MySQL — это ситуация, когда реплика применяет изменения медленнее, чем источник их генерирует. Итог знакомый: чтения с реплики становятся «устаревшими», отчёты показывают вчерашние данные, а при переключении ролей вы рискуете получить долгий «догон» или потерять хвост транзакций (если переключение сделано без учёта фактического прогресса).

На VDS лаг проявляется чаще, чем на «железе», по двум причинам: дисковая подсистема (IOPS/latency) менее предсказуема и чувствительна к пикам fsync, а CPU и планировщик могут давать больше вариативности под смешанной нагрузкой. Репликация любит стабильное хранилище и понятный профиль записи.

Для диагностики полезно сразу разделить проблему на две разные истории:

  • I/O-thread не успевает читать события из binlog источника (узкое место: сеть, источник, ограничения канала, настройки semi-sync).
  • SQL-thread (apply) не успевает применять то, что уже скачано в relay log (узкое место: диск на реплике, блокировки, параллелизм, большие транзакции, flush-профиль InnoDB).

Почему Seconds_Behind_Master часто вводит в заблуждение

Почти все начинают с Seconds_Behind_Master из SHOW REPLICA STATUS (или SHOW SLAVE STATUS в старых версиях). Это полезный индикатор, но далеко не «истинное время отставания».

Типичные ловушки:

  • NULL — не «0». Обычно это означает, что репликация не работает как ожидалось: поток остановлен, есть ошибка или метрика не вычисляется.
  • «0 при проблемах». Если источник временно не генерирует события, метрика может стать 0, даже если у вас есть зависшие/долго применяющиеся транзакции.
  • Часы и NTP. Расчёт зависит от времени события в binlog и локального времени реплики; при скачках времени возможны странные значения.

В продакшене полезно иметь внешний SLI лага (например, heartbeat-таблица). Ниже тоже обсудим, как это помогает увидеть «микролаги» и реальные хвосты.

Быстрая проверка статуса репликации

Снимите статус одной командой и смотрите не только Seconds_Behind_Master, а состояние потоков и ошибки.

mysql -e "SHOW REPLICA STATUS\G"

Поля, которые обычно дают ответ «где затык» за 1 минуту:

  • Replica_IO_Running и Replica_SQL_Running (или Slave_IO_Running/Slave_SQL_Running)
  • Last_IO_Error, Last_SQL_Error
  • Master_Log_File, Read_Master_Log_Pos (дочитали ли binlog)
  • Relay_Log_File, Relay_Log_Pos, Relay_Log_Space (насколько вырос relay log)
  • Retrieved_Gtid_Set, Executed_Gtid_Set (если включён GTID)

Экран со статусом MySQL реплики: Seconds_Behind_Master и GTID-наборы

GTID: как понять, где именно «застряли»

GTID (Global Transaction ID) делает репликацию управляемее: проще сравнивать прогресс, пересоздавать реплики и выполнять безопасные переключения. Для диагностики лага GTID особенно удобен тем, что показывает разницу между «скачано» и «применено».

Ключевая логика:

  • Если Retrieved_Gtid_Set растёт, а Executed_Gtid_Set заметно отстаёт — I/O-thread успевает, а apply (SQL-thread/worker’ы) не вывозит.
  • Если оба растут медленно — проблема может быть вне реплики: сеть, лимиты канала, источник не отдаёт binlog достаточно быстро, особенности semi-sync.

Если ваша операционная процедура включает planned failover, полезно держать отдельный короткий ранбук по переключениям и GTID. У нас есть связанная заметка про практику переключений: failover с GTID и semi-sync в MySQL.

Практичная метрика «очереди применений»

В терминах реплики есть две скорости: «получать события» и «применять события». Когда скачивание обгоняет применение, растёт «очередь» в relay log, чаще всего это видно по Relay_Log_Space и по разнице GTID-наборов. Даже без углубления в performance_schema этого обычно достаточно, чтобы выбрать направление: тюнинг диска/flush/параллелизма или поиск сетевого/источникового ограничения.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Relay log: почему «диск решает»

Relay log — это локальные файлы на реплике, куда I/O-thread записывает события, прочитанные из binlog источника. Затем apply-поток(и) их выполняют. На VDS именно этот слой часто первым упирается в диск: запись relay log плюс запись InnoDB (redo/двойная запись, фоновые flush’и) создают пилообразную нагрузку и чувствительность к latency.

Типичный сценарий: сеть и источник «быстрые», I/O-thread активно пишет relay log, очередь растёт, а применение тормозит из-за высокой latency диска или из-за блокировок при применении изменений. В статусе это часто выглядит как рост Relay_Log_Space и увеличение Seconds_Behind_Master.

Проверьте место и I/O-профиль на реплике

Минимальный набор команд, который помогает подтвердить «дисковую» природу лага:

df -h
ls -lh /var/lib/mysql
iostat -x 1
pidstat -d 1

Что обычно настораживает: высокий await и util в iostat, рост очереди, резкие пики записи, а также ситуации, когда диск почти постоянно занят даже при умеренном QPS на реплике.

Parallel replication: как догонять источник, а не ждать часами

Если apply упирается в последовательность выполнения транзакций, самый «дешёвый» по времени эффект даёт parallel replication: несколько worker-потоков применяют независимые транзакции параллельно. На практике это часто превращает «час догоняем» в «минуту догоняем» — но только если транзакции действительно можно распараллелить.

Важно помнить ограничения:

  • Если все изменения идут в одну «горячую» таблицу/строку (hot rows), параллелизм упрётся в блокировки.
  • Если выставить слишком много worker’ов, можно получить конкуренцию за CPU и рост переключений контекста, а не ускорение.

Базовая настройка parallel replication (MySQL 8)

Стартовая конфигурация для реплики с несколькими vCPU (значения подбирайте по наблюдениям):

mysql -e "SET PERSIST replica_parallel_workers=8;"
mysql -e "SET PERSIST replica_parallel_type='LOGICAL_CLOCK';"

Если у вас старые имена переменных, используйте аналоги slave_parallel_workers и slave_parallel_type.

После включения проверьте, что worker’ы реально заняты. Если они простаивают — значит распараллеливать нечего (высокая конфликтность) или bottleneck в другом месте (I/O, flush, CPU на декодирование, индексы).

binlog и формат: почему ROW часто спасает (и чем платите)

Формат бинарного лога влияет и на объём данных, и на предсказуемость применения. Row Based Replication (RBR) передаёт изменения на уровне строк. Это снижает риск расхождений из-за недетерминированных выражений и обычно лучше сочетается с параллельным применением.

Обратная сторона — больше объём binlog/relay log, больше диска и трафика. На VDS это важно: «толстые» логи могут стать новой причиной лага, особенно если диск и так близок к пределам по IOPS.

Что проверить в binlog-профиле при лаге

  • Хватает ли места под binlog/relay log и корректна ли политика очистки.
  • Нет ли гигантских транзакций (миллионы строк в одном commit) — они применяются долго и плохо параллелятся.
  • Соответствует ли формат (STATEMENT/MIXED/ROW) вашему профилю нагрузки и требованиям к детерминизму.

Если вы часто разбираете инциденты репликации, пригодится отдельный материал про восстановление/точку во времени и работу с binlog: PITR и binlog/GTID в MySQL/MariaDB.

Semi-sync: когда помогает, а когда добавляет задержки

Semi-synchronous replication заставляет источник дождаться подтверждения от реплики, что транзакция получена (как минимум дошла до реплики и записана), прежде чем подтверждать commit клиенту. Это уменьшает риск потери последних транзакций при аварии, но увеличивает latency записи и может «сцепить» судьбу мастера и реплики при деградации реплики.

Если semi-sync включён, при проблемах диска/CPU на реплике вы увидите не только lag, но и просадку записи на источнике. В этом режиме критично иметь мониторинг времени подтверждения и адекватные таймауты/политику fallback на async, чтобы мастер не «встал» вместе с репликой.

innodb_flush_log_at_trx_commit и fsync: цена надёжности

Параметр innodb_flush_log_at_trx_commit определяет, как часто InnoDB делает flush redo log на диск. Значение 1 даёт максимальную надёжность (fsync на каждый commit), но на дисках с высокой latency или при лимитах IOPS это легко становится главным ограничителем и на источнике, и на реплике.

Иногда рассматривают 2 как компромисс (меньше fsync, но риск потери последних секунд при падении ОС). Это решение должно быть осознанным и согласованным с требованиями к целостности данных.

Если лаг приходит «волнами» и совпадает с пиками fsync, начните с измерений (iostat, задержки commit, очереди I/O), а уже потом меняйте innodb_flush_log_at_trx_commit. Иначе легко обменять один класс проблем на другой.

Мониторинг дисковой подсистемы для MySQL: задержки I/O и очередь записи

Heartbeat-замер: как измерять лаг «по-настоящему»

Самый полезный подход в эксплуатации — иметь отдельную метрику лага, не зависящую от особенностей вычисления Seconds_Behind_Master. Классический вариант — heartbeat-таблица: на источнике регулярно обновляется отметка времени, на реплике вы читаете её и считаете разницу.

Почему это лучше для SLI/SLO:

  • метрика понятна бизнесу («задержка данных в секундах»);
  • легче строить графики и алерты по порогам;
  • видны микролаги и «пила», которые статус может сглаживать.

Если вы используете Percona Toolkit, то pt-heartbeat — один из самых популярных готовых инструментов для этого. Но даже самодельная heartbeat-таблица даёт огромный прирост наблюдаемости при минимальной сложности.

FastFox SSL
Надежные SSL-сертификаты
Мы предлагаем широкий спектр SSL-сертификатов от GlobalSign по самым низким ценам. Поможем с покупкой и установкой SSL бесплатно!

Типовые причины лага и что делать: чек-лист

1) Одна огромная транзакция или массовая миграция

Большие транзакции плохо параллелятся и могут надолго «заклинить» применение. Дробите батчи, избегайте гигантских INSERT ... SELECT и UPDATE без разумной стратегии разбиения. Для репликации это часто разница между минутами и часами.

2) Конфликтные записи (hot rows) и блокировки

Если все транзакции бьют в одни и те же ключи, worker’ы не дадут выигрыша: вы упрётесь в блокировки. Ищите горячие таблицы/индексы и меняйте паттерн записи (например, «распределённые» счётчики, append-only логирование) или оптимизируйте индексы.

3) Диск не вывозит relay log и flush InnoDB

Проверьте, где лежит datadir, нет ли конкурирующих нагрузок (бэкапы, архиваторы, логирование). На VDS иногда проще и надёжнее решить проблему инфраструктурно: выбрать тариф/диск с меньшей latency, выделить MySQL отдельный том, уменьшить фоновые задачи в пиковые окна.

4) Недостаток CPU (или неверный параллелизм)

RBR, сложные вторичные индексы и высокая частота коммитов требуют CPU. Слишком высокий replica_parallel_workers может дать контеншн, слишком низкий — не позволит догонять. Подбирайте по наблюдениям: загрузка CPU, run queue, активность worker’ов, время применения транзакций.

5) Сеть и semi-sync

При включённом semi-sync лаг и деградация реплики могут влиять на latency записи на источнике. Мониторьте RTT/подтверждения и заранее определите политику деградации (таймауты, fallback), чтобы не «заморозить» запись.

Мини-ранбук: что делать, когда lag уже случился

  1. Проверьте, что репликация жива: оба потока running, нет ошибок в Last_IO_Error/Last_SQL_Error.

  2. Определите тип проблемы: I/O-thread не успевает читать binlog или apply не успевает применять relay log.

  3. Проверьте, не «висит» одна жирная транзакция или блокировка (частая причина резкого скачка лага).

  4. Посмотрите диск: latency/очередь, свободное место, динамику Relay_Log_Space.

  5. Если проблема хроническая — включайте/тюньте parallel replication, пересматривайте размер транзакций и профиль binlog.

Итоги: как свести replication lag к управляемому уровню

Лаг репликации — это баланс между тем, сколько изменений генерирует источник, и тем, как быстро реплика их применяет. На VDS чаще всего упираются в I/O и настройки параллелизма. Начните с корректного измерения лага (heartbeat), затем разделите проблему на «читать» vs «применять», проверьте GTID-наборы и динамику relay log, и только потом меняйте настройки (parallel replication, flush-профиль, формат binlog) и инфраструктуру.

Стабильная репликация получается там, где есть метрики, алерты и понятный ранбук — тогда lag превращается из «пожара» в управляемую величину.

Поделиться статьей

Вам будет интересно

CPU throttling на VDS в Linux: TDP/thermal лимиты, частоты и квоты cgroups v2 (cpu.max) OpenAI Статья написана AI (GPT 5)

CPU throttling на VDS в Linux: TDP/thermal лимиты, частоты и квоты cgroups v2 (cpu.max)

Если на VDS растёт load average и задержки, а CPU «не на 100%», причина часто в throttling: тепловые/мощностные лимиты, steal time ...
Let’s Encrypt через DNS-01: wildcard, автоматизация продления и безопасные deploy-хуки OpenAI Статья написана AI (GPT 5)

Let’s Encrypt через DNS-01: wildcard, автоматизация продления и безопасные deploy-хуки

DNS-01 удобен для wildcard и закрытых сетей: владение доменом подтверждается TXT-записью в DNS. Разбираем выбор certbot/lego/acme. ...
Linux: EIO и Buffer I/O error on dev — диагностика диска, ФС и контроллера OpenAI Статья написана AI (GPT 5)

Linux: EIO и Buffer I/O error on dev — диагностика диска, ФС и контроллера

EIO, I/O error и Buffer I/O error on dev обычно означают сбой чтения/записи: диск, контроллер, кабели, RAID или файловая система. ...