1. 首页
  2. 博客
  3. ClickHouse 增量备份操作文档

ClickHouse 增量备份操作文档

一只会飞的鱼儿 18天前 ⋅ 10 阅读
ad
## 一、环境信息

 

| 角色 | 服务器 | 说明 |
|------|--------|------|
| 源服务器(staging CK) | `81.132.201.61` | Docker ClickHouse 24.3.2.23,数据约 21GB |
| 远程备份服务器 | `41.111.222.115` | SFTP 备份存储目标,磁盘 40G |

 

### 源服务器关键信息

 

| 项目 | 值 |
|------|-----|
| Docker 容器名 | `clickhouse-server` |
| ClickHouse 版本 | 24.3.2.23 |
| 数据目录(宿主机) | `/data/docker/clickhouse/data` |
| 数据目录(容器内) | `/var/lib/clickhouse` |
| clickhouse-backup 路径 | `/usr/local/bin/clickhouse-backup`(安装在宿主机上,非容器内) |
| clickhouse-backup 版本 | 2.5.17 |
| 配置文件路径 | `/etc/clickhouse-backup/config.yml` |
| 脚本目录 | `/home/tools/` |
| 端口映射 | 8123→8123, 9000→9000, 9009→9009 |
| 系统架构 | x86_64 |

 

### ClickHouse 用户信息

 

| 用户名 | 密码 | 说明 |
|--------|------|------|
| `webfunny_user` | `123` | 唯一可用用户,有 access_management 权限 |
| ~~`default`~~ | ~~已移除~~ | users.d/default-user.xml 中 remove="remove" |
| ~~`root`~~ | ~~不可用~~ | docker-compose 中配置但已被 users.xml 覆盖 |

 

### 备份策略

 

采用「周度全量基准 + 日度增量更新」策略:

 

- **周日 00:00**:执行全量基准备份,记录基准名称到本地和远程标记文件
- **周一至周六 00:00**:基于周日全量基准,用 `--diff-from-remote` 增量上传差异数据
- 所有增量直连全量基准,不接力上一日增量,杜绝级联损坏风险
- 本地保留最近 2 份,远程保留最近 7 份(保护全量基准,仅清理增量)
- 备份成功/失败均推送微信告警

 

---

 

## 二、完整部署步骤

 

### 步骤 1:初始化远程备份服务器目录

 

登录远程备份服务器,创建备份目录和基准目录:

 

```bash
ssh root@41.111.222.135
# 密码:xxx

 

mkdir -p /home/data_dev/clickhouse_backup/base/
```

 

验证:

 

```bash
ls -la /home/data_dev/clickhouse_backup/
# 应看到 base/ 目录
```

 

### 步骤 2:在源服务器创建符号链接

 

clickhouse-backup 安装在宿主机上,但需要访问容器的数据目录。容器内 `/var/lib/clickhouse` 挂载到宿主机 `/data/docker/clickhouse/data`,因此需要创建符号链接:

 

```bash
ssh root@81.132.211.6
# 密码:xxx

 

mkdir -p /var/lib
ln -sf /data/docker/clickhouse/data /var/lib/clickhouse
```

 

验证:

 

```bash
ls -la /var/lib/clickhouse/
# 应看到 store/、metadata/、data/ 等目录
```

 

> **重要**:如果不创建此符号链接,clickhouse-backup 会报错找不到数据目录。

 

### 步骤 3:部署配置文件

 

将 `config.yml` 上传到源服务器的 `/etc/clickhouse-backup/config.yml`:

 

```bash
scp config.yml root@8.133.201.61:/etc/clickhouse-backup/config.yml
```

 

关键配置项确认:

 

```yaml
general:
remote_storage: sftp# 使用 SFTP 远程存储
backups_to_keep_local: 7# 本地保留 7 份
backups_to_keep_remote: 7# 远程保留 7 份
download_concurrency: 4# 下载并发
upload_concurrency: 4# 上传并发

 

clickhouse:
username: "webfunny_user"# ClickHouse 用户名
password: "abc345jdhgga@0886smnbv"# ClickHouse 密码
host: "127.0.0.1"# 本地连接
port: 9000# ClickHouse 原生端口
freeze_by_part: true# 增量备份核心依赖!必须开启
skip_tables:
- system.* # 跳过系统表
timeout: 30m# 超时时间

 

sftp:
address: "41.111.222.135"# 远程备份服务器 IP
port: 22
username: "root"
password: "xxx"
path: "/home/data_dev/clickhouse_backup"# 远程备份路径
compression_format: tar
compression_level: 6# 压缩级别
concurrency: 1# SFTP 并发
connection_timeout: 60s
transfer_timeout: 10800s# 3 小时传输超时
```

 

