目 录CONTENT

文章目录

OceanBase 物理备份与日志归档方案

javalx
2026-05-31 / 0 评论 / 0 点赞 / 3 阅读 / 0 字

OceanBase 物理备份与日志归档方案

1. 方案概述

1.1 目标

针对 OceanBase 4.2.1 社区版单节点部署环境,通过 日志归档(持续)+ 全量/增量备份(定时) 的组合策略,防止单节点故障导致数据丢失,满足业务连续性与数据安全要求。

1.2 架构说明

┌──────────────────────────────────────────────────────────────────────┐
│                   OceanBase 单节点集群                               │
│                   (10.0.0.3  obtest)                                 │
│  ┌──────────────────────────────────────────────────────┐            │
│  │  OBServer (rs_port:2882 / mysql_port:2881)           │            │
│  │       │                                              │            │
│  │       ├── 日志归档(CLOG 持续归档)────► /opt/ob_backup/archive    │
│  │       │                                              │            │
│  │       ├── 全量备份(每周日)────► /opt/ob_backup/data              │
│  │       │                                              │            │
│  │       └── 增量备份(每日)────► /opt/ob_backup/data   │            │
│  └──────────────────────────────────────────────────────┘            │
└──────────────────────────────────────────────────────────────────────┘
                           │
                     rsync 异地同步
                           │
                           ▼
              ┌─────────────────────────┐
              │   备用服务器 (8C16G)     │
              │   /opt/ob_backup_remote │
              └─────────────────────────┘

数据流: OBServer → 日志归档(持续写入)+ 数据备份(定时触发)→ 本地备份目录 → rsync 异地同步到备机

1.3 RPO / RTO 目标

指标目标值说明
RPO≤ 1 小时日志持续归档 + 每日增量备份,最坏情况丢失归档窗口内数据
RTO2~4 小时全量恢复 + 归档日志回放,取决于数据量与磁盘 IO
RPO=0日志归档模式下可达归档无延迟时,可恢复到任意时间点(PITR)

2. OceanBase 部署

本章描述从零开始部署 OceanBase + OBProxy 的完整步骤,确保文档自成体系。仅涉及 OceanBase 相关组件,不含 MySQL、Canal、DataX 等其他组件。

2.1 系统准备

2.1.1 关闭防火墙

# 停止并禁用防火墙(需 sudo 权限)
sudo systemctl stop firewalld
sudo systemctl disable firewalld

# 验证防火墙状态
sudo systemctl status firewalld

2.1.2 关闭 SELinux

# 临时关闭
setenforce 0

# 永久关闭
sed -i 's/SELINUX=enforcing/SELINUX=disabled/g' /etc/selinux/config
sed -i 's/SELINUX=permissive/SELINUX=disabled/g' /etc/selinux/config

# 验证
getenforce

2.1.3 时钟同步

# 安装 chrony
yum install -y chrony

# 启动并设置开机自启
systemctl start chronyd
systemctl enable chronyd

# 验证时间同步
chronyc tracking
timedatectl

2.1.4 系统参数优化

# 配置文件句柄数和核心参数
cat >> /etc/security/limits.conf << 'EOF'
*    soft    nofile    655350
*    hard    nofile    655350
*    soft    nproc     655350
*    hard    nproc     655350
*    soft    core      unlimited
*    hard    core      unlimited
*    soft    memlock   unlimited
*    hard    memlock   unlimited
*    soft    stack     10240
*    hard    stack     10240
EOF

# 配置 sysctl 内核参数
cat >> /etc/sysctl.conf << 'EOF'
fs.file-max = 655350
fs.aio-max-nr = 1048576
vm.swappiness = 0
vm.min_free_kbytes = 2097152
vm.max_map_count = 655360
net.core.somaxconn = 2048
net.core.netdev_max_backlog = 2000
net.ipv4.tcp_max_syn_backlog = 2048
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_rmem = 4096 87380 16777216
net.ipv4.tcp_wmem = 4096 65536 16777216
net.ipv4.ip_local_port_range = 1024 65535
EOF

# 立即生效
sysctl -p

# 关闭透明大页
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag

# 永久关闭透明大页
cat >> /etc/rc.d/rc.local << 'EOF'
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
EOF
chmod +x /etc/rc.d/rc.local

2.1.5 磁盘规划(测试环境)

挂载点总容量可用空间用途说明
/50G3.9G系统目录不可用于安装,空间不足
/data49G47G预留扩展IO 隔离
/opt1.2T988GOceanBase 全套组件主安装目录,空间充裕

重要: / 分区仅剩 3.9G,所有 OceanBase 组件安装和数据存储必须放在 /opt 下,切勿使用 /home/var 等根分区目录。

目录规划:

/opt/oceanbase/          # OceanBase All-in-One 安装目录(home_path)
/opt/oceanbase/store/    # OceanBase 数据文件 (datadir)
/opt/oceanbase/log/      # OceanBase 日志 (redo_dir)
/opt/oceanbase/obproxy/  # OBProxy 安装目录
/opt/software/            # 软件包存放目录

2.1.6 验证部署用户和创建目录

使用已有的 ucd 用户进行部署,无需创建新用户:

# 验证 ucd 用户已存在
id ucd

# 创建软件包存放目录
mkdir -p /opt/software

# 设置目录属主
sudo chown -R ucd:ucd /opt/software

注意: OBD 部署要求 home_path 目录为空,因此不要预先创建 /opt/oceanbase 及其子目录,部署时 OBD 会自动创建。

2.1.7 配置 SSH 免密登录

OBD 部署工具即使在单机部署模式下,也需要通过 SSH 协议连接到目标节点进行安装和配置操作。如果未配置 SSH 免密登录,会报错 OBD-1013: connect failed: No authentication methods available

# 1. 生成 SSH 密钥(一路回车,不设置密码)
ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa

# 2. 将公钥添加到 authorized_keys
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

# 3. 设置正确的权限(权限不对会导致免密失败)
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

# 4. 确保 SSH 服务已启动
sudo systemctl start sshd
sudo systemctl enable sshd

