Ошибка replication lag в мониторинге или расхождение данных между основным сервером и копией — типичный признак того, что реплика работает, но отстаёт от мастера. Чтобы понять, почему это происходит и нормально ли это, нужно разобраться в самом механизме: реплика — это копия базы данных, которая автоматически получает изменения с основного сервера и применяет их у себя.

Репликация используется повсеместно: от небольших сайтов на MySQL до распределённых систем вроде PostgreSQL, MongoDB или Redis. Она решает три задачи: отказоустойчивость (если основной сервер упал, копия подхватит работу), распределение нагрузки (запросы на чтение идут на реплики) и географическую близость данных к пользователям. Ниже разберём, как именно устроен этот процесс изнутри.

Основной принцип: поток изменений от мастера к реплике

В классической схеме есть мастер (primary, source) — сервер, который принимает все операции записи, и одна или несколько реплик (slave, standby, secondary), которые эти изменения копируют. Ключевая идея: реплика не получает данные «целиком» при каждом изменении — она получает поток событий, описывающих, что именно изменилось.

В большинстве реляционных СУБД этот поток строится на основе журнала изменений. В MySQL это binlog (binary log), в PostgreSQLWAL (Write-Ahead Log). Каждая транзакция сначала фиксируется в журнале, а реплика читает этот журнал и последовательно применяет записанные операции к своей копии данных. Пока журнал читается быстрее, чем пишется, реплика находится в актуальном состоянии.

Упрощённо цикл выглядит так: клиент выполняет INSERT или UPDATE на мастере → изменение попадает в журнал → реплика забирает запись из журнала по сети → применяет её локально → подтверждает позицию в журнале. Позиция важна: именно по ней реплика знает, с какого места продолжать после перезапуска или разрыва соединения.

💡

Реплика не копирует данные заново — она непрерывно применяет поток изменений из журнала мастера (binlog или WAL), отслеживая свою позицию в нём.

Синхронная и асинхронная репликация

Главный архитектурный выбор — когда мастер считает запись завершённой. При асинхронной репликации мастер подтверждает транзакцию клиенту сразу, не дожидаясь реплик. Это быстро, но создаёт окно риска: если мастер упадёт в этот момент, последние изменения могут не дойти до реплики и будут потеряны при переключении.

При синхронной репликации мастер ждёт подтверждения хотя бы от одной реплики, прежде чем ответить клиенту. Данные надёжнее защищены, но каждая запись становится медленнее — добавляется сетевая задержка до реплики. Существует и промежуточный вариант — полусинхронная репликация, где мастер ждёт подтверждения о получении события репликой, но не обязательно о его применении.

РежимСкорость записиРиск потери данныхТипичное применение
АсинхроннаяМаксимальнаяЕсть, при падении мастераВеб-приложения, аналитика
ПолусинхроннаяСредняяМинимальныйБаланс скорости и надёжности
СинхроннаяНиже из-за ожиданияПрактически отсутствуетФинансовые и критичные данные
⚠️ Внимание: синхронная репликация не делает систему абсолютно защищённой. Если реплика недоступна, мастер может либо блокировать записи, либо (в зависимости от настроек) молча переходить в асинхронный режим. Проверяйте поведение вашей СУБД при потере реплики в документации конкретной версии.

Топологии: как соединяются мастер и реплики

Одна реплика — это только начало. На практике топологии бывают разными, и каждая решает свою задачу.

  • 🔗 Master–Slave (Primary–Replica) — классика: один мастер на запись, реплики на чтение. Просто и предсказуемо.
  • 🔄 Master–Master — оба сервера принимают запись и обмениваются изменениями. Гибко, но требует решения конфликтов, когда одна строка меняется на обоих узлах.
  • 🌳 Каскадная (цепочка) — реплика сама выступает источником для других реплик, разгружая мастер.
  • 🌍 Геораспределённая — реплики в разных дата-центрах или регионах для отказоустойчивости и низкой задержки у пользователей.

Отдельно стоит упомянуть логическую и физическую репликацию. Физическая копирует данные на уровне блоков хранения — реплика побайтово идентична мастеру. Логическая передаёт изменения на уровне строк и таблиц, что позволяет реплицировать только часть базы или даже между разными версиями СУБД. В PostgreSQL, например, логическая репликация работает через механизм публикаций и подписок.

📊 Какая топология репликации используется в ваших проектах?
Один мастер и реплики на чтение
Master-Master
Каскадная цепочка
Пока не использую репликацию

Лаг реплики: почему копия отстаёт

Самая частая проблема на практике — lag реплики, отставание копии от мастера. Проверить его можно штатными средствами: в MySQL команда SHOW REPLICA STATUS (в старых версиях — SHOW SLAVE STATUS) показывает поле Seconds_Behind_Master, в PostgreSQL — представление pg_stat_replication на мастере.

Причины отставания почти всегда сводятся к тому, что реплика применяет изменения медленнее, чем мастер их генерирует. Возможные причины: тяжёлые запросы на чтение, конкурирующие с потоком репликации; однопоточное применение событий при параллельной записи на мастере; медленные диски или сеть; большие транзакции, которые реплика применяет целиком.

