掘金 后端 ( ) • 2024-04-09 13:38

1、概述

用于 ClickHouse 备份和恢复的工具,支持多种云和非云存储类型。要备份数据,需要访问与文件夹中clickhouse-backup相同的文件。因此,最好在同一主机或同一 Kubernetes Pod 上运行,或者在运行的同一主机上的邻居容器上运行。

项目简介

需要备份的目录

目前备份对比

特点

  • 轻松创建和恢复所有或特定表的备份
  • 在文件系统上高效存储多个备份
  • 使用流式压缩上传和下载
  • 适用于 AWS、GCS、Azure、腾讯 COS、FTP、SFTP
  • 支持原子数据库引擎
  • 支持多磁盘安装
  • rclone
  • 支持远程存储增量备份

限制

  • 仅 MergeTree 系列表引擎(更多表类型适用于clickhouse-server22.7+ 和USE_EMBEDDED_BACKUP_RESTORE=true)

工作原理

数据文件在clickhouse-server 在备份操作期间,通过执行查询clickhouse-backup创建到现有数据部分的文件系统硬链接。在恢复操作期间,将硬链接复制到文件夹并对备份中的每个数据部分和每个表执行查询

更详细的描述请参见此处https://www.youtube.com/watch?v=megsNh9Q-dwclickhouse-serverALTER TABLE ... FREZZEclickhouse-backupdetachedALTER TABLE ... ATTACH PART

备份原理

use_embedded_backup_restore为false

  • clickhouse-backup执行alter table 命令
  • 备份移动到backup
  • 上传备份

use_embedded_backup_restore为true

  • clickhouse-backup执行BACKUP SQL 命令
  • clickhouse-server上传物理数据或执行 CopyObject 到 s3 远程存储
  • 在文件夹上创建元数据文件/var/lib/clickhouse/disks/backup_s3/backup_name/
  • clickhouse-backup创建/var/lib/clickhouse/disks/backups_s3/backup_name/metadata.json和/var/lib/clickhouse/disks/backups_s3/backup_name/metadata/db/table_name.json
  • upload上传到配置文件中定义的s3远程存储中

在源码中可以看到这部分逻辑:https://github.com/Altinity/clickhouse-backup/blob/2692ec8e830af13a8b292443fc36608b18cb8f01/pkg/backup/create.go

Clickhouse备份恢复参考:https://clickhouse.com/docs/en/operations/backup#configure-a-backup-destination

当use_embedded_backup_restore: true时,使用BACKUP/RESTORE SQL语句而不是常规SQL

恢复原理

  • 下载备份文件
  • 创建库表
  • 将文件move到clickhouse 相关表的detatched目录
  • alter恢复数据

use_embedded_backup_restore为true 在恢复数据时执行SQL 命令,读取 s3 密钥并将数据部分下载到磁盘的 /var/lib/clickhouse/tmp

2、安装

二进制安装

wget https://github.com/Altinity/clickhouse-backup/releases/download/v2.4.35/clickhouse-backup-linux-amd64.tar.gz 
解压文件即可

部署在k8s中

可以采用operator的方式部署,跟Clickhouse在同一个pod或者在同一个容器中

containers:
- name: clickhouse-cluster
  image: {{ .Values.image.registry }}
  volumeMounts:
  - mountPath: /etc/clickhouse-server/config.xml
    name: chi-clickhouse-cluster-config-file
    subPath: config.xml
  resources:
    {{- toYaml (index $.Values.resources $.Values.global.resourceProfile).resource | nindent 14 }}
- name: clickhouse-backup
  volumeMounts:
    - mountPath: /var/lib/clickhouse
      name: ck-data-dir
  image: altinity/clickhouse-backup:master

3、配置

默认配置文件在/etc/clickhouse-backup/config.yaml, 默认是没有配置文件的,可以用命令生成默认的配置文件

clickhouse-backup default-config > config.yml

参数:

general:
    backups_to_keep_local: 0   # 保留多少本地备份,0表示所有创建备份都在本地保留,-1表示将在create之后保留,但在create_remote之后删除
    backups_to_keep_remote:0  # 保留多少远程存储,0为所有的都保留
    download_concurrency:1    # 最大值255 
    upload_concurrency:1      # 最大值255 
clickhouse:
  use_embedded_backup_restore:true #   use BACKUP / RESTORE SQL statements instead of regular SQL queries to use features of modern ClickHouse server versions
api:
    create_integration_tables  # create `system.backup_list` and `system.backup_actions` 
    enable_metrics: true       # 开启metrics
    enable_pprof: true         # /debug/pprof
    allow_parallel             # 启用并行操作

更多配置可以参考:https://github.com/Altinity/clickhouse-backup?tab=readme-ov-file#default-config 内容还是比较详细的

4、开始备份

  • 备份的时候默认不会备份系统表
  • 只能在clickhouse的机器上备份
  • metadata里存储的是元数据信息,创建表的语句啥的
NAME:
   clickhouse-backup - Tool for easy backup of ClickHouse with cloud support

USAGE:
   clickhouse-backup <command> [-t, --tables=<db>.<table>] <backup_name>

VERSION:
   2692ec8e830af13a8b292443fc36608b18cb8f01

DESCRIPTION:
   Run as 'root' or 'clickhouse' user