> **重要**:`freeze_by_part: true` 是增量备份生效的核心配置,关闭后增量等同于全量。

 

### 步骤 4:部署微信通知脚本

 

将 `wechat_notify.sh` 上传到源服务器:

 

```bash
scp wechat_notify.sh root@81.133.211.61:/home/tools/wechat_notify.sh
ssh root@81.133.211.6 "chmod +x /home/tools/wechat_notify.sh"
```

 

### 步骤 5:部署增量备份脚本

 

将 `clickhouse_backup_incremental.sh` 上传到源服务器:

 

```bash
scp 增量备份/clickhouse_backup_incremental.sh root@81.133.211.61:/home/tools/clickhouse_backup_incremental.sh
ssh root@81.133.211.61 "chmod +x /home/tools/clickhouse_backup_incremental.sh"
```

 

> **注意**:此脚本直接在宿主机上运行 `clickhouse-backup` 命令(不使用 `docker exec`),因为 clickhouse-backup 安装在宿主机上。

 

### 步骤 6:配置 SSH 免密登录

 

脚本中需要通过 SSH 写入远程标记文件,必须配置免密登录:

 

```bash
ssh root@81.133.211.61

 

# 如果没有 SSH 密钥,先生成
ssh-keygen -t rsa -N "" -f ~/.ssh/id_rsa

 

# 将公钥复制到远程备份服务器
ssh-copy-id -o StrictHostKeyChecking=no root@41.111.222.135
# 输入远程服务器密码:xxx

 

# 验证免密登录
ssh root@41.11·.222.135 'echo SSH_OK && hostname'
# 应输出 SSH_OK 和主机名,无需输入密码
```

 

### 步骤 7:手动执行首次全量备份(初始化基准)

 

首次运行前必须先执行一次全量备份,建立基准:

 

```bash
ssh root@81.133.211.61

 

# 1. 创建本地全量备份
clickhouse-backup create full_global_backup_initial -v

 

# 2. 上传到远程服务器(14.8GB 数据约需 20-30 分钟)
clickhouse-backup upload full_global_backup_initial -v

 

# 3. 写入本地追踪文件
echo 'full_global_backup_initial' > /home/tools/.ck_incremental_tracker

 

# 4. 写入远程基准标记
ssh root@47.116.222.135 "mkdir -p /home/data_dev/clickhouse_backup/base && echo 'full_global_backup_initial' > /home/data_dev/clickhouse_backup/base/.last_full_backup"

 

# 5. 清理本地缓存
rm -rf /var/lib/clickhouse/backup/full_global_backup_initial
```

 

### 步骤 8:配置定时任务

 

```bash
ssh root@81.133.211.61

 

# 添加 crontab 定时任务(每天凌晨 00:00 执行)
(crontab -l 2>/dev/null; echo '0 0 * * * /bin/bash /home/tools/clickhouse_backup_incremental.sh > /home/tools/backup_incremental.log 2>&1') | sort -u | crontab -

 

# 验证
crontab -l
```

 

### 步骤 9:验证

 

```bash
ssh root@81.133.211.61

 

# 验证 clickhouse-backup 可以正常连接
clickhouse-backup list

 

# 验证本地追踪文件
cat /home/tools/.ck_incremental_tracker
# 应输出:full_global_backup_initial

 

# 验证远程备份文件
ssh root@41.111.222.135 "ls -la /home/data_dev/clickhouse_backup/full_global_backup_initial/"
# 应看到 metadata/、metadata.json、shadow/ 目录
```

 

---

 

## 三、备份脚本工作原理

 

### 脚本逻辑流程

 

