Oracle RMAN 备份与恢复
Oracle RMAN 备份与恢复
目录
简介
RMAN(Recovery Manager)是 Oracle 提供的官方备份与恢复工具,支持:
- 物理备份(数据文件、控制文件、归档日志)
- 块级增量备份
- 自动化恢复
- 与 Oracle Secure Backup、NFS、磁带库等集成
本文重点讲解如何通过 RMAN 实现 全量 + 增量备份策略,并提供可直接用于生产环境的脚本。
环境准备
确保以下条件满足:
# 设置环境变量(建议写入 ~/.bash_profile)
export ORACLE_SID=orcl
export ORACLE_HOME=/u01/app/oracle/product/19.0.0/dbhome_1
export PATH=$ORACLE_HOME/bin:$PATH
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
| 变量 | 作用 |
|---|---|
ORACLE_SID | 指定要操作的数据库实例名(必须与实际一致)。 |
ORACLE_HOME | Oracle 软件安装目录,RMAN 可执行文件在此目录的 bin/ 下。 |
PATH | 让系统能找到 rman 命令。 |
NLS_LANG | 设置字符集和语言,避免日志中出现乱码或日期格式错误。 |
启用归档模式(必须):
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP MOUNT;
SQL> ALTER DATABASE ARCHIVELOG;
SQL> ALTER DATABASE OPEN;
SQL> ARCHIVE LOG LIST; -- 确认处于 Archive Mode
配置 RMAN 默认参数(可选但推荐):
RMAN> CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 7 DAYS;
RMAN> CONFIGURE CONTROLFILE AUTOBACKUP ON;
RMAN> CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO '/backup/rman/cf_%F';
RMAN> CONFIGURE CHANNEL DEVICE TYPE DISK FORMAT '/backup/rman/%U';
| 命令 | 作用说明 |
|---|---|
CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 7 DAYS; | 设置保留策略:RMAN 只保留足够恢复到最近 7 天内任意时间点的备份。超过 7 天的备份会被标记为“obsolete”(过期),可用 DELETE OBSOLETE 删除。 |
CONFIGURE CONTROLFILE AUTOBACKUP ON; | 启用控制文件自动备份。每次 RMAN 备份后(或结构变更如添加数据文件),RMAN 会自动备份控制文件和 SPFILE。 |
CONFIGURE CONTROLFILE AUTOBACKUP FORMAT ... TO '/backup/rman/cf_%F'; | 指定自动备份的控制文件保存路径和命名格式。 - %F 是一个特殊占位符,生成唯一名称(如 c-1234567890-20250101-00),包含 DBID、日期、序列号,确保不冲突。 |
CONFIGURE CHANNEL DEVICE TYPE DISK FORMAT '/backup/rman/%U'; | 设置默认磁盘通道的备份文件命名规则。 - %U 生成唯一文件名(如 01abc123_1_1),避免重名。 |
✅ 为什么重要?
这些配置让 RMAN 自动化程度更高,减少手动指定路径的错误,也便于恢复时定位文件。
全量备份(Full Backup)
全量备份 = Level 0 增量备份(Oracle 中全备通常用 BACKUP INCREMENTAL LEVEL 0 实现)。
RMAN 命令
RUN {
ALLOCATE CHANNEL c1 TYPE DISK;
BACKUP INCREMENTAL LEVEL 0
DATABASE
PLUS ARCHIVELOG
DELETE INPUT;
BACKUP CURRENT CONTROLFILE;
RELEASE CHANNEL c1;
}
| 行 | 说明 |
|---|---|
RUN { ... } | RMAN 的执行块,用于组合多个命令。 |
ALLOCATE CHANNEL c1 TYPE DISK; | 手动分配一个名为 c1 的磁盘通道。通道是 RMAN 与存储设备通信的“管道”。这里使用本地磁盘。 |
BACKUP INCREMENTAL LEVEL 0 DATABASE | 执行 Level 0 增量备份,即备份数据库中所有使用过的数据块(等效于全量备份)。 ⚠️ 注意:Oracle 中没有单独的 “FULL BACKUP” 命令,Level 0 就是全量。 |
PLUS ARCHIVELOG | 在备份数据库前/后,自动备份所有归档日志。确保恢复时有完整的 redo 流。 |
DELETE INPUT | 备份完归档日志后,删除源归档日志文件(仅限已成功备份的)。节省空间,但需确保备份可靠! |
BACKUP CURRENT CONTROLFILE; | 显式备份当前控制文件(虽然启用了 autobackup,但显式再备一次更保险)。 |
RELEASE CHANNEL c1; | 释放通道资源。 |
📌 关键概念:
- Level 0 ≠ FULL?实际上在恢复时,Level 0 被当作全量使用。
PLUS ARCHIVELOG DELETE INPUT是生产环境常用组合,但务必监控归档空间!
增量备份(Incremental Backup)
Oracle 支持两种增量:
- Level 0:包含所有数据块(等同于全量)
- Level 1:
- Differential(默认):备份自上次 Level 0 或 Level 1 以来变化的块
- Cumulative:备份自上次 Level 0 以来所有变化的块
Level 1 差异增量备份(推荐)
RUN {
ALLOCATE CHANNEL c1 TYPE DISK;
BACKUP INCREMENTAL LEVEL 1
DATABASE
PLUS ARCHIVELOG
DELETE INPUT;
RELEASE CHANNEL c1;
}
LEVEL 1:只备份自上一次 Level 0 或 Level 1 以来发生变化的数据块(差异增量)。- 默认是 Differential(差异),不是 Cumulative。
- 例如:
- 周日:Level 0
- 周一:Level 1 → 备周一变化
- 周二:Level 1 → 备周二变化(不是周一周二总和)
- 恢复时需:Level 0 + 所有后续 Level 1 + 归档日志。
✅ 优点:节省备份时间和空间。
❗ 风险:若中间某天 Level 1 丢失,之后所有增量都无法用。
恢复操作
完全恢复(数据库崩溃后)
假设整个数据库丢失(如磁盘故障),需从备份完全恢复:
# 启动到 nomount
RMAN> STARTUP FORCE NOMOUNT;
# 恢复控制文件(若启用了 autobackup)
RMAN> RESTORE CONTROLFILE FROM '/backup/rman/cf_c-1234567890-20250101-00';
RMAN> ALTER DATABASE MOUNT;
# 恢复数据库
RMAN> RESTORE DATABASE;
# 应用归档日志进行恢复
RMAN> RECOVER DATABASE;
# 打开数据库(需 resetlogs,因控制文件是恢复的)
RMAN> ALTER DATABASE OPEN RESETLOGS;
⚠️ 注意:
OPEN RESETLOGS会重置日志序列号,之后需立即做一次 Level 0 备份!
表空间级恢复
RMAN> SQL 'ALTER TABLESPACE users OFFLINE IMMEDIATE';
RMAN> RESTORE TABLESPACE users;
RMAN> RECOVER TABLESPACE users;
RMAN> SQL 'ALTER TABLESPACE users ONLINE';
不完全恢复(时间点恢复)
例如恢复到 2025-01-05 14:00:00:
RMAN> STARTUP MOUNT;
RMAN> RUN {
SET UNTIL TIME "TO_DATE('2025-01-05 14:00:00', 'YYYY-MM-DD HH24:MI:SS')";
RESTORE DATABASE;
RECOVER DATABASE;
ALTER DATABASE OPEN RESETLOGS;
}
自动化备份脚本
全量备份脚本(rman_full_backup.sh)
#!/bin/bash
# Oracle RMAN Level 0 Backup Script (Optimized)
# Author: DBA Team
# Date: 2026-01-06
# --- 1. 加载环境变量 ---
source /home/oracle/.bash_profile
# --- 2. 强制设置关键环境变量 ---
export ORACLE_SID=orcl1
export DBNAME=orcl
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8 # 防止日期格式或字符集问题
# --- 3. 时间变量 ---
year=$(date "+%Y")
month=$(date "+%m")
day=$( date "+%d")
hour=$(date "+%H")
min=$(date "+%M")
sec=$(date "+%S")
bakdate=${year}${month}${day}
baktime=${hour}${min}${sec}
# --- 4. 路径定义 ---
BACKUP_DIR=/orabak/scsbgjb/${bakdate}
DATABAK=${BACKUP_DIR}/databak
ARCHBAK=${BACKUP_DIR}/archbak
SCRIPT_DIR=/home/oracle/enmo/backup/scripts
LOG_DIR=/home/oracle/enmo/backup/log
CMDFILE=${SCRIPT_DIR}/scsbgjb_level_0_${bakdate}_${baktime}.rman
LOGFILE=${LOG_DIR}/${bakdate}_${baktime}_level_0.log
# --- 5. 创建目录 ---
mkdir -p "${DATABAK}" "${ARCHBAK}" "${SCRIPT_DIR}" "${LOG_DIR}"
# --- 6. 记录开始时间 ---
echo "[$(date)] Starting RMAN Level 0 Backup for DB: ${DBNAME} (SID: ${ORACLE_SID})" | tee "${LOGFILE}"
# --- 7. 生成 RMAN 命令文件 ---
cat > "${CMDFILE}" << EOF
RUN {
# 分配 10 个并行通道(根据 I/O 能力调整)
ALLOCATE CHANNEL ch1 DEVICE TYPE DISK;
ALLOCATE CHANNEL ch2 DEVICE TYPE DISK;
ALLOCATE CHANNEL ch3 DEVICE TYPE DISK;
ALLOCATE CHANNEL ch4 DEVICE TYPE DISK;
ALLOCATE CHANNEL ch5 DEVICE TYPE DISK;
ALLOCATE CHANNEL ch6 DEVICE TYPE DISK;
ALLOCATE CHANNEL ch7 DEVICE TYPE DISK;
ALLOCATE CHANNEL ch8 DEVICE TYPE DISK;
ALLOCATE CHANNEL ch9 DEVICE TYPE DISK;
ALLOCATE CHANNEL ch10 DEVICE TYPE DISK;
# 强制归档当前日志,确保一致性
SQL 'ALTER SYSTEM ARCHIVE LOG CURRENT';
# 备份数据库(Level 0 + 压缩)
BACKUP AS COMPRESSED BACKUPSET
INCREMENTAL LEVEL 0
FILESPERSET 20
FORMAT '${DATABAK}/${DBNAME}_level_0_%U_%T'
DATABASE;
# 备份所有尚未备份过的归档日志(更安全)
BACKUP AS COMPRESSED BACKUPSET
SKIP INACCESSIBLE
FILESPERSET 20
FORMAT '${ARCHBAK}/${DBNAME}_arch_%U_%T'
ARCHIVELOG ALL NOT BACKED UP 1 TIMES;
# 显式备份控制文件和 SPFILE(即使启用了 autobackup)
BACKUP CURRENT CONTROLFILE FORMAT '${BACKUP_DIR}/${DBNAME}_control_bak_%T';
BACKUP SPFILE TAG 'spfile' FORMAT '${BACKUP_DIR}/${DBNAME}_spfile_%U_%T';
# 释放通道
RELEASE CHANNEL ch1; RELEASE CHANNEL ch2; RELEASE CHANNEL ch3; RELEASE CHANNEL ch4;
RELEASE CHANNEL ch5; RELEASE CHANNEL ch6; RELEASE CHANNEL ch7; RELEASE CHANNEL ch8;
RELEASE CHANNEL ch9; RELEASE CHANNEL ch10;
}
# 清理:仅本次使用 30 天保留策略(不修改全局配置)
REPORT OBSOLETE RECOVERY WINDOW OF 30 DAYS;
DELETE NOPROMPT OBSOLETE RECOVERY WINDOW OF 30 DAYS;
# 校验并清理失效备份
CROSSCHECK BACKUP;
CROSSCHECK ARCHIVELOG ALL;
DELETE NOPROMPT EXPIRED BACKUP;
DELETE NOPROMPT EXPIRED ARCHIVELOG;
EOF
# --- 8. 执行 RMAN ---
echo "[$(date)] Executing RMAN command from: ${CMDFILE}" >> "${LOGFILE}"
$ORACLE_HOME/bin/rman TARGET / CMDLINE="SET ECHO ON" LOG="${LOGFILE}" < "${CMDFILE}"
# --- 9. 检查执行结果 ---
if [ ${?} -eq 0 ]; then
echo "[$(date)] ✅ RMAN Level 0 Backup SUCCESSFUL." >> "${LOGFILE}"
echo "Backup completed successfully. Log: ${LOGFILE}"
else
echo "[$(date)] ❌ RMAN Level 0 Backup FAILED!" >> "${LOGFILE}"
echo "ERROR: Backup failed! Check log: ${LOGFILE}" >&2
exit 1
fi
增量 Level 1 备份脚本(rman_incr_backup.sh)
#!/bin/bash
# Oracle RMAN Level 1 Incremental Backup Script (Optimized)
# Author: DBA Team
# Date: 2026-01-06
# --- 1. 加载环境变量 ---
source /home/oracle/.bash_profile
# --- 2. 强制设置关键环境变量 ---
export ORACLE_SID=orcl1
export DBNAME=orcl
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8 # 避免日期/字符集问题
# --- 3. 时间变量 ---
year=$(date "+%Y")
month=$(date "+%m")
day=$(date "+%d")
hour=$(date "+%H")
min=$(date "+%M")
sec=$(date "+%S")
bakdate=${year}${month}${day}
baktime=${hour}${min}${sec}
# --- 4. 路径定义 ---
BACKUP_DIR=/orabak/scsbgjb/${bakdate}
DATABAK=${BACKUP_DIR}/databak
ARCHBAK=${BACKUP_DIR}/archbak
SCRIPT_DIR=/home/oracle/enmo/backup/scripts
LOG_DIR=/home/oracle/enmo/backup/log
CMDFILE=${SCRIPT_DIR}/scsbgjb_level_1_${bakdate}_${baktime}.rman
LOGFILE=${LOG_DIR}/${bakdate}_${baktime}_level_1.log
# --- 5. 创建目录 ---
mkdir -p "${DATABAK}" "${ARCHBAK}" "${SCRIPT_DIR}" "${LOG_DIR}"
# --- 6. 记录开始时间 ---
echo "[$(date)] Starting RMAN Level 1 Incremental Backup for DB: ${DBNAME} (SID: ${ORACLE_SID})" | tee "${LOGFILE}"
# --- 7. 生成 RMAN 命令文件 ---
cat > "${CMDFILE}" << EOF
RUN {
# 分配 10 个并行通道
ALLOCATE CHANNEL ch1 DEVICE TYPE DISK;
ALLOCATE CHANNEL ch2 DEVICE TYPE DISK;
ALLOCATE CHANNEL ch3 DEVICE TYPE DISK;
ALLOCATE CHANNEL ch4 DEVICE TYPE DISK;
ALLOCATE CHANNEL ch5 DEVICE TYPE DISK;
ALLOCATE CHANNEL ch6 DEVICE TYPE DISK;
ALLOCATE CHANNEL ch7 DEVICE TYPE DISK;
ALLOCATE CHANNEL ch8 DEVICE TYPE DISK;
ALLOCATE CHANNEL ch9 DEVICE TYPE DISK;
ALLOCATE CHANNEL ch10 DEVICE TYPE DISK;
# 强制切换日志,确保最新变更被归档
SQL 'ALTER SYSTEM ARCHIVE LOG CURRENT';
# Level 1 增量备份(仅备份自上次 Level 0/1 后变化的块)
BACKUP AS COMPRESSED BACKUPSET
INCREMENTAL LEVEL 1
FILESPERSET 20
FORMAT '${DATABAK}/${DBNAME}_level_1_%U_%T'
DATABASE;
# 备份所有尚未备份过的归档日志(比 sysdate-1 更可靠)
BACKUP AS COMPRESSED BACKUPSET
SKIP INACCESSIBLE
FILESPERSET 20
FORMAT '${ARCHBAK}/${DBNAME}_arch_%U_%T'
ARCHIVELOG ALL NOT BACKED UP 1 TIMES;
# 显式备份控制文件和 SPFILE(双重保障)
BACKUP CURRENT CONTROLFILE FORMAT '${BACKUP_DIR}/${DBNAME}_control_bak_%T';
BACKUP SPFILE TAG 'spfile' FORMAT '${BACKUP_DIR}/${DBNAME}_spfile_%U_%T';
# 释放通道
RELEASE CHANNEL ch1; RELEASE CHANNEL ch2; RELEASE CHANNEL ch3; RELEASE CHANNEL ch4;
RELEASE CHANNEL ch5; RELEASE CHANNEL ch6; RELEASE CHANNEL ch7; RELEASE CHANNEL ch8;
RELEASE CHANNEL ch9; RELEASE CHANNEL ch10;
}
# 清理:仅本次使用 30 天保留策略(不修改全局配置)
REPORT OBSOLETE RECOVERY WINDOW OF 30 DAYS;
DELETE NOPROMPT OBSOLETE RECOVERY WINDOW OF 30 DAYS;
# 校验并清理失效备份
CROSSCHECK BACKUP;
CROSSCHECK ARCHIVELOG ALL;
DELETE NOPROMPT EXPIRED BACKUP;
DELETE NOPROMPT EXPIRED ARCHIVELOG;
EOF
# --- 8. 执行 RMAN ---
echo "[$(date)] Executing RMAN command from: ${CMDFILE}" >> "${LOGFILE}"
$ORACLE_HOME/bin/rman TARGET / CMDLINE="SET ECHO ON" LOG="${LOGFILE}" < "${CMDFILE}"
# --- 9. 检查执行结果 ---
if [ ${?} -eq 0 ]; then
echo "[$(date)] ✅ RMAN Level 1 Backup SUCCESSFUL." >> "${LOGFILE}"
echo "Incremental backup completed successfully. Log: ${LOGFILE}"
else
echo "[$(date)] ❌ RMAN Level 1 Backup FAILED!" >> "${LOGFILE}"
echo "ERROR: Incremental backup failed! Check log: ${LOGFILE}" >&2
exit 1
fi
赋予执行权限:
chmod +x rman_full_backup.sh rman_incr_backup.sh
定期调度(crontab)
编辑 crontab:
crontab -e
添加以下内容(每周日全备,其他天增量):
# 每周日凌晨 2 点全量备份
0 2 * * 0 /home/oracle/scripts/rman_full_backup.sh
# 周一至周六凌晨 2 点增量备份
0 2 * * 1-6 /home/oracle/scripts/rman_incr_backup.sh
注意事项
- 归档日志必须保留:恢复依赖归档日志,确保磁盘空间充足。
- 测试恢复流程:定期在测试环境演练恢复,避免“备份成功但无法恢复”。
- 监控日志:检查
$BACKUP_LOG是否有RMAN-错误。 - 保留策略:根据业务需求调整
RETENTION POLICY。 - 加密与压缩(可选):
CONFIGURE COMPRESSION ALGORITHM 'BASIC'; CONFIGURE ENCRYPTION FOR DATABASE ON;
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 龙羽