# 5. 测试 SSH 免密登录本机(首次连接需输入 yes 确认 host key)
ssh ucd@10.0.0.3 "echo 'SSH免密配置成功'"

2.1.8 安装依赖

# 安装基础依赖包
yum install -y wget curl tar gzip bzip2 unzip perl net-tools vim lrzsz

# 验证安装
which wget && which tar

2.2 OceanBase All-in-One 安装

2.2.1 下载 All-in-One 包

从 OceanBase 官方软件中心下载 All-in-One 包,上传到服务器 /opt/software/ 目录:

  1. 访问 OceanBase 官方软件中心:https://www.oceanbase.com/softwarecenter
  2. 下载 oceanbase-all-in-one-*.tar.gz(具体版本号以官网最新发布为准,如 oceanbase-all-in-one-4.2.1_20231228_x86_64.tar.gz
  3. 上传到服务器 /opt/software/ 目录

说明: OceanBase All in One 包为 tar.gz 格式(不是 RPM),国内镜像源没有 oceanbase-all-in-one 的 RPM 包,因此需从官方软件中心手动下载 tar.gz 格式的安装包。All in One 包已包含以下组件:

  • OceanBase Database(OBServer)
  • OBProxy(代理层)
  • OBD(部署工具)
  • OBClient(命令行客户端)
  • OBAgent(监控代理)
  • 相关依赖库
# 切换到 ucd 用户
su - ucd

# 确认上传的 All-in-One 包
cd /opt/software
ls -lh oceanbase-all-in-one-*.tar.gz

2.2.2 解压安装

# 切换到 ucd 用户
su - ucd

# 解压 All-in-One 包
cd /opt/software
tar -xzf oceanbase-all-in-one-*.tar.gz

# 进入解压后的目录并执行安装脚本
cd oceanbase-all-in-one/
bash bin/install.sh

# 安装脚本会自动安装 OBD、OBClient、OBProxy 等组件

2.2.3 加载环境变量

# 加载环境变量
source ~/.oceanbase-all-in-one/bin/env.sh

# 验证 OBD 安装
obd --version

# 验证 obclient 可用
which obclient

注意: 每次新开终端会话时,都需要先执行 source ~/.oceanbase-all-in-one/bin/env.sh 加载环境变量,否则 obdobclient 命令不可用。可将该命令添加到 ~/.bashrc 中实现自动加载:

echo 'source ~/.oceanbase-all-in-one/bin/env.sh' >> ~/.bashrc

2.3 OBD 配置文件编写

针对 16核 32GB 单机环境,创建 OBD 部署配置文件:

cat > ~/.oceanbase-all-in-one/ob-test.yaml << 'EOF'
oceanbase-ce:
  servers:
    - ip: 10.0.0.3
  global:
    home_path: /opt/oceanbase
    data_dir: /opt/oceanbase/store
    redo_dir: /opt/oceanbase/log
    memory_limit: 24G
    system_memory: 8G
    datafile_size: 300G
    cpu_count: 16
    devname: eth0
    syslog_level: INFO
    enable_syslog_wf: true
    enable_syslog_recycle: true
    max_syslog_file_count: 10
    mysql_port: 2881
    rpc_port: 2882
    cluster_id: 1
    appname: obtest
    zone: zone1

obproxy-ce:
  depends:
    - oceanbase-ce
  servers:
    - ip: 10.0.0.3
  global:
    home_path: /opt/oceanbase/obproxy
    listen_port: 2883
    prometheus_listen_port: 2884
    cluster_name: obtest
    enable_strict_kernel_release: false
EOF

参数说明:

  • memory_limit: 24G — OBServer 进程最大内存,建议为物理内存的 75%(32G × 75% ≈ 24G)
  • system_memory: 8G — 5001 临时租户预留内存,用于 Sort/Join 等内部操作(24G × 33% ≈ 8G)
  • datafile_size: 300G — 数据文件磁盘预占大小,/opt 可用 988G,预留空间给备份和日志
  • cpu_count: 16 — OBServer 可用 CPU 核数
  • enable_syslog_recycle: true + max_syslog_file_count: 10 — 自动回收日志文件,防止日志撑满磁盘

如需修改 IP 地址:

# 查看本机 IP 地址
ip addr show | grep "inet " | grep -v 127.0.0.1

# 替换配置文件中的 IP 地址(将 10.0.0.3 替换为实际 IP)
sed -i 's/10.0.0.3/实际IP/g' ~/.oceanbase-all-in-one/ob-test.yaml

# 验证替换结果
grep "ip:" ~/.oceanbase-all-in-one/ob-test.yaml

2.4 部署启动和验证

# 确保已加载环境变量
source ~/.oceanbase-all-in-one/bin/env.sh

# 使用 OBD 部署集群
obd cluster deploy obtest -c ~/.oceanbase-all-in-one/ob-test.yaml

# 启动集群
obd cluster start obtest

# 查看集群状态
obd cluster display obtest

连接验证:

# 通过 OBProxy 连接(proxysys 用户,首次使用 OBD 自动生成的密码)
obclient -h10.0.0.3 -P2883 -uroot@proxysys -p'自动生成密码' -Doceanbase -A

# 直接连接 OBServer(sys 租户,首次使用 OBD 自动生成的密码)
obclient -h10.0.0.3 -P2881 -uroot@sys -p'自动生成密码' -Doceanbase -A

提示: OBD 首次启动后会自动生成 sys 租户和 proxysys 的密码,可在 obd cluster display obtest 输出中查看,也可在 observer.log 中找到。下文将立即修改为自定义密码。

在 OceanBase 内验证集群状态:

-- 查看集群参数(直接连接 OBServer 才能查看这些参数,通过 OBProxy 查看不了)
SHOW PARAMETERS LIKE 'memory_limit';
SHOW PARAMETERS LIKE 'system_memory';
SHOW PARAMETERS LIKE 'datafile_size';

-- 查看 Zone 和 Server 状态
SELECT zone, svr_ip, svr_port, status FROM __all_server;

-- 确认版本
SELECT version();

部署失败处理: 如果部署过程中出现错误需要重新部署,必须先清理已部署的集群,再重新执行部署命令:

# 如果部署失败需要重新部署,先执行清理:
obd cluster destroy obtest -f

# 然后重新执行部署命令
obd cluster deploy obtest -c ~/.oceanbase-all-in-one/ob-test.yaml

2.5 修改 sys 租户密码

安全建议: 部署完成后应立即修改默认密码,避免使用 OBD 自动生成的密码。

# 使用 OBD 自动生成的密码连接 sys 租户
obclient -h10.0.0.3 -P2881 -uroot@sys -p'自动生成密码' -Doceanbase -A
-- 修改 sys 租户 root 密码(注意:不要在用户名后加 @sys,sys 是租户名不是 host)
ALTER USER root IDENTIFIED BY 'Ob#2026';
# 使用新密码重新连接验证
obclient -h10.0.0.3 -P2881 -uroot@sys -p'Ob#2026' -Doceanbase -A

注意: 修改密码后,后续所有连接 sys 租户的命令都需要使用新密码 Ob#2026

2.6 修改 OBProxy proxysys 密码

OBProxy 的 proxysys 用户密码与 OBServer 的 sys 租户密码相互独立,需要单独修改。

# 使用 OBD 自动生成的密码连接 OBProxy proxysys 用户
obclient -h10.0.0.3 -P2883 -uroot@proxysys -p'自动生成密码' -Doceanbase -A
-- 修改 proxysys 密码
ALTER PROXYCONFIG SET obproxy_sys_password = 'Op#2026';

-- 验证(退出后用新密码重新连接)
# 使用新密码连接 OBProxy
obclient -h10.0.0.3 -P2883 -uroot@proxysys -p'Op#2026' -Doceanbase -A

注意: OBProxy 的 proxysys 密码修改后,后续通过 2883 端口连接 proxysys 时使用新密码 Op#2026。普通业务租户通过 OBProxy 连接不受影响。

2.7 创建业务租户 cpz

2.7.1 资源池和租户创建

# 连接 sys 租户
obclient -h10.0.0.3 -P2881 -uroot@sys -p'Ob#2026' -Doceanbase -A
-- 查看可用资源
SELECT UNIT_CONFIG_ID, NAME, MAX_CPU, MIN_CPU, MEMORY_SIZE, MAX_IOPS, MIN_IOPS, LOG_DISK_SIZE
FROM __all_unit_config;

-- 创建资源单元(8核 CPU,12GB 内存)
CREATE RESOURCE UNIT cpz_unit
  MAX_CPU 8, MIN_CPU 4,
  MEMORY_SIZE '12G',
  MAX_IOPS 10240, MIN_IOPS 1024,
  LOG_DISK_SIZE '5G';

-- 创建资源池
CREATE RESOURCE POOL cpz_pool
  UNIT = 'cpz_unit',
  UNIT_NUM = 1;

-- 创建业务租户
CREATE TENANT cpz
  RESOURCE_POOL_LIST = ('cpz_pool'),
  CHARSET = 'utf8mb4',
  PRIMARY_ZONE = 'RANDOM',
  LOCALITY = 'F{1}@zone1'
  SET ob_compatibility_mode = 'mysql', ob_tcp_invited_nodes = '%';

2.7.2 配置租户密码

# 连接 cpz 租户(新建租户 root 用户初始密码为空)
obclient -h10.0.0.3 -P2881 -uroot@cpz -Doceanbase -A
-- 修改 cpz 租户 root 密码
ALTER USER root IDENTIFIED BY 'Cpz#2026';
# 使用新密码重新连接
obclient -h10.0.0.3 -P2881 -uroot@cpz -p'Cpz#2026' -Doceanbase -A

2.8 创建业务用户和数据库

# 连接 cpz 租户
obclient -h10.0.0.3 -P2881 -uroot@cpz -p'Cpz#2026' -Doceanbase -A
-- 创建业务数据库
CREATE DATABASE IF NOT EXISTS ucd_cpz DEFAULT CHARACTER SET utf8mb4;

-- 创建业务用户
CREATE USER 'cpz_user'@'%' IDENTIFIED BY 'ucd@cpz2026';
GRANT ALL PRIVILEGES ON ucd_cpz.* TO 'cpz_user'@'%';

-- 验证
SHOW DATABASES;
SELECT user, host FROM mysql.user WHERE user = 'cpz_user';
# 验证业务用户连接(通过 OBProxy)
obclient -h10.0.0.3 -P2883 -ucpz_user@cpz#obtest -p'ucd@cpz2026' -Ducd_cpz -A

# 验证业务用户连接(直连 OBServer)
obclient -h10.0.0.3 -P2881 -ucpz_user@cpz -p'ucd@cpz2026' -Ducd_cpz -A

3. 前置条件

3.1 版本确认

OceanBase 4.2.1 社区版支持租户级物理备份与恢复,确认版本:

obclient -h10.0.0.3 -P2883 -uroot@cpz#obtest -p'Cpz#2026' -e "SELECT version();"

预期输出包含 4.2.1 版本号。

重要: 物理备份的 ALTER SYSTEM 系列命令需要 sys 租户 权限。下文备份管理命令统一使用 sys 租户连接,业务查询使用 cpz 租户连接。

3.2 磁盘空间规划

目录用途空间估算
/opt/ob_backup/archive日志归档归档大小 ≈ 日均 CLOG 量 × 归档保留天数(建议保留 7 天)
/opt/ob_backup/data数据备份全量 ≈ 租户数据量 × 1.5;增量 ≈ 日均数据变更量 × 增量保留天数

估算公式:

归档空间(GB) = 日均CLOG增量(GB) × 归档保留天数(7)
备份空间(GB) = 全量备份大小(GB) × 全量保留份数(2) + 日均增量(GB) × 增量保留天数(7)
总空间(GB)   = 归档空间 + 备份空间 + 20%预留

示例: 假设租户数据 50GB,日均 CLOG 5GB,日均变更 2GB:

归档 = 5GB × 7 = 35GB
备份 = 50GB × 1.5 × 2 + 2GB × 7 = 164GB
总计 = 35 + 164 + 40(预留) ≈ 240GB

3.3 目录权限检查

# 检查备份目录是否存在及属主
ls -ld /opt/ob_backup/archive /opt/ob_backup/data

# 确认属主为 ucd(OceanBase 运行用户)
# 预期输出:drwxr-xr-x ... ucd ... /opt/ob_backup/archive
#           drwxr-xr-x ... ucd ... /opt/ob_backup/data

# 若属主不对,修正:
sudo chown -R ucd:ucd /opt/ob_backup

注意: 备份目录必须对 OceanBase 运行用户(ucd)可写,否则备份任务会失败。


4. 测试环境配置步骤

以下所有 ALTER SYSTEM 命令需使用 sys 租户 连接执行。
sys 租户连接方式:obclient -h10.0.0.3 -P2883 -uroot@sys#obtest -p'Cpz#2026' -A

4.1 配置日志归档目的地

# 连接 sys 租户
obclient -h10.0.0.3 -P2883 -uroot@sys#obtest -p'Cpz#2026' -A

# 在 obclient 中执行
ALTER SYSTEM SET log_archive_dest='location=/opt/ob_backup/archive';

验证配置:

-- 查看归档目的地配置
SHOW PARAMETERS LIKE 'log_archive_dest';

预期 VALUE 列显示 /opt/ob_backup/archive

4.2 开启归档模式

# 连接 sys 租户
obclient -h10.0.0.3 -P2883 -uroot@sys#obtest -p'Cpz#2026' -A
-- 开启归档
ALTER SYSTEM ARCHIVELOG;

说明: OceanBase 默认为 NOARCHIVELOG 模式。开启 ARCHIVELOG 后,CLOG 会持续归档到 log_archive_dest 指定的目录。

4.3 验证归档状态

# 方式一:通过内部表查询归档状态
obclient -h10.0.0.3 -P2883 -uroot@sys#obtest -p'Cpz#2026' -A \
  -e "SELECT status, start_scn, checkpoint_scn FROM oceanbase.DBA_OB_ARCHIVELOG WHERE tenant_id = (SELECT tenant_id FROM oceanbase.DBA_OB_TENANTS WHERE tenant_name = 'cpz');"
-- 方式二:在 obclient 交互模式查询
SELECT tenant_name, status, start_scn, checkpoint_scn
FROM oceanbase.DBA_OB_ARCHIVELOG
WHERE tenant_id = (SELECT tenant_id FROM oceanbase.DBA_OB_TENANTS WHERE tenant_name = 'cpz');

预期 statusDOING,表示归档正在运行。

检查归档目录文件生成:

ls -lhR /opt/ob_backup/archive/

预期看到归档文件(以租户 ID + round 编号组织的目录结构)。

4.4 配置数据备份目的地

obclient -h10.0.0.3 -P2883 -uroot@sys#obtest -p'Cpz#2026' -A
-- 配置数据备份目的地
ALTER SYSTEM SET data_backup_dest='/opt/ob_backup/data';

验证:

SHOW PARAMETERS LIKE 'data_backup_dest';

4.5 执行全量备份

obclient -h10.0.0.3 -P2883 -uroot@sys#obtest -p'Cpz#2026' -A
-- 对整个集群执行全量备份(包含所有租户数据)
ALTER SYSTEM BACKUP DATABASE;

说明: BACKUP DATABASE 会备份集群中所有租户的数据。如需仅备份 cpz 租户,可使用 ALTER SYSTEM BACKUP TENANT cpz;(OceanBase 4.x 支持租户级备份)。

仅备份 cpz 租户:

ALTER SYSTEM BACKUP TENANT cpz;

4.6 查看备份任务状态

obclient -h10.0.0.3 -P2883 -uroot@sys#obtest -p'Cpz#2026' -A
-- 查看备份任务列表
SELECT job_id, backup_type, start_time, end_time, status
FROM oceanbase.DBA_OB_BACKUP_JOBS
ORDER BY start_time DESC;

-- 查看备份任务详情(含进度)
SELECT job_id, task_id, tenant_name, src_path, dst_path, status
FROM oceanbase.DBA_OB_BACKUP_TASKS
ORDER BY start_time DESC;

预期 statusCOMPLETED 表示备份成功。

4.7 执行增量备份

obclient -h10.0.0.3 -P2883 -uroot@sys#obtest -p'Cpz#2026' -A
-- 执行增量备份(基于最近一次全量备份)
ALTER SYSTEM BACKUP INCREMENTAL DATABASE;

-- 仅对 cpz 租户执行增量备份
ALTER SYSTEM BACKUP INCREMENTAL TENANT cpz;

验证增量备份状态:

SELECT job_id, backup_type, inc_type, start_time, end_time, status
FROM oceanbase.DBA_OB_BACKUP_JOBS
WHERE inc_type = 'INCIDENTAL'
ORDER BY start_time DESC;

说明: 增量备份依赖于全量备份基线,首次增量前必须先完成至少一次全量备份。


5. 生产环境部署方案

5.1 备份策略设计

备份类型频率执行时间保留策略
全量备份每周 1 次周日 01:00保留 2 周(2 份)
增量备份每天 1 次凌晨 02:00保留 7 天
日志归档持续(实时)保留 7 天

5.2 Crontab 定时任务配置

10.0.0.3 服务器上,以 ucd 用户配置 crontab:

# 切换到 ucd 用户
sudo su - ucd

# 编辑 crontab
crontab -e

添加以下内容:

# OceanBase 物理备份定时任务
# 每周日凌晨 01:00 执行全量备份(cpz 租户)
0 1 * * 0 /home/ucd/ob_backup_scripts/full_backup.sh >> /opt/ob_backup/logs/full_backup.log 2>&1

# 每天凌晨 02:00 执行增量备份(cpz 租户)
0 2 * * 1-6 /home/ucd/ob_backup_scripts/incr_backup.sh >> /opt/ob_backup/logs/incr_backup.log 2>&1

全量备份脚本 /home/ucd/ob_backup_scripts/full_backup.sh

#!/bin/bash
# 全量备份脚本 - cpz 租户
# 执行时间:每周日 01:00

OB_HOST="10.0.0.3"
OB_PORT="2883"
OB_USER="root@sys#obtest"
OB_PASS="Cpz#2026"
LOG_FILE="/opt/ob_backup/logs/full_backup_$(date +%Y%m%d_%H%M%S).log"

echo "========== 全量备份开始: $(date '+%Y-%m-%d %H:%M:%S') =========="

# 执行全量备份
obclient -h${OB_HOST} -P${OB_PORT} -u${OB_USER} -p"${OB_PASS}" -A \
  -e "ALTER SYSTEM BACKUP TENANT cpz;" 2>&1 | tee -a ${LOG_FILE}

# 等待备份完成
sleep 30

# 检查备份状态
STATUS=$(obclient -h${OB_HOST} -P${OB_PORT} -u${OB_USER} -p"${OB_PASS}" -A \
  -N -e "SELECT status FROM oceanbase.DBA_OB_BACKUP_JOBS ORDER BY start_time DESC LIMIT 1;")

if [ "$STATUS" = "COMPLETED" ]; then
    echo "全量备份成功: $(date '+%Y-%m-%d %H:%M:%S')"
else
    echo "全量备份异常,当前状态: ${STATUS},请检查!"
fi

echo "========== 全量备份结束: $(date '+%Y-%m-%d %H:%M:%S') =========="

增量备份脚本 /home/ucd/ob_backup_scripts/incr_backup.sh

#!/bin/bash
# 增量备份脚本 - cpz 租户
# 执行时间:每天 02:00(周一至周六)

OB_HOST="10.0.0.3"
OB_PORT="2883"
OB_USER="root@sys#obtest"
OB_PASS="Cpz#2026"
LOG_FILE="/opt/ob_backup/logs/incr_backup_$(date +%Y%m%d_%H%M%S).log"

echo "========== 增量备份开始: $(date '+%Y-%m-%d %H:%M:%S') =========="

# 执行增量备份
obclient -h${OB_HOST} -P${OB_PORT} -u${OB_USER} -p"${OB_PASS}" -A \
  -e "ALTER SYSTEM BACKUP INCREMENTAL TENANT cpz;" 2>&1 | tee -a ${LOG_FILE}

# 等待备份完成
sleep 30

# 检查备份状态
STATUS=$(obclient -h${OB_HOST} -P${OB_PORT} -u${OB_USER} -p"${OB_PASS}" -A \
  -N -e "SELECT status FROM oceanbase.DBA_OB_BACKUP_JOBS ORDER BY start_time DESC LIMIT 1;")

if [ "$STATUS" = "COMPLETED" ]; then
    echo "增量备份成功: $(date '+%Y-%m-%d %H:%M:%S')"
else
    echo "增量备份异常,当前状态: ${STATUS},请检查!"
fi

echo "========== 增量备份结束: $(date '+%Y-%m-%d %H:%M:%S') =========="

创建脚本目录与日志目录:

sudo mkdir -p /home/ucd/ob_backup_scripts
sudo mkdir -p /opt/ob_backup/logs
sudo chown -R ucd:ucd /home/ucd/ob_backup_scripts /opt/ob_backup/logs
sudo chmod +x /home/ucd/ob_backup_scripts/*.sh

5.3 备份清理策略

方式一:通过系统参数自动清理

obclient -h10.0.0.3 -P2883 -uroot@sys#obtest -p'Cpz#2026' -A
-- 设置备份文件回收器保留时间(单位:天,建议 14 天)
ALTER SYSTEM SET backup_data_file_recycler_age = '14d';

-- 开启备份文件自动回收
ALTER SYSTEM SET backup_data_file_recycler = true;

方式二:手动清理过期备份

-- 查看当前备份集
SELECT backup_set_id, tenant_name, backup_type, start_time, end_time, status
FROM oceanbase.DBA_OB_BACKUP_SET_FILES
ORDER BY start_time DESC;

-- 手动删除指定备份集(backup_set_id 替换为实际值)
-- ALTER SYSTEM DELETE BACKUPSET backup_set_id;

-- 清理过期的归档日志(删除指定时间之前的归档)
-- ALTER SYSTEM DELETE ARCHIVELOG BEFORE TIME '2026-05-25 00:00:00';

方式三:定时清理脚本

添加到 ucd 用户 crontab,每天凌晨 04:00 执行:

# 每天凌晨 04:00 清理过期备份(保留 14 天)
0 4 * * * /home/ucd/ob_backup_scripts/cleanup_backup.sh >> /opt/ob_backup/logs/cleanup.log 2>&1

/home/ucd/ob_backup_scripts/cleanup_backup.sh

#!/bin/bash
# 清理过期备份脚本
# 保留策略:全量备份保留 14 天,归档日志保留 7 天

OB_HOST="10.0.0.3"
OB_PORT="2883"
OB_USER="root@sys#obtest"
OB_PASS="Cpz#2026"
RETAIN_DAYS=14
ARCHIVE_RETAIN_DAYS=7

echo "========== 备份清理开始: $(date '+%Y-%m-%d %H:%M:%S') =========="

# 清理过期归档日志
ARCHIVE_CUTOFF=$(date -d "-${ARCHIVE_RETAIN_DAYS} days" '+%Y-%m-%d %H:%M:%S')
obclient -h${OB_HOST} -P${OB_PORT} -u${OB_USER} -p"${OB_PASS}" -A \
  -e "ALTER SYSTEM DELETE ARCHIVELOG BEFORE TIME '${ARCHIVE_CUTOFF}';"

# 清理过期数据备份
BACKUP_CUTOFF=$(date -d "-${RETAIN_DAYS} days" '+%Y-%m-%d %H:%M:%S')
obclient -h${OB_HOST} -P${OB_PORT} -u${OB_USER} -p"${OB_PASS}" -A \
  -e "ALTER SYSTEM DELETE OBSOLETE BACKUPPOLICY BEFORE TIME '${BACKUP_CUTOFF}';"

echo "========== 备份清理结束: $(date '+%Y-%m-%d %H:%M:%S') =========="

5.4 监控告警

归档延迟监控脚本

/home/ucd/ob_backup_scripts/check_archive.sh

#!/bin/bash
# 归档延迟监控脚本
# 检查归档延迟是否超过阈值(默认 600 秒 = 10 分钟)

OB_HOST="10.0.0.3"
OB_PORT="2883"
OB_USER="root@sys#obtest"
OB_PASS="Cpz#2026"
THRESHOLD_SEC=600
ALERT_LOG="/opt/ob_backup/logs/archive_alert.log"

# 查询归档状态
RESULT=$(obclient -h${OB_HOST} -P${OB_PORT} -u${OB_USER} -p"${OB_PASS}" -A -N \
  -e "SELECT status, checkpoint_scn FROM oceanbase.DBA_OB_ARCHIVELOG
      WHERE tenant_id = (SELECT tenant_id FROM oceanbase.DBA_OB_TENANTS WHERE tenant_name = 'cpz');")

STATUS=$(echo "$RESULT" | awk '{print $1}')

if [ "$STATUS" != "DOING" ]; then
    echo "[ALERT] $(date '+%Y-%m-%d %H:%M:%S') 归档状态异常: ${STATUS}" >> ${ALERT_LOG}
fi

# 检查归档延迟(对比当前 SCN 与归档 SCN)
ARCHIVE_DELAY=$(obclient -h${OB_HOST} -P${OB_PORT} -u${OB_USER} -p"${OB_PASS}" -A -N \
  -e "SELECT TIMESTAMPDIFF(SECOND,
        FROM_UNIXTIME(checkpoint_scn / 1000000000),
        NOW())
      FROM oceanbase.DBA_OB_ARCHIVELOG
      WHERE tenant_id = (SELECT tenant_id FROM oceanbase.DBA_OB_TENANTS WHERE tenant_name = 'cpz')
      LIMIT 1;")

if [ -n "$ARCHIVE_DELAY" ] && [ "$ARCHIVE_DELAY" -gt "$THRESHOLD_SEC" ]; then
    echo "[ALERT] $(date '+%Y-%m-%d %H:%M:%S') 归档延迟 ${ARCHIVE_DELAY} 秒,超过阈值 ${THRESHOLD_SEC} 秒!" >> ${ALERT_LOG}
fi

备份任务状态监控脚本

/home/ucd/ob_backup_scripts/check_backup.sh

#!/bin/bash
# 备份状态监控脚本
# 检查最近一次备份是否成功

OB_HOST="10.0.0.3"
OB_PORT="2883"
OB_USER="root@sys#obtest"
OB_PASS="Cpz#2026"
ALERT_LOG="/opt/ob_backup/logs/backup_alert.log"

# 查询最近备份任务状态
RESULT=$(obclient -h${OB_HOST} -P${OB_PORT} -u${OB_USER} -p"${OB_PASS}" -A -N \
  -e "SELECT job_id, backup_type, start_time, status
      FROM oceanbase.DBA_OB_BACKUP_JOBS
      ORDER BY start_time DESC LIMIT 1;")

STATUS=$(echo "$RESULT" | awk '{print $4}')

if [ "$STATUS" != "COMPLETED" ]; then
    echo "[ALERT] $(date '+%Y-%m-%d %H:%M:%S') 最近备份任务状态异常: ${RESULT}" >> ${ALERT_LOG}
else
    echo "[INFO] $(date '+%Y-%m-%d %H:%M:%S') 最近备份任务正常: ${RESULT}" >> /opt/ob_backup/logs/backup_status.log
fi

监控 crontab 条目:

# 每 30 分钟检查归档状态
*/30 * * * * /home/ucd/ob_backup_scripts/check_archive.sh

# 每小时检查备份状态
0 * * * * /home/ucd/ob_backup_scripts/check_backup.sh

5.5 异地备份(rsync 到备机)

假设备机 IP 为 10.0.0.4(8C16G 服务器),需要配置免密 SSH 登录和 rsync 同步。

5.5.1 配置 SSH 免密

# 在 10.0.0.3 上以 ucd 用户执行
sudo su - ucd
ssh-keygen -t rsa -b 4096 -f ~/.ssh/id_rsa -N ""
ssh-copy-id ucd@10.0.0.4

# 验证免密登录
ssh ucd@10.0.0.4 "echo OK"

5.5.2 备机创建备份目录

# 在 10.0.0.4 上执行
sudo mkdir -p /opt/ob_backup_remote/archive /opt/ob_backup_remote/data
sudo chown -R ucd:ucd /opt/ob_backup_remote

5.5.3 rsync 同步脚本

/home/ucd/ob_backup_scripts/rsync_to_remote.sh

#!/bin/bash
# 异地备份同步脚本
# 将本地备份目录 rsync 到备机 10.0.0.4

REMOTE_HOST="10.0.0.4"
REMOTE_USER="ucd"
REMOTE_DIR="/opt/ob_backup_remote"
LOCAL_DIR="/opt/ob_backup/"
LOG_FILE="/opt/ob_backup/logs/rsync_$(date +%Y%m%d_%H%M%S).log"

echo "========== 异地同步开始: $(date '+%Y-%m-%d %H:%M:%S') =========="

# 同步归档目录
rsync -avz --delete ${LOCAL_DIR}/archive/ ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}/archive/ >> ${LOG_FILE} 2>&1