```
脚本启动
│
├── 判断今天星期几(date +%u)
│
├── 周日(DOW=7)
│ ├── clickhouse-backup create full_global_backup_时间戳 # 创建全量
│ ├── clickhouse-backup upload 全量备份名 # 上传到远程
│ ├── echo 备份名 > /home/tools/.ck_incremental_tracker # 写本地追踪
│ └── ssh root@远程 "echo 备份名 > base/.last_full_backup" # 写远程标记
│
└── 周一~周六(DOW=1~6)
├── 读取 /home/tools/.ck_incremental_tracker 获取全量基准名
├── clickhouse-backup create inc_global_backup_时间戳 # 创建增量
└── clickhouse-backup upload --diff-from-remote=基准名 增量备份名 # 增量上传
│
├── 统计耗时 + 微信告警(成功/失败)
├── 清理本地备份缓存
├── 本地保留最近 2 份
└── 远程保留最近 7 份(仅删除 inc_* 增量,保护 full_* 全量基准)
```

 

### 关键文件说明

 

| 文件路径 | 作用 | 所在服务器 |
|----------|------|-----------|
| `/etc/clickhouse-backup/config.yml` | clickhouse-backup 主配置文件 | 源服务器 81.133.211.61 |
| `/home/tools/clickhouse_backup_incremental.sh` | 增量备份脚本 | 源服务器81.133.211.61 |
| `/home/tools/wechat_notify.sh` | 微信通知函数 | 源服务器81.133.211.61 |
| `/home/tools/.ck_incremental_tracker` | 本地全量基准追踪文件 | 源服务器81.133.211.61 |
| `/home/data_dev/clickhouse_backup/base/.last_full_backup` | 远程全量基准标记文件 | 备份服务器 41.111.222.135 |
| `/home/data_dev/clickhouse_backup/` | SFTP 远程备份根目录 | 备份服务器 41.111.222.135 |
| `/home/tools/backup_incremental.log` | 备份日志 | 源服务器81.133.211.61 |

 

---

 

## 四、数据恢复流程

 

增量备份恢复遵循「先基准、后增量」原则:

 

```bash
ssh root@81.133.211.61

 

# 1. 恢复基准全量备份(本周周日备份)
clickhouse-backup download full_global_backup_2026-XX-XXT00-00-01
clickhouse-backup restore full_global_backup_2026-XX-XXT00-00-01 --rm

 

# 2. 叠加恢复对应日期增量备份
clickhouse-backup download inc_global_backup_2026-XX-XXT00-00-01
clickhouse-backup restore inc_global_backup_2026-XX-XXT00-00-01 --rm
```

 

> `--rm` 参数表示恢复前先删除现有数据。

 

---

 

## 五、部署过程中遇到的问题及解决方案

 

### 问题 1:clickhouse-backup 不在 Docker 容器内

 

**现象**:执行 `docker exec clickhouse-server clickhouse-backup` 报错 `executable file not found in $PATH`

 

**原因**:原方案设计为在容器内运行 clickhouse-backup(类似生产环境),但 staging 服务器上 clickhouse-backup 安装在宿主机 `/usr/local/bin/` 而非容器内。

 

**解决方案**:
- 将备份脚本从 `docker exec $CONTAINER clickhouse-backup ...` 改为直接 `clickhouse-backup ...`
- 由于宿主机上端口 9000 已映射,clickhouse-backup 可直接通过 `127.0.0.1:9000` 连接 ClickHouse

 

### 问题 2:`/var/lib/clickhouse` 在宿主机上不存在

 

**现象**:clickhouse-backup 运行时报错找不到数据目录

 

**原因**:clickhouse-backup 通过查询 ClickHouse 的 `system.disks` 获取数据路径 `/var/lib/clickhouse`,但宿主机上该路径不存在(数据实际在 `/data/docker/clickhouse/data`)。

 

**解决方案**:创建符号链接
```bash
ln -sf /data/docker/clickhouse/data /var/lib/clickhouse
```

 

### 问题 3:ClickHouse 认证失败

 

**现象**:`clickhouse-backup list` 报错 `Authentication failed: password is incorrect`

 

**原因**:
- 旧配置使用 `default` 用户 + 密码 `das345jdlka@0976sfda`
- docker-compose 配置 `root` 用户 + 密码 `clickhouse`
- 但 `users.d/default-user.xml` 中 **移除了 default 用户**,创建了 `webfunny_user` 用户
- 实际可用用户只有 `webfunny_user`,密码为 `abc345jdhgga@0886smnbv`

 

