Новинка Виртуальный VDS сервер в Финляндии от 390р
Выберите продукт

Репликация MySQL/MariaDB на малом VDS: GTID, semi‑sync и безопасное переключение

Практический разбор репликации MySQL/MariaDB на малом VDS: включаем GTID, настраиваем semi‑sync, подбираем параметры binlog и показываем пошаговый сценарий безопасного switchover/failover без потерь данных с учётом ограничений CPU и RAM.
Репликация MySQL/MariaDB на малом VDS: GTID, semi‑sync и безопасное переключение

Если база данных — сердце вашего проекта, репликация на малом VDS — это страховка, производительность и контроль RPO/RTO. Разберём, как настроить репликацию MySQL/MariaDB с GTID и semi‑sync, подобрать параметры binlog и безопасно переключать роли (switchover) без потерь.

Зачем репликация на малом VDS и чего ожидать

Даже на маленьком инстансе репликация даёт три ощутимые выгоды: горячая копия для аварий, разгрузка чтения (реплика под отчёты/аналитику) и безопасное окно для обновлений. Цена — записи в binlog, небольшой overhead фиксации транзакций и RAM под метаданные.

Цель: RPO → 0 и RTO в пределах 1–5 минут. GTID упрощает переключения, semi‑sync снижает риск потери коммитов при падении ведущего.

Топология и ограничения малого VDS

Базовая схема: один primary и одна реплика. На малом VDS критичны экономные настройки I/O и памяти. Начинайте с двух узлов в одной зоне доступности, затем по необходимости добавляйте третью реплику только для чтения. Держите узлы ближе — задержки бьют по semi‑sync.

Если выбираете конфигурацию железа под БД, ориентируйтесь на CPU/IOPS/RAM и рабочий набор данных. Полезно свериться с материалом о подборе ресурсов VDS: как выбрать план по CPU и RAM.

Пример минимальной конфигурации MySQL 8.0 для GTID‑репликации на малом VDS.

MySQL 8.0: включаем GTID и готовим к replication

Для MySQL 8.0 GTID — стандарт де‑факто. Он позволяет включить автопозиционирование (SOURCE_AUTO_POSITION=1) и забыть о ручном управлении позициями binlog.

Минимальный my.cnf для малого VDS (MySQL 8.0)

[mysqld]
server_id = 101
log_bin = mysql-bin
binlog_format = ROW
binlog_row_image = FULL
binlog_expire_logs_seconds = 604800
relay_log = relay-bin
skip_name_resolve = ON

# GTID и репликация
gtid_mode = ON
enforce_gtid_consistency = ON
log_slave_updates = ON
read_only = ON
super_read_only = ON

# Долговечность и предсказуемость
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1

# Память и лимиты для маленького VDS
innodb_buffer_pool_size = 512M
max_connections = 100
table_open_cache = 400
thread_cache_size = 50
performance_schema = ON
performance_schema_consumer_events_statements_history = OFF

# Устойчивость репликации
relay_log_recovery = ON
sync_relay_log = 1
sync_relay_log_info = 1
sync_master_info = 1

innodb_flush_log_at_trx_commit=1 и sync_binlog=1 минимизируют риск потерь (ценой TPS на медленном диске). Если есть semi‑sync и TPS критичен, допустим sync_binlog=0 как компромисс — но осознанно.

Пользователь для репликации

CREATE USER 'repl'@'10.0.%' IDENTIFIED BY 'S3cureP4ss!';
GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl'@'10.0.%';
FLUSH PRIVILEGES;

Ограничьте доступ по сети/подсети и включайте TLS на канале репликации. Для этого используйте валидные SSL-сертификаты и шифрованные соединения между узлами.

Начальная загрузка данных

Для InnoDB используйте «горячий» дамп в рамках одной транзакции. Для GTID включите экспорт GTID:

mysqldump --single-transaction --set-gtid-purged=ON --triggers --routines --events \
--databases appdb > dump.sql

