跳到主要内容
跳到主要内容

ClickHouse 中的备份和恢复

本节将对 ClickHouse 中的备份和恢复进行总体介绍。若需要了解各备份方法的详细说明,请参阅侧边栏中相应方法的页面。

介绍

虽然复制可以防止硬件故障,但它无法 防止人为错误:例如误删数据、删除了错误的表,或者删除了错误集群上的表,以及软件缺陷导致的数据处理不正确或数据损坏。

在很多情况下,这类错误会影响所有副本。ClickHouse 内置了一些保护机制来防止某些类型的错误,例如,在默认情 况下,你不能直接删除使用 MergeTree 系列表引擎且包含超过 50 GB 数据的表。然而,这些保护机制并不能覆盖所有可能的情况,问题仍然可能发生。

为了有效降低人为错误带来的影响,你应当在事前认真规划数据备份与恢复策略。

每家公司的可用资源和业务需求都不同,因此不存在一种通用的 ClickHouse 备份与恢复方案可以适用于所有场景。对 1 GB 数据有效的方法,很可能并不适用于数十 PB 的数据。本节文档介绍了多种可选方案及其优缺点。一个好的做法是组合使用多种方案,而不是只依赖单一方案,以此弥补各自的不足。

注意

请记住,如果你只做过备份,却从未尝试恢复,那么在真正需要恢复时,很有可能恢复过程无法正常工作(或者至少会比业务可接受的时间长得多)。因此,无论选择哪种备份方案,都务必要同时实现恢复过程的自动化,并定期在备用的 ClickHouse 集群上进行恢复演练。

以下页面详细介绍了 ClickHouse 中可用的各种备份与恢复方法:

页面说明
使用本地磁盘或 S3 磁盘进行备份/恢复详细说明使用本地磁盘或 S3 磁盘进行备份/恢复的方法
使用 S3 endpoint 进行备份/恢复详细说明使用 S3 endpoint 进行备份/恢复的方法
使用 AzureBlobStorage 进行备份/恢复详细说明使用 Azure Blob 存储进行备份/恢复的方法
替代方法讨论其他备份替代方法

备份可以:

备份类型

备份可以分为全量备份和增量备份。全量备份是数据的完整副本,而增量备份则是相对于上一次全量备份的数据变更(差异)部分。

全量备份的优点是简单、独立(不依赖其他备份),并且是一种可靠的恢复方式。但它可能需要较长的完成时间,并占用大量存储空间。相比之下,增量备份在时间和空间占用方面都更加高效,但在恢复数据时需要所有相关备份都可用。

根据您的需求,可以考虑:

  • 对于较小的数据库或关键数据,使用 全量备份
  • 对于较大的数据库,或需要频繁且具成本效益地执行备份的场景,使用 增量备份
  • 两者结合使用,例如每周进行全量备份,每天进行增量备份。

同步备份与异步备份

BACKUPRESTORE 命令也可以标记为 ASYNC。在这种情况下, 备份命令会立即返回,备份过程在后台运行。 如果命令未标记为 ASYNC,则备份过程是同步的, 命令会阻塞直到备份完成。

并发与非并发备份

默认情况下,ClickHouse 允许并发执行备份与恢复操作。这意味着可以同时发起多个备份或恢复操作。不过, 也可以通过服务器级别的设置来禁用这种行为。如果将这些设置设为 false,则在任意时刻 集群上只允许运行一个备份或恢复操作。这有助于避免资源争用或操作之间的潜在冲突。

要禁止备份/恢复并发执行,可以分别使用如下设置:

<clickhouse>
    <backups>
        <allow_concurrent_backups>false</allow_concurrent_backups>
        <allow_concurrent_restores>false</allow_concurrent_restores>
    </backups>
</clickhouse>

这两个设置的默认值都是 true,因此默认情况下允许并发执行备份/恢复操作。 当在集群上将这些设置设为 false 时,任意时刻该集群上只允许运行一个备份或恢复操作。

压缩备份与未压缩备份

ClickHouse 备份通过 compression_methodcompression_level 设置来支持压缩。

在创建备份时,可以指定:

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

使用命名集合

命名集合允许你存储键值对(例如 S3 凭证、端点和设置),并在备份/恢复等操作中重复使用。 它们有助于:

  • 对没有管理员权限的用户隐藏凭证
  • 通过集中存储复杂配置来简化命令
  • 在各类操作之间保持一致性
  • 避免在查询日志中暴露凭证

有关更多详细信息,请参阅“命名集合”

备份系统、日志或访问管理表

系统表也可以包含在你的备份和恢复工作流中,但是否包含取决于你的具体使用场景。

存储历史数据的系统表(例如以 _log 结尾的表,如 query_logpart_log)可以像其他任意表一样进行备份和恢复。
如果你的使用场景依赖于分析历史数据——例如使用 query_log 跟踪查询性能或排查问题——建议将这些表纳入备份策略中。
但是,如果不需要这些表中的历史数据,则可以将其排除,以节省备份存储空间。

