GBase 8a
备份恢复
文章
精选

GBase 8a 备份恢复完整指南:gcrcman 从入门到生产实践

发表于2026-03-30 09:53:52263次浏览3个评论

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 恢复是快照级别,恢复到某个备份点后,该点之后的所有变更都会消失。如果只是想恢复误删的某张表,应使用表级恢复而非集群级恢复,避免影响其他数据。

评论

登录后才可以发表评论
GBase用户21182发表于 6个月前
感谢分享
GBase用户47954发表于 5个月前
感谢作者的精彩分享!
流泪猫猫头发表于 3个月前
很详细实用的文章