При полном отключении трёхузлового MariaDB Galera Cluster все серверы теряют действующий Primary Component. Обычный запуск службы сразу на трёх узлах не гарантирует восстановления: каждый сервер пытается найти существующий компонент, но ни один из них не уполномочен создать новый. Более опасная ошибка — произвольно выполнить bootstrap на первом доступном узле. Если его состояние отстаёт, кластер примет устаревший набор данных за актуальный, а более свежие транзакции могут быть потеряны.

Безопасная последовательность состоит из четырёх этапов: остановить MariaDB и клиентские записи на всех узлах, определить наиболее актуальное состояние, выполнить bootstrap только на выбранном сервере и затем подключить остальные узлы обычным запуском службы. Инструкция рассчитана на три Linux VDS с root-доступом и уже настроенным Galera Cluster. Установка MariaDB, создание нового кластера и восстановление базы из резервной копии здесь не рассматриваются. Подробнее об устройстве и сценариях применения технологии читайте в материале MariaDB Galera Cluster: когда нужен и как устроен.
Для кластера с административным доступом потребуется подходящий VPS-сервер. На виртуальном хостинге нельзя безопасно выполнить описанные действия: они требуют управления службой MariaDB, доступа к каталогу данных и системным журналам.
Главное правило: команду bootstrap выполняют ровно один раз и только на узле с наиболее свежей Galera-позицией.
Что происходит после полного отключения Galera
Galera обслуживает запросы только в Primary Component — группе узлов, обладающей кворумом. В штатно работающем трёхузловом кластере большинство образуют любые два доступных сервера. Если все три узла остановлены, действующий компонент исчезает. После включения серверы могут обмениваться данными, но им требуется определить, какое сохранённое состояние следует принять за исходное.
Для этого Galera хранит в каталоге данных файл grastate.dat. В нём важны три поля:
uuid— идентификатор состояния кластера;seqno— порядковый номер последней зафиксированной транзакции в этом состоянии;safe_to_bootstrap— признак того, разрешено ли считать узел безопасной отправной точкой.
Пример файла:
# GALERA saved state
version: 2.1
uuid: 9acf4d34-acdb-11e6-bcc3-d3e36276629f
seqno: 15842
safe_to_bootstrap: 1
При корректной последовательной остановке Galera помечает последний выключенный узел значением safe_to_bootstrap: 1. Именно он должен содержать наиболее новое состояние. На остальных серверах обычно останется safe_to_bootstrap: 0.
После аварии питания, сбоя гипервизора или одновременного завершения процессов состояние часто не удаётся записать корректно. Тогда на всех узлах могут оказаться seqno: -1 и safe_to_bootstrap: 0. Это не означает, что данные уничтожены: позицию нужно восстановить из локальных журналов InnoDB с помощью wsrep recovery.
Подготовка к восстановлению
До любых действий отключите приложение, прокси или балансировщик от всех трёх серверов базы данных. Пока кластер не восстановлен и не проверен, новые записи поступать не должны. Если на VDS настроен автоматический перезапуск MariaDB внешней системой мониторинга, временно приостановите его.
Условно обозначим серверы как node1, node2 и node3. Все команды проверки состояния нужно выполнить на каждом из них. Не полагайтесь только на имена: записывайте рядом IP-адрес VDS, содержимое grastate.dat и результат recovery, чтобы не перепутать кандидата на bootstrap.
Остановите MariaDB на всех узлах
На системах с systemd служба обычно называется mariadb:
systemctl stop mariadb
systemctl is-active mariadb
Ожидаемый результат второй команды — inactive. В некоторых пакетах и старых дистрибутивах unit может называться mysql. Фактическое имя можно проверить так:
systemctl list-unit-files | grep -E '^(mariadb|mysql)\.service'
Дополнительно убедитесь, что процесс базы действительно завершён:
pgrep -a -x mariadbd
pgrep -a -x mysqld
Если команды ничего не вывели, сервер остановлен. Не применяйте kill -9 только ради ускорения остановки: принудительное завершение может лишить Galera возможности сохранить корректную позицию. Если процесс завис, сначала изучите статус и журнал службы:
systemctl status mariadb --no-pager
journalctl -u mariadb -n 100 --no-pager
Определите каталог данных
Путь /var/lib/mysql распространён, но не универсален. Каталог мог быть изменён параметром datadir, настройками пакета или схемой хранения конкретного VDS. Перед чтением и изменением grastate.dat проверьте конфигурацию MariaDB. Эффективное значение часто можно увидеть в выводе серверного бинарного файла:
mariadbd --verbose --help 2>/dev/null | awk '$1 == "datadir" {print $2; exit}'
Если команда mariadbd отсутствует, проверьте mysqld --verbose --help. Также просмотрите конфигурационные файлы, подключаемые вашей установкой MariaDB. После проверки задайте переменную отдельно на каждом сервере:
DATADIR=/var/lib/mysql
printf '%s\n' "$DATADIR"
ls -l "$DATADIR/grastate.dat"
Замените путь в первой строке, если используется другой каталог. Все дальнейшие примеры предполагают, что переменная DATADIR уже содержит правильное значение.
Сохраните исходные state-файлы
До редактирования сделайте копию grastate.dat. Это не резервная копия самой базы, но она позволит восстановить исходные служебные значения и проверить, что именно было изменено:
mkdir -p /root/galera-recovery
cp -a "$DATADIR/grastate.dat" "/root/galera-recovery/grastate.dat.$(hostname -s)"
[ ! -f "$DATADIR/gvwstate.dat" ] || cp -a "$DATADIR/gvwstate.dat" "/root/galera-recovery/gvwstate.dat.$(hostname -s)"
Файл gvwstate.dat связан с механизмом автоматического восстановления компонента pc.recovery. В рамках обычного ручного восстановления редактировать его не нужно. Ошибка в составе сохранённого view может помешать запуску или привести к неверному объединению узлов.
Шаг 1. Сравните grastate.dat на трёх узлах
На каждом сервере выполните:
grep -E '^(uuid|seqno|safe_to_bootstrap):' "$DATADIR/grastate.dat"
Сведите результаты в таблицу или текстовый файл. Например:
node1 uuid=9acf4d34-acdb-11e6-bcc3-d3e36276629f seqno=15840 safe=0
node2 uuid=9acf4d34-acdb-11e6-bcc3-d3e36276629f seqno=15842 safe=1
node3 uuid=9acf4d34-acdb-11e6-bcc3-d3e36276629f seqno=15841 safe=0
В этом примере кандидатом является node2: у него стоит safe_to_bootstrap: 1, а значение seqno самое большое.
Если один узел помечен safe_to_bootstrap: 1
После штатной остановки используйте именно этот сервер. Не переносите флаг на другой узел ради удобства, более быстрого диска или желаемого порядка имён. Назначение флага — зафиксировать, какой узел завершил работу последним и может безопасно открыть новый Primary Component.
Перед продолжением убедитесь, что:
- только один из трёх узлов имеет
safe_to_bootstrap: 1; - его
seqnoне равен-1; - MariaDB на остальных серверах остановлена;
- после аварии вы не запускали на другом узле отдельный кластер.
Если условия выполнены, recovery обычно не требуется: переходите к bootstrap выбранного сервера.
Если safe_to_bootstrap равен 0 везде
Не меняйте флаг наугад. Сначала посмотрите на seqno. Если файлы содержат корректные неотрицательные позиции и одинаковый uuid, наиболее актуальным считается узел с максимальным seqno. Однако после аварийного завершения надёжнее выполнить wsrep recovery на всех трёх серверах: значение в state-файле могло не отразить последнюю локально зафиксированную транзакцию.
Если seqno: -1 хотя бы на одном потенциально актуальном узле, сравнения только файлов grastate.dat недостаточно. Переходите к восстановлению позиции.
Если UUID различаются
Числа seqno следует сравнивать в рамках одного UUID. Позиция Galera представляет пару UUID:seqno, поэтому большое число из другой истории состояния нельзя автоматически считать более свежим. Различающиеся UUID могут остаться после предыдущего bootstrap, незавершённого SST, замены содержимого datadir или разделения кластера.
В такой ситуации не выбирайте узел только по максимальному числу после двоеточия. Проверьте журналы, историю административных действий и recovered position всех серверов. Если узлы действительно работали как независимые Primary Components и принимали разные записи, это уже восстановление после расхождения данных, а не стандартный перезапуск после общего отключения.
Шаг 2. Восстановите позиции через wsrep recovery
Recovery запускается только при остановленной MariaDB. Процедуру необходимо повторить на каждом узле, иначе нельзя доказать, что выбранный сервер содержит последнюю транзакцию.
Вариант с galera_recovery
В пакетах MariaDB для systemd обычно доступен служебный скрипт galera_recovery. Он запускает сервер в режиме wsrep_recover, извлекает позицию и завершает диагностический процесс без обычного запуска узла:
command -v galera_recovery
galera_recovery
Сохраните полученную пару UUID:seqno. В зависимости от сборки скрипт может вывести параметр --wsrep_start_position либо перенаправить диагностический вывод во временный файл вида /tmp/wsrep_recovery.XXXXXX. Найти созданные файлы можно так:
ls -lt /tmp/wsrep_recovery.* 2>/dev/null | head
Искомая строка выглядит примерно так:
WSREP: Recovered position: 9acf4d34-acdb-11e6-bcc3-d3e36276629f:15843
Вариант с mariadbd --wsrep-recover
Если скрипта нет, используйте серверный бинарный файл. Запускайте его от системного пользователя MariaDB и записывайте вывод в отдельный файл для каждого VDS:
sudo -u mysql mariadbd --wsrep-recover 2>&1 | tee "/root/galera-recovery/wsrep-recover.$(hostname -s).log"
На установках со старым именем бинарного файла применяется аналогичная команда с mysqld:
sudo -u mysql mysqld --wsrep-recover 2>&1 | tee "/root/galera-recovery/wsrep-recover.$(hostname -s).log"
Если recovered position не появилась в терминале, проверьте журнал ошибок MariaDB: параметр log_error может перенаправлять сообщения туда. Расположение журнала зависит от конфигурации; на systemd-системах полезно также проверить:
journalctl -u mariadb -n 100 --no-pager | grep -i 'Recovered position'
После процедуры убедитесь, что диагностический процесс завершился, а обычная служба осталась остановленной:
systemctl is-active mariadb
pgrep -a -x mariadbd
pgrep -a -x mysqld
Как выбрать результат recovery
Предположим, получены позиции:
node1 9acf4d34-acdb-11e6-bcc3-d3e36276629f:15841
node2 9acf4d34-acdb-11e6-bcc3-d3e36276629f:15843
node3 9acf4d34-acdb-11e6-bcc3-d3e36276629f:15842
Все UUID совпадают, поэтому выбирается node2 с максимальным seqno 15843. Значения из recovery имеют приоритет над устаревшим seqno: -1 в grastate.dat.
Если два или три узла получили одну и ту же максимальную позицию с одинаковым UUID, их данные находятся на одном уровне Galera. Для bootstrap можно выбрать один из них, но команда всё равно должна быть выполнена только на одном сервере. Практически удобнее использовать узел без ошибок файловой системы и InnoDB, с достаточным свободным местом и стабильной сетевой связью с двумя остальными VDS.
Если recovery завершается ошибкой, не маскируйте проблему ручным назначением safe_to_bootstrap: 1. Сначала изучите диагностический журнал. Ошибки доступа к datadir, повреждение InnoDB, нехватка места и неверные параметры конфигурации требуют отдельного устранения. При нехватке места поможет инструкция о поиске больших файлов и освобождении места на диске Linux-сервера.
Шаг 3. Назначьте выбранный узел безопасным
Если правильный сервер уже имеет safe_to_bootstrap: 1, файл менять не нужно. После аварии, когда флаг равен нулю на всех узлах, установите единицу только на узле с максимальной recovered position.
Сначала ещё раз проверьте имя сервера и сохранённый результат:
hostname -f
grep -E '^(uuid|seqno|safe_to_bootstrap):' "$DATADIR/grastate.dat"
Затем измените флаг:
sed -i -E 's/^safe_to_bootstrap:*.*/safe_to_bootstrap: 1/' "$DATADIR/grastate.dat"
grep -E '^(uuid|seqno|safe_to_bootstrap):' "$DATADIR/grastate.dat"
Если строка отсутствует или формат файла отличается, не добавляйте значения вслепую. Откройте копию и исходный файл, проверьте их структуру и отредактируйте только поле safe_to_bootstrap. Не подставляйте recovered seqno вручную без необходимости: для выбора кандидата достаточно результата recovery и разрешающего флага.
На двух остальных узлах должно оставаться safe_to_bootstrap: 0. Если из-за предыдущих действий единица обнаружена более чем на одном сервере, верните ноль всем невыбранным узлам. Это снижает риск случайного запуска второго независимого компонента.
Шаг 4. Выполните bootstrap Primary Component
Перед командой ещё раз проверьте два условия: MariaDB остановлена на всех трёх VDS, а терминал открыт именно на выбранном узле. На systemd-системах с пакетами MariaDB используется:
galera_new_cluster
Этот скрипт запускает MariaDB с параметром --wsrep-new-cluster. Параметр предназначен только для первого узла: он сообщает Galera, что сервер должен создать новый компонент, а не подключаться к уже существующему.
На системах с SysVinit пакетный способ может выглядеть так:
service mysql bootstrap
Не выполняйте galera_new_cluster на втором и третьем узлах. Не добавляйте --wsrep-new-cluster в постоянный конфигурационный файл: при последующих перезапусках это способно создавать отдельный кластер вместо подключения к действующему.
Проверьте первый узел
Сразу после bootstrap проверьте службу:
systemctl status mariadb --no-pager
journalctl -u mariadb -n 100 --no-pager
Затем запросите основные wsrep-показатели:
mariadb -e "SHOW GLOBAL STATUS WHERE Variable_name IN ('wsrep_cluster_status','wsrep_cluster_size','wsrep_connected','wsrep_ready','wsrep_local_state_comment','wsrep_cluster_state_uuid','wsrep_last_committed');"
Для единственного запущенного узла ожидаются:
wsrep_cluster_status = Primary;wsrep_cluster_size = 1;wsrep_connected = ON;wsrep_ready = ON;wsrep_local_state_comment = Synced.
Если статус не стал Primary, не запускайте остальные узлы. Проверьте журнал на отказ Safe-to-Bootstrap, ошибки wsrep provider, проблемы с datadir и неверный адрес кластера. Повторять bootstrap на другом сервере до выяснения причины опасно.
Шаг 5. Подключите второй и третий узлы
После появления исправного компонента размером 1 запустите MariaDB на втором узле обычной командой:
systemctl start mariadb
Никаких bootstrap-параметров на присоединяемом узле не требуется. Он использует настроенный wsrep_cluster_address, найдёт действующий Primary Component и запросит передачу недостающего состояния.
Следите за журналом:
journalctl -u mariadb -f
В другом терминале периодически проверяйте состояние второго узла:
mariadb -e "SHOW GLOBAL STATUS WHERE Variable_name IN ('wsrep_cluster_status','wsrep_cluster_size','wsrep_connected','wsrep_ready','wsrep_local_state_comment');"
Дождитесь wsrep_local_state_comment = Synced и размера компонента 2. Только после этого обычным способом запустите третий сервер и дождитесь его перехода в Synced.
В зависимости от сохранённого GCache и размера отставания узел получит IST — только недостающие write-sets — либо полный SST. Во время SST нагрузка на donor может заметно вырасти, поэтому последовательное подключение узлов проще контролировать и безопаснее для небольших VDS с ограниченными дисковыми ресурсами.
Если запуск присоединяемого узла долго остаётся в промежуточном состоянии, не выполняйте на нём bootstrap. Проверьте свободное место, доступность donor, выбранный SST-метод, права на datadir и журнал systemd. На некоторых системах продолжительный SST может столкнуться с ограничением времени запуска службы; это видно по сообщениям unit и MariaDB.
Итоговая проверка кластера
После подключения всех серверов выполните запрос на каждом узле:
mariadb -e "SHOW GLOBAL STATUS WHERE Variable_name IN ('wsrep_cluster_status','wsrep_cluster_size','wsrep_cluster_state_uuid','wsrep_connected','wsrep_ready','wsrep_local_state_comment');"
Исправный трёхузловой кластер должен показывать:
wsrep_cluster_status = Primaryна всех узлах;wsrep_cluster_size = 3;- одинаковый
wsrep_cluster_state_uuid; wsrep_connected = ONиwsrep_ready = ON;wsrep_local_state_comment = Synced.
Удобно получить короткую сводку следующей командой:
mariadb -NBe "SHOW GLOBAL STATUS WHERE Variable_name IN ('wsrep_cluster_status','wsrep_cluster_size','wsrep_ready','wsrep_local_state_comment');"
После проверки верните узлы в балансировщик и включите приложение. Делайте это только тогда, когда размер компонента равен трём, если эксплуатационная схема не предусматривает временную работу на двух узлах.
Когда применяется pc.bootstrap вместо galera_new_cluster
Команда galera_new_cluster нужна, когда процесс MariaDB остановлен и выбранный узел требуется запустить как начало нового Primary Component. Возможен другой сценарий: серверы MariaDB продолжают работать, но все находятся в состоянии Non-Primary из-за потери кворума.
Если наиболее актуальный узел уже запущен, а остальные гарантированно остановлены или изолированы, компонент можно восстановить динамически:
SET GLOBAL wsrep_provider_options='pc.bootstrap=YES';
Команда выполняется через клиент MariaDB на выбранном узле. Она не должна одновременно выполняться в разных сетевых сегментах. Иначе могут появиться два независимых Primary Components, каждый из которых начнёт принимать записи. Для полного отключения, когда все процессы остановлены, основной и понятный путь — выбор состояния, safe_to_bootstrap и galera_new_cluster.
Типичные опасные ошибки
Bootstrap на первом доступном сервере
Скорость включения VDS, имя node1 или прежняя роль donor ничего не говорят об актуальности данных. Кандидата выбирают по safe_to_bootstrap либо по максимальной recovered position.
Запуск всех служб до сравнения позиций
Одновременный запуск усложняет диагностику, может активировать автоматическое восстановление сохранённого view и создаёт риск ошибочных ручных действий. На время выбора кандидата все процессы должны оставаться остановленными.
Сравнение seqno при разных UUID
Число seqno не является самостоятельным глобальным счётчиком. Сравнивается полная позиция, а числовой выбор максимума безопасен для узлов из одной истории состояния с одинаковым UUID.
Установка safe_to_bootstrap: 1 на всех узлах
Флаг не синхронизирует данные и не объединяет серверы. Он только разрешает конкретному узлу стать исходным. Единица на нескольких узлах повышает риск случайно создать несколько кластеров.
Обычный запуск выбранного узла вместо bootstrap
systemctl start mariadb заставляет сервер искать существующий компонент. После полного отключения его ещё нет. Первый узел запускают специальной командой, а обычный старт используют только для второго и третьего.
Повторный bootstrap при проблеме подключения узла
Если первый узел уже показывает Primary, новый bootstrap не исправит сетевую ошибку, SST или неверный wsrep_cluster_address. Он способен создать конкурирующую историю. Неполадки присоединения диагностируют по журналам donor и joiner.
Краткий порядок восстановления
- Отключить клиентские записи и автоматический перезапуск MariaDB.
- Остановить службу на всех трёх VDS и проверить отсутствие процессов.
- Определить фактический datadir и сохранить копии state-файлов.
- Сравнить
uuid,seqnoиsafe_to_bootstrapвgrastate.dat. - Если безопасный узел не определён, выполнить wsrep recovery на всех узлах.
- Выбрать максимальную позицию в одной истории UUID.
- Установить
safe_to_bootstrap: 1только на выбранном сервере. - Выполнить на нём
galera_new_cluster. - Проверить статус
Primary, размер 1 и состояниеSynced. - Обычным запуском поочерёдно подключить второй и третий узлы.
- Убедиться, что размер компонента равен 3, UUID одинаков, а все узлы готовы к работе.
Ключ к безопасному восстановлению Galera — не сама команда bootstrap, а правильный выбор исходного состояния. safe_to_bootstrap надёжен после штатной остановки, а после аварии его заменяет сравнение recovered position. Только после этого один узел создаёт новый Primary Component, а два остальных присоединяются к нему как обычные участники кластера.


