Перейти к основному содержанию
Перейти к основному содержанию

Резервное копирование и восстановление на локальный диск

Синтаксис

-- основные команды
BACKUP | RESTORE [ASYNC]
--- что включить в резервную копию/восстановление (или исключить)
TABLE [db.]table_name           [AS [db.]table_name_in_backup] |
DICTIONARY [db.]dictionary_name [AS [db.]name_in_backup] |
DATABASE database_name          [AS database_name_in_backup] |
TEMPORARY TABLE table_name      [AS table_name_in_backup] |
VIEW view_name                  [AS view_name_in_backup] |
[EXCEPT TABLES ...] |
ALL [EXCEPT {TABLES|DATABASES}...] } [,...]
--- 
[ON CLUSTER 'cluster_name']
--- куда сохранять резервную копию или откуда выполнять восстановление
TO|FROM 
File('<path>/<filename>') | 
Disk('<disk_name>', '<path>/') | 
S3('<S3 endpoint>/<path>', '<Access key ID>', '<Secret access key>', '<extra_credentials>') |
AzureBlobStorage('<connection string>/<url>', '<container>', '<path>', '<account name>', '<account key>')
--- дополнительные настройки
[SETTINGS ...]

Дополнительные сведения о каждой команде см. в разделе "краткий обзор команд".

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

Настройка пути назначения резервного копирования для локального диска

В приведённых ниже примерах вы увидите, что путь назначения резервного копирования указан как Disk('backups', '1.zip').
Чтобы использовать движок резервного копирования Disk, необходимо сначала создать файл, задающий путь назначения резервного копирования, по следующему пути:

/etc/clickhouse-server/config.d/backup_disk.xml

Например, в приведённой ниже конфигурации определяется диск с именем backups, после чего этот диск добавляется в список allowed_disk политики backups:

<clickhouse>
    <storage_configuration>
        <disks>
<!--highlight-next-line -->
            <backups>
                <type>local</type>
                <path>/backups/</path>
            </backups>
        </disks>
    </storage_configuration>
<!--highlight-start -->
    <backups>
        <allowed_disk>backups</allowed_disk>
        <allowed_path>/backups/</allowed_path>
    </backups>
<!--highlight-end -->
</clickhouse>

Настройка назначения резервного копирования для диска S3

Также можно выполнять операции BACKUP/RESTORE в S3, настроив диск S3 в настройках хранилища ClickHouse. Настройте диск следующим образом, добавив файл в /etc/clickhouse-server/config.d, как это было сделано выше для локального диска.

<clickhouse>
    <storage_configuration>
        <disks>
            <s3_plain>
                <type>s3_plain</type>
                <endpoint></endpoint>
                <access_key_id></access_key_id>
                <secret_access_key></secret_access_key>
            </s3_plain>
        </disks>
        <policies>
            <s3>
                <volumes>
                    <main>
                        <disk>s3_plain</disk>
                    </main>
                </volumes>
            </s3>
        </policies>
    </storage_configuration>

    <backups>
        <allowed_disk>s3_plain</allowed_disk>
    </backups>
</clickhouse>

Операции 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 country
FROM numbers(1000);

Далее вам нужно создать файл, указывающий место назначения резервной копии по следующему пути:

/etc/clickhouse-server/config.d/backup_disk.xml
<clickhouse>
    <storage_configuration>
        <disks>
            <backups>
                <type>local</type>
                <path>/backups/</path> -- для MacOS выберите: /Users/backups/
            </backups>
        </disks>
    </storage_configuration>
    <backups>
        <allowed_disk>backups</allowed_disk>
        <allowed_path>/backups/</allowed_path> -- для MacOS выберите: /Users/backups/
    </backups>
</clickhouse>
Примечание

Если clickhouse-server запущен, вам нужно будет перезапустить его, чтобы изменения вступили в силу.

Чтобы создать резервную копию таблицы, выполните:

BACKUP TABLE test_db.test_table TO Disk('backups', '1.zip')
   ┌─id───────────────────────────────────┬─status─────────┐
