Перейти к основному содержанию
Резервное копирование снимков — это облегчённый режим резервного копирования для cloud-native движков таблиц. Вместо копирования данных он записывает в ClickHouse Keeper узлы блокировки для каждой части. Эти блокировки не позволяют серверу удалять части в объектном хранилище, на которые ссылается снимок, пока этот снимок хранится. Затем резервная копия сохраняет ссылки на объекты в хранилище вместо физического копирования данных, поэтому снимок создаётся быстро независимо от размера таблицы. Облегчённый режим применяется к таблицам SharedMergeTree, SharedSet и SharedJoin. Для всех остальных типов движков — например, Log или Memory — резервное копирование автоматически возвращается к стандартному режиму с копированием данных.

Создание снимка

Для резервного копирования снимков используется стандартная команда BACKUP с параметром experimental_lightweight_snapshot = true. Параметр id обязателен — он задаёт имя снимка и используется для обращения к нему в командах разблокировки и обсервабилити:
BACKUP { TABLE [db.]table_name | DATABASE db_name | ALL [EXCEPT {TABLES | DATABASES} ...] }
TO { S3(...) | AzureBlobStorage(...) }
SETTINGS experimental_lightweight_snapshot = true, id = '<snapshot_id>'
Команда возвращает id и status, а id можно использовать для отслеживания операции в system.backups. Создайте резервную копию отдельной таблицы в S3:
BACKUP TABLE mydb.events
TO S3('https://my-bucket.s3.us-east-1.amazonaws.com/snapshots/events/', 'ACCESS_KEY_ID', 'SECRET_ACCESS_KEY')
SETTINGS experimental_lightweight_snapshot = true, id = 'events_snapshot_1'
Создайте резервную копию всей базы данных:
BACKUP DATABASE mydb
TO S3('https://my-bucket.s3.us-east-1.amazonaws.com/snapshots/mydb/', 'ACCESS_KEY_ID', 'SECRET_ACCESS_KEY')
SETTINGS experimental_lightweight_snapshot = true, id = 'mydb_snapshot_1'
Создайте резервную копию всех таблиц, кроме одной:
BACKUP ALL
EXCEPT TABLES mydb.staging_table
TO S3('https://my-bucket.s3.us-east-1.amazonaws.com/snapshots/full/', 'ACCESS_KEY_ID', 'SECRET_ACCESS_KEY')
SETTINGS experimental_lightweight_snapshot = true, id = 'full_snapshot_1'
Те же команды подходят и для Azure Blob Storage:
BACKUP TABLE mydb.events
TO AzureBlobStorage('DefaultEndpointsProtocol=https;AccountName=myaccount;AccountKey=...', 'my-container', 'snapshots/events/')
SETTINGS experimental_lightweight_snapshot = true, id = 'events_snapshot_1'

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

Поскольку снимок хранит ссылки на файлы в Объектном хранилище, а не копии данных, для восстановления в новый или другой сервис ClickHouse нужен доступ к исходному Объектному хранилищу. Поэтому межсервисное восстановление через SQL не поддерживается — оно доступно только через интерфейс. Через SQL можно восстановить снимок в тот же сервис из бакета с внешней резервной копией, используя snapshot_from_current_service = 1. В этом случае объекты считываются напрямую через диск пункта назначения, а не через механизм чтения удалённого снимка:
RESTORE TABLE mydb.events AS mydb.events_restored
FROM S3('https://my-bucket.s3.us-east-1.amazonaws.com/snapshots/events/', 'ACCESS_KEY_ID', 'SECRET_ACCESS_KEY')
SETTINGS snapshot_from_current_service = 1
Предложение AS выполняет восстановление в таблицу с новым именем, сохраняя исходную таблицу. Чтобы перезаписать исходную таблицу, сначала удалите её:
DROP TABLE mydb.events;

RESTORE TABLE mydb.events
FROM S3('https://my-bucket.s3.us-east-1.amazonaws.com/snapshots/events/', 'ACCESS_KEY_ID', 'SECRET_ACCESS_KEY')
SETTINGS snapshot_from_current_service = 1

Разблокировка снимка

Каждый снимок удерживает блокировки в ClickHouse Keeper, из-за которых файлы объектного хранилища, на которые он ссылается, не удаляются сборщиком мусора. После завершения восстановления — или когда снимок больше не нужен — разблокируйте его, чтобы снять эти блокировки. Есть два варианта: разблокировка на уровне системы, которая сразу снимает все блокировки снимка, и разблокировка на уровне отдельной таблицы, которая снимает блокировку только для одной таблицы, оставляя остальную часть снимка без изменений. Разблокировка на уровне системы — снимает все блокировки снимка:
SYSTEM UNLOCK SNAPSHOT '<snapshot_id>'
FROM S3('https://my-bucket.s3.us-east-1.amazonaws.com/snapshots/events/', 'ACCESS_KEY_ID', 'SECRET_ACCESS_KEY')
Разблокировка для отдельной таблицы — снимает блокировку только для одной таблицы:
ALTER TABLE mydb.events UNLOCK SNAPSHOT '<snapshot_id>'
FROM S3('https://my-bucket.s3.us-east-1.amazonaws.com/snapshots/events/', 'ACCESS_KEY_ID', 'SECRET_ACCESS_KEY')
Предложение FROM необязательно, если пункт назначения снимка был сохранён в Keeper при создании (это видно в столбце info таблицы system.snapshot_locks):
SYSTEM UNLOCK SNAPSHOT '<snapshot_id>'

