GBase 8a 备份恢复完整指南:gcrcman 从入门到生产实践
GBase 8a 作为 MPP 分析型数据库,没有 WAL 事务日志,备份策略与 OLTP 数据库有本质区别。本文完整覆盖 gcrcman 工具的集群级、库级、表级备份恢复,以及生产环境的备份调度方案和常见问题处理。
一、gcrcman 基础概念
1.1 为什么没有 binlog/WAL
GBase 8a 为了追求大吞吐的 MPP 扫描性能,去掉了事务日志(Write-Ahead Log)。这意味着:
- 不支持基于日志的 Point-in-Time Recovery(PITR)
- 不支持像 MySQL 那样用 binlog 做逻辑复制
- 必须使用专用工具 gcrcman 做周期性快照备份
gcrcman(GBase Cluster Recovery Manager)随集群安装,位于:
$GCLUSTER_BASE/server/bin/gcrcman.py
1.2 备份类型矩阵
| 粒度 | 全量(level 0) | 增量(level 1) | 在线执行 |
|---|---|---|---|
| 集群级 | ✅ | ✅ | ❌(需切 readonly) |
| 库级 | ✅ | ✅ | ❌(需切 readonly) |
| 表级 | ✅ | ✅ | ✅(仅锁该表) |
关键区别:集群级和库级备份需要将集群切换到只读状态,期间业务只能读不能写;表级备份不影响集群整体状态,只锁目标表,对在线业务更友好。
1.3 备份周期与备份点
gcrcman 用**周期(cycle)和备份点(point)**两个维度管理备份历史:
周期 0(全量):2024-06-01 02:00 → cycle=0, point=0, level=0(全量)
2024-06-02 02:00 → cycle=0, point=1, level=1(增量)
2024-06-03 02:00 → cycle=0, point=2, level=1(增量)
周期 1(新全量):2024-06-04 02:00 → cycle=1, point=0, level=0(全量,开启新周期)
2024-06-05 02:00 → cycle=1, point=1, level=1(增量)
恢复时可以指定 cycle_id + point_id,精确还原到任意历史快照点。
二、执行前提条件检查
# 1. 确认集群状态正常(必须 ACTIVE,无 CLOSED 节点)
gcadmin
# 2. 确认各节点时间同步(备份点时间戳依赖系统时钟)
date # 在各节点分别执行,时间差应 < 1 秒
# 3. 创建备份目录(所有节点必须存在,且 gbase 用户有读写权限)
# 在所有节点执行:
mkdir -p /data/backup/gbase8a
chown gbase:gbase /data/backup/gbase8a
# 4. 确认 pexpect 包可用
python -c "import pexpect; print('OK')"
# 如果报错,从安装包目录复制:
cp $GCLUSTER_BASE/../gcinstall/pexpect.py $GCLUSTER_BASE/server/bin/
⚠️ 备份目录不能设置在
$GCLUSTER_BASE、$GBASE_BASE、$GCWARE_BASE及其子目录下。
三、集群级备份与恢复
3.1 执行全量备份
集群级备份前必须先将集群切换为只读:
# 步骤 1:切换为只读状态(gbase 用户执行)
gcadmin switchmode readonly
# 确认状态
gcadmin # CLUSTER STATE 应显示 READONLY
# 步骤 2:进入 gcrcman 交互模式
python $GCLUSTER_BASE/server/bin/gcrcman.py \
-d /data/backup/gbase8a \
-p your_db_password # gbase 数据库用户密码
# 若节点间未配置 SSH 免密,还需指定 -P os_password(操作系统密码)
# 步骤 3:执行全量备份(level 0)
gcrcman> backup level 0
# 步骤 4:备份完成后切回正常状态
gcrcman> exit
gcadmin switchmode normal
3.2 执行增量备份
必须已有全量备份(level 0)才能执行增量:
gcadmin switchmode readonly
python $GCLUSTER_BASE/server/bin/gcrcman.py -d /data/backup/gbase8a -p password
gcrcman> backup level 1 # 增量备份,续写当前周期
gcrcman> exit
gcadmin switchmode normal
3.3 查看备份记录
python $GCLUSTER_BASE/server/bin/gcrcman.py -d /data/backup/gbase8a -p password
gcrcman> show backup
输出示例:
cycle point level time
0 0 0 2024-06-01 02:00:05 ← 全量,开启周期 0
0 1 1 2024-06-02 02:00:08 ← 增量
0 2 1 2024-06-03 02:00:06 ← 增量
1 0 0 2024-06-04 02:00:03 ← 全量,开启周期 1
1 1 1 2024-06-05 02:00:07 ← 增量
3.4 集群级恢复
恢复前必须切换为 recovery 状态:
# 步骤 1:切换为恢复状态
gcadmin switchmode recovery
# 步骤 2:进入 gcrcman 执行恢复
python $GCLUSTER_BASE/server/bin/gcrcman.py -d /data/backup/gbase8a -p password
# 恢复到最新备份点
gcrcman> recover
# 或恢复到指定周期的最新点(恢复到周期 0 的最后一个增量)
gcrcman> recover 0
# 或恢复到指定周期的指定点(恢复到周期 0 的第 1 个增量,即 2024-06-02 的快照)
gcrcman> recover 0 1
gcrcman> exit
# 步骤 3:恢复完成后重启 gcware
su - root
service gcware restart # 或 gcware_services all restart
# 步骤 4:切回正常状态
su - gbase
gcadmin switchmode normal
⚠️ 重要:恢复会将集群数据回滚到备份时间点,备份之后写入的数据会全部丢失。正式环境恢复前务必二次确认。
四、表级备份与恢复
表级备份是生产中使用最频繁的方式:不影响集群整体状态,只锁目标表。
4.1 表级全量备份
python $GCLUSTER_BASE/server/bin/gcrcman.py -d /data/backup/gbase8a -p password
# 备份单张表(全量)
gcrcman> backup table sales_db.orders level 0
# 备份库下所有表(批量表备份)
gcrcman> backup database sales_db level 0
gcrcman> exit
4.2 表级增量备份
gcrcman> backup table sales_db.orders level 1
4.3 表级恢复
表级恢复不需要切换集群状态,直接执行:
python $GCLUSTER_BASE/server/bin/gcrcman.py -d /data/backup/gbase8a -p password
# 恢复表到最新备份点
gcrcman> recover table sales_db.orders
# 恢复到指定备份点(cycle=0, point=1)
gcrcman> recover table sales_db.orders 0 1
gcrcman> exit
五、清理过期备份
python $GCLUSTER_BASE/server/bin/gcrcman.py -d /data/backup/gbase8a -p password
# 查看当前备份记录
gcrcman> show backup
# 删除指定周期(会删除该周期的所有备份点)
# 注意:至少要保留一个完整的"全量+增量"周期,不能全部删除
gcrcman> delete 0 # 删除周期 0 的所有备份
# 清理无效/垃圾备份(备份中断留下的残余文件)
gcrcman> clean
gcrcman> exit
六、生产备份调度方案
6.1 推荐策略
| 备份类型 | 频率 | 执行时间 | 保留周期数 |
|---|---|---|---|
| 集群级全量 | 每周 1 次 | 周日凌晨 01:00 | 2 个周期 |
| 集群级增量 | 每天 1 次(排除全量当天) | 凌晨 02:00 | 随全量周期 |
| 重要表级全量 | 每天 1 次 | 凌晨 00:30 | 7 天 |
6.2 自动化备份脚本
#!/bin/bash
# /home/gbase/scripts/daily_backup.sh
# 每天凌晨 02:00 执行,周日执行全量,其余天执行增量
BACKUP_DIR=/data/backup/gbase8a
DB_PASS=your_db_password
LOG_FILE=/home/gbase/logs/backup_$(date +%Y%m%d).log
GCRCMAN=$GCLUSTER_BASE/server/bin/gcrcman.py
echo "[$(date)] 备份开始" >> $LOG_FILE
# 判断今天是否周日(周日做全量)
DOW=$(date +%u)
if [ "$DOW" -eq 7 ]; then
LEVEL=0
echo "[$(date)] 执行全量备份 (level 0)" >> $LOG_FILE
else
LEVEL=1
echo "[$(date)] 执行增量备份 (level 1)" >> $LOG_FILE
fi
# 集群切只读
gcadmin switchmode readonly >> $LOG_FILE 2>&1
# 执行备份
python $GCRCMAN -d $BACKUP_DIR -p $DB_PASS << EOF >> $LOG_FILE 2>&1
backup level $LEVEL
exit
EOF
BACKUP_STATUS=$?
# 切回正常
gcadmin switchmode normal >> $LOG_FILE 2>&1
if [ $BACKUP_STATUS -eq 0 ]; then
echo "[$(date)] 备份成功" >> $LOG_FILE
else
echo "[$(date)] 备份失败!请检查日志" >> $LOG_FILE
# 此处可以接报警通知(邮件/钉钉/企业微信 webhook)
exit 1
fi
注册为 cron 任务(gbase 用户):
crontab -e
# 追加:
0 2 * * * /home/gbase/scripts/daily_backup.sh
七、扩容/缩容后的备份注意事项
集群拓扑结构(coordinator 节点、datanode 节点、distribution 分片信息)改变后,旧的备份记录无法用于恢复。
正确做法:扩容或缩容操作完成后,立即执行一次新的全量备份(level 0),开启新的备份周期。旧周期的备份可保留一段时间作为紧急回退参考,但不能在新拓扑下直接 recover。
八、常见问题
问题 1:fail to get gcrcman instance backup or recover lock
原因:已有另一个 gcrcman 进程在运行(或上次异常中断遗留了锁)。
-- 查看集群锁
gcadmin showlock
如果确认没有正在运行的备份进程,锁是残留的,可以手动清除:
-- 连接 gcluster 执行
SELECT * FROM gclusterdb.gcluster_lock WHERE lock_name LIKE '%gcrcman%';
-- 联系 DBA 评估后手动删除残留锁记录
问题 2:备份时报磁盘空间不足
gcrcman 在备份前检查磁盘剩余空间。全量备份所需空间约等于数据目录大小的 1.2 倍(含压缩),增量备份约为变更量的 1.5 倍。
# 检查各节点数据目录和备份目录的磁盘使用
df -h /opt/gbase /data/backup
问题 3:恢复后数据与预期不符
gcrcman 恢复是快照级别,恢复到某个备份点后,该点之后的所有变更都会消失。如果只是想恢复误删的某张表,应使用表级恢复而非集群级恢复,避免影响其他数据。
评论
热门帖子
- 12025-12-01浏览数:183621
- 22023-05-09浏览数:26316
- 42023-09-25浏览数:19987
- 52020-05-11浏览数:18691