Восстановите дамп на реплике и не подключайте к ней приложение, пока не запустите репликацию.

Подключение реплики с GTID

MySQL 8.0 поддерживает новый синтаксис (SOURCE/REPLICA) и старый (MASTER/SLAVE), используйте подходящий для вашей версии.

-- Новый синтаксис (8.0.26+)
CHANGE REPLICATION SOURCE TO 
  SOURCE_HOST='10.0.0.10', SOURCE_PORT=3306,
  SOURCE_USER='repl', SOURCE_PASSWORD='S3cureP4ss!',
  SOURCE_AUTO_POSITION = 1,
  GET_SOURCE_PUBLIC_KEY = 1;
START REPLICA;

-- Старый синтаксис
CHANGE MASTER TO 
  MASTER_HOST='10.0.0.10', MASTER_PORT=3306,
  MASTER_USER='repl', MASTER_PASSWORD='S3cureP4ss!',
  MASTER_AUTO_POSITION = 1,
  GET_MASTER_PUBLIC_KEY = 1;
START SLAVE;

Проверка статуса:

SHOW REPLICA STATUS\G
-- или
SHOW SLAVE STATUS\G

Должны работать I/O и SQL потоки, задержка — секунды, ошибок нет. Формат ROW избегает недетерминизма функций.

FastFox VDS
Облачный VDS-сервер
Виртуальные серверы с быстрым запуском и гибкой конфигурацией от 390₽ / мес
Доступные локации
Россия Нидерланды Финляндия

MariaDB: отличия GTID и настройка

В MariaDB GTID реализован с domain_id и строгим режимом. Автопозиционирование поддерживается, но синтаксис другой.

Конфигурация MariaDB 10.6+

[mariadb]
server_id = 201
log_bin = mariadb-bin
binlog_format = ROW
binlog_row_image = FULL
expire_logs_days = 7
relay_log = relay-bin
skip_name_resolve = ON

# GTID
gtid_domain_id = 10
gtid_strict_mode = ON
log_slave_updates = ON
read_only = ON

# Надёжность
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1

# Малый VDS
innodb_buffer_pool_size = 512M
max_connections = 100
table_open_cache = 400
thread_cache_size = 50

# Репликация
relay_log_recovery = ON
sync_relay_log = 1
sync_relay_log_info = 1
sync_master_info = 1

Инициализация и подключение в MariaDB

Сделайте консистентный дамп (аналогично MySQL). Для подключения укажите использование GTID:

CHANGE MASTER TO 
  MASTER_HOST='10.0.0.10', MASTER_PORT=3306,
  MASTER_USER='repl', MASTER_PASSWORD='S3cureP4ss!',
  MASTER_USE_GTID=slave_pos;
START SLAVE;

Проверьте SHOW SLAVE STATUS\G: задержка, ошибки, отставание по GTID.

Полусинхронная репликация (semi‑sync): меньше потерь при авариях

Асинхронная репликация подтверждает коммит клиенту сразу после фиксации на ведущем — реплика может отставать. Semi‑sync ждёт ACK хотя бы от одной реплики (запись в relay‑log/журнал), что повышает шанс RPO=0 при фейловере.

Включение semi‑sync в MySQL 8.0

-- На ведущем
INSTALL PLUGIN rpl_semi_sync_source SONAME 'semisync_source.so';
SET GLOBAL rpl_semi_sync_source_enabled = ON;
SET GLOBAL rpl_semi_sync_source_timeout = 1000;  -- мс ожидания ACK
SET GLOBAL rpl_semi_sync_source_wait_for_slave_count = 1;
SET PERSIST rpl_semi_sync_source_enabled = ON;

-- На реплике
INSTALL PLUGIN rpl_semi_sync_replica SONAME 'semisync_replica.so';
SET GLOBAL rpl_semi_sync_replica_enabled = ON;
SET PERSIST rpl_semi_sync_replica_enabled = ON;

В старых релизах используются плагины/переменные rpl_semi_sync_master/rpl_semi_sync_slave.