-- или для конкретной таблицы:
ALTER TABLE mydb.events UNLOCK SNAPSHOT '<snapshot_id>'
После разблокировки соответствующая строка исчезает из system.snapshot_locks, а части, на которые больше не ссылаются другие снимки, пропадают из system.snapshot_parts.

Обсервабилити

system.backups

Все операции со снимками появляются в system.backups наряду с обычными операциями резервного копирования и восстановления. Выполните запрос к этой таблице по заданному id (или по UUID, возвращённому командой):
SELECT id, name, status, error, start_time, end_time, num_files, uncompressed_size, compressed_size
FROM system.backups
WHERE id = 'events_snapshot_1'
FORMAT Vertical
Row 1:
──────
id:                events_snapshot_1
name:              S3('https://my-bucket.s3.us-east-1.amazonaws.com/snapshots/events/', '[HIDDEN]')
status:            BACKUP_CREATED
error:
start_time:        2024-06-01 10:00:00
end_time:          2024-06-01 10:00:03
num_files:         42
uncompressed_size: 1073741824
compressed_size:   0

system.snapshot_locks

system.snapshot_locks показывает зафиксированные снимки, которые в данный момент зарегистрированы в Keeper. Когда снимок фиксируется, в Keeper создаётся узел по пути /clickhouse/snapshot/committed/{snapshot_id}. Перед удалением любой части данных сервер проверяет, не удерживает ли какой-либо зафиксированный снимок блокировку на эту часть. Если удерживает, удаление не выполняется. Блокировка сохраняется, пока вы явно не разблокируете снимок.
SELECT *
FROM system.snapshot_locks
СтолбецТипОписание
idStringИдентификатор снимка
infoStringПункт назначения снимка, например S3('...')
ctimeDateTimeВремя создания этой блокировки в Keeper
lock_pathStringПуть в Keeper для этой блокировки
Каждая строка соответствует одному зафиксированному снимку. Если вы видите блокировки для снимков, у которых больше нет действительного пункта назначения резервной копии, выполните SYSTEM UNLOCK SNAPSHOT, чтобы удалить их. Чтобы проверить, существует ли блокировка для конкретного снимка:
SELECT id, info, lock_path
FROM system.snapshot_locks
WHERE id = 'events_snapshot_1'

system.snapshot_parts

system.snapshot_parts показывает части данных, которые в данный момент закреплены как минимум одной блокировкой снимка. Для каждой заблокированной части в Keeper существует узел по пути /clickhouse/snapshot/{table_uuid}/{part_name}, содержащий размер части в сжатом и несжатом виде. Эта таблица читает эти узлы, чтобы показать, какие части в настоящее время защищены от удаления.
SELECT *
FROM system.snapshot_parts
ORDER BY data_compressed_bytes DESC
LIMIT 20
СтолбецТипОписание
nameStringИмя части данных
table_idStringUUID таблицы, которой принадлежит эта часть
data_compressed_bytesUInt64Размер этой части в сжатом виде
data_uncompressed_bytesUInt64Размер этой части в несжатом виде
snapshots_sizeUInt64Количество снимков, которые в данный момент удерживают блокировку этой части
На части с snapshots_size > 1 ссылаются несколько снимков, и они не будут удалены из Объектного хранилища, пока не будут разблокированы все удерживающие их снимки. Чтобы проверить общий объём закреплённого хранилища:
SELECT
    formatReadableSize(sum(data_compressed_bytes)) AS total_pinned_compressed,
    formatReadableSize(sum(data_uncompressed_bytes)) AS total_pinned_uncompressed,
    count() AS parts_count
FROM system.snapshot_parts
Чтобы найти части, заблокированные снимком, но уже удалённые или больше не являющиеся активными на сервере — то есть данные, которые сохраняются в Объектном хранилище исключительно из-за блокировок снимка:
SELECT
    count(*),
    sum(data_uncompressed_bytes)
FROM system.snapshot_parts
WHERE (name, table_id) NOT IN (
    SELECT
        name,
        toString(tables.uuid)
    FROM system.parts
    INNER JOIN system.tables ON (parts.`table` = tables.name) AND parts.active
)
┌─count()─┬─sum(data_uncompressed_bytes)─┐
│    1000 │                        96037 │
└─────────┴──────────────────────────────┘
Это полезно для оценки дополнительных затрат на хранение снимков после изменения или удаления исходных данных.

Настройки сервера

Следующие параметры конфигурации сервера управляют поведением снимков. Они задаются в файле конфигурации сервера, а не в SQL.
НастройкаТипПо умолчаниюМожно изменить без перезапускаОписание
max_held_snapshotsUInt640НетМаксимальное количество облегчённых снимков, которые можно одновременно хранить. 0 означает без ограничений. Если предел достигнут, при создании нового снимка будет сгенерировано исключение.
max_snapshot_commit_thread_pool_sizeUInt6464ДаКоличество потоков, используемых для фиксации узлов блокировки снимков в Keeper. Увеличьте это значение, если на больших таблицах с большим количеством частей снимки создаются медленно.
max_snapshot_commit_thread_pool_free_sizeUInt640ДаЕсли число бездействующих потоков в пуле фиксации снимков превышает это значение, ClickHouse освобождает их и сокращает пул. При необходимости потоки создаются снова. 0 означает, что бездействующие потоки никогда не освобождаются.
snapshot_cleaner_periodUInt64120НетКак часто (в секундах) запускается очистка снимков, чтобы удалять части, на которые больше не ссылается ни одна блокировка снимка. Только в ClickHouse Cloud.
snapshot_cleaner_pool_sizeUInt64128НетКоличество потоков в пуле очистки снимков. Только в ClickHouse Cloud.
Последнее изменение 10 июня 2026 г.