# 同步数据备份目录
rsync -avz --delete ${LOCAL_DIR}/data/ ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}/data/ >> ${LOG_FILE} 2>&1

if [ $? -eq 0 ]; then
    echo "异地同步成功: $(date '+%Y-%m-%d %H:%M:%S')"
else
    echo "[ALERT] 异地同步失败: $(date '+%Y-%m-%d %H:%M:%S')" >> /opt/ob_backup/logs/rsync_alert.log
fi

echo "========== 异地同步结束: $(date '+%Y-%m-%d %H:%M:%S') =========="

5.5.4 异地同步 crontab

# 每天凌晨 05:00 执行异地同步(在全量/增量备份完成之后)
0 5 * * * /home/ucd/ob_backup_scripts/rsync_to_remote.sh >> /opt/ob_backup/logs/rsync_cron.log 2>&1

6. 恢复演练流程

OceanBase 4.x 关键约束: 租户级恢复不能覆盖原租户,必须先创建一个新租户,然后将备份数据恢复到新租户中。

6.1 恢复到最新时间点(全量恢复)

步骤一:确认备份集信息

obclient -h10.0.0.3 -P2883 -uroot@sys#obtest -p'Cpz#2026' -A
-- 查看可用的备份集
SELECT backup_set_id, tenant_name, backup_type, inc_type, start_time, end_time, status
FROM oceanbase.DBA_OB_BACKUP_SET_FILES
WHERE tenant_name = 'cpz'
ORDER BY start_time DESC;

