Настройка пункта назначения резервной копии для локального диска
В примерах ниже пункт назначения резервной копии задается как Disk('backups', '1.zip').
Чтобы использовать движок резервного копирования Disk, сначала добавьте файл, который задает
пункт назначения резервной копии по указанному ниже пути:
/etc/clickhouse-server/config.d/backup_disk.xml
Например, в приведённой ниже конфигурации задаётся диск с именем backups, а затем этот диск добавляется в
список allowed_disk раздела backups:
Настройка пункта назначения резервной копии для S3-диска
Также можно выполнять BACKUP/RESTORE в S3, настроив S3-диск в
конфигурации хранилища ClickHouse. Настройте диск следующим образом, добавив файл в
/etc/clickhouse-server/config.d, как это было сделано выше для локального диска.
BACKUP/RESTORE для S3-диска выполняется так же, как для локального диска:
BACKUP TABLE data TO Disk('s3_plain', 'cloud_backup');RESTORE TABLE data AS data_restored FROM Disk('s3_plain', 'cloud_backup');
Этот диск не следует использовать для самого MergeTree, только для BACKUP/RESTORE
Если ваши таблицы используют хранилище S3, а типы дисков различаются,
для копирования частей в бакет назначения вызовы CopyObject не используются; вместо этого
части скачиваются и загружаются заново, что очень неэффективно. В этом случае лучше использовать
синтаксис BACKUP ... TO S3(<endpoint>).
Выполните следующие команды, чтобы создать тестовую базу данных и таблицу, резервную копию и восстановление которых мы будем рассматривать в этом примере:
Команды настройки
Создайте базу данных и таблицу:
CREATE DATABASE test_db;CREATE TABLE test_db.test_table ( id UUID, name String, email String, age UInt8, salary UInt32, created_at DateTime, is_active UInt8, department String, score Float32, country String) ENGINE = MergeTree()ORDER BY id;
Подготовьте и вставьте тысячу строк случайных данных:
INSERT INTO test_table (id, name, email, age, salary, created_at, is_active, department, score, country)SELECT generateUUIDv4() as id, concat('User_', toString(rand() % 10000)) as name, concat('user', toString(rand() % 10000), '@example.com') as email, 18 + (rand() % 65) as age, 30000 + (rand() % 100000) as salary, now() - toIntervalSecond(rand() % 31536000) as created_at, rand() % 2 as is_active, arrayElement(['Engineering', 'Marketing', 'Sales', 'HR', 'Finance', 'Operations'], (rand() % 6) + 1) as department, rand() / 4294967295.0 * 100 as score, arrayElement(['USA', 'UK', 'Germany', 'France', 'Canada', 'Australia', 'Japan', 'Brazil'], (rand() % 8) + 1) as countryFROM numbers(1000);
Далее вам нужно создать файл, указав в нем пункт назначения резервной копии по
пути ниже:
Указанная выше команда RESTORE завершится ошибкой, если таблица test.table содержит данные.
Параметр allow_non_empty_tables=true позволяет RESTORE TABLE выполнять вставку данных
в непустые таблицы. Это приведет к смешиванию уже имеющихся в таблице данных с данными, извлеченными из резервной копии.
Поэтому этот параметр может вызвать дублирование данных в таблице и должен использоваться с осторожностью.
Чтобы восстановить таблицу, в которой уже есть данные, выполните:
RESTORE TABLE test_db.test_table FROM Disk('backups', '1.zip')SETTINGS allow_non_empty_tables=true
Таблицы можно восстановить или сохранить в резервную копию под новыми именами:
RESTORE TABLE test_db.test_table AS test_db.test_table_renamed FROM Disk('backups', '1.zip')
Архив этой резервной копии имеет следующую структуру:
Базовая резервная копия в ClickHouse — это исходная полная резервная копия, на основе которой создаются последующие
инкрементные резервные копии. Инкрементные резервные копии хранят только изменения,
внесённые после создания базовой резервной копии, поэтому базовая резервная копия должна оставаться доступной, чтобы
можно было восстановиться из любой инкрементной резервной копии. Пункт назначения базовой резервной копии можно задать с помощью параметра
base_backup.
Инкрементные резервные копии зависят от базовой резервной копии. Базовая резервная копия должна оставаться доступной,
чтобы можно было восстановиться из инкрементной резервной копии.
Чтобы создать инкрементную резервную копию таблицы, сначала создайте базовую резервную копию:
BACKUP TABLE test_db.test_table TO Disk('backups', 'd.zip')
BACKUP TABLE test_db.test_table TO Disk('backups', 'incremental-a.zip')SETTINGS base_backup = Disk('backups', 'd.zip')
Все данные из инкрементной и базовой резервных копий можно восстановить в
новую таблицу test_db.test_table2 командой:
RESTORE TABLE test_db.test_table AS test_db.test_table2FROM Disk('backups', 'incremental-a.zip');
Для резервной копии, записанной на диск, можно задать пароль.
Пароль можно указать с помощью настройки password.
Защита паролем поддерживается только для ZIP-архивов (.zip, .zipx).
Чтобы пароль был принят, путь к резервной копии должен оканчиваться на .zip или .zipx.
Использование пароля с любым другим форматом — включая tar-архивы и пути, не указывающие на архив, —
приведет к ошибке BAD_ARGUMENTS: Password is not applicable, backup cannot be encrypted.
Резервные копии можно хранить не только в zip-архивах, но и в tar-архивах.
Функциональность такая же, как у zip, за исключением того, что защита паролем
для tar-архивов не поддерживается. Кроме того, tar-архивы поддерживают различные
методы сжатия.Чтобы создать резервную копию таблицы в виде tar:
BACKUP TABLE test_db.test_table TO Disk('backups', '1.tar')
для восстановления из tar-архива:
RESTORE TABLE test_db.test_table FROM Disk('backups', '1.tar')
Чтобы изменить метод сжатия, к имени резервной копии следует добавить
соответствующий суффикс файла. Например, чтобы сжать tar-архив с помощью gzip, выполните:
BACKUP TABLE test_db.test_table TO Disk('backups', '1.tar.gz')
Если нужно восстановить определённые партиции таблицы, их можно явно указать.Давайте создадим простую таблицу, разбитую на четыре партиции, вставим в неё данные, а затем
создадим резервную копию только первой и четвёртой партиций:
Подготовка
CREATE IF NOT EXISTS test_db;-- Создаём таблицу с партиционированиемCREATE TABLE test_db.partitioned ( id UInt32, data String, partition_key UInt8) ENGINE = MergeTree()PARTITION BY partition_keyORDER BY id;INSERT INTO test_db.partitioned VALUES(1, 'data1', 1),(2, 'data2', 2),(3, 'data3', 3),(4, 'data4', 4);SELECT count() FROM test_db.partitioned;SELECT partition_key, count() FROM test_db.partitionedGROUP BY partition_keyORDER BY partition_key;