Включение semi‑sync в MariaDB

-- На ведущем
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
SET GLOBAL rpl_semi_sync_master_enabled = ON;
SET GLOBAL rpl_semi_sync_master_timeout = 1000;

-- На реплике
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
SET GLOBAL rpl_semi_sync_slave_enabled = ON;

Статус:

SHOW STATUS LIKE 'Rpl_semi_sync%';

Важно: при недоступности реплик semi‑sync откатывается в async — мониторьте метрики и настраивайте алерты.

Безопасный switchover (переключение роли) с GTID

Switchover — плановая замена ведущего без потерь. При GTID и semi‑sync это делается быстро и предсказуемо.

Предварительная проверка

  • Реплика здорова: нет ошибок в SHOW REPLICA/SLAVE STATUS, задержка минимальна.
  • На ведущем read_only=OFF, на реплике read_only=ON, super_read_only=ON.
  • semi‑sync (если включён) активен, задержки сети стабильны.

Пошаговая процедура (MySQL)

  1. Замораживаем запись на текущем ведущем:
    -- На ведущем
    SET GLOBAL super_read_only = ON;
    SET GLOBAL read_only = ON;
    -- (опционально) SET GLOBAL event_scheduler = OFF;
    
  2. Ждём догон по GTID. На реплике дожидаемся выполнения всех GTID ведущего:
    -- На ведущем
    SELECT @@GLOBAL.gtid_executed \G
    -- Скопируйте значение и выполните на реплике:
    SELECT WAIT_FOR_EXECUTED_GTID_SET('gtid_set_с_ведущего', 30);
    
    Если вернулся 0 — реплика синхронизирована. Если -1 — истёк таймаут, разберитесь с долгими транзакциями.
  3. Останавливаем репликацию на кандидате (будущем ведущем):
    -- На реплике
    STOP REPLICA;  -- или STOP SLAVE;
    
  4. Делаем реплику ведущей:
    -- На реплике (новом ведущем)
    SET GLOBAL super_read_only = OFF;
    SET GLOBAL read_only = OFF;
    
  5. Подключаем старого ведущего как реплику к новому ведущему:
    -- На старом ведущем
    CHANGE REPLICATION SOURCE TO 
      SOURCE_HOST='IP_нового_ведущего', SOURCE_PORT=3306,
      SOURCE_USER='repl', SOURCE_PASSWORD='S3cureP4ss!',
      SOURCE_AUTO_POSITION = 1,
      GET_SOURCE_PUBLIC_KEY = 1;
    START REPLICA;  -- или START SLAVE;
    
  6. Возвращаем события/джобы, если отключали:
    -- На новом ведущем
    SET GLOBAL event_scheduler = ON;  -- если используется
    
  7. Переключаем приложение на новый ведущий (DNS/конфиг/виртуальный IP). Проверьте записи и задержку.

Для MariaDB логика аналогична. Вместо WAIT_FOR_EXECUTED_GTID_SET используйте сравнение GTID‑позиций или дождитесь Seconds_Behind_Master=0, затем остановите SQL‑поток и снимите read_only.

Если что-то пошло не так

  • WAIT вернул -1: ищите долгие транзакции (SHOW PROCESSLIST, sys.schema_table_lock_waits), дождитесь или отмените по регламенту.
  • Реплика отстаёт по I/O: проверьте сеть, relay_log, I/O квоты диска, innodb_io_capacity.
  • Ошибки DDL после промоушена: убедитесь, что binlog_format=ROW, триггеры/события не пишут в недоступные базы.

Failover (аварийное переключение): краткие заметки

При падении ведущего и включённом semi‑sync новая ведущая, как правило, имеет все зафиксированные транзакции. Проверьте целостность, снимите read_only, переведите трафик. Старый ведущий поднимайте как реплику через GTID‑автопозиционирование. Избегайте split‑brain: используйте единый IP/маршрутизатор включений или строгий ручной регламент.