-- 查看归档日志范围
SELECT tenant_name, start_scn, checkpoint_scn, status
FROM oceanbase.DBA_OB_ARCHIVELOG
WHERE tenant_id = (SELECT tenant_id FROM oceanbase.DBA_OB_TENANTS WHERE tenant_name = 'cpz');

步骤二:创建恢复目标租户

-- 创建新租户(资源配额与原租户一致,名称加 _restored 后缀)
CREATE RESOURCE UNIT unit_cpz_restore MAX_CPU 4, MIN_CPU 4, MEMORY_SIZE '4G', MAX_IOPS 10000, MIN_IOPS 1000, LOG_DISK_SIZE '2G';
CREATE RESOURCE POOL pool_cpz_restore UNIT = 'unit_cpz_restore', UNIT_NUM = 1, ZONE_LIST = ('zone1');
CREATE TENANT cpz_restore RESOURCE_POOL_LIST = ('pool_cpz_restore') SET ob_tcp_invited_nodes='%';

步骤三:执行恢复

-- 恢复 cpz 租户到 cpz_restore(最新时间点)
ALTER SYSTEM RESTORE cpz_restore FROM cpz
  URI='local:///opt/ob_backup/data'
  UNTIL TIME='2026-12-31 23:59:59'
  WITH 'pool_list=pool_cpz_restore&local_stream=true';

