• Русский
  • Как создать резервную копию ClickHouse в S3 и восстановить данные

    Обзор

    В этом документе описывается, как создавать резервные копии и восстанавливать таблицы ClickHouse в базе данных observability с использованием S3-хранилища. Эта процедура применима к кластерам, использующим движок таблиц ReplicatedMergeTree.

    В этом документе приведены следующие рекомендации:

    • Создание полной резервной копии.
    • Создание инкрементальной резервной копии на основе полной.
    • Сохранение данных резервной копии в заданном пути S3.
    • Восстановление данных из резервной копии в S3.
    • Проверка результатов резервного копирования и восстановления.

    В качестве примера в документе используется таблица observability.audit. Вы можете применить ту же процедуру и к другим таблицам.

    Ниже приведены типовые таблицы:

    • audit: хранит данные аудита.
    • event: хранит данные событий.
    • log_kubernetes: хранит журналы Kubernetes.
    • log_platform: хранит журналы сервисов платформы.
    • log_system: хранит системные журналы на уровне узла.
    • log_workload: хранит журналы приложений и рабочих нагрузок.

    Предварительные условия

    Перед началом убедитесь, что выполнены следующие условия.

    Требования к окружению

    ПараметрТребование
    ClickHouseВерсия 25.3 или выше
    Table engineReplicatedMergeTree

    Требования к доступу

    Все SQL-операторы в этом документе используют встроенную учетную запись администратора ClickHouse default.

    Вы можете выполнять SQL-операторы на любом исправном экземпляре ClickHouse. Для единообразия в этом документе в качестве примера используется один Pod ClickHouse.

    Перед выполнением SQL-операторов подключитесь к целевому Pod:

    kubectl exec -ti -n cpaas-system chi-cpaas-clickhouse-replicated-0-0-0 -- bash

    Затем подключитесь к ClickHouse в контейнере:

    clickhouse-client

    Пользователь default уже имеет необходимые привилегии для этой процедуры, включая BACKUP, RESTORE, SELECT и ALTER.

    Разрешения S3

    Учетные данные S3 должны иметь следующие разрешения:

    • PutObject
    • GetObject
    • ListBucket
    • DeleteObject, если требуется удалять просроченные резервные копии

    Стратегия резервного копирования

    Используйте следующую стратегию резервного копирования:

    • Выполняйте операцию резервного копирования только один раз на любом исправном реплике.
    • Используйте BACKUP TABLE для создания согласованного снимка без остановки сервиса.
    • Используйте base_backup для дедупликации на уровне файлов в инкрементальных резервных копиях.
    • При восстановлении инкрементальной резервной копии сохраняйте доступность базовой полной резервной копии.
    • Используйте одну полную резервную копию в неделю и одну инкрементальную в день, чтобы сбалансировать сложность восстановления и стоимость хранения.

    Процедура

    В следующих примерах используется исходная полная резервная копия и ежедневная инкрементальная резервная копия.

    Создание полной резервной копии

    Полная резервная копия создает базовую точку для последующих инкрементальных резервных копий.

    Выполните следующую команду на любом исправном экземпляре ClickHouse:

    BACKUP TABLE observability.audit
    TO S3(
      'http://<s3_endpoint>/<bucket>/clickhouse-backup/audit/full_20260423',
      '<access_key_id>',
      '<secret_access_key>'
    )
    SETTINGS compression_method = 'zstd';

    Замените переменные следующим образом:

    ПараметрОписание
    <s3_endpoint>Адрес конечной точки S3
    <bucket>Имя S3 bucket
    <access_key_id>Идентификатор ключа доступа для аутентификации в S3
    <secret_access_key>Секретный ключ доступа для аутентификации в S3

    Примечания:

    • S3(...) записывает резервную копию в указанный путь объектного хранилища.
    • compression_method = 'zstd' сжимает содержимое резервной копии с помощью zstd, уменьшая использование хранилища и объем сетевой передачи.

    Проверка успешного создания резервной копии

    После завершения резервного копирования проверьте результат.

    Проверка статуса задачи резервного копирования

    Выполните следующий запрос на экземпляре ClickHouse, где была выполнена команда резервного копирования:

    SELECT
        id,
        name,
        status,
        error,
        start_time,
        end_time,
        num_files,
        total_size
    FROM system.backups
    ORDER BY start_time DESC
    LIMIT 10
    FORMAT Vertical;

    Ожидаемый результат:

    Найдите запись резервного копирования для observability.audit по полю name. Резервное копирование успешно, если выполнены следующие условия:

    • status = 'BACKUP_CREATED'
    • error пуст
    • end_time имеет значение
    • num_files > 0
    • total_size > 0

    Проверка пути в S3

    Выполните следующую команду в окружении, которое имеет доступ к целевому bucket S3:

    mc ls <s3_alias>/<bucket>/clickhouse-backup/audit/

    Замените переменные следующим образом:

    ПараметрОписание
    <s3_alias>Псевдоним, настроенный в S3-клиенте
    <bucket>Имя S3 bucket

    Ожидаемый результат:

    • Целевой путь существует.
    • Путь содержит файлы, созданные этой резервной копией.
    • Количество файлов и общий размер больше 0.

    Создание инкрементальной резервной копии

    Инкрементальная резервная копия использует base_backup и передает только новые или измененные файлы данных.

    Выполните следующую команду на любом исправном экземпляре ClickHouse:

    BACKUP TABLE observability.audit
    TO S3(
      'http://<s3_endpoint>/<bucket>/clickhouse-backup/audit/incr_20260424',
      '<access_key_id>',
      '<secret_access_key>'
    )
    SETTINGS
      base_backup = S3(
        'http://<s3_endpoint>/<bucket>/clickhouse-backup/audit/full_20260423',
        '<access_key_id>',
        '<secret_access_key>'
      ),
      compression_method = 'zstd';

    Примечания:

    • Инкрементальная резервная копия зависит от резервной копии, указанной в base_backup.
    • В этом документе рекомендуется, чтобы каждая ежедневная инкрементальная резервная копия использовала последнюю полную резервную копию в качестве base_backup, а не предыдущую инкрементальную копию в качестве базы. Это упрощает зависимость при восстановлении: для восстановления ежедневной инкрементальной копии требуется только сама инкрементальная копия и соответствующая полная копия.
    • Сохраняйте зависимую полную резервную копию при восстановлении инкрементальной.
    • Периодически создавайте новую полную резервную копию, чтобы не опираться на одну и ту же базовую точку слишком долго.

    Восстановление

    Используйте эту процедуру, если данные таблицы повреждены, каталог данных удален или состояние таблицы является ненормальным.

    Предварительные условия для восстановления

    Перед началом процедуры восстановления убедитесь, что выполнены следующие условия:

    • У вас есть действительная полная или инкрементальная резервная копия.
    • Если вы восстанавливаете из инкрементальной резервной копии, соответствующая полная резервная копия по-прежнему доступна.
    • Вы подтвердили S3 endpoint, bucket, путь к резервной копии, access key и secret key.
    • У вас есть доступ к кластеру Kubernetes и к узлам хоста, на которых запущены экземпляры ClickHouse.

    Процедура восстановления

    Эта процедура восстанавливает данные ClickHouse по таблицам. Выберите шаги подготовки в зависимости от масштаба сбоя, а затем выполните ту же процедуру восстановления для каждой требуемой таблицы.

    Остановка записи

    Сначала остановите razor, чтобы предотвратить запись новых данных во время восстановления.

    Войдите на master-узел кластера и создайте ResourcePatch для остановки razor:

    cat <<EOF > /tmp/rp-stop-razor.yaml
    apiVersion: operator.alauda.io/v1alpha1
    kind: ResourcePatch
    metadata:
      generateName: rp-
      name: rp-stop-razor
    spec:
      jsonPatch:
      - op: replace
        path: /spec/replicas
        value: 0
      release: cpaas-system/logclickhouse
      target:
        apiVersion: apps/v1
        kind: StatefulSet
        name: razor
        namespace: cpaas-system
    EOF
    
    kubectl apply -f /tmp/rp-stop-razor.yaml

    Подготовка ClickHouse в зависимости от масштаба сбоя

    Выберите один из следующих вариантов подготовки в зависимости от масштаба сбоя. После завершения подготовки продолжите ту же процедуру восстановления по таблицам.

    Случай A: Данные таблицы повреждены, но каталог данных исправен

    Используйте этот вариант, если одна или несколько таблиц повреждены, случайно удалены или содержат ненормальные данные, а каталог данных ClickHouse и состояние Keeper по-прежнему исправны.

    В этом случае не останавливайте ClickHouse и не очищайте /cpaas/data/clickhouse/*. Сразу переходите к процедуре восстановления таблиц.

    Случай B: Поврежден каталог данных или метаданные Keeper

    Используйте этот вариант только если каталог данных ClickHouse поврежден, узел перестроен или метаданные Keeper недоступны.

    В этой конфигурации ClickHouse Keeper интегрирован с ClickHouse, и его данные также хранятся в каталоге данных ClickHouse. Поэтому очистка /cpaas/data/clickhouse/* также удаляет локальные данные ClickHouse Keeper.

    Предупреждение: Очистка каталога данных удаляет локальные данные ClickHouse на целевых узлах. Перед продолжением убедитесь, что резервная копия доступна.

    Выполняйте команду rm -rf /cpaas/data/clickhouse/* на каждом хост-узле ClickHouse, а не внутри контейнера ClickHouse.

    Войдите на master-узел кластера и создайте ResourcePatch для остановки ClickHouse:

    cat <<EOF > /tmp/rp-stop-ck.yaml
    apiVersion: operator.alauda.io/v1alpha1
    kind: ResourcePatch
    metadata:
      generateName: rp-
      name: rp-stop-ck
    spec:
      jsonPatch:
      - op: add
        path: /spec/stop
        value: "true"
      release: cpaas-system/logclickhouse
      target:
        apiVersion: clickhouse.altinity.com/v1
        kind: ClickHouseInstallation
        name: cpaas-clickhouse
        namespace: cpaas-system
    EOF
    
    kubectl apply -f /tmp/rp-stop-ck.yaml

    Убедитесь, что все Pods ClickHouse остановлены:

    kubectl get pod -n cpaas-system | grep -i "chi-cpaas-clickhouse-replicated"

    На каждом хост-узле, где развернут экземпляр ClickHouse, очистите локальный каталог данных ClickHouse:

    rm -rf /cpaas/data/clickhouse/*

    Запустите только компоненты ClickHouse, удалив ResourcePatch ClickHouse. Пока не запускайте razor.

    kubectl delete -f /tmp/rp-stop-ck.yaml

    Убедитесь, что все Pods ClickHouse запущены:

    kubectl get pod -n cpaas-system | grep -i "chi-cpaas-clickhouse-replicated"

    Проверка готовности кластера

    Перед выполнением команды восстановления убедитесь, что конфигурация кластера ClickHouse и макросы доступны.

    Проверьте конфигурацию кластера replicated:

    SELECT *
    FROM system.clusters
    WHERE cluster = 'replicated';

    Проверьте локальные макросы ClickHouse:

    SELECT *
    FROM system.macros;

    Убедитесь, что кластер содержит ожидаемые реплики ClickHouse, а также доступны макросы, такие как shard и replica.

    Восстановление таблиц по одной

    Выполните следующую процедуру восстановления для каждой таблицы, которую необходимо восстановить.

    Удалите целевую таблицу в кластере ClickHouse:

    DROP TABLE observability.audit ON CLUSTER 'replicated' SYNC;

    Восстановите таблицу из S3:

    RESTORE TABLE observability.audit
    ON CLUSTER 'replicated'
    FROM S3(
      'http://<S3_ENDPOINT>/<bucket>/clickhouse-backup/audit/incr_20260424',
      '<access_key_id>',
      '<secret_access_key>'
    );

    Примечания:

    • Для таблицы ReplicatedMergeTree в этой развернутой конфигурации с 3 репликами используйте ON CLUSTER 'replicated', чтобы операция восстановления была распределена по всем репликам ClickHouse в кластере.
    • При восстановлении из инкрементальной резервной копии ClickHouse автоматически читает зависимую базовую резервную копию.
    • Сохраняйте доступность соответствующего пути полной резервной копии во время восстановления.
    • Замените observability.audit и путь S3 на фактические таблицу и путь резервной копии, которые требуется восстановить.
    • Повторите ту же процедуру для каждой таблицы, которую необходимо восстановить. Список таблиц определяется заказчиком.

    Проверка статуса задачи восстановления

    После выполнения каждой команды восстановления проверьте статус задачи восстановления, прежде чем запускать какие-либо связанные компоненты:

    SELECT
        id,
        name,
        status,
        error,
        start_time,
        end_time,
        num_files,
        total_size
    FROM system.backups
    ORDER BY start_time DESC
    LIMIT 10
    FORMAT Vertical;

    Ожидаемый результат:

    Восстановление успешно, если выполнены следующие условия:

    • status показывает, что операция восстановления успешно завершена.
    • error пуст.
    • end_time имеет значение.

    Проверка успешности восстановления

    После завершения восстановления проверьте результат с точки зрения данных, разделов и реплик.

    Проверка общего количества строк

    Выполните следующий запрос на каждом экземпляре ClickHouse:

    SELECT count(*) AS total_rows
    FROM observability.audit;

    Ожидаемый результат:

    Значение total_rows одинаково на всех экземплярах ClickHouse.

    Проверка данных на уровне разделов

    Выполните следующий запрос на каждом экземпляре ClickHouse:

    SELECT
        partition,
        sum(rows) AS rows,
        count() AS active_parts
    FROM system.parts
    WHERE active
      AND database = 'observability'
      AND table = 'audit'
    GROUP BY partition
    ORDER BY partition;

    Ожидаемый результат:

    • Список partition одинаков на всех экземплярах ClickHouse.
    • Значение rows для каждого раздела одинаково на всех экземплярах ClickHouse.

    active_parts используется только для наблюдения за физическим расположением частей. Разное количество частей не обязательно означает сбой восстановления.

    Проверка состояния реплик

    Выполните следующий запрос на любом экземпляре ClickHouse:

    SELECT
        database,
        table,
        total_replicas,
        active_replicas,
        queue_size,
        absolute_delay
    FROM system.replicas
    WHERE database = 'observability'
      AND table = 'audit';

    Ожидаемый результат:

    Для кластера с 3 репликами восстановление успешно, если выполнены следующие условия:

    • total_replicas = 3
    • active_replicas = 3
    • queue_size = 0
    • absolute_delay близко к 0

    Запуск связанных компонентов

    После успешной проверки восстановления снова запустите razor, удалив ResourcePatch:

    kubectl delete -f /tmp/rp-stop-razor.yaml

    Рекомендации

    Для production используйте следующие рекомендации:

    • Поддерживайте цепочку резервного копирования: одна полная копия в неделю и одна инкрементальная в день.
    • Используйте единообразную схему именования каталогов резервных копий S3, например full_YYYYMMDD и incr_YYYYMMDD.
    • Регулярно выполняйте тестовые восстановления в тестовом окружении.