
一、引言为什么 ClickHouse 备份如此重要ClickHouse 作为一款面向在线分析处理场景的列式数据库以其极高的查询性能、优异的压缩率和灵活的分布式架构被广泛应用于实时数仓、用户行为分析、广告投放统计、日志分析和时序数据仓库等领域。随着业务规模的扩大ClickHouse 集群中存储的数据量动辄达到数十 TB 甚至 PB 级数据已经成为企业最核心的资产之一。然而很多团队在使用 ClickHouse 的初期阶段把主要精力都放在建表优化、查询调优和集群扩容上却容易忽视一个至关重要的问题——数据备份与恢复。数据丢失的场景远比想象中常见磁盘损坏、误执行 DELETE 或 DROP 语句、升级失败导致元数据损坏、机房断电、人为操作失误、勒索病毒攻击甚至云厂商的底层故障都可能导致数据不可恢复。对于分析型数据库来说虽然部分数据可以从上游业务系统重新回灌但回灌成本往往极高而且对于已经做过聚合、去重、物化视图计算的结果数据往往根本无法通过重放日志恢复。因此建立一套可靠的备份与恢复体系是 ClickHouse 生产环境落地的基本要求。本文将从 ClickHouse 的存储架构讲起深入介绍冷备份、FREEZE 命令、文件系统快照、clickhouse-backup 工具、原生 BACKUP/RESTORE 语句等多种备份方案并结合实战脚本和场景演练帮助读者建立一套完整的备份恢复能力。无论你是刚开始接触 ClickHouse 的初学者还是需要为现有集群补齐容灾体系的老手都能从本文中找到可以直接落地的操作方案。二、ClickHouse 存储架构基础要理解备份与恢复必须先弄清楚 ClickHouse 的数据到底存在哪里、以什么形式存储、修改数据时会发生什么。ClickHouse 的数据存储与传统的行式数据库有很大的不同其底层基于 MergeTree 表引擎家族采用 LSM 风格的分区、分片与后台合并机制。只有理解了这些机制才能知道在备份时应该关注哪些文件、如何保证数据一致性、以及为什么某些场景下简单复制文件会带来风险。2.1 数据目录结构ClickHouse 默认的数据目录位于/var/lib/clickhouse/可以通过配置文件config.xml中的path参数修改。一个典型的数据目录结构如下/var/lib/clickhouse/ ├── metadata/ # 元数据目录 │ ├── default/ # 数据库目录 │ │ └── events.sql # 表定义文件 │ ├── default.sql # 数据库定义文件 │ └── system/ # 系统库元数据 ├── data/ # 数据文件目录 │ ├── default/ # 数据库目录 │ │ └── events/ # 表数据目录 │ │ ├── 202501_1_1_0/ # 分区目录 │ │ ├── detached/ # 分离的分区 │ │ └── format_version.txt │ └── system/ # 系统库数据 ├── store/ # 磁盘存储映射 ├── shadow/ # FREEZE 命令生成的影子副本 ├── tmp/ # 临时文件 ├── flags/ # 标志文件 ├── format_schemas/ # 格式 Schema ├── access/ # 用户和权限相关文件 └── user_files/ # 用户文件其中metadata目录保存了所有数据库和表的 DDL 定义每个库对应一个目录每个表对应一个.sql文件。例如default/events.sql的内容通常是一行完整的ATTACH TABLE或CREATE TABLE语句包含表引擎、字段定义、排序键、分区键等完整信息。如果这个文件丢失或损坏即使数据文件还在ClickHouse 也无法识别这张表。data目录保存的是各表真正的列数据文件按数据库和表名组织。对于 MergeTree 表表数据目录下会按分区键的取值生成分区目录例如202501_1_1_0表示 2025 年 1 月分区、最小块编号 1、最大块编号 1、层级 0。每个分区目录内部存放.bin数据文件、.mrk标记文件和count.txt行数信息等。2.2 MergeTree 存储机制MergeTree 表引擎是 ClickHouse 最核心的存储引擎绝大多数业务表都基于它或其变体ReplicatedMergeTree、AggregatingMergeTree、ReplacingMergeTree 等。它的写入机制是数据先以 Part数据片的形式写入磁盘后台会周期性地将多个小 Part 合并成大 Part。这种机制带来的一个直接后果是数据目录中的文件会不断变化Part 会被创建、合并和删除。具体来说每次 INSERT 操作都会生成一个新的 Part 目录命名格式为分区_最小块号_最大块号_层级。当后台合并线程将多个 Part 合并后会生成一个新 Part并把旧 Part 标记为过期稍后物理删除。这意味着如果我们直接复制数据目录必须保证在复制过程中没有正在进行的写入和合并操作否则复制出来的文件集合可能处于不一致状态恢复后会出现数据缺失或重复的情况。2.3 ZooKeeper 元数据对于使用 ReplicatedMergeTree 表引擎的复制表ClickHouse 依赖 ZooKeeper 来协调多个副本之间的数据同步。ZooKeeper 中保存了每个复制表的副本列表、Part 清单、队列信息、块编号分配等元数据。备份复制表时仅仅备份 ClickHouse 数据目录是不够的还需要考虑 ZooKeeper 元数据的备份否则恢复后副本之间的状态可能不一致导致无法正常同步。一般来说ReplicatedMergeTree 表的数据文件备份后恢复时可以先恢复到某一个副本节点然后让该节点作为数据源通过 ZooKeeper 向其他副本同步。但如果 ZooKeeper 中该表的元数据也发生了损坏或丢失那么只备份数据文件就无法直接恢复复制关系。因此完整的企业级备份方案必须同时兼顾 ClickHouse 数据文件和 ZooKeeper 元数据。三、备份的核心概念与选型依据在动手写备份脚本之前我们需要先明确几个关键概念和选型依据。备份不是简单的「把文件复制一份」而是一个涉及一致性、恢复时间目标、恢复点目标、存储成本和运维复杂度的系统工程。不同的业务场景对备份的要求差异很大盲目追求最复杂的方案反而会带来不必要的成本。3.1 冷备份与热备份冷备份是指在数据库停止服务或表处于冻结状态时进行的备份。由于此时不会有新的写入和合并操作直接复制数据文件即可获得一致的数据快照。冷备份的优点是实现简单、成本低、一致性有保证缺点是停机或冻结期间无法提供服务对于 7x24 小时运行的业务来说不可接受。热备份是指数据库在正常运行状态下进行的备份。热备份需要借助文件系统快照、FREEZE 命令或专门的备份工具来保证一致性。热备份的优点是业务不中断缺点是实现相对复杂需要处理并发写入带来的文件变化问题。3.2 RPO 与 RTORPORecovery Point Objective恢复点目标是指灾难发生后能够容忍丢失多少时间的数据。例如 RPO 为 1 小时意味着最多允许丢失最近 1 小时的数据。RPO 决定了备份的频率全量备份加增量备份的时间间隔越短RPO 越小但备份开销越大。RTORecovery Time Objective恢复时间目标是指灾难发生后从开始恢复到业务可用的目标时间。例如 RTO 为 2 小时意味着需要在 2 小时内完成数据恢复。RTO 决定了备份方案和恢复流程的复杂度使用裸文件复制恢复比使用压缩备份包恢复更快本地备份比远程备份恢复更快。在设计备份方案时需要与业务方明确 RPO 和 RTO 指标然后据此选择备份频率、备份介质和恢复流程。例如对于核心交易分析数据可能需要 RPO 接近 0、RTO 在小时级而对于可以重新计算的历史日志数据RPO 可以放宽到天级。3.3 备份粒度ClickHouse 备份的粒度可以分为四种整库备份备份所有数据库、所有表及元数据恢复时整体还原。适合一次性搭建完整容灾环境。数据库级备份备份某个数据库的全部表恢复时还原整个库。表级备份只备份指定的表适合数据量巨大但只有部分核心表需要高频备份的场景。分区级备份备份表的某个分区的数据适合按月分区、历史分区不再变化的场景可以只对新分区做增量动作。不同粒度的备份成本差异很大。在实践中通常采用「全量备份 增量备份」的组合策略定期做全量备份期间对变化的分区做增量备份以平衡备份时间和恢复时间。四、冷备份实战停止服务复制数据目录冷备份是所有备份方案中最基础、最直观的一种也是理解 ClickHouse 备份原理的起点。虽然它在生产环境的适用场景有限但对于测试环境、开发环境以及在窗口期允许短暂停机的业务它仍然是一个简单有效的方案。4.1 完整冷备份流程完整冷备份的基本思路是先停止 ClickHouse 服务保证数据目录处于静止状态然后将数据目录和配置目录整体打包复制到备份位置最后重新启动服务。具体步骤如下# 1. 停止 ClickHouse 服务 sudo systemctl stop clickhouse-server 2. 确认服务已停止没有残留进程 ps -ef | grep clickhouse | grep -v grep 3. 创建备份目录 BACKUP_DIR/data/backup/clickhouse_full_$(date %Y%m%d_%H%M%S) mkdir -p $BACKUP_DIR 4. 复制数据目录和配置目录 cp -a /var/lib/clickhouse $BACKUP_DIR/data cp -a /etc/clickhouse-server $BACKUP_DIR/config 5. 重新启动 ClickHouse 服务 sudo systemctl start clickhouse-server 6. 验证备份完整性 ls -lh $BACKUP_DIR/data du -sh $BACKUP_DIR/data在上面的脚本中cp -a参数表示归档方式复制会保留文件的权限、所有者和时间戳等信息这对于 ClickHouse 的数据文件非常重要因为某些文件的所有权和权限在恢复后必须与原来一致否则服务可能无法正常读取。4.2 使用 tar 打包压缩如果数据量较大直接cp会占用大量磁盘空间。更推荐的做法是边压缩边打包使用tar命令sudo systemctl stop clickhouse-server BACKUP_FILE/data/backup/clickhouse_full_$(date %Y%m%d_%H%M%S).tar.gz sudo tar -czf $BACKUP_FILE -C /var/lib clickhouse -C /etc clickhouse-server sudo systemctl start clickhouse-server需要注意的是ClickHouse 的数据压缩率通常很高列式存储本身已经做了压缩所以再经过gzip压缩后体积并不会显著减小但tar打包可以避免大量小文件传输时的开销。如果备份介质是对象存储打包成单个文件也更便于上传和管理。对于压缩比敏感的场景可以尝试使用zstd或lz4压缩兼顾速度和体积。4.3 冷备份的恢复冷备份的恢复同样简单直接停止服务清空或移动当前数据目录将备份文件还原到原位置然后启动服务。需要注意的是恢复前要备份当前可能还存在的新数据避免覆盖后无法回退。# 假设备份文件为 /data/backup/clickhouse_full_20250120_030000.tar.gz 1. 停止服务 sudo systemctl stop clickhouse-server 2. 将当前数据目录移走便于回退 sudo mv /var/lib/clickhouse /var/lib/clickhouse_bak_$(date %Y%m%d_%H%M%S) 3. 解压备份文件 sudo mkdir -p /var/lib/clickhouse sudo tar -xzf /data/backup/clickhouse_full_20250120_030000.tar.gz -C /var/lib 4. 检查文件所有者 sudo chown -R clickhouse:clickhouse /var/lib/clickhouse 5. 启动服务 sudo systemctl start clickhouse-server 6. 验证数据 clickhouse-client --query SELECT count() FROM default.events冷备份的优点是操作简单、可靠性高但由于需要停机在大多数在线业务中无法直接使用。不过它的思路——「保证数据目录在备份时刻处于一致静止状态」——是所有其他备份方案的基础。理解了这一点就理解了为什么 FREEZE 命令和 clickhouse-backup 工具要设计特定的机制来处理并发写入。五、FREEZE 命令与影子副本备份如果业务不能接受长时间停机但又不想引入额外工具那么 ClickHouse 提供的FREEZE命令是一个很好的折中方案。它可以在不停止服务的情况下创建一个数据目录的一致性快照然后我们就可以从容地复制这个快照而不用担心并发写入导致的文件不一致。5.1 FREEZE 命令的工作原理FREEZE命令的核心机制是「硬链接影子副本」。当对表执行FREEZE后ClickHouse 会在数据目录下的shadow/N/目录中创建该表所有现有数据文件的硬链接。硬链接的特点是多个文件名指向同一个 inode不额外占用实际磁盘空间但修改原始文件不会影响硬链接指向的文件内容。由于 MergeTree 的合并操作总是生成新的 Part 文件后再删除旧文件而不是原地修改所以通过硬链接建立的影子副本始终能保持稳定不变即使 FREEZE 之后表继续写入新数据、合并旧 Part影子副本中的内容也不会被破坏。这个机制的巧妙之处在于它利用 Linux 文件系统的硬链接特性以几乎零成本的方式获得了一个一致的数据快照从而避免了热备份中的数据不一致问题。FREEZE 就是通过这种方式实现了「先冻结、后复制」的热备份能力。5.2 FREEZE 命令的使用FREEZE 命令支持库级、表级和分区级三种粒度。使用方法如下-- 冻结整个数据库的所有表 ALTER DATABASE default FREEZE; -- 冻结单张表 ALTER TABLE default.events FREEZE; -- 冻结表的指定分区 ALTER TABLE default.events FREEZE PARTITION 202501; -- 为同一张表多次冻结使用 WITH NAME 指定快照名称 ALTER TABLE default.events FREEZE WITH NAME backup_20250120;执行 FREEZE 后可以在文件系统中看到影子副本目录ls -l /var/lib/clickhouse/shadow/ # 输出类似 # drwxr-x--- 2 clickhouse clickhouse 4096 Jan 20 03:00 1/ # drwxr-x--- 2 clickhouse clickhouse 4096 Jan 20 03:00 backup_20250120/影子目录中的文件结构与原表数据目录一致但都是硬链接。backup_20250120这个目录下会包含data/default/events/这样的路径其中是当时冻结的所有 Part 的硬链接。5.3 基于 FREEZE 的完整备份流程基于 FREEZE 的备份思路是先执行 FREEZE 生成一致性快照然后复制 shadow 目录中的内容到备份介质本地目录、NFS 或对象存储。由于影子副本是静态的复制过程可以慢慢进行不会影响数据库的持续写入。#!/bin/bash # clickhouse_freeze_backup.sh # 基于 FREEZE 命令的 ClickHouse 热备份脚本 BACKUP_BASE/data/backup/clickhouse STAMP$(date %Y%m%d_%H%M%S) SNAPSHOT_NAMEbackup_$STAMP CH_HOST127.0.0.1 CH_PORT9000 1. 对需要备份的表执行 FREEZE clickhouse-client --host $CH_HOST --port $CH_PORT --query ALTER TABLE default.events FREEZE WITH NAME $SNAPSHOT_NAME clickhouse-client --host $CH_HOST --port $CH_PORT --query ALTER TABLE default.orders FREEZE WITH NAME $SNAPSHOT_NAME 2. 复制影子副本到备份目录 SHADOW_DIR/var/lib/clickhouse/shadow/$SNAPSHOT_NAME if [ -d $SHADOW_DIR ]; then mkdir -p $BACKUP_BASE/freeze cp -a $SHADOW_DIR $BACKUP_BASE/freeze/$STAMP echo 备份完成: $BACKUP_BASE/freeze/$STAMP else echo 错误未找到影子副本目录 $SHADOW_DIR exit 1 fi 3. 准备元数据备份 clickhouse-client --host $CH_HOST --port $CH_PORT --query SHOW CREATE TABLE default.events $BACKUP_BASE/freeze/$STAMP/events_ddl.sql 4. 清理旧的影子副本FREEZE 本身需要在后续手动清理 rm -rf $SHADOW_DIR echo FREEZE 备份流程执行完毕备份完成后$BACKUP_BASE/freeze/$STAMP目录中就包含了一致性的表数据硬链接副本。这些文件可以在任何时间恢复即使原始数据已经被修改或删除。5.4 清理 shadow 目录FREEZE 命令会持续消耗磁盘空间吗答案是不会因为硬链接本身而消耗但随着表继续合并和写入被冻结的旧 Part 在被删除时由于影子目录中还持有硬链接这些文件的实际磁盘空间不会被释放。因此如果长时间不清理 shadow 目录磁盘使用量会持续增长。最佳实践是备份完成后立即删除对应的 shadow 目录或者使用SYSTEM UNFREEZE命令清理。-- 清理指定名称的快照 SYSTEM UNFREEZE WITH NAME backup_20250120;# 直接删除文件系统中的影子副本 rm -rf /var/lib/clickhouse/shadow/backup_20250120值得注意的是在较新版本的 ClickHouse 中FREEZE 的 shadow 目录管理得到了一定优化但手动清理仍然是一个好习惯。建议在备份脚本的末尾加上清理逻辑避免磁盘被无形的硬链接占满。六、文件系统快照备份文件系统快照是另一种常见的热备份手段它在文件系统或存储层面对整个数据卷做瞬时快照从而实现一致性备份。与 FREEZE 命令相比文件系统快照的粒度更粗通常是整个卷但实现更底层可以覆盖所有数据库和表也不需要为每张表单独执行命令。对于运行在云环境或使用 LVM/ZFS 这类支持快照的文件系统的场景这是一种非常实用的方案。6.1 LVM 快照备份LVMLogical Volume Manager逻辑卷管理器是 Linux 下常用的磁盘管理工具支持对逻辑卷创建快照。LVM 快照使用写时复制COW机制创建瞬间即可完成随后原始卷的写入会触发数据块的保留。借助 LVM 快照可以在不停止 ClickHouse 的情况下获得整个数据卷的一致性视图。但需要注意的是LVM 快照本身捕获的是文件系统层面的块状态。如果 ClickHouse 在快照时刻正在进行写入那么快照中可能包含部分写入的文件。为了保证一致性建议在创建快照前先执行SYSTEM FLUSH LOGS或短暂冻结写入或者与 FREEZE 结合使用。对于大多数单节点 ClickHouse 场景直接在低峰期做 LVM 快照通常也能满足需求。# 1. 创建 LVM 快照假设卷组为 vg0逻辑卷为 lv_clickhouse sudo lvcreate -L 50G -s -n clickhouse_snap_20250120 /dev/vg0/lv_clickhouse 2. 挂载快照卷 sudo mkdir -p /mnt/clickhouse_snap sudo mount -o ro /dev/vg0/clickhouse_snap_20250120 /mnt/clickhouse_snap 3. 从挂载的快照中复制数据可以边压缩边复制 sudo tar -czf /data/backup/clickhouse_snap_20250120.tar.gz -C /mnt/clickhouse_snap . 4. 卸载并删除快照卷释放写时复制的空间 sudo umount /mnt/clickhouse_snap sudo lvremove -f /dev/vg0/clickhouse_snap_20250120LVM 快照的优势是速度快、对整个卷生效劣势是快照本身有容量限制创建时指定的 50G如果备份时间过长、期间写入量很大快照空间可能被耗尽导致快照失效。因此创建快照后应尽快完成备份并及时删除快照。6.2 云盘快照备份如果 ClickHouse 运行在云服务器上可以直接使用云厂商提供的云盘快照功能。例如阿里云 ESSD 云盘快照、腾讯云 CBS 快照、AWS EBS 快照等。云盘快照在存储层面对整个数据盘做备份不占用服务器本身的 I/O 资源而且通常由云厂商保证底层一致性。使用云盘快照备份 ClickHouse 的基本流程是在低峰期创建数据盘快照快照完成后即可继续服务。恢复时基于快照创建新的云盘挂载到新的服务器或替换旧盘。这种方案的最大优点是运维简单、可靠性高甚至可以配置自动快照策略例如每天凌晨自动快照、保留 7 天。缺点是快照粒度是整个云盘无法满足表级粒度恢复的要求而且跨云厂商的兼容性有限。以下是一个使用阿里云 CLI 创建云盘快照的示例# 获取数据盘 ID假设 ClickHouse 数据单独挂载在 /dev/vdb DISK_ID$(lsblk -o NAME,SERIAL -n | grep vdb | awk {print $2}) 创建快照 aliyun ecs CreateSnapshot --DiskId $DISK_ID --SnapshotName clickhouse_backup_$(date %Y%m%d) 查看快照状态 aliyun ecs DescribeSnapshots --DiskId $DISK_ID --SnapshotName clickhouse_backup_*在实际生产环境中云盘快照常常作为兜底方案与其他更精细的备份工具配合使用。例如每天用 clickhouse-backup 做逻辑全量增量备份上传到对象存储同时每周做一次云盘快照这样既能满足快速恢复又能覆盖底层故障。6.3 ZFS 与 Btrfs 快照如果底层文件系统使用了 ZFS 或 Btrfs它们天生支持高效的快照。ZFS 快照同样基于写时复制创建和删除都很快。以下是一个 ZFS 快照备份 ClickHouse 的示例# 假设 ClickHouse 数据位于 zpool/clickhouse 数据集 zfs snapshot zpool/clickhousebackup_20250120 查看快照 zfs list -t snapshot 基于快照导出备份可以发送到远程 zfs send zpool/clickhousebackup_20250120 | gzip /data/backup/clickhouse_zfs_20250120.zfs.gz 删除快照 zfs destroy zpool/clickhousebackup_20250120ZFS 快照方案在自建机房和 NAS 环境中非常流行它的发送/接收机制还天然支持增量备份和远程复制适合构建高可用和异地容灾体系。七、clickhouse-backup 工具详解clickhouse-backup是 Altinity 公司开源的 ClickHouse 备份恢复工具也是目前社区中使用最广泛的第三方备份方案。它支持全量备份、增量备份、备份压缩、上传到 S3/GCS/Azure 等对象存储、表级备份和恢复并且可以集成到 Kubernetes 和多种自动化运维平台中。相比原生 FREEZE 命令它封装了一套完整的工作流大大降低了备份运维的复杂度。7.1 工作原理clickhouse-backup 的核心思路与 FREEZE 类似但做了更完整的封装。备份时它首先对目标表执行ALTER TABLE ... FREEZE命令在 shadow 目录中建立一致性的硬链接快照然后将 shadow 目录中的数据文件和元数据打包成归档文件存储到配置的本地目录或远程对象存储中最后清理 shadow 目录。由于 FREEZE 保证了数据一致性整个备份过程可以在数据库持续写入的情况下安全进行。对于增量备份clickhouse-backup 会记录上次备份的表分区状态只备份新增或有变化的分区数据从而大幅减少备份体积和时间。恢复时则可以直接从远程存储拉取备份包并解压还原。7.2 安装clickhouse-backup 提供了预编译的二进制文件支持 Linux 和 macOS。安装步骤如下# 下载最新版本以 v2.5.x 为例请根据实际需要选择版本 VERSION2.5.4 wget https://github.com/Altinity/clickhouse-backup/releases/download/v${VERSION}/clickhouse-backup-linux-amd64.tar.gz 解压 tar -xzf clickhouse-backup-linux-amd64.tar.gz 安装到系统 PATH sudo mv clickhouse-backup /usr/local/bin/ 验证版本 clickhouse-backup version也可以使用 Docker 方式运行便于在 Kubernetes 环境中使用docker run --rm -it --network host \ -v /var/lib/clickhouse:/var/lib/clickhouse \ -v /etc/clickhouse-server:/etc/clickhouse-server \ -v /data/backup:/backup \ altinity/clickhouse-backup:2.5.4 --config/etc/clickhouse-backup/config.yml \ create backup_name7.3 配置文件clickhouse-backup 的默认配置文件位于/etc/clickhouse-backup/config.yml也可以在运行时通过--config参数指定。一个完整的配置示例general: remote_storage: s3 # 远程存储类型none、s3、gcs、ftp、sftp、azblob 等 max_file_size: 1073741824 # 单个备份文件的最大大小1GB disable_progress_bar: false backups_to_keep_local: 7 # 本地保留的备份数量 backups_to_keep_remote: 30 # 远程保留的备份数量 log_level: info allow_empty_backups: false clickhouse: username: default # ClickHouse 用户 password: # 密码 host: 127.0.0.1 # ClickHouse 地址 port: 9000 # 原生协议端口 data_path: /var/lib/clickhouse # ClickHouse 数据目录 skip_tables: # 跳过系统表 - system.* - INFORMATION_SCHEMA.* timeout: 5m s3: access_key: your_access_key secret_key: your_secret_key bucket: clickhouse-backups endpoint: # 自定义 S3 端点如 MinIO region: us-east-1 path: clickhouse/prod # 存储路径前缀 compression_level: 1 # 压缩级别 force_path_style: false storage_class: STANDARD如果使用本地磁盘作为备份存储remote_storage: none备份文件会保存在/var/lib/clickhouse-backup/目录下。对于生产环境强烈建议配置对象存储作为远程备份位置实现异地容灾。7.4 全量备份配置完成后执行全量备份只需要一条命令# 创建本地全量备份 clickhouse-backup create my_first_backup 创建备份并立即上传到远程存储 clickhouse-backup create_remote my_backup_name 查看所有备份 clickhouse-backup list 输出示例 Name Created Size Status my_first_backup 2025-01-20 03:00:00 12.5GB local my_backup_name 2025-01-20 04:00:00 12.5GB remote备份完成后可以使用clickhouse-backup list local和clickhouse-backup list remote分别查看本地和远程备份。7.5 增量备份增量备份是 clickhouse-backup 的重要特性。它通过比较分区状态只备份自上次备份以来新增或变化的分区。由于 ClickHouse 常用按时间分区的设计历史分区不会再变化因此增量备份通常只需要备份最新的一两个分区体积和时间都会大幅下降。# 先创建全量备份自动成为增量基准 clickhouse-backup create_remote full_20250120 之后创建增量备份 clickhouse-backup create_remote inc_20250121 使用 --diff-from-remote 指定远程基准备份 clickhouse-backup create_remote inc_20250122 --diff-from-remote full_20250120增量备份的恢复通常需要先恢复基准全量备份再恢复后续的增量备份。clickhouse-backup 在处理时能够识别备份之间的依赖关系。7.6 表级备份与恢复clickhouse-backup 还支持只备份指定的表这在大表场景下非常有用# 备份指定表 clickhouse-backup create backup_events_only --tables default.events 备份多个表 clickhouse-backup create backup_two_tables --tables default.events,default.orders 排除某些表 clickhouse-backup create backup_except_some --exclude-tables system.*恢复时可以只恢复指定表# 从备份中只恢复 default.events 表 clickhouse-backup restore backup_name --tables default.events7.7 恢复操作恢复备份的基本命令如下# 从本地备份恢复 clickhouse-backup restore backup_name 从远程备份恢复自动下载 clickhouse-backup restore_remote backup_name 只下载远程备份到本地不恢复 clickhouse-backup download backup_name 恢复时指定 schema 变更 clickhouse-backup restore backup_name --tables default.events --schema恢复操作的执行时间取决于备份的体积和存储介质。恢复完成后建议执行查询验证数据完整性clickhouse-client --query SELECT count(), max(event_date) FROM default.events clickhouse-client --query SELECT * FROM system.backups # 查看备份相关系统表7.8 clickhouse-backup 的优缺点优点主要体现在以下几个方面功能完整原生支持全量备份、增量备份、表级备份与恢复并且能够自动管理备份之间的依赖关系。远程存储集成好可以直接上传到 S3、GCS、Azure Blob、FTP/SFTP 等对象存储适合异地容灾。自动化程度高提供 Docker 镜像和 Kubernetes 支持可以接入 CronJob、Airflow 等调度平台。运维成本低相比手工 FREEZE 加 tar命令更简洁备份元数据统一管理便于清单查询和按需恢复。缺点也需要客观认识仍是逻辑备份底层依赖 FREEZE 和 shadow 目录超大集群首次全量备份耗时仍然较长。版本兼容要求工具版本需要与 ClickHouse 版本保持兼容升级 ClickHouse 后应及时升级 clickhouse-backup。权限与配置要求需要能够访问 ClickHouse 数据目录、配置文件和 ZooKeeper并对备份账号有一定权限要求。大规模表多时管理复杂虽然支持批量操作但表数量极多、备份策略差异大时仍需借助脚本或配置管理。八、原生 BACKUP/RESTORE 语句从 ClickHouse 22.x 版本开始社区推出了原生BACKUP和RESTORE语句并在后续版本中不断完善。原生备份支持把数据库或表备份到本地磁盘、S3 对象存储等位置恢复时也能按库、按表粒度还原。相比第三方工具原生 BACKUP 更贴近内核能够直接复用 ClickHouse 自身的 Part 管理和元数据能力。8.1 BACKUP 语句的基本用法原生 BACKUP 支持库级、表级和分区级备份语法整体比较统一。最基础的库级备份示例-- 备份整个 default 数据库到磁盘 BACKUP DATABASE default TO Disk(backups, default_20250120.zip);其中Disk(backups, path)表示使用 ClickHouse 配置中名为backups的磁盘备份文件保存为对应路径。表级备份可以写成-- 备份单张表 BACKUP TABLE default.events TO Disk(backups, events_20250120.zip); -- 备份指定分区 BACKUP TABLE default.events PARTITION 202501 TO Disk(backups, events_202501.zip);8.2 备份到 S3 对象存储原生 BACKUP 也支持 S3 兼容对象存储需要先在配置中声明 S3 磁盘或直接使用S3函数。示例BACKUP DATABASE default TO S3(https://oss.example.com/backups/default_20250120.zip, access_key, secret_key);使用 S3 备份时ClickHouse 会把备份写入对象存储适合异地容灾。实际使用中建议把访问密钥放入config.xml或密钥管理工具中避免直接在 SQL 中暴露。8.3 RESTORE 恢复操作恢复时使用RESTORE语句。需要注意的是恢复目标表默认不能已经存在同名对象否则会报错除非使用REPLACE参数覆盖-- 恢复 default 数据库 RESTORE DATABASE default FROM Disk(backups, default_20250120.zip); -- 恢复单张表并覆盖现有表 RESTORE TABLE default.events FROM Disk(backups, events_20250120.zip) REPLACE;从 S3 恢复时把目标改为对应的 S3 位置即可。恢复完成后建议立即校验行数和分区范围确认数据符合预期。8.4 原生 BACKUP/RESTORE 的适用场景原生 BACKUP/RESTORE 的优势是与内核版本同步演进无需额外安装工具而且支持对象存储和压缩适合对备份链路要求简单、希望减少第三方依赖的团队。但它目前在大规模集群、跨版本恢复、增量备份和细粒度审计方面的能力相比 clickhouse-backup 仍有一定差距。因此生产环境仍建议结合实际场景在原生 BACKUP 与 clickhouse-backup、文件系统快照之间组合选择。九、备份验证与恢复演练备份任务只能算完成了一半真正的容灾能力必须通过「可恢复」来证明。实际生产环境中很多团队做了长期备份却从未验证过备份是否真的可以还原。等到灾难发生时才发现备份文件损坏、元数据缺失或权限错误后果非常严重。因此必须把恢复演练纳入运维规范。9.1 备份清单与元数据检查每一次备份完成后都应记录并检查以下信息备份名称、备份时间、备份范围、备份体积、备份位置、是否包含 DDL 和 ZooKeeper 元数据、校验和等。对于 clickhouse-backup可以通过list命令查看清单对于手工备份可以在备份目录中生成backup_manifest.txt内容包括backup_nameclickhouse_full_20250120 created_at2025-01-20 03:00:00 scopeall_databases size12582912000 ddlincluded zookeepernot_applicable checksum_algorithmsha2569.2 周期性恢复演练建议按周或月为单位在独立的演练环境执行一次完整恢复。演练环境最好与生产使用相同版本的 ClickHouse 和相同的操作系统、文件权限配置。演练流程如下创建一台干净的 ClickHouse 节点版本与生产一致。从备份介质拉取最近一次全量备份以及后续增量备份。按先全量、后增量的顺序执行恢复。启动服务执行SELECT count()、分区分布、抽样查询校验。记录演练耗时作为 RTO 的实测依据。如果恢复脚本或文档在演练中发现不适用应及时修正。演练本身不应影响生产备份任务。9.3 数据一致性校验恢复后不能只看行数是否一致还要检查分区、排序键、数据分布和关键指标。常用校验 SQL-- 对比总行数 SELECT count() FROM default.events; -- 按分区查看数据量 SELECT partition, count() FROM system.parts WHERE database default AND table events AND active GROUP BY partition ORDER BY partition; -- 抽样校验明细 SELECT * FROM default.events ORDER BY event_time DESC LIMIT 100;如果生产环境可以接受只读验证还可以将恢复后的表临时挂载为只读表抽样对比业务指标进一步确认数据正确性。十、备份监控与告警备份任务如果不能被有效监控就可能在无人察觉的情况下长期失败。调度脚本、clickhouse-backup、云平台快照都应有对应的监控与告警。10.1 关键监控指标备份成功率每次备份任务是否返回成功状态。备份耗时防止备份时间过长影响下一个备份窗口。备份体积快速发现数据异常激增或遗漏。备份留存数量检查本地和远程保留的策略是否满足要求。磁盘剩余空间防止 shadow 目录、本地备份和临时文件占满磁盘。10.2 使用 system 表观察备份状态对于原生 BACKUP/RESTOREClickHouse 提供system.backups和system.backup_log表可以查看备份记录SELECT * FROM system.backups ORDER BY start_time DESC LIMIT 10; SELECT * FROM system.backup_log ORDER BY start_time DESC LIMIT 10;对于 clickhouse-backup可以在 CronJob 或调度脚本中捕获退出码、输出日志并把这些结果写入监控系统。10.3 告警示例以 shell 脚本为例当备份失败或超过预期时间时可以调用 Webhook 通知#!/bin/bash set -e START$(date %s) clickhouse-backup create_remote full_$(date %Y%m%d_%H%M%S) END$(date %s) DURATION$((END - START)) if [ $DURATION -gt 7200 ]; then curl -X POST $ALERT_WEBHOOK -H Content-Type: application/json -d {text: ClickHouse 备份耗时异常${DURATION} 秒} fi生产环境建议把备份结果接入 Prometheus、Zabbix、Alertmanager 或企业微信、钉钉、飞书等通知渠道做到失败即告警。十一、总结与最佳实践ClickHouse 备份没有银弹不同方案在一致性、停机影响、恢复粒度、自动化程度和运维成本上各有取舍。下表对本文介绍的方案做了横向对比备份方案是否停机粒度实现复杂度适用场景冷备份是整库低测试、开发、可接受停机的环境FREEZE 加影子副本否库/表/分区中单表或少量核心表热备份文件系统/LVM/ZFS 快照否整卷中底层快速恢复、兜底备份云盘快照否整盘低云上容灾兜底clickhouse-backup否库/表/分区中日常全量与增量备份、对象存储上传原生 BACKUP/RESTORE否库/表/分区中希望减少第三方依赖、使用内核能力最后给出几条可以直接落地的实践建议先定目标和业务方明确 RPO、RTO再选择备份组合避免过度设计。全量加增量按时间分区时优先使用周全量、天增量策略控制备份体积和时间。元数据不遗漏同时备份 DDL、用户权限、ZooKeeper 元数据和配置文件。备份要传得出去生产备份至少保留一份在异地或对象存储中防止同机房故障。演练才算数定期恢复演练实测 RTO验证备份可用性和恢复文档。全程可观测对备份状态、耗时、体积和磁盘空间做监控告警。只要把备份、校验、恢复、演练、监控五个环节串成闭环ClickHouse 的备份体系就能从看起来有备份升级为真正可恢复为业务数据提供可靠保障。