注意: UNTIL TIME 应设置为当前时间或未来的时间点以恢复到最新状态。实际执行时请替换为恢复时刻的时间。

步骤四:验证恢复

# 连接恢复后的租户
obclient -h10.0.0.3 -P2883 -uroot@cpz_restore#obtest -p'' -A
-- 检查租户状态
SHOW TENANT;

-- 查看数据库列表
SHOW DATABASES;

-- 查询关键业务表数据量
SELECT COUNT(*) FROM your_database.your_table;

6.2 恢复到指定时间点(PITR)

obclient -h10.0.0.3 -P2883 -uroot@sys#obtest -p'Cpz#2026' -A
-- 创建目标租户(如果尚未创建)
CREATE RESOURCE UNIT unit_cpz_pitr MAX_CPU 4, MIN_CPU 4, MEMORY_SIZE '4G', MAX_IOPS 10000, MIN_IOPS 1000, LOG_DISK_SIZE '2G';
CREATE RESOURCE POOL pool_cpz_pitr UNIT = 'unit_cpz_pitr', UNIT_NUM = 1, ZONE_LIST = ('zone1');
CREATE TENANT cpz_pitr RESOURCE_POOL_LIST = ('pool_cpz_pitr') SET ob_tcp_invited_nodes='%';

-- 恢复到指定时间点(示例:2026-05-30 14:00:00)
ALTER SYSTEM RESTORE cpz_pitr FROM cpz
  URI='local:///opt/ob_backup/data'
  UNTIL TIME='2026-05-30 14:00:00'
  WITH 'pool_list=pool_cpz_pitr&local_stream=true';