与访问管理相关的系统表,例如 usersrolesrow_policiessettings_profilesquotas,在备份和恢复操作期间会被特殊处理。
当这些表被包含在备份中时,其内容会导出到一个特殊的 accessXX.txt 文件中,该文件封装了用于创建和配置访问实体的等效 SQL 语句。
在恢复时,恢复过程会解析这些文件,并重新执行 SQL 命令以重新创建用户、角色和其他配置。
此功能确保 ClickHouse 集群的访问控制配置可以作为集群整体配置的一部分进行备份和恢复。

此功能仅适用于通过 SQL 命令管理的配置(称为 "SQL-driven Access Control and Account Management")。
在 ClickHouse 服务器配置文件中定义的访问配置(例如 users.xml)不会包含在备份中,也无法通过此方法恢复。

通用语法

-- 核心命令
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 ...]

有关各命令的详细信息,请参阅《命令汇总》

命令摘要

上述每个命令的详细说明如下:

命令说明
BACKUP创建指定对象的备份
RESTORE从备份中恢复对象
[ASYNC]使操作异步执行(立即返回一个可用于监控的 ID)
TABLE [db.]table_name [AS [db.]table_name_in_backup]备份/恢复某个特定表(可重命名)
[PARTITION[S] partition_expr [,...]]仅备份/恢复表中的指定分区
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备份/恢复全部内容(所有数据库、表等)。在 ClickHouse 23.4 版本之前,ALL 仅适用于 RESTORE 命令。
[EXCEPT {TABLES|DATABASES}...]在使用 ALL 时排除指定的表或数据库
[ON CLUSTER 'cluster_name']在 ClickHouse 集群范围内执行备份/恢复
TO|FROM方向:TO 表示备份目标,FROM 表示恢复来源
File('<path>/<filename>')存储到本地文件系统 / 从本地文件系统恢复
Disk('<disk_name>', '<path>/')存储到已配置的磁盘 / 从已配置的磁盘恢复
S3('<S3 endpoint>/<path>', '<Access key ID>', '<Secret access key>')存储到 Amazon S3 或 S3 兼容存储 / 从中恢复
[SETTINGS ...]完整的设置列表见下文

设置

通用备份/恢复设置

设置说明默认值
id备份或恢复操作的 ID,如果未指定,则使用随机生成的 UUID。如果已经存在具有相同 ID 的正在运行的操作,则会抛出异常。
compression_method指定备份的压缩方式。参见章节 “列压缩编解码器”
compression_level指定备份压缩级别
password磁盘上该文件的密码。
base_backup用于增量备份的基础备份目标位置。例如:Disk('backups', '1.zip')
use_same_password_for_base_backup基础备份归档是否应从查询继承密码。
structure_only如果启用,则只备份或恢复表的 CREATE 语句,而不包含实际的表数据。
storage_policy正在恢复的表的存储策略。参见《将多个块设备用于数据存储》。仅适用于 RESTORE 命令。只对使用 MergeTree 系列表引擎的表生效。
allow_non_empty_tables允许 RESTORE TABLE 向非空表中插入数据。这样会将表中已有的数据与从备份中提取的数据混合在一起。因此,该设置可能导致表内数据重复,请谨慎使用。0
backup_restore_keeper_max_retries在执行 BACKUP 或 RESTORE 操作过程中,[Zoo]Keeper 操作的最大重试次数。应设置得足够大,以避免整个操作因临时性的 [Zoo]Keeper 故障而失败。1000
backup_restore_keeper_retry_initial_backoff_ms备份或恢复过程中 [Zoo]Keeper 操作的初始退避超时时间100
backup_restore_keeper_retry_max_backoff_ms在备份或恢复过程中 [Zoo]Keeper 操作的最大退避超时时间5000
backup_restore_failure_after_host_disconnected_for_seconds如果在执行 BACKUP ON CLUSTERRESTORE ON CLUSTER 操作期间,某个主机在 ZooKeeper 中在这段时间内未重新创建其临时的“alive”节点,则整个备份或恢复将被视为失败。该值应大于主机在发生故障后重新连接到 ZooKeeper 所需的任何合理时间。设置为零表示无限制。3600
backup_restore_keeper_max_retries_while_initializing在初始化 BACKUP ON CLUSTERRESTORE ON CLUSTER 操作时,针对 [Zoo]Keeper 操作的最大重试次数。20
backup_restore_keeper_max_retries_while_handling_error在处理 BACKUP ON CLUSTERRESTORE ON CLUSTER 操作时出现错误时,[Zoo]Keeper 操作的最大重试次数。20
backup_restore_finish_timeout_after_error_sec在当前 BACKUP ON CLUSTERRESTORE ON CLUSTER 操作中,发起方应等待其他主机对“error”节点作出反应并停止其工作的最长时间。180
backup_restore_keeper_value_max_size备份期间 [Zoo]Keeper 单个节点数据的最大大小1048576
backup_restore_batch_size_for_keeper_multi在备份或恢复期间向 [Zoo]Keeper 发送 multi 请求时的最大批量大小1000
backup_restore_batch_size_for_keeper_multiread在备份或恢复过程中向 [Zoo]Keeper 发送 multiread 请求时的最大批处理大小10000
backup_restore_keeper_fault_injection_probability在备份或恢复操作期间 keeper 请求的大致失败概率。有效取值范围为 [0.0f, 1.0f]0
backup_restore_keeper_fault_injection_seed0 表示使用随机种子,否则使用该配置值0
backup_restore_s3_retry_attemptsAws::Client::RetryStrategy 的配置。Aws::Client 会自行进行重试,0 表示不重试。仅在备份/恢复操作中生效。1000
max_backup_bandwidth服务器上某个备份的最大读取速度(字节/秒)。0 表示不限制。0
max_backups_io_thread_pool_sizeClickHouse 使用 Backups IO Thread 线程池中的线程来执行 S3 备份 I/O 操作。max_backups_io_thread_pool_size 用于限制该线程池中的线程数上限。1000
max_backups_io_thread_pool_free_size如果 Backups IO 线程池中空闲线程的数量超过 max_backup_io_thread_pool_free_size,ClickHouse 将释放空闲线程占用的资源并减少线程池大小。如有需要,可以重新创建这些线程。0
backups_io_thread_pool_queue_size可在 Backups IO 线程池中调度的作业最大数量。鉴于当前的 S3 备份逻辑,建议将此队列保持为无限制。注意:值为 0(默认)表示无限制。0
backup_threads用于执行 BACKUP 请求的最大线程数。
max_backup_bandwidth_for_server服务器上所有备份的最大读取速度(字节/秒)。为 0 表示无限制。0
shutdown_wait_backups_and_restores如果设置为 true,ClickHouse 会在关闭前等待正在运行的备份和恢复操作完成。1

