文章目录
- 一、备份方案全景对比
- 二、方案一:物理备份(传统方式)
- [三、方案二:内置 BACKUP / RESTORE(21.8+ 推荐)](#三、方案二:内置 BACKUP / RESTORE(21.8+ 推荐))
-
- [3.1 配置备份存储磁盘](#3.1 配置备份存储磁盘)
- [3.2 执行备份](#3.2 执行备份)
- [3.3 查看和管理备份](#3.3 查看和管理备份)
- [3.4 恢复数据](#3.4 恢复数据)
- [3.5 集群场景的分布式备份](#3.5 集群场景的分布式备份)
- [四、方案三:逻辑备份(clickhouse-client 导出)](#四、方案三:逻辑备份(clickhouse-client 导出))
-
- [4.1 导出为 CSV](#4.1 导出为 CSV)
- [4.2 导入恢复](#4.2 导入恢复)
- [4.3 并行导出脚本(适用于大表)](#4.3 并行导出脚本(适用于大表))
- 五、方案对比与选型建议
- 六、生产环境最佳实践
-
- [6.1 定期备份脚本(crontab 示例)](#6.1 定期备份脚本(crontab 示例))
- [6.2 备份验证清单](#6.2 备份验证清单)
- [6.3 常见问题处理](#6.3 常见问题处理)
- 七、总结
数据备份是数据库运维的最后一道防线。ClickHouse 作为一款列式 OLAP 数据库,提供了多种备份恢复方案------从传统的物理文件拷贝,到内置的
BACKUP语句,再到逻辑导出。本文将从生产环境实战角度,系统梳理每种方案的适用场景、操作步骤和注意事项,帮助你建立可靠的 ClickHouse 数据保护体系。
一、备份方案全景对比
在开始具体操作前,先了解各种方案的定位:
| 备份方式 | 是否需要停服务 | 一致性保证 | 恢复速度 | 适用场景 |
|---|---|---|---|---|
| 物理拷贝(停止服务) | ✅ 需要 | 强一致性 | 快 | 全量迁移、紧急恢复 |
| FREEZE 快照(在线) | ❌ 不需要 | 强一致性 | 快 | 生产环境在线全量备份 |
| BACKUP 语句 | ❌ 不需要 | 强一致性(MVCC) | 快 | 21.8+ 推荐,日常周期性备份 |
| CSV 逻辑导出 | ❌ 不需要 | 弱(导出时间点) | 慢 | 小表备份、跨版本迁移 |
核心建议:
- 生产环境优先使用
BACKUP语句(21.8+ 版本) - 旧版本或需要在线物理备份时,使用
FREEZE快照 - 直接
cp/rsync数据目录必须停服务,否则可能产生不一致备份
二、方案一:物理备份(传统方式)
2.1 停服务拷贝(不推荐生产环境)
这种方式简单直接,但需要停止 ClickHouse 服务,适合紧急恢复或全量迁移场景。
备份步骤
bash
# 1. 停止 ClickHouse 服务
sudo systemctl stop clickhouse-server
# 2. 复制数据目录(使用 rsync 支持断点续传)
rsync -avz /var/lib/clickhouse/ /backup/clickhouse/
# 3. 启动服务
sudo systemctl start clickhouse-server
恢复步骤
bash
# 1. 停止服务
sudo systemctl stop clickhouse-server
# 2. 清空并恢复数据目录
rm -rf /var/lib/clickhouse/*
rsync -avz /backup/clickhouse/ /var/lib/clickhouse/
# 3. 修复权限并启动
chown -R clickhouse:clickhouse /var/lib/clickhouse/
sudo systemctl start clickhouse-server
⚠️ 缺点:备份期间服务不可用,不适合在线生产环境。
2.2 FREEZE 快照(在线物理备份,推荐传统方式)
ClickHouse 提供了 ALTER TABLE ... FREEZE 命令,可以在不停服务的情况下创建数据快照。
原理
FREEZE为数据文件创建硬链接 (hard link),存放在/var/lib/clickhouse/shadow/目录下- 硬链接几乎不占用额外磁盘空间(只是增加文件引用计数)
- 创建过程秒级完成,不影响正常读写
在线备份步骤
sql
-- 1. 冻结单张表(推荐方式)
ALTER TABLE my_database.my_table FREEZE;
-- 或者冻结整个数据库
ALTER DATABASE my_database FREEZE;
bash
# 2. 拷贝快照文件到备份目录
rsync -avz /var/lib/clickhouse/shadow/ /backup/clickhouse_snapshot/
# 3. 删除快照(释放硬链接,不删除实际数据)
ALTER TABLE my_database.my_table DROP DETACHED PARTITION ALL;
# 或直接删除 shadow 目录下的对应快照文件(需谨慎)
恢复步骤
bash
# 1. 停止服务
sudo systemctl stop clickhouse-server
# 2. 将备份文件复制回数据目录
rsync -avz /backup/clickhouse_snapshot/ /var/lib/clickhouse/
# 3. 启动服务
sudo systemctl start clickhouse-server
三、方案二:内置 BACKUP / RESTORE(21.8+ 推荐)
从 ClickHouse 21.8 版本开始,官方提供了 BACKUP 和 RESTORE 语句,这是生产环境最推荐的备份方式。
3.1 配置备份存储磁盘
在使用 BACKUP 前,需要先在配置文件中定义备份存储位置。
编辑 /etc/clickhouse-server/config.d/backup.xml:
xml
<clickhouse>
<disks>
<backup_disk>
<type>local</type>
<path>/data/clickhouse_backups/</path>
</backup_disk>
<!-- 可选:使用 S3 作为备份存储 -->
<s3_backup_disk>
<type>s3</type>
<endpoint>https://your-bucket.s3.amazonaws.com/clickhouse_backups/</endpoint>
<access_key_id>YOUR_ACCESS_KEY</access_key_id>
<secret_access_key>YOUR_SECRET_KEY</secret_access_key>
</s3_backup_disk>
</disks>
</clickhouse>
bash
# 重启服务使配置生效
sudo systemctl restart clickhouse-server
3.2 执行备份
sql
-- 备份整个数据库
BACKUP DATABASE my_database TO Disk('backup_disk', 'backup_20250601');
-- 备份单张表
BACKUP TABLE my_database.user_behavior TO Disk('backup_disk', 'backup_user_behavior');
-- 备份多张表(TABLE 后可跟多个表名)
BACKUP TABLE my_database.table1, my_database.table2 TO Disk('backup_disk', 'backup_multiple');
-- 带压缩选项的备份
BACKUP DATABASE my_database TO Disk('backup_disk', 'backup_compressed')
SETTINGS compression_method = 'lz4', compression_level = 3;
-- 增量备份(基于已有全量备份)
BACKUP DATABASE my_database TO Disk('backup_disk', 'backup_incremental')
SETTINGS base_backup = Disk('backup_disk', 'backup_20250601');
3.3 查看和管理备份
sql
-- 查看备份历史
SELECT * FROM system.backups;
-- 删除旧备份(需要在磁盘上手动删除文件)
-- 备份文件位于 /data/clickhouse_backups/ 目录下
3.4 恢复数据
sql
-- 从备份恢复整个数据库(注意:会覆盖现有数据)
RESTORE DATABASE my_database FROM Disk('backup_disk', 'backup_20250601');
-- 恢复单张表
RESTORE TABLE my_database.user_behavior FROM Disk('backup_disk', 'backup_user_behavior');
-- 恢复到新表名
RESTORE TABLE my_database.user_behavior AS my_database.user_behavior_old
FROM Disk('backup_disk', 'backup_user_behavior');
-- 允许覆盖已存在的表(需谨慎)
RESTORE DATABASE my_database FROM Disk('backup_disk', 'backup_20250601')
SETTINGS allow_non_empty_tables = true;
3.5 集群场景的分布式备份
在 ClickHouse 集群中,BACKUP 语句会自动协调所有分片:
sql
-- 在任意一个节点执行,会自动备份整个分布式表的所有分片
BACKUP TABLE my_distributed_table TO Disk('backup_disk', 'distributed_backup');
集群备份注意事项:
| 注意点 | 说明 |
|---|---|
| 磁盘配置一致 | 所有节点的 backup_disk 配置必须相同(路径可不同) |
| 共享存储推荐 | 建议使用 NFS 或 S3 作为统一备份目标,方便集中管理 |
| 网络带宽 | 集群备份会产生跨节点数据传输,建议在低峰期执行 |
四、方案三:逻辑备份(clickhouse-client 导出)
4.1 导出为 CSV
适用于小表或需要跨版本迁移的场景。
bash
# 导出单表
clickhouse-client --query "SELECT * FROM my_database.my_table FORMAT CSV" > /backup/my_table.csv
# 导出带条件的部分数据
clickhouse-client --query "SELECT * FROM my_database.my_table WHERE event_date = '2025-06-01' FORMAT CSV" > /backup/my_table_20250601.csv
# 导出为 Parquet 格式(压缩更好,推荐)
clickhouse-client --query "SELECT * FROM my_database.my_table FORMAT Parquet" > /backup/my_table.parquet
4.2 导入恢复
bash
# 从 CSV 导入
clickhouse-client --query "INSERT INTO my_database.my_table FORMAT CSV" < /backup/my_table.csv
# 从 Parquet 导入
clickhouse-client --query "INSERT INTO my_database.my_table FORMAT Parquet" < /backup/my_table.parquet
4.3 并行导出脚本(适用于大表)
bash
#!/bin/bash
# 按分区并行导出
for partition in $(clickhouse-client --query "SELECT DISTINCT partition FROM system.parts WHERE table='my_table'"); do
clickhouse-client --query "SELECT * FROM my_table WHERE partition = '$partition' FORMAT CSV" > /backup/my_table_$partition.csv &
done
wait
五、方案对比与选型建议
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 日常周期性备份(21.8+) | BACKUP 语句 |
在线、增量、自动协调集群 |
| 在线全量物理备份(旧版本) | FREEZE + rsync |
不停服务,硬链接快照 |
| 紧急恢复/全量迁移 | 物理拷贝(停服务) | 最简单直接,恢复快 |
| 小表/跨版本迁移 | CSV/Parquet 导出 | 格式通用,灵活 |
| 集群分布式备份 | BACKUP + S3/NFS 共享存储 |
统一管理,配置简单 |
六、生产环境最佳实践
6.1 定期备份脚本(crontab 示例)
bash
#!/bin/bash
# /opt/scripts/clickhouse_backup.sh
BACKUP_NAME="backup_$(date +%Y%m%d_%H%M%S)"
RETENTION_DAYS=30
# 执行备份
clickhouse-client --query "BACKUP DATABASE analytics TO Disk('backup_disk', '$BACKUP_NAME')"
# 清理 30 天前的旧备份
find /data/clickhouse_backups/ -type d -name "backup_*" -mtime +$RETENTION_DAYS -exec rm -rf {} \;
bash
# 添加到 crontab:每天凌晨 2 点执行
0 2 * * * /opt/scripts/clickhouse_backup.sh
6.2 备份验证清单
| 验证项 | 方法 |
|---|---|
| 备份文件完整性 | 定期在测试环境执行 RESTORE 演练 |
| 备份大小监控 | 设置磁盘空间告警(建议使用率 < 80%) |
| 备份耗时监控 | 记录备份开始/结束时间,发现异常增长 |
| 跨集群备份 | 重要数据建议备份到异地(S3 跨区域复制) |
6.3 常见问题处理
| 问题 | 解决方案 |
|---|---|
| 备份失败:Disk not found | 检查配置文件中的磁盘名称是否正确,所有节点配置一致 |
| 恢复时报错:Table already exists | 使用 SETTINGS allow_non_empty_tables = true 覆盖 |
| 备份文件过大 | 启用压缩 compression_method = 'lz4',或使用增量备份 |
| 集群备份不一致 | 检查各节点时间是否同步(NTP),网络延迟是否过高 |
七、总结
| 备份方式 | 核心命令 | 是否停服务 | 推荐场景 |
|---|---|---|---|
| 停服务拷贝 | rsync /var/lib/clickhouse/ |
✅ 需要 | 紧急全量恢复 |
| FREEZE 快照 | ALTER TABLE ... FREEZE |
❌ 不需要 | 旧版本在线备份 |
| BACKUP 语句 | BACKUP DATABASE ... TO Disk(...) |
❌ 不需要 | 日常生产备份(推荐) |
| CSV/Parquet 导出 | clickhouse-client --query ... |
❌ 不需要 | 小表、跨版本迁移 |
一句话建议:
21.8 及以上版本,使用
BACKUP语句;旧版本使用FREEZE快照。无论哪种方式,定期在测试环境做恢复演练,才是备份策略的最后闭环。
如需深入了解 ClickHouse 的部署架构选型、分片与副本机制详解、分布式表原理剖析、无中心架构设计哲学、生产环境集群调优、多副本一致性实践、ClickHouse Keeper 核心原理等内容,请持续关注本专栏《ClickHouse 一站式从入门到实战》系列文章。
如果觉得本文对你有帮助,欢迎点赞、收藏、转发支持~
数据备份是数据库运维的最后一道防线。ClickHouse 作为一款列式 OLAP 数据库,提供了多种备份恢复方案------从传统的物理文件拷贝,到内置的