查看恢复进度:

-- 查询恢复任务状态
SELECT tenant_name, restore_scn, restore_start_time, status
FROM oceanbase.DBA_OB_RESTORE_PROGRESS
WHERE tenant_name IN ('cpz_restore', 'cpz_pitr');

-- 查询恢复历史
SELECT tenant_name, backup_set_id, restore_start_time, restore_end_time, status
FROM oceanbase.DBA_OB_RESTORE_HISTORY
ORDER BY restore_start_time DESC;

6.3 恢复验证步骤

恢复完成后,按以下清单逐一验证:

验证项命令/方法
租户可连接obclient -h10.0.0.3 -P2883 -uroot@cpz_restore#obtest -A
数据库列表一致SHOW DATABASES; 与原租户对比
核心表行数一致SELECT COUNT(*) FROM db.table; 关键表逐一对比
关键业务数据抽检抽查最近写入的记录是否存在
时间点准确性(PITR)查询目标时间点之后写入的数据,应不存在
索引与约束完整性SHOW INDEX FROM db.table; 与原租户对比

7. 常见问题与排错

7.1 归档延迟过大

现象: DBA_OB_ARCHIVELOG 中 checkpoint_scn 远落后于当前 SCN,或归档目录长时间无新文件写入。

排查步骤:

obclient -h10.0.0.3 -P2883 -uroot@sys#obtest -p'Cpz#2026' -A
-- 查看归档详细状态
SELECT tenant_name, status, start_scn, checkpoint_scn,
       TIMESTAMPDIFF(SECOND, FROM_UNIXTIME(checkpoint_scn/1000000000), NOW()) AS delay_sec
FROM oceanbase.DBA_OB_ARCHIVELOG;

-- 检查是否有归档相关报错
SELECT * FROM oceanbase.DBA_OB_ARCHIVELOG_PARAMETERS;

常见原因与处理:

原因处理方式
磁盘 IO 瓶颈检查 iostat -x 1,归档目录是否与其他 IO 竞争
磁盘空间不足df -h /opt/ob_backup/archive,清理过期归档
CLOG 生成速度过快检查业务写入量是否突发增长,考虑扩容或限流
归档进程异常查看 observer 日志:grep ARCHIVE /data/obtest/log/observer.log

7.2 备份空间不足

现象: 备份任务报错 No space left on deviceIO error

排查与处理:

# 检查磁盘使用率
df -h /opt/ob_backup/

# 查看备份集占用
du -sh /opt/ob_backup/archive /opt/ob_backup/data
-- 查看备份集列表与大小
SELECT backup_set_id, tenant_name, backup_type, start_time, status
FROM oceanbase.DBA_OB_BACKUP_SET_FILES
ORDER BY start_time DESC;