COMMANDS:
   tables               List of tables, exclude skip_tables
   create               Create new backup
   create_remote        Create and upload new backup
   upload               Upload backup to remote storage
   list                 List of backups
   download             Download backup from remote storage
   restore              Create schema and restore data from backup
   restore_remote       Download and restore
   delete               Delete specific backup
   default-config       Print default config
   print-config         Print current config merged with environment variables
   clean                Remove data in 'shadow' folder from all 'path' folders available from 'system.disks'
   clean_remote_broken  Remove all broken remote backups
   watch                Run infinite loop which create full + incremental backup sequence to allow efficient backup sequences
   server               Run API server
   help, h              Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --config value, -c value  Config 'FILE' name. (default: "/etc/clickhouse-backup/config.yml") [$CLICKHOUSE_BACKUP_CONFIG]
   --help, -h                show help
   --version, -v             print the version

命令还是比较直观的

print-config: 打印当前配置
default-config: 打印默认配置
create: 创建备份
create_remote: 创建备份,并上传到指定存储
restore:创建表结构,恢复数据
restore_remote: 下载备份文件,恢复数据
list:列出备份集
download:下载备份集
delete:删除备份集
server:启动服务。外部可以使用api方式发起备份、恢复任务。适合在容器化环境中使用。
clean: 清理备份
watch: 循环备份,创建完整+增量备份序列

增量备份的注意事项

在增量备份期间,如果修改表,删除表之类的。会扰乱增量备份的机制

原因是 删除更改表,每个单独的部分会创建一堆具有新名称的部分,在这种情况下,用clickhouse备份来进行增量时,会有些问题。比如修改字段后 会有两个字段都有着相同的数据这样

5、接口备份

GET /

列出当前所有适用的 HTTP 路由


/restart                            # 重新启动 HTTP 服务器
/backup/kill                        # 从命令列表中杀死选定的命令GET /backup/actions,杀死进程,但某些 go 例程(上传一个数据部分)可以继续运行。可选查询参数command可能包含要终止的命令名称,或者如果省略,则终止第一个“正在进行的”命令。
/backup/watch                       # 运行后台监视进程并创建完整+增量备份序列
/backup/tables                      # 打印表列表
/backup/tables/all                  # 打印全部表列表
/backup/list                        # 查看备份列表
/backup/list/{where}                # 查看特定的备份列表

/backup/create                      # 创建备份
/backup/clean                       # 从system.disk中可用的所有path文件夹中删除shadow文件夹中的数据
/backup/clean/remote_broken         # 删除所有损坏的远程备份
/backup/upload/{name}               # 上传备份
/backup/download/{name}             # 下载备份
/backup/restore/{name}              # 恢复备份
/backup/delete/{where}/{name}       # 删除特定的指定备份
/backup/status                      # 显示当前正在运行的异步操作的列表
/backup/actions                     # 显示 API 服务器启动以来的所有操作的列表

每个接口都有对应的参数,具体i可以参考:https://github.com/Altinity/clickhouse-backup/?tab=readme-ov-file#api

6、通过接口恢复

1、表级别恢复

删除test表

使用备份文件恢复

# 查看备份列表
curl "chi-clickhouse-cluster-dtstack-0-0:7171/backup/list"
# 下载备份
curl "chi-clickhouse-cluster-dtstack-0-0:7171/backup/download/shard0-increment-20240408044511" -XPOST  
{"status":"acknowledged","operation":"download","backup_name":"shard0-increment-20240408044511"}
# 恢复备份
curl "chi-clickhouse-cluster-dtstack-0-0:7171/backup/restore/shard0-increment-20240408044511?table=local_1.test&rm" -X POST 
{"status":"acknowledged","operation":"restore","backup_name":"shard0-increment-20240408044511"}

恢复时如果不加rm会报错:can't create table local_1.test: code: 57, message: Directory for table data store/287/2875f3f9-466f-43ac-938a-62fe69210777/ already exists after 1 times, please check your schema dependencies

原因是:删除后不会立即删除,而是等待一段时间后删除,默认是8min, 当然也可以直接重启,也是可以的

查看恢复状态

数据没有删除之前多是正常状态,因为中间差了一个小时的数据,一个小时备份一次

2、库级别恢复

删除库

恢复库

curl "chi-clickhouse-cluster-dtstack-0-0:7171/backup/restore/shard0-increment-20240408044511?table=local_1.*&rm" -X POST 
{"status":"acknowledged","operation":"restore","backup_name":"shard0-increment-20240408044511"}
curl "chi-clickhouse-cluster-dtstack-0-0:7171/backup/actions"
{"command":"restore --tables="local_1.*" --rm shard0-increment-20240408044511","status":"success","start":"2024-04-08 06:31:55","finish":"2024-04-08 06:31:56"}

验证是否恢复

库中表已恢复

库中数据已恢复

最后记录下踩过的坑

问题一: use_embedded_backup_restore改为true报错

error clickhouse `timeout: 5m`, not enough for `use_embedded_backup_restore: true` logger=server.Run

解决办法:

调整对应的参数, 时间改长,原因是BACKUP/RESTORE SQL命令在执行过程中可能会花费大量时间

- name: CLICKHOUSE_TIMEOUT
  value: 4h

扩展:

use_backup_embedded_restore:true需要定义单独的备份磁盘

参考

https://github.com/Altinity/clickhouse-backup/blob/master/test/integration/config-s3-embedded.yml#L20-L23

https://github.com/Altinity/clickhouse-backup/blob/master/test/integration/dynamic_settings.sh#L214-L238

问题二:使用watch进行持续增量和全量备份报错

 'error Watch error: fullInterval 24h is too long to keep 3 remote backups with watchInterval 1h logger=server. 

解决办法:

调整BACKUPS_TO_KEEP_REMOTE保留参数为24 ,因为当前设置BACKUPS_TO_KEEP_REMOTE保留3个不满足当前需求,1小时一个备份,24小时进行一次全备,那么至少需要保留24个