Ответ
Падение master-узла — это критическое событие, которое запускает процесс восстановления доступности системы (failover).
Основные этапы:
- Остановка репликации: Slave-реплики перестают получать обновления от master-узла. Запись в базу данных становится невозможной.
- Обнаружение сбоя: Системы мониторинга (внешние или встроенные в кластер) фиксируют недоступность master-узла.
- Процесс выбора нового master (Failover):
- Автоматический Failover: Специализированное ПО (например, Patroni для PostgreSQL, Orchestrator для MySQL) автоматически выбирает наиболее подходящую реплику и "повышает" её до нового master.
- Ручной Failover: Администратор вручную выполняет команды, чтобы назначить одну из реплик новым master.
- Перенастройка топологии: Остальные slave-реплики перенастраиваются так, чтобы получать данные уже от нового master.
- Переключение клиентов: Приложения должны перенаправить свои запросы на запись на адрес нового master-узла.
Как это обрабатывается в Go-приложении?
Наивный подход с попыткой переподключения в коде — плохая практика. Правильные архитектурные решения:
-
Использование прокси/балансировщика: Приложение подключается не напрямую к БД, а к прокси (например, PgBouncer, HAProxy), который отслеживает состояние кластера и автоматически направляет трафик на активный master-узел. Для приложения смена master-узла выглядит как кратковременный разрыв соединения.
-
Драйвер с поддержкой Failover: Некоторые драйверы баз данных позволяют указать в строке подключения несколько хостов. Драйвер сам будет пытаться подключиться к доступному master.
// Пример строки подключения для PostgreSQL // Драйвер попробует подключиться к host1, а в случае неудачи — к host2 connStr := "host=host1,host2 port=5432 user=user dbname=db sslmode=disable target_session_attrs=read-write" db, err := sql.Open("postgres", connStr)
Важный аспект: При асинхронной репликации возможна потеря транзакций, которые были успешно выполнены на старом master, но не успели реплицироваться на новый.