**排查过程**:
1. 尝试 `root/clickhouse` → 认证失败
2. 尝试 `default/xxx` → 认证失败
3. 查看 `/etc/clickhouse-server/users.d/default-user.xml` 发现 default 被 remove
4. 使用无密码连接 `clickhouse-client`(容器内)返回 `webfunny_user`
5. 最终确认正确凭证:`webfunny_user` / `xxx`

 

**解决方案**:更新 config.yml 中的 clickhouse 凭证。

 

### 问题 4:远程备份出现 broken 条目

 

**现象**:`clickhouse-backup list` 显示远程有一个 `base` 的 broken 条目:`base ??? remote broken (can't stat metadata.json)`

 

**原因**:初始化时在远程服务器创建了 `base/` 目录用于存储标记文件,但 clickhouse-backup 将其误认为备份目录。

 

**解决方案**:删除 broken 条目
```bash
clickhouse-backup delete remote base
```

 

### 问题 5:`freeze_by_part` 配置默认为 false

 

**现象**:如果不开启此配置,增量备份无法实现 Part 级别差异对比,增量等同于全量。

 

**原因**:旧配置文件中 `freeze_by_part: false`。

 

**解决方案**:修改为 `freeze_by_part: true`,这是增量备份的核心依赖配置。

 

### 问题 6:expect 脚本中 `!` 是特殊字符

 

**现象**:自动化部署时 expect 脚本报错 `invalid command name "!"`

 

**原因**:Tcl/expect 中 `!` 是特殊字符,不能直接在 `send` 命令中使用。

 

**解决方案**:避免在 expect 脚本中使用含 `!` 的 shell 条件判断,改用其他写法或直接跳过。

 

---

 

## 六、日常运维检查

 

### 查看备份状态

 

```bash
ssh root@81.133.211.61

 

# 查看本地和远程备份列表
clickhouse-backup list

 

# 查看仅本地备份
clickhouse-backup list local

 

# 查看仅远程备份
clickhouse-backup list remote

 

# 查看备份日志
tail -100 /home/tools/backup_incremental.log
```

 

### 查看远程备份文件

 

```bash
ssh root@41.111.222.135

 

# 查看备份目录
ls -la /home/data_dev/clickhouse_backup/

 

# 查看各备份大小
du -sh /home/data_dev/clickhouse_backup/*/

 

# 查看磁盘使用
df -h /
```

 

### 检查定时任务

 

```bash
ssh root@81.133.211.61
crontab -l
```

 

---

 

## 七、注意事项

 

1. **freeze_by_part 必须为 true**:增量备份的核心配置,关闭后增量等同于全量
2. **基准不断层**:每周日全量备份必须执行成功,否则后续一周增量备份全部失效
3. **SSH 免密配置**:脚本中需要通过 SSH 写入远程标记文件,必须配置免密登录
4. **符号链接持久性**:`/var/lib/clickhouse` 符号链接在服务器重启后依然有效,但容器重建后需确认
5. **磁盘空间监控**:远程服务器磁盘 40G 已使用约 82%(15G 备份 + 系统占用),增量备份体积很小但需定期关注
6. **定期演练**:每月至少一次备份恢复演练,验证备份文件可用性
7. **日志监控**:定期查看 `/home/tools/backup_incremental.log`,结合微信告警及时发现异常
8. **ClickHouse 重启后**:如果 ClickHouse 容器重建,需确认端口映射 9000 仍然生效

 

关于Webfunny

Webfunny专注于前端监控系统,前端埋点系统的研发。 致力于帮助开发者快速定位问题,帮助企业用数据驱动业务,实现业务数据的快速增长。支持H5/Web/PC前端、微信小程序、支付宝小程序、UniApp和Taro等跨平台框架。实时监控前端网页、前端数据分析、错误统计分析监控和BUG预警,第一时间报警,快速修复BUG!支持私有化部署,Docker容器化部署,可支持千万级PV的日活量!

  点赞 0   收藏 0
  • 一只会飞的鱼儿
    共发布87篇文章 获得10个收藏
全部评论: 0 条