S3 特定设置

SettingDescriptionDefault value
use_same_s3_credentials_for_base_backup是否让基础备份到 S3 时继承查询使用的凭证。仅在使用 S3 时生效。
s3_storage_class用于 S3 备份的存储类型。例如:STANDARD

Azure 特定设置

SettingDescriptionDefault value
azure_attempt_to_create_container在使用 Azure Blob Storage 时,如果指定的容器不存在,是否尝试创建该容器。true

管理与故障排查

备份命令会返回一个 idstatus,可以使用该 id 来 查询备份状态。这对于检查耗时较长的 ASYNC 备份进度非常有用。下面的示例展示了在尝试 覆盖现有备份文件时出现的失败示例:

BACKUP TABLE helloworld.my_first_table TO Disk('backups', '1.zip') ASYNC
┌─id───────────────────────────────────┬─status──────────┐
│ 7678b0b3-f519-4e6e-811f-5a0781a4eb52 │ CREATING_BACKUP │
└──────────────────────────────────────┴─────────────────┘

返回 1 行。耗时: 0.001 秒。
SELECT
*
FROM system.backups
WHERE id='7678b0b3-f519-4e6e-811f-5a0781a4eb52'
FORMAT Vertical
第 1 行:
──────
id:                7678b0b3-f519-4e6e-811f-5a0781a4eb52
name:              Disk('backups', '1.zip')
#highlight-next-line
status:            BACKUP_FAILED
num_files:         0
uncompressed_size: 0
compressed_size:   0
#highlight-next-line
error:             Code: 598. DB::Exception: Backup Disk('backups', '1.zip') already exists. (BACKUP_ALREADY_EXISTS) (version 22.8.2.11 (official build))
start_time:        2022-08-30 09:21:46
end_time:          2022-08-30 09:21:46

返回 1 行。用时:0.002 秒。

除了 system.backups 表之外,所有备份和恢复操作同样会记录在系统日志表 system.backup_log 中:

SELECT *
FROM system.backup_log
WHERE id = '7678b0b3-f519-4e6e-811f-5a0781a4eb52'
ORDER BY event_time_microseconds ASC
FORMAT Vertical
第 1 行:
──────
event_date:              2023-08-18
event_time_microseconds: 2023-08-18 11:13:43.097414
id:                      7678b0b3-f519-4e6e-811f-5a0781a4eb52
name:                    Disk('backups', '1.zip')
status:                  CREATING_BACKUP
error:
start_time:              2023-08-18 11:13:43
end_time:                1970-01-01 03:00:00
num_files:               0
total_size:              0
num_entries:             0
uncompressed_size:       0
compressed_size:         0
files_read:              0
bytes_read:              0

第 2 行:
──────
event_date:              2023-08-18
event_time_microseconds: 2023-08-18 11:13:43.174782
id:                      7678b0b3-f519-4e6e-811f-5a0781a4eb52
name:                    Disk('backups', '1.zip')
status:                  BACKUP_FAILED
#highlight-next-line
error:                   Code: 598. DB::Exception: Backup Disk('backups', '1.zip') already exists. (BACKUP_ALREADY_EXISTS) (version 23.8.1.1)
start_time:              2023-08-18 11:13:43
end_time:                2023-08-18 11:13:43
num_files:               0
total_size:              0
num_entries:             0
uncompressed_size:       0
compressed_size:         0
files_read:              0
bytes_read:              0

结果集包含 2 行。用时:0.075 秒。