Репликация — это не бэкап. Она защищает от отказа узла, но не от DROP TABLE, кривой миграции или испорченных данных: ошибка честно и быстро размножится по всем репликам.
Что вообще нужно сохранять
Полный набор для восстановления состоит из трёх частей, и про две последние регулярно забывают:
- Данные таблиц — куски
MergeTree. - DDL и конфигурация — схема таблиц, пользователи, настройки, словари. Лучший способ — держать всё это в git как код и раскатывать оператором; тогда «восстановление схемы» =
kubectl apply. - Метаданные координации. Keeper хранит состояние репликации. При катастрофе восстанавливать его как есть обычно не нужно, но нужно понимать: восстановленные из бэкапа таблицы придётся заново «прописать» в репликации.
Как это устроено технически
ClickHouse удобен для бэкапов благодаря иммутабельности кусков. Команда ALTER TABLE ... FREEZE создаёт жёсткие ссылки на текущие куски в служебном каталоге shadow/. Это:
- мгновенно (ссылки, а не копирование);
- не занимает дополнительного места в момент создания;
- даёт консистентный снимок, который можно спокойно выгружать наружу.
Восстановление — обратная операция: файлы кладутся в detached/, затем ALTER TABLE ... ATTACH PARTITION подключает их к таблице.
Два инструмента
Встроенные BACKUP / RESTORE
В современных версиях есть SQL-команды, умеющие писать в том числе прямо в S3:
BACKUP TABLE analytics.events
TO S3('https://s3.example.com/backups/events-2026-08-15', 'access_key', 'secret');
RESTORE TABLE analytics.events
FROM S3('https://s3.example.com/backups/events-2026-08-15', 'access_key', 'secret');Плюсы: ничего не нужно ставить, работает из коробки, понятный SQL-интерфейс. Подходит, когда логика бэкапа простая.
clickhouse-backup
Altinity/clickhouse-backup
— специализированная утилита, ставшая стандартом для самостоятельных инсталляций. Она использует тот же FREEZE с жёсткими ссылками, но добавляет то, чего не хватает:
- инкрементальные бэкапы на удалённом хранилище;
- поддержка S3, GCS, Azure Blob, COS, FTP/SFTP, а также rclone/restic/kopia;
- работа с несколькими дисками и объектными дисками (включая копирование на стороне сервера);
- совместимость с
AtomicиReplicatedдвижками БД; - параллельная загрузка/выгрузка.
Базовый цикл команд:
clickhouse-backup create my-backup # локальный снимок (FREEZE)
clickhouse-backup upload my-backup # выгрузка в удалённое хранилище
clickhouse-backup list # что есть локально и удалённо
clickhouse-backup restore my-backup # восстановление из локального
clickhouse-backup restore_remote my-backup # скачать и восстановить
clickhouse-backup delete local my-backup # прибратьсяВ Kubernetes её обычно запускают sidecar-контейнером в поде ClickHouse (нужен доступ к тому с данными) и дёргают по расписанию через CronJob, который ходит в её REST API или выполняет команду через kubectl exec.
Схема бэкапов, которая работает
Практичный набор для продового кластера:
- Полный бэкап — раз в неделю; инкрементальный — ежедневно.
- Только с одной реплики каждого шарда — данные идентичны, копировать всё бессмысленно и дорого. Выберите реплику по стабильному признаку и учтите смену ролей.
- Хранилище — вне кластера. Объектное хранилище в другом регионе/аккаунте. Бэкап на том же диске не спасает от отказа диска, а в том же аккаунте — от компрометации.
- Immutable/versioned бакет с политикой блокировки удаления — защита от «удалили всё, включая бэкапы».
- Ретеншен — политика жизненного цикла бакета, чтобы старые копии удалялись сами.
- Мониторинг результата. Провалившийся ночной бэкап должен создавать алерт, а не тишину.
Дополнительный дешёвый уровень защиты — DROP PARTITION вместо DROP TABLE и включённая «корзина»: настройка database_atomic_delay_before_drop_table_sec даёт окно, в течение которого удалённую таблицу можно вернуть.
Восстановление: то, ради чего всё затевалось
Ключевая мысль, которую стоит повторять: бэкап, который ни разу не восстанавливали, — это не бэкап, а надежда.
Что обязательно проверить на регулярных учениях:
- Время восстановления. Замерьте фактическое RTO на реальном объёме. Терабайты из объектного хранилища едут часами — если бизнес ждёт 30 минут, узнать об этом лучше заранее.
- Полнота. Восстанавливается ли не только таблица, но и пользователи, права, словари, настройки.
- Репликация после восстановления. Реплицируемые таблицы после
RESTOREнужно корректно вернуть в строй: обычно данные восстанавливают на одну реплику, а остальные синхронизируются с неё — и это тоже время. - Процедура записана. Не в голове дежурного, а в runbook: команды, порядок, куда смотреть.
Хороший ритм — раз в квартал восстанавливать прод-бэкап в отдельный namespace, гонять по нему проверочные запросы и фиксировать время. Это же даёт тестовое окружение с реальными данными.
Частые ошибки
- Считать репликацию бэкапом.
DROP TABLEреплицируется мгновенно. - Бэкапить все реплики — тратить время и деньги на копии одного и того же.
- Хранить бэкапы рядом с кластером — в том же аккаунте, регионе, а то и на том же диске.
- Не бэкапить схему и пользователей — данные есть, а поднять сервис нельзя.
- Не мониторить успешность — обнаружить сломанный пайплайн в момент аварии.
- Не мерить RTO — обещать бизнесу минуты, имея часы.
Дальше: Часть 10. Безопасность и эксплуатация: доступы, обновления, анти-паттерны.