☑️ Диагностика отставания реплики

Выполнено: 0 / 5

Если поток репликации остановлен с ошибкой (например, из-за конфликта данных или повреждённого события), лаг будет расти неограниченно. Поэтому мониторинг должен отслеживать не только величину отставания, но и сам факт работы потоков репликации.

💡

Настройте алерт не только на значение лага, но и на состояние потоков репликации — остановленный поток опаснее, чем отставание в несколько секунд.

Что происходит при падении мастера: переключение на реплику

Когда мастер выходит из строя, одна из реплик повышается до нового мастера — это называется failover. Переключение может выполняться вручную администратором или автоматически с помощью инструментов оркестрации и кластерных менеджеров (набор таких решений зависит от СУБД и инфраструктуры).

Тонкий момент — данные, записанные на мастере, но ещё не дошедшие до реплики, при асинхронной репликации теряются. Именно поэтому перед повышением реплики проверяют её отставание: если лаг большой, нужно либо дождаться догона, либо осознанно принять потерю части транзакций.

⚠️ Внимание: после аварийного переключения старый мастер нельзя просто включить обратно в кластер. На нём могли остаться транзакции, которых нет на новом мастере, — это приведёт к расхождению данных (split-brain). Старый узел обычно пересоздают из копии нового мастера.

Для автоматического failover обычно требуется кворум — нечётное число узлов или внешний арбитр, чтобы избежать ситуации, когда два сервера одновременно считают себя мастером. Это отдельная большая тема, и её реализация сильно различается между СУБД.

Что такое GTID и зачем он нужен

GTID (Global Transaction Identifier) в MySQL и аналогичные механизмы в других СУБД присваивают каждой транзакции глобально уникальный идентификатор. Благодаря этому реплику можно переключить на другой источник без ручного поиска позиции в журнале — сервер сам определяет, какие транзакции уже применены. Это заметно упрощает failover и восстановление после сбоев.

Типичные проблемы репликации и как их избежать

Помимо лага, администраторы регулярно сталкиваются с несколькими характерными сбоями. Знание их природы экономит часы диагностики.

  • 💥 Конфликты данных — запись на реплике напрямую или в схеме master-master приводит к ошибкам применения событий. Правило: реплика в классической схеме должна быть read-only.
  • 🧩 Расхождение схемы — разные версии таблиц на мастере и реплике ломают применение событий. Миграции нужно выполнять в правильном порядке.
  • 📦 Переполнение журнала — если реплика долго недоступна, мастер может удалить старые сегменты журнала до того, как реплика их прочитает. Тогда копию придётся пересоздавать из бэкапа.
  • 🕸️ Сетевые разрывы — кратковременные обрывы обычно переживаются автоматически, но длительная недоступность требует контроля срока хранения журналов.

Общая профилактика проста: мониторинг лага и состояния потоков, запрет записи на реплики, регулярная проверка целостности копии и репетиция процедуры failover. Репликация, которую никогда не проверяли «в бою», в критический момент может подвести.

💡

Репликация — это не резервное копирование. Реплика мгновенно повторяет и ошибочные изменения: случайный DELETE или DROP TABLE на мастере тут же уедет на копию. Бэкапы нужны независимо от числа реплик.

Часто задаваемые вопросы

Чем реплика отличается от бэкапа?

Реплика — это постоянно обновляемая живая копия, доступная для чтения и быстрого переключения. Бэкап — это снимок данных на конкретный момент, хранящийся отдельно. Реплика защищает от отказа сервера, но не от ошибочного удаления данных: такие изменения реплицируются вместе со всем остальным.

Можно ли писать данные на реплику?

В классической схеме master–slave — нет: запись на реплике создаст расхождение с мастером и, скорее всего, сломает репликацию при первом же конфликте. Запись на несколько узлов возможна только в специально спроектированных топологиях master–master или мультимастер-кластерах с механизмом разрешения конфликтов.

Насколько реплика отстаёт от мастера в норме?

Универсальной нормы нет: при асинхронной репликации в здоровой системе отставание обычно близко к нулю, но допустимое значение зависит от требований приложения. Если бизнес-логика читает с реплики данные, которые только что записал пользователь, даже секундный лаг может быть критичен. Порог определяется для каждого проекта отдельно.

Что делать, если репликация сломалась с ошибкой?

Сначала посмотрите текст ошибки в статусе реплики — чаще всего это конфликт данных или недоступность журнала. Небольшие расхождения иногда устраняют вручную, но общий надёжный путь при серьёзном рассинхроне — пересоздать реплику из свежей копии мастера. Конкретные команды зависят от СУБД и версии, сверяйтесь с официальной документацией.

Замедляет ли репликация работу мастера?

При асинхронном режиме влияние минимально — мастер лишь пишет журнал и отдаёт его по сети. При синхронной репликации каждая запись ждёт подтверждения от реплики, поэтому задержка сети напрямую добавляется ко времени транзакции. Это осознанная плата за гарантию сохранности данных.