Если база данных — сердце вашего проекта, репликация на малом 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 и готовим к 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 избегает недетерминизма функций.
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)
- Замораживаем запись на текущем ведущем:
-- На ведущем SET GLOBAL super_read_only = ON; SET GLOBAL read_only = ON; -- (опционально) SET GLOBAL event_scheduler = OFF; - Ждём догон по GTID. На реплике дожидаемся выполнения всех GTID ведущего:
Если вернулся 0 — реплика синхронизирована. Если -1 — истёк таймаут, разберитесь с долгими транзакциями.-- На ведущем SELECT @@GLOBAL.gtid_executed \G -- Скопируйте значение и выполните на реплике: SELECT WAIT_FOR_EXECUTED_GTID_SET('gtid_set_с_ведущего', 30); - Останавливаем репликацию на кандидате (будущем ведущем):
-- На реплике STOP REPLICA; -- или STOP SLAVE; - Делаем реплику ведущей:
-- На реплике (новом ведущем) SET GLOBAL super_read_only = OFF; SET GLOBAL read_only = OFF; - Подключаем старого ведущего как реплику к новому ведущему:
-- На старом ведущем 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; - Возвращаем события/джобы, если отключали:
-- На новом ведущем SET GLOBAL event_scheduler = ON; -- если используется - Переключаем приложение на новый ведущий (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/маршрутизатор включений или строгий ручной регламент.

Тюнинг репликации и БД для малого VDS
- Память:
innodb_buffer_pool_size50–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_seconds3–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, дисциплина процедур и постоянный мониторинг. Для миграции с минимальным простоем полезно посмотреть: переезд без простоя. Тестируйте на стенде, учитывайте задержки сети и характеристики диска — и база переживёт плановые релизы и внезапные аварии.


