RMAN是Oracle官方推荐的备份工具,默认情况下备份集会写入本地磁盘或磁带。当数据库规模不断增长,备份文件占用大量空间,本地存储的压力会越来越大,而且一旦存储介质损坏,备份和数据库可能同时丢失。MinIO作为一款兼容S3协议的开源对象存储,部署简单、成本低廉,非常适合作为Oracle备份的归档层。本文介绍如何把RMAN产生的备份集自动推送到MinIO,形成本地加对象存储的双重备份体系。

一、方案整体思路与环境准备
整体方案分为两层:第一层是RMAN在数据库服务器本地生成备份集,写入一个专用的备份目录;第二层通过MinIO客户端工具mc把备份目录同步上传到MinIO的指定桶中。之所以不直接让RMAN写对象存储,是因为RMAN原生并不支持S3协议,除非购买Oracle Secure Backup Cloud模块。使用mc工具做二次搬运,成本几乎为零,逻辑上也更清晰,备份失败和上传失败可以分开监控。
环境准备包括三部分。首先是搭建好MinIO服务端,创建一个专用桶,例如命名为oracle-backup,并为其创建一个只允许读写该桶的访问密钥,遵循最小权限原则。其次是在Oracle数据库服务器上安装mc客户端,mc是一个静态编译的单文件程序,直接下载解压即可使用。最后确认服务器时间同步正常,因为备份和上传日志都依赖准确的时间戳做轮转判断。
安装mc并配置别名的方式如下:
# 下载mc客户端 wget https://dl.min.io/client/mc/release/linux-amd64/mc chmod +x mc mv mc /usr/local/bin/ # 配置别名,指向MinIO服务端 mc alias set myminio http://192.168.10.20:9000 BACKUP_USER BACKUP_PASSKEY # 创建备份桶并验证 mc mb myminio/oracle-backup mc ls myminio
注意这里的IP是MinIO服务端地址,端口默认为9000。别名配置好后,后续所有命令都用别名操作,不用每次输入密钥,密钥也不会出现在脚本参数里,安全性更好。
二、编写RMAN备份脚本并自动上传MinIO
RMAN脚本建议采用全量加归档的组合,备份集中写到一个带日期的目录,方便后续按日期清理。脚本中要使用FORMAT参数控制备份集路径,并通过CONFIGURE CONTROLFILE AUTOBACKUP ON保证控制文件和spfile也被自动备份,否则丢失控制文件会给恢复带来很大麻烦。
一个可用的备份脚本示例如下:
#!/bin/bash
# oracle_rman_backup.sh
export ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1
export ORACLE_SID=orcl
export PATH=$ORACLE_HOME/bin:$PATH
DATE=$(date +%Y%m%d)
BACKUP_DIR=/backup/oracle/$DATE
LOG_FILE=/backup/logs/rman_$DATE.log
mkdir -p $BACKUP_DIR
rman target / log=$LOG_FILE <<EOF
run {
allocate channel c1 type disk;
backup as compressed backupset
format '$BACKUP_DIR/full_%U.bkp'
database plus archivelog delete input;
release channel c1;
}
EOF
# 检查RMAN是否成功,成功才上传
if grep -i "ERROR" $LOG_FILE; then
echo "RMAN failed, skip upload" >> $LOG_FILE
exit 1
fi
# 上传到MinIO
mc cp --recursive $BACKUP_DIR myminio/oracle-backup/$DATE/ >> $LOG_FILE 2>&1
脚本的核心逻辑是先备份、后检查、再上传。只有当日志中没有ERROR关键字时才执行mc cp,避免把不完整的备份集传上去。上传同样采用递归方式,把整个日期目录推到MinIO对应路径下,目录结构与本地保持一致,排查问题时非常直观。
如果希望本地只保留最近几天的备份、MinIO上保留更长时间,可以在脚本末尾追加清理逻辑,例如用find /backup/oracle -mtime +3 -type d -exec rm -rf {} \;删除三天前的本地目录,对象存储侧则用mc rm --recursive --older-than 30d myminio/oracle-backup清理一个月前的历史备份。
三、定时任务配置与备份校验
把脚本加入crontab即可实现每日自动备份。建议安排在业务低峰期,例如凌晨两点执行:
# 编辑oracle用户的crontab crontab -e # 每天凌晨2点执行备份并上传 0 2 * * * /home/oracle/scripts/oracle_rman_backup.sh >> /backup/logs/cron.log 2>&1
备份不能只看有没有报错,必须定期校验。RMAN提供了RESTORE DATABASE VALIDATE和VALIDATE BACKUPSET命令,可以在不真正恢复的情况下检查备份集的完整性。对于存放在MinIO上的备份,建议每个季度做一次真实恢复演练:先用mc cp把某个日期目录下载回本地,再通过CATALOG START WITH命令把备份集注册到控制文件中,然后执行完整的restore和recover流程。演练通过,才说明这套备份体系真正可靠。
从MinIO下载备份并注册的命令如下:
# 从MinIO拉取备份集到本地 mc cp --recursive myminio/oracle-backup/20250110/ /restore/20250110/ # 用RMAN注册本地备份集 rman target / <<EOF catalog start with '/restore/20250110/'; restore database; recover database; EOF
四、方案对比与优化建议
与Oracle官方的Secure Backup Cloud方案相比,mc搬运方式不需要额外购买许可,配置门槛低,任何版本的Oracle都适用。缺点是备份数据要先落地本地磁盘再上传,占用临时空间,整体窗口会拉长。如果数据库备份量达到数TB,可以考虑在RMAN中使用压缩备份集(如上例的compressed backupset),通常能压缩到原始大小的五分之一左右,既节省本地空间也减少网络传输量。
上传速度方面,mc默认会根据文件大小自动选择并发和分段策略,大文件走multipart上传,吞吐表现不错。如果带宽仍然是瓶颈,可以把mc cp换成mc mirror --watch,让上传进程常驻并实时监控备份目录,RMAN一边写、mc一边传,两者并行执行,能明显缩短整体备份窗口。此外,务必为MinIO服务端配置多块数据盘的纠删码模式,这样对象存储侧自身也具备冗余能力,即使坏一块盘数据也不丢失,真正实现备份的多副本保护。
最后提醒一点,生产环境建议给备份脚本加上告警通知,例如上传完成后检查mc ls返回的对象数量是否与本地文件数一致,不一致时发送邮件或调用企业微信机器人,确保每一次备份都真正到达了对象存储,而不是静默失败。