-- 手动清理过期备份(替换为实际 backup_set_id)
ALTER SYSTEM DELETE BACKUPSET <backup_set_id>;

-- 清理过期归档
ALTER SYSTEM DELETE ARCHIVELOG BEFORE TIME '2026-05-24 00:00:00';

预防措施:

  • 设置自动回收策略(见 5.3 节)
  • 磁盘使用率告警阈值设为 80%
  • 定期检查磁盘空间

7.3 备份失败处理

现象: DBA_OB_BACKUP_JOBSstatusFAILEDCANCELED

排查步骤:

-- 查看失败任务详情
SELECT job_id, backup_type, start_time, end_time, status, result
FROM oceanbase.DBA_OB_BACKUP_JOBS
WHERE status IN ('FAILED', 'CANCELED')
ORDER BY start_time DESC;

-- 查看任务级别的错误信息
SELECT task_id, task_type, status, comment
FROM oceanbase.DBA_OB_BACKUP_TASKS
WHERE job_id = <失败的job_id>;

-- 查看 observer 日志中的备份报错
-- 在服务器上执行:
-- grep BACKUP /data/obtest/log/observer.log | tail -50

常见失败原因与处理:

原因处理方式
备份目录权限不足chown -R ucd:ucd /opt/ob_backup
磁盘空间不足清理过期备份或扩容磁盘
归档未开启先执行 ALTER SYSTEM ARCHIVELOG;
并发备份任务冲突等待当前任务完成后再提交新任务
全量备份缺失(增量依赖)先执行一次全量备份

重新执行备份:

-- 取消失败任务(如有卡住的任务)
ALTER SYSTEM CANCEL BACKUP;

-- 重新执行全量备份
ALTER SYSTEM BACKUP TENANT cpz;

8. 维护命令速查

连接方式

# sys 租户连接(备份管理操作)
obclient -h10.0.0.3 -P2883 -uroot@sys#obtest -p'Cpz#2026' -A

# 业务租户连接(数据查询验证)
obclient -h10.0.0.3 -P2883 -uroot@cpz#obtest -p'Cpz#2026' -A

归档相关

-- 查看归档状态
SELECT tenant_name, status, start_scn, checkpoint_scn
FROM oceanbase.DBA_OB_ARCHIVELOG
WHERE tenant_id = (SELECT tenant_id FROM oceanbase.DBA_OB_TENANTS WHERE tenant_name = 'cpz');

-- 开启归档
ALTER SYSTEM ARCHIVELOG;

-- 关闭归档(谨慎操作,关闭后无法进行 PITR)
ALTER SYSTEM NOARCHIVELOG;

-- 查看归档目的地配置
SHOW PARAMETERS LIKE 'log_archive_dest';

-- 修改归档目的地
ALTER SYSTEM SET log_archive_dest='location=/opt/ob_backup/archive';

-- 清理过期归档
ALTER SYSTEM DELETE ARCHIVELOG BEFORE TIME '2026-05-24 00:00:00';

备份相关

-- 查看备份任务历史
SELECT job_id, backup_type, start_time, end_time, status
FROM oceanbase.DBA_OB_BACKUP_JOBS
ORDER BY start_time DESC;

-- 查看备份任务详情
SELECT job_id, task_id, tenant_name, status, comment
FROM oceanbase.DBA_OB_BACKUP_TASKS
ORDER BY start_time DESC;

-- 查看备份集列表
SELECT backup_set_id, tenant_name, backup_type, inc_type, start_time, end_time, status
FROM oceanbase.DBA_OB_BACKUP_SET_FILES
ORDER BY start_time DESC;

-- 执行全量备份(cpz 租户)
ALTER SYSTEM BACKUP TENANT cpz;

-- 执行增量备份(cpz 租户)
ALTER SYSTEM BACKUP INCREMENTAL TENANT cpz;

-- 执行全集群备份
ALTER SYSTEM BACKUP DATABASE;

-- 取消当前备份任务
ALTER SYSTEM CANCEL BACKUP;

-- 查看备份目的地配置
SHOW PARAMETERS LIKE 'data_backup_dest';

-- 修改备份目的地
ALTER SYSTEM SET data_backup_dest='/opt/ob_backup/data';

-- 删除指定备份集
ALTER SYSTEM DELETE BACKUPSET <backup_set_id>;

-- 设置自动回收
ALTER SYSTEM SET backup_data_file_recycler = true;
ALTER SYSTEM SET backup_data_file_recycler_age = '14d';

恢复相关

-- 查看恢复进度
SELECT tenant_name, restore_scn, restore_start_time, status
FROM oceanbase.DBA_OB_RESTORE_PROGRESS;

-- 查看恢复历史
SELECT tenant_name, backup_set_id, restore_start_time, restore_end_time, status
FROM oceanbase.DBA_OB_RESTORE_HISTORY
ORDER BY restore_start_time DESC;

-- 恢复租户到最新时间点
ALTER SYSTEM RESTORE cpz_restore FROM cpz
  URI='local:///opt/ob_backup/data'
  UNTIL TIME='2026-12-31 23:59:59'
  WITH 'pool_list=pool_cpz_restore&local_stream=true';

-- 恢复租户到指定时间点(PITR)
ALTER SYSTEM RESTORE cpz_pitr FROM cpz
  URI='local:///opt/ob_backup/data'
  UNTIL TIME='2026-05-30 14:00:00'
  WITH 'pool_list=pool_cpz_pitr&local_stream=true';

磁盘与文件检查

# 检查备份目录磁盘使用率
df -h /opt/ob_backup/

# 查看归档目录文件
ls -lhR /opt/ob_backup/archive/ | head -30

# 查看数据备份目录文件
ls -lhR /opt/ob_backup/data/ | head -30

# 查看备份目录空间占用
du -sh /opt/ob_backup/archive /opt/ob_backup/data

# 检查 observer 日志中的备份/归档相关信息
grep -E 'ARCHIVE|BACKUP|RESTORE' /data/obtest/log/observer.log | tail -50
0

评论区