1. │ 065a8baf-9db7-4393-9c3f-ba04d1e76bcd │ BACKUP_CREATED │
   └──────────────────────────────────────┴────────────────┘

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

RESTORE TABLE test_db.test_table FROM Disk('backups', '1.zip')
   ┌─id───────────────────────────────────┬─status───┐
1. │ f29c753f-a7f2-4118-898e-0e4600cd2797 │ RESTORED │
   └──────────────────────────────────────┴──────────┘
Примечание

Выполнение приведённой выше команды RESTORE завершится ошибкой, если таблица test.table уже содержит данные. Настройка allow_non_empty_tables=true позволяет команде RESTORE TABLE вставлять данные в непустые таблицы. В этом случае прежние данные в таблице будут смешаны с данными, извлечёнными из резервной копии. Поэтому эта настройка может привести к дублированию данных в таблице и должна использоваться с осторожностью.

Чтобы восстановить таблицу, уже содержащую данные, выполните:

RESTORE TABLE test_db.table_table FROM Disk('backups', '1.zip')
SETTINGS allow_non_empty_tables=true

Таблицы можно восстанавливать или создавать их резервные копии под новыми именами:

RESTORE TABLE test_db.table_table AS test_db.test_table_renamed FROM Disk('backups', '1.zip')

Архив этой резервной копии имеет следующую структуру:

├── .backup
└── metadata
    └── test_db
        └── test_table.sql

Могут использоваться и другие форматы, помимо zip. См. раздел "Резервные копии в виде tar-архивов" ниже для получения дополнительной информации.

Инкрементные резервные копии на диск

Базовая резервная копия в 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_table2
FROM Disk('backups', 'incremental-a.zip');

Защита резервной копии

К файлам резервных копий, записанным на диск, можно применить пароль. Пароль можно указать с помощью настройки password:

BACKUP TABLE test_db.test_table
TO Disk('backups', 'password-protected.zip')
SETTINGS password='qwerty'

Для восстановления резервной копии, защищённой паролем, следует повторно указать пароль в настройке password:

RESTORE TABLE test_db.test_table
FROM Disk('backups', 'password-protected.zip')
SETTINGS password='qwerty'

Резервные копии в виде tar-архивов

Резервные копии могут храниться не только в виде 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')

Поддерживаемые суффиксы файлов сжатых архивов:

  • tar.gz
  • .tgz
  • tar.bz2
  • tar.lzma
  • .tar.zst
  • .tzst
  • .tar.xz

Настройки сжатия

Метод сжатия и степень сжатия можно задать с помощью параметров compression_method и compression_level соответственно.

BACKUP TABLE test_db.test_table
TO Disk('backups', 'filename.zip')
SETTINGS compression_method='lzma', compression_level=3

Восстановление отдельных партиций

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

Создадим простую партиционированную таблицу на четыре партиции, вставим в неё данные, а затем сделаем резервную копию только первой и четвёртой партиций:

Setup
CREATE IF NOT EXISTS test_db;
       
-- Создадим партиционированную таблицу
CREATE TABLE test_db.partitioned (
    id UInt32,
    data String,
    partition_key UInt8
) ENGINE = MergeTree()
PARTITION BY partition_key
ORDER 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.partitioned
GROUP BY partition_key
ORDER BY partition_key;
   ┌─count()─┐
1. │       4 │
   └─────────┘
   ┌─partition_key─┬─count()─┐
1. │             1 │       1 │
2. │             2 │       1 │
3. │             3 │       1 │
4. │             4 │       1 │
   └───────────────┴─────────┘

Выполните следующую команду, чтобы создать резервную копию партиций 1 и 4:

BACKUP TABLE test_db.partitioned PARTITIONS '1', '4'
TO Disk('backups', 'partitioned.zip')

Выполните следующую команду, чтобы восстановить партиции 1 и 4:

RESTORE TABLE test_db.partitioned PARTITIONS '1', '4'
FROM Disk('backups', 'partitioned.zip')
SETTINGS allow_non_empty_tables=true