Doris(Apache Doris)的备份与恢复是确保数据安全的核心运维任务。以下为您提供一套完整、可操作的备份恢复方案,涵盖不同场景和策略。
一、核心备份策略对比
| 策略 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| **逻辑备份(官方推荐)** | 生产环境定期备份、跨集群迁移、表/分区级恢复 | 支持增量、粒度灵活、无需停机 | 恢复速度依赖网络,需规划存储空间 |
| 物理快照 | 重大升级前、集群迁移(同拓扑) | 恢复最快、完整一致 | 需停机、灵活性差、拓扑必须一致 |
| 导出/导入 | 数据归档、跨系统交换、小规模数据迁移 | 格式通用、可用于ETL | 速度慢、需单独处理元数据 |
二、逻辑备份详细方案(生产环境首选)
1. 准备工作
sql
-- 查看已有Broker(用于访问远程存储)
SHOW BROKER;
-- 如果没有Broker,需先配置(通常在fe.conf中配置)
-- 创建远程仓库(以S3为例)
CREATE REPOSITORY `doris_backup_repo`
WITH S3
ON LOCATION "s3://your-bucket/doris-backup/"
PROPERTIES
(
"s3.endpoint" = "https://s3.amazonaws.com",
"s3.access_key" = "your_access_key",
"s3.secret_key" = "your_secret_key",
"s3.region" = "us-east-1"
);
-- 查看仓库状态
SHOW REPOSITORIES;
2. 备份操作
sql
-- 全库备份(推荐按业务分库备份)
BACKUP SNAPSHOT `your_db`.`snapshot_20241105`
TO `doris_backup_repo`
ON (
`table1`,
`table2`,
`table3`
)
PROPERTIES (
"type" = "full", -- 首次用full,后续可用incremental
"label" = "full_backup_20241105",
"timeout" = "7200"
);
-- 增量备份(必须基于最近一次成功的全量/增量快照)
BACKUP SNAPSHOT `your_db`.`snapshot_20241106`
TO `doris_backup_repo`
ON (`table1`)
PROPERTIES (
"type" = "incremental",
"label" = "inc_backup_20241106"
);
-- 查看备份任务
SHOW BACKUP FROM `your_db`\G;
-- 查看所有快照
SHOW SNAPSHOT ON `doris_backup_repo`;
3. 恢复操作
sql
-- 方案1:恢复到原表(表需存在且结构一致)
RESTORE SNAPSHOT `your_db`.`snapshot_20241105`
FROM `doris_backup_repo`
ON (
`backup_table1` TO `your_db`.`table1`
)
PROPERTIES (
"backup_timestamp" = "2024-11-05-18-30-00", -- 从SHOW SNAPSHOT获取
"replication_num" = "3"
);
-- 方案2:恢复到新表(重命名)
RESTORE SNAPSHOT `your_db`.`snapshot_20241105`
FROM `doris_backup_repo`
ON (
`backup_table1` TO `your_db`.`table1_restored`
);
-- 方案3:跨集群恢复(在新集群执行)
-- 先创建同名数据库,或恢复到不同数据库
RESTORE SNAPSHOT `your_db`.`snapshot_20241105`
FROM `doris_backup_repo`
ON (
`backup_table1` TO `new_db`.`table1`
);
-- 查看恢复进度
SHOW RESTORE FROM `your_db`\G;
4. 备份保留策略
sql
-- 手动清理旧快照(自动清理需结合外部脚本)
DROP SNAPSHOT ON `doris_backup_repo`
WHERE SNAPSHOT = "snapshot_20241001";
三、物理备份方案(全量冷备)
1. 备份流程
bash
#!/bin/bash
# 物理备份脚本示例
# 1. 停止所有写入(业务层停止或设置readonly)
mysql -hFE_HOST -P9030 -uroot -e "SET GLOBAL read_only = true;"
# 2. 备份FE元数据
scp -r doris-fe/doris-meta/ backup/fe-meta-$(date +%Y%m%d)/
# 3. 备份BE数据(每个BE节点执行)
# 方案A:直接打包storage目录
tar czf be-storage-$(date +%Y%m%d).tar.gz be/storage/
# 方案B:使用rsync增量同步
rsync -av --delete be/storage/ backup/be-storage/
# 4. 备份配置文件
cp -r fe/conf/ backup/fe-conf-$(date +%Y%m%d)/
cp -r be/conf/ backup/be-conf-$(date +%Y%m%d)/
# 5. 恢复写入
mysql -hFE_HOST -P9030 -uroot -e "SET GLOBAL read_only = false;"
2. 恢复流程
bash
#!/bin/bash
# 物理恢复脚本(集群拓扑必须一致)
# 1. 停止整个Doris集群
./fe/bin/stop_fe.sh
./be/bin/stop_be.sh
# 2. 恢复FE元数据
rm -rf doris-fe/doris-meta/*
cp -r backup/fe-meta-20241105/* doris-fe/doris-meta/
# 3. 恢复BE数据(每个BE节点执行)
rm -rf be/storage/*
tar xzf be-storage-20241105.tar.gz -C ./
# 4. 恢复配置文件(如有修改)
cp backup/fe-conf-20241105/* fe/conf/
cp backup/be-conf-20241105/* be/conf/
# 5. 启动集群(先启动所有FE,再启动所有BE)
./fe/bin/start_fe.sh --daemon
./be/bin/start_be.sh --daemon
四、导出/导入方案(数据交换)
1. 数据导出
sql
-- 导出为Parquet(推荐)
SELECT * FROM your_table
INTO OUTFILE "s3://your-bucket/export/table_parquet/"
FORMAT AS PARQUET
PROPERTIES (
"broker.name" = "broker_name",
"compression" = "snappy"
);
-- 导出为CSV
SELECT * FROM your_table
INTO OUTFILE "hdfs://path/export/table.csv"
FORMAT AS CSV
PROPERTIES (
"column_separator" = ",",
"line_delimiter" = "\n"
);
2. 数据导入恢复
sql
-- 先创建表结构(从SHOW CREATE TABLE获取)
CREATE TABLE your_table_restored LIKE your_table;
-- 使用Broker Load导入Parquet
LOAD LABEL db1.label1
(
DATA INFILE("s3://your-bucket/export/table_parquet/*")
INTO TABLE your_table_restored
FORMAT AS "parquet"
)
WITH BROKER "broker_name"
PROPERTIES (
"timeout" = "3600"
);
五、生产环境最佳实践
1. 备份策略设计
# 多级备份策略示例
daily_backup:
type: incremental
retention: 7 days
time: "02:00"
targets: 所有业务库
weekly_backup:
type: full
retention: 30 days
day: "Sunday"
time: "03:00"
monthly_backup:
type: full
retention: 1 year
day: "first day"
export_format: parquet # 额外导出归档
2. 自动化脚本框架
python
#!/usr/bin/env python3
# backup_scheduler.py
import schedule
import subprocess
import datetime
def backup_job():
snapshot_name = f"snapshot_{datetime.datetime.now().strftime('%Y%m%d_%H%M')}"
backup_type = "incremental" if datetime.datetime.now().weekday() != 6 else "full"
cmd = f"""
mysql -h{fe_host} -P9030 -uroot -e "
BACKUP SNAPSHOT `prod_db`.`{snapshot_name}`
TO `backup_repo`
ON (`table1`, `table2`)
PROPERTIES ('type' = '{backup_type}');
"
"""
subprocess.run(cmd, shell=True)
# 清理过期快照(保留策略)
cleanup_old_snapshots()
# 每日2点执行
schedule.every().day.at("02:00").do(backup_job)
3. 关键注意事项
-
测试恢复流程:定期在测试集群验证备份可恢复性
-
监控备份任务:集成到监控系统(Prometheus + AlertManager)
-
异地备份:至少一份备份在异地存储(如S3跨区域复制)
-
元数据备份 :除了数据,定期备份
SHOW CREATE TABLE语句 -
版本兼容性:确保备份恢复的Doris版本兼容
-
加密与权限:远程存储启用加密,最小权限访问
六、紧急恢复流程图
python
graph TD
A[数据丢失/损坏] --> B{损坏程度评估}
B -->|单表/分区| C[逻辑备份恢复]
B -->|整个集群| D[物理快照恢复]
C --> C1[使用RESTORE命令]
C1 --> C2[验证数据完整性]
C2 --> E[恢复完成]
D --> D1[停止集群]
D1 --> D2[恢复FE元数据]
D2 --> D3[恢复BE数据]
D3 --> D4[重启集群]
D4 --> E
B -->|无可用备份| F[尝试Binlog恢复]
F -->|有Binlog| G[通过Binlog重放]
F -->|无Binlog| H[从下游系统重建]
七、常见问题解决
Q1: 恢复时提示Table already exists?
sql
-- 先删除原表(确认可删除)
DROP TABLE IF EXISTS your_table FORCE;
-- 或恢复到新表名
Q2: 增量备份失败?
sql
-- 查看最后一次成功备份
SHOW BACKUP FROM db_name WHERE STATE = "FINISHED";
-- 可能需要重新做全量备份
Q3: 恢复速度太慢?
-
增加
timeout参数 -
调整BE的
download_thread_num -
确保网络带宽和存储性能
Q4: 磁盘空间不足?
sql
-- 清理本地临时快照(恢复完成后)
ADMIN CLEAN REPOSITORY ON backup_repo;
总结建议
-
核心生产集群 :采用
逻辑全量(每周)+ 增量(每日)组合 -
备份验证:每月至少进行一次恢复演练
-
文档记录:详细记录备份策略、恢复步骤、负责人
-
容量规划:备份存储空间 = 数据量 × 保留周期 × 1.5(冗余系数)
这套方案覆盖了Doris备份恢复的主要场景,您可以根据实际环境进行调整。关键是要定期测试恢复流程,确保备份真正可用。