Визуализация semi‑sync и шагов безопасного switchover.

Тюнинг репликации и БД для малого VDS

  • Память: innodb_buffer_pool_size 50–70% RAM; max_connections по факту нагрузки; следите за table_open_cache и thread_cache_size.
  • Долговечность: innodb_flush_log_at_trx_commit=1, sync_binlog=1 для RPO≈0. При упоре в диск — батч‑записи, пулы соединений, уменьшение чата запросов.
  • Binlog: ROW, binlog_row_image=FULL (или MINIMAL при понимании рисков); binlog_expire_logs_seconds 3–7 дней.
  • Репликация: relay_log_recovery=ON, sync_*_info=1; на репликах держите read_only=ON и super_read_only=ON.
  • Сеть: включите TCP keepalive на уровне ОС; на высокой задержке semi‑sync может снижать TPS — настройте rpl_semi_sync_*_timeout.
  • Диагностика: slow_query_log=ON, анализируйте отчёты Performance Schema; резервное копирование проверьте на стенде и автоматизируйте. Подробно о S3‑бэкапах: руководство по бэкапам.

Проверка и мониторинг

  • Репликация: SHOW REPLICA/SLAVE STATUS\G, Seconds_Behind_*, ошибки SQL/I/O потоков.
  • semi‑sync: SHOW STATUS LIKE 'Rpl_semi_sync%', алерт при откате в async.
  • GTID: сравнивайте @@GLOBAL.gtid_executed/@@GLOBAL.gtid_purged (MySQL) или позиции (MariaDB).
  • Диск: IOPS/latency, заполнение binlog/relay‑log, ротация логов.

Типичные ошибки

  • Смешивание MySQL и MariaDB в одном контуре — не поддерживается.
  • Отключённый log_slave_updates ломает цепочку GTID при будущих переключениях.
  • STATEMENT или MIXED формат binlog — риск дрейфа данных.
  • Слишком широкие права пользователя репликации (% без сетевых ограничений) — риск безопасности.
  • Отключённый relay_log_recovery — шанс поломки после крэша узла.
  • Switchover без super_read_only на старом ведущем — риск split‑brain.

Чек‑лист перед продом

  • GTID включён на обоих узлах, log_slave_updates=ON, ROW формат binlog.
  • semi‑sync протестирован под реальной сетевой задержкой, таймауты подобраны.
  • Бэкапы и восстановление проверены на отдельной среде.
  • Процедура switchover документирована и отрепетирована.
  • Мониторинг репликации, binlog и диска настроен, алерты валидированы.

Итоги

Даже на малом VDS можно построить надёжную репликацию MySQL/MariaDB с GTID и semi‑sync, добиться RPO≈0 и быстро делать switchover/failover. Ключ — аккуратная настройка binlog, дисциплина процедур и постоянный мониторинг. Для миграции с минимальным простоем полезно посмотреть: переезд без простоя. Тестируйте на стенде, учитывайте задержки сети и характеристики диска — и база переживёт плановые релизы и внезапные аварии.

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

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

Как безопасно выполнить bootstrap MariaDB Galera после полного останова

Как безопасно выполнить bootstrap MariaDB Galera после полного останова

После одновременной остановки всех узлов Galera обычного запуска MariaDB недостаточно. Сначала найдите сервер с последней транзакц ...
CoreDNS в Kubernetes: исправляем CrashLoopBackOff, SERVFAIL и DNS-петлю

CoreDNS в Kubernetes: исправляем CrashLoopBackOff, SERVFAIL и DNS-петлю

Разберём, почему CoreDNS перезапускается или отвечает SERVFAIL, как обнаружить замкнутую пересылку DNS-запросов, проверить доступн ...
Apache Kafka KRaft на VDS: отдельные controller и broker

Apache Kafka KRaft на VDS: отдельные controller и broker

Соберём новый Kafka-кластер без ZooKeeper на шести Linux VDS: три узла controller образуют отказоустойчивый metadata quorum, а три ...