Репликация MariaDB решает две задачи: разгружает мастер чтением и даёт копию данных на случай отказа. Настройка несложная, но ошибки проявляются позже — расхождение данных, отставание на часах, потеря транзакций при переключении. Разберём схему master-slave на GTID, мониторинг и контролируемый switchover.
Когда хватает одной реплики
Асинхронная репликация подходит для чтения отчётов, резервного копирования и быстрого подъёма после сбоя. Она не гарантирует нулевую потерю данных: при падении мастера часть транзакций может не дойти до slave. Если простой недопустим, нужны полусинхронный режим, кластер Galera или внешний менеджер отказоустойчивости, но начинать всё равно стоит с обычной реплики.
Для небольшого сервиса достаточно двух узлов на разных машинах.
Подготовка серверов
Возьмите LTS-ветку MariaDB — 11.4 или 11.8. Версии на мастере и реплике должны совпадать, иначе возможны расхождения в формате событий. Каждому узлу нужен уникальный server_id, включённый binary log и строгий GTID.
Файл /etc/mysql/mariadb.conf.d/99-replication.cnf на мастере:
[mysqld]
server_id = 1
log_bin = /var/log/mysql/mariadb-bin
binlog_format = ROW
binlog_row_image = FULL
gtid_strict_mode = ON
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1
На реплике те же параметры, но server_id = 2 и log_bin тоже включён — это пригодится при переключении, когда бывший slave станет мастером. После правки перезапустите службу и проверьте переменные:
sudo systemctl restart mariadb
mariadb -e "SHOW VARIABLES LIKE 'server_id'"
mariadb -e "SHOW VARIABLES LIKE 'gtid_strict_mode'"
mariadb -e "SHOW MASTER STATUS\G"
Учётная запись для репликации
Создайте отдельного пользователя с правом REPLICATION SLAVE и ограничьте его сетью. Пароль должен быть длинным, а доступ — только с адреса реплики. Не используйте root: при компрометации реплики это лишний риск.
CREATE USER 'repl'@'10.0.0.12' IDENTIFIED BY 'Repl_Pass_2026!';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'10.0.0.12';
FLUSH PRIVILEGES;
SELECT user, host FROM mysql.user WHERE user = 'repl';
Проверьте подключение с реплики: mariadb -h 10.0.0.11 -u repl -p. Если соединение не устанавливается, смотрите bind-address и правила файрвола — порт 3306 должен быть открыт только для второго узла.
Снятие согласованного дампа
Для небольшой базы достаточно mariadb-dump с --single-transaction и --master-data=2. Флаг добавляет в дамп комментарий с координатами binlog, по которым реплика догонит мастер. Для баз в сотни гигабайт используйте mariadb-backup, иначе дамп будет идти часами.
mariadb-dump --single-transaction --master-data=2 --routines --triggers --events --all-databases > /backup/all.sql
grep -m1 'CHANGE MASTER' /backup/all.sql
scp /backup/all.sql replica:/backup/
mariadb < /backup/all.sql
На реплике дамп применяется до включения репликации. Если в нём есть CREATE DATABASE и USE, базы создадутся автоматически. Убедитесь, что на реплике нет локальных записей в этих базах — иначе начнутся конфликты.
Запуск и проверка
В MariaDB с GTID удобно указать MASTER_USE_GTID=slave_pos: реплика возьмёт позицию из gtid_slave_pos и продолжит с неё. Если значение не задано, укажите MASTER_LOG_FILE и MASTER_LOG_POS из комментария в дампе.
CHANGE MASTER TO
MASTER_HOST='10.0.0.11',
MASTER_USER='repl',
MASTER_PASSWORD='Repl_Pass_2026!',
MASTER_USE_GTID=slave_pos;
START SLAVE;
SHOW SLAVE STATUS\G
В выводе важны поля Slave_IO_Running: Yes, Slave_SQL_Running: Yes, Seconds_Behind_Master и Last_Error. Ноль в отставании не гарантирует синхронность: значение считается по последней применённой транзакции, поэтому сравнивайте Retrieved_Gtid_Set и Executed_Gtid_Set.
Для проверки записи выполните на мастере CREATE DATABASE test_repl; и через пару секунд проверьте наличие базы на реплике.
Мониторинг отставания
Простой опрос SHOW SLAVE STATUS раз в минуту достаточен для домашнего сервера. В продакшене лучше снимать метрики в Prometheus через mysqld_exporter и строить графики. Отдельно настройте алерт на Slave_SQL_Running=No — остановка SQL-потока почти всегда означает конфликт или ошибку схемы.
mariadb -e "SHOW ALL SLAVES STATUS\G" | grep -E 'Connection_name|Running|Behind|Error'
mariadb -e "SELECT @@gtid_current_pos"
mariadb -e "SHOW PROCESSLIST"
Полусинхронный режим включается плагинами semisync_master и semisync_slave. Он ждёт подтверждения хотя бы от одной реплики, увеличивая задержку записи, но сокращая окно потери данных. Включайте его, только если задержка в несколько миллисекунд допустима.
Плановое переключение
Switchover — это управляемая смена ролей, а не аварийный failover. Порядок такой: перевести мастер в режим только для чтения, дождаться, пока реплика догонит его, затем повысить реплику и перенастроить старый мастер как новый slave.
На мастере прекратите запись и зафиксируйте позицию:
SET GLOBAL read_only = ON;
SET GLOBAL super_read_only = ON;
SHOW MASTER STATUS;
На реплике дождитесь применения этой позиции и повысьте её:
SELECT MASTER_GTID_WAIT('0-1-12345', 10);
STOP SLAVE;
RESET SLAVE ALL;
SET GLOBAL read_only = OFF;
SET GLOBAL super_read_only = OFF;
Проверку MASTER_GTID_WAIT выполняйте на реплике с позицией мастера: она вернётся, когда все транзакции применены. Затем остановите приложение или переключите его на новый адрес. Не выполняйте RESET MASTER на новом мастере — это обнулит историю GTID и сломает репликацию.
Бывший мастер перенастройте на нового: задайте gtid_slave_pos равным его текущей позиции и выполните CHANGE MASTER TO ... MASTER_USE_GTID=slave_pos. Если позиции разошлись, сначала разберитесь, какие транзакции потеряны, и только потом запускайте реплику.
Аварийный failover и split-brain
При падении мастера реплика может стать новым мастером, но автоматическое повышение без fencing опасно: старый узел вернётся и продолжит принимать записи. Используйте STONITH, отключение питания или сетевую изоляцию, а также прокси вроде MaxScale, который направляет трафик на актуальный узел.
После аварийного переключения проверьте gtid_current_pos на обоих узлах и сравните контрольные суммы таблиц. Если старый мастер успел записать транзакции, которых нет на новом, их придётся переносить вручную — автоматика тут не поможет.
Чек-лист перед продакшеном
- Уникальные
server_id, включёнlog_bin,binlog_format=ROW. - Пользователь репликации ограничен по хосту и имеет только нужные права.
- Дамп снят согласованно, позиция GTID зафиксирована.
- Настроены алерты на остановку потоков и отставание.
- Проведена учебная смена ролей на копии стенда.
- Приложение умеет переключаться на новый адрес без ручной правки кода.
Итог
Репликация MariaDB строится вокруг трёх вещей: корректного дампа, GTID и дисциплины переключения. Настройка занимает полчаса, но настоящая надёжность появляется после учебного switchover и проверки, что приложение действительно переехало. Начните с одной реплики, настройте мониторинг и только потом усложняйте схему — так вы избежите split-brain и потери данных.