Oracle 11g RAC 异机恢复实战(漫画版)

举报
Lucifer三思而后行 发表于 2026/10/14 15:47:13 2026/10/14
【摘要】 前言节后刚到公司,业务那边就来了一个需求:有一套测试库的数据太老了,需要从生产库恢复一份数据过去。生产库和测试库都是 Oracle 11g RAC,准备使用 RMAN DUPLICATE 完成恢复。原本以为很简单,就是清理旧库、恢复数据、配置 RAC,没想到过程中还是遇到了几个问题:RMAN DUPLICATE 成功后,修改参数时报 ORA-01565,找不到 SPFILE;RAC 第二节...

前言

节后刚到公司,业务那边就来了一个需求:有一套测试库的数据太老了,需要从生产库恢复一份数据过去。

生产库和测试库都是 Oracle 11g RAC,准备使用 RMAN DUPLICATE 完成恢复。原本以为很简单,就是清理旧库、恢复数据、配置 RAC,没想到过程中还是遇到了几个问题:

  1. RMAN DUPLICATE 成功后,修改参数时报 ORA-01565,找不到 SPFILE;
  2. RAC 第二节点启动后一直停留在 STARTED 状态;
  3. 登录第二节点时,又遇到了 ORA-09925 报错。

好在最后都解决了,两个实例正常 OPEN,完整启停测试也顺利通过。

这类生产库恢复到测试环境的需求应该挺常见,索性就把这次从旧库清理、RMAN 恢复到 RAC 重建的完整操作过程记录下来,方便以后遇到类似需求时直接参考。

一、环境及恢复方案

先看一下环境:

项目 源端生产库 目标测试库
Oracle 版本 11.2.0.4 11.2.0.4
数据库架构 双节点 RAC 双节点 RAC
DB_NAME PRODDB PRODDB
DB_UNIQUE_NAME proddb testdb
实例名称 proddb1 / proddb2 testdb1 / testdb2
节点名称 生产 RAC 节点 rac-test01 / rac-test02
数据存储 ASM +DATA
FRA ASM +FRA
恢复方式 RMAN 备份 Backup-Based DUPLICATE

目标端 Oracle Home:

/u01/app/oracle/product/11.2.0/dbhome_1

RMAN 备份目录:

/backup/rman

本次采用 Backup-Based DUPLICATE,直接使用已有的 RMAN 备份恢复,不需要连接生产库。

主要分为三个步骤:

  1. 清理原测试库,保留现有 RAC 和 ASM 环境。
  2. 执行 RMAN DUPLICATE,先恢复为单实例数据库。
  3. 配置 RAC 参数及 Clusterware,恢复双节点运行。

源端和目标端的 DB_NAME 均为 PRODDB,目标端使用独立的 DB_UNIQUE_NAME:testdb。

二、恢复前检查

1. 检查 RMAN 备份目录

这套生产库的 RMAN 备份是通过 NFS 挂载到目标服务器作为存储,先检查:

df -h /backup/rman
mount | grep /backup
ls -ld /backup/rman
ls -lh /backup/rman | head

确认 Oracle 用户可以正常读取备份文件,并检查数据文件、控制文件及归档日志备份是否齐全。

如果可以连接源库,可通过 RMAN 查看备份信息:

LIST BACKUP SUMMARY;
LIST BACKUP OF DATABASE;
LIST BACKUP OF ARCHIVELOG ALL;

本次使用 Level 0 备份,结合归档日志恢复,最终恢复至 SCN 73594150946。

2. 检查目标 RAC 集群

首先确认目标 RAC 环境正常,使用 grid 用户执行:

crsctl stat res -t

重点检查 ASM、监听、VIP、SCAN 等资源,再检查 ASM 磁盘组:

asmcmd lsdg

确认 +DATA、+FRA 正常挂载,并且有足够的可用空间,需要注意:ASM 磁盘组的 Free_MB 不一定等于实际可用空间,特别是 NORMAL、HIGH 冗余磁盘组,还要关注 Usable_file_MB。

接着查看当前 Clusterware 中注册的数据库:

srvctl config database

如果已经存在 testdb,还需要进一步检查:

srvctl config database -d testdb -a
srvctl status database -d testdb
srvctl config service -d testdb

这次目标端原本就有一套测试数据库,所以不能直接启动 DUPLICATE,必须先处理旧数据库。

3. 检查 Oracle 软件环境

两个节点都要确认 Oracle Home 和软件版本:

echo $ORACLE_HOME
echo $ORACLE_SID
which sqlplus
which rman
sqlplus -v

本次使用 Oracle 11.2.0.4,恢复阶段先在第一个节点操作:

export ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1
export ORACLE_SID=testdb1
export PATH=$ORACLE_HOME/bin:$PATH

第二节点后续使用:

export ORACLE_SID=testdb2

三、清理原测试数据库

目标端已有一套测试 RAC,本次需要使用生产数据重新恢复,因此需要先清理原测试库,保留现有 GI、ASM 和监听环境,再执行 RMAN DUPLICATE。

1. 保存原数据库信息

先连接旧测试数据库:

sqlplus / as sysdba

检查数据库身份:

SELECT name,
       db_unique_name,
       dbid,
       open_mode
FROM v$database;

检查 RAC 实例:

SELECT inst_id,
       instance_name,
       host_name,
       status
FROM gv$instance
ORDER BY inst_id;

保存 SPFILE 和控制文件位置:

SHOW PARAMETER spfile;
SHOW PARAMETER control_files;

查询数据文件:

SELECT file#, name
FROM v$datafile
ORDER BY file#;

查询临时文件:

SELECT file#, name
FROM v$tempfile
ORDER BY file#;

查询 REDO:

SELECT group#, member
FROM v$logfile
ORDER BY group#;

提前记录原测试库的数据文件、控制文件和 REDO 路径,方便后续清理 ASM 文件时核对,避免误删其他数据库文件。

2. 备份原测试库配置

先导出参数文件:

CREATE PFILE='/home/oracle/init_testdb_before_rebuild.ora'
FROM SPFILE;

再保存 Clusterware 配置:

srvctl config database -d testdb -a \
  > /home/oracle/testdb_srvctl_before_rebuild.txt

如果原测试库的数据还需要保留,应提前做好备份,避免清理后无法恢复。

3. 停止原测试数据库

确认旧测试库已停用、数据允许覆盖后,停止数据库:

srvctl stop database -d testdb -o immediate

检查:

srvctl status database -d testdb

确认两个实例均已停止:

Instance testdb1 is not running on node rac-test01
Instance testdb2 is not running on node rac-test02

两个节点分别检查 PMON 进程:

ps -ef | grep '[p]mon'

确认原实例已退出。

4. 注销旧 Clusterware 资源

注销旧数据库的 Clusterware 资源:

srvctl remove database -d testdb
srvctl config database

确认 testdb 已注销。注意,srvctl remove database 不会删除 ASM 中的数据文件。

5. 检查并清理 ASM 文件

使用 grid 用户:

asmcmd lsdg
asmcmd ls +DATA/
asmcmd ls +FRA/

查看旧数据库目录:

asmcmd ls -l +DATA/TESTDB/
asmcmd ls -l +FRA/TESTDB/

结合前面记录的控制文件、数据文件和 REDO 路径,逐一核对待清理文件的归属。

确认文件已废弃且没有其他资源引用后,再执行:

asmcmd rm <已确认废弃文件的完整ASM路径>

清理 ASM 文件前,建议先确认好文件的归属,避免误删。也可以根据实际情况使用 RMAN DROP DATABASE 删除旧库,但要确保不影响现有 GI、ASM、监听、VIP 和 SCAN 等集群资源。

6. 清理旧实例本地配置

两个节点分别检查:

ls -l $ORACLE_HOME/dbs/*testdb*

主要关注:

inittestdb1.ora
inittestdb2.ora
spfiletestdb1.ora
orapwtestdb1
orapwtestdb2

先备份旧配置:

mkdir -p /home/oracle/testdb_old_config

将旧 PFILE、SPFILE 和密码文件移入备份目录,核实后再清理原文件。

清理完成后,再确认:

srvctl config database
crsctl stat res -t
asmcmd lsdg

确认旧库已清理,GI 和 ASM 正常,准备恢复。

四、准备 RMAN 辅助实例

在第一个节点准备 RMAN 辅助实例,恢复阶段暂不启用 RAC。

1. 创建 PFILE

使用 oracle 用户:

export ORACLE_HOME=/u01/app/oracle/product/11.2.0/dbhome_1
export ORACLE_SID=testdb1
export PATH=$ORACLE_HOME/bin:$PATH

创建初始化参数文件:

vi $ORACLE_HOME/dbs/inittestdb1.ora
## 写入以下内容
db_name='PRODDB'
db_unique_name='testdb'
instance_name='testdb1'
cluster_database=FALSE
db_create_file_dest='+DATA'
db_recovery_file_dest='+FRA'
db_recovery_file_dest_size=100G
diagnostic_dest='/u01/app/oracle'
audit_file_dest='/u01/app/oracle/admin/testdb/adump'
job_queue_processes=0

以上为参考参数,FRA 大小、内存及兼容性参数按实际环境调整;db_name 必须与源库备份一致。

2. 创建审计目录

mkdir -p /u01/app/oracle/admin/testdb/adump
chmod 750 /u01/app/oracle/admin/testdb/adump

两个节点都需要创建审计目录,后面遇到的 ORA-09925 就与此有关。

3. 启动 NOMOUNT

sqlplus / as sysdba

执行:

STARTUP NOMOUNT
PFILE='/u01/app/oracle/product/11.2.0/dbhome_1/dbs/inittestdb1.ora';

检查:

SELECT instance_name, status
FROM v$instance;

INSTANCE_NAME STATUS
------------- -------
testdb1       STARTED

辅助实例处于 STARTED(NOMOUNT)即可,后续由 RMAN 完成恢复。

五、执行 RMAN DUPLICATE

这里采用 Backup-Based DUPLICATE,直接通过 RMAN 备份恢复,无需连接生产库。

1. 确认备份和恢复目标

恢复前确认备份目录、源库 DBID、数据文件及控制文件路径,以及归档日志和目标恢复 SCN。

本次分配 4 个辅助通道,共恢复 59 个数据文件,最终恢复至 SCN 73594150946,并通过 RESETLOGS 打开数据库。

2. 准备 RMAN 脚本

以下为 RMAN DUPLICATE 参考脚本,实际执行时需根据备份信息、ASM 路径和目标恢复 SCN 调整。

先通过辅助实例连接 RMAN:

rman auxiliary /

参考脚本:

RUN {
  ALLOCATE AUXILIARY CHANNEL a1 DEVICE TYPE DISK;
  ALLOCATE AUXILIARY CHANNEL a2 DEVICE TYPE DISK;
  ALLOCATE AUXILIARY CHANNEL a3 DEVICE TYPE DISK;
  ALLOCATE AUXILIARY CHANNEL a4 DEVICE TYPE DISK;

  DUPLICATE DATABASE 'PRODDB' DBID 1234567890
    TO 'PRODDB'
    BACKUP LOCATION '/backup/rman'
    NOFILENAMECHECK;

  RELEASE CHANNEL a1;
  RELEASE CHANNEL a2;
  RELEASE CHANNEL a3;
  RELEASE CHANNEL a4;
}

该脚本仅供参考,实际执行前需确认 RMAN 语法、ASM 文件路径及恢复 SCN,避免覆盖其他数据库文件。

3. 执行恢复

将 RMAN 脚本保存为:

/home/oracle/duplicate_testdb.rman

执行:

rman auxiliary / \
  cmdfile=/home/oracle/duplicate_testdb.rman \
  log=/home/oracle/duplicate_testdb.log

查看恢复日志:

tail -f /home/oracle/duplicate_testdb.log

重点查看数据文件恢复、归档应用及 RESETLOGS 是否成功。

RMAN 日志显示:

database opened

Finished Duplicate Db

Recovery Manager complete.

DUPLICATE 完成。

4. 检查恢复结果

SELECT name,
       db_unique_name,
       dbid,
       open_mode,
       database_role,
       resetlogs_time
FROM v$database;

NAME     DB_UNIQUE_NAME OPEN_MODE  DATABASE_ROLE
-------- -------------- ---------- -------------
PRODDB   testdb         READ WRITE PRIMARY

确认目标库 DBID 已更新,再检查数据文件:

SELECT file#, name, status
FROM v$datafile
ORDER BY file#;

确认数据文件已恢复至目标 ASM,接下来配置双节点 RAC。

六、处理 SPFILE 丢失问题

恢复完成后,准备修改 RAC 参数:

ALTER SYSTEM SET cluster_database=TRUE SCOPE=SPFILE SID='*';

结果报错:

ORA-01565: error in identifying file
ORA-27037: unable to obtain file status
Linux-x86_64 Error: 2: No such file or directory

检查:

SHOW PARAMETER spfile;

发现当前实例引用的仍然是本地 SPFILE:

/u01/app/oracle/product/11.2.0/dbhome_1/dbs/spfiletestdb1.ora

但是操作系统上已经没有这个文件:

ls -l $ORACLE_HOME/dbs/*testdb*

实例虽然已经 OPEN,但引用的 SPFILE 文件不存在,导致无法写入参数。

重新创建 ASM 共享 SPFILE:

CREATE SPFILE='+DATA/TESTDB/spfiletestdb.ora' FROM MEMORY;

File created.

检查 ASM:

asmcmd ls -l +DATA/TESTDB/spfiletestdb.ora

在两个节点分别配置 PFILE,指向共享 ASM SPFILE。

rac-test01:

cat > $ORACLE_HOME/dbs/inittestdb1.ora <<'EOF'
SPFILE='+DATA/TESTDB/spfiletestdb.ora'
EOF

rac-test02:

cat > $ORACLE_HOME/dbs/inittestdb2.ora <<'EOF'
SPFILE='+DATA/TESTDB/spfiletestdb.ora'
EOF

新 SPFILE 不会自动生效,重启第一个实例:

SHUTDOWN IMMEDIATE;
STARTUP;

再次检查:

SHOW PARAMETER spfile;

确认已经指向:

+DATA/TESTDB/spfiletestdb.ora

确认 SPFILE 已切换。

七、配置双节点 RAC 参数

接下来配置 RAC 参数。

1. 配置集群参数

ALTER SYSTEM SET cluster_database=TRUE SCOPE=SPFILE SID='*';
ALTER SYSTEM SET cluster_database_instances=2 SCOPE=SPFILE SID='*';

2. 配置实例编号

ALTER SYSTEM SET instance_number=1 SCOPE=SPFILE SID='testdb1';
ALTER SYSTEM SET instance_number=2 SCOPE=SPFILE SID='testdb2';

3. 配置 REDO Thread

ALTER SYSTEM SET thread=1 SCOPE=SPFILE SID='testdb1';
ALTER SYSTEM SET thread=2 SCOPE=SPFILE SID='testdb2';

4. 配置 UNDO

ALTER SYSTEM SET undo_tablespace='UNDOTBS1' SCOPE=SPFILE SID='testdb1';
ALTER SYSTEM SET undo_tablespace='UNDOTBS2' SCOPE=SPFILE SID='testdb2';

5. 禁用自动任务

由于数据库来自生产环境,暂时不允许自动执行原生产库的任务:

ALTER SYSTEM SET job_queue_processes=0 SCOPE=SPFILE SID='*';

6. 清理遗留参数

检查:

SELECT sid, name, value
FROM v$spparameter
WHERE name IN (
  'cluster_database',
  'cluster_database_instances',
  'instance_name',
  'instance_number',
  'thread',
  'undo_tablespace',
  'job_queue_processes'
)
AND isspecified = 'TRUE'
ORDER BY name, sid;

*.instance_name = testdb1

恢复阶段遗留了全局 instance_name,需要清理,避免第二节点继承。

执行:

ALTER SYSTEM RESET instance_name SCOPE=SPFILE SID='*';

同时清理全局 UNDO 参数:

ALTER SYSTEM RESET undo_tablespace SCOPE=SPFILE SID='*';

最终保留实例级配置:

*.cluster_database           TRUE
*.cluster_database_instances 2
testdb1.instance_number       1
testdb2.instance_number       2
testdb1.thread                1
testdb2.thread                2
testdb1.undo_tablespace       UNDOTBS1
testdb2.undo_tablespace       UNDOTBS2
*.job_queue_processes         0

7. 检查 REDO 和 UNDO

先检查 REDO:

SELECT group#,
       thread#,
       bytes/1024/1024 mb,
       status
FROM v$log
ORDER BY thread#, group#;

本次两个 Thread 均已配置,每个 Thread 5 组 REDO,每组 300MB。

检查:

SELECT thread#, status, enabled
FROM v$thread
ORDER BY thread#;

第二节点尚未启动时,Thread 2 可能显示 CLOSED。

再检查 UNDO:

SELECT tablespace_name, status
FROM dba_tablespaces
WHERE contents='UNDO';

本次 REDO 和两个 UNDO 表空间均已存在,无需重新创建。

八、准备密码文件并注册 Clusterware

1. 准备密码文件

两个节点分别需要:

rac-test01: $ORACLE_HOME/dbs/orapwtestdb1
rac-test02: $ORACLE_HOME/dbs/orapwtestdb2

使用 orapwd 创建密码文件,密码应与目标数据库 SYS 密码一致。

Oracle 11g 环境可以使用:

orapwd file=$ORACLE_HOME/dbs/orapwtestdb1

设置 SYS 密码后,将密码文件复制到第二节点并调整文件名,确保两个节点保持一致。

2. 注册数据库

使用 oracle 用户执行:

srvctl add database \
  -d testdb \
  -o /u01/app/oracle/product/11.2.0/dbhome_1 \
  -p +DATA/TESTDB/spfiletestdb.ora \
  -r PRIMARY \
  -s OPEN

注册实例:

srvctl add instance -d testdb -i testdb1 -n rac-test01
srvctl add instance -d testdb -i testdb2 -n rac-test02

添加 ASM 磁盘组依赖:

srvctl modify database -d testdb -a "DATA,FRA"

检查:

srvctl config database -d testdb -a

确认:

Database unique name: testdb
Spfile: +DATA/TESTDB/spfiletestdb.ora
Database instances: testdb1,testdb2
Disk Groups: DATA,FRA
Type: RAC
Database is enabled

3. 启动 RAC

先确保手工启动的实例已经关闭:

SHUTDOWN IMMEDIATE;

然后通过 Clusterware 启动:

srvctl start database -d testdb

检查:

srvctl status database -d testdb

Instance testdb1 is running on node rac-test01
Instance testdb2 is running on node rac-test02

继续检查实例状态。

九、第二节点启动后停留在 STARTED

虽然 srvctl 显示两个实例都在运行,但进一步检查:

SELECT inst_id,
       instance_name,
       host_name,
       status,
       thread#
FROM gv$instance
ORDER BY inst_id;

INST_ID INSTANCE_NAME HOST_NAME  STATUS  THREAD#
------- ------------- ---------- ------- -------
1       testdb1       rac-test01 OPEN    1
2       testdb2       rac-test02 STARTED 0

第二节点仍停留在 STARTED。srvctl 显示 running,不代表实例已经 OPEN,继续登录第二节点检查。

export ORACLE_SID=testdb2

sqlplus / as sysdba

ORA-09925: Unable to create audit trail file
Linux-x86_64 Error: 2: No such file or directory

先检查磁盘:

df -h

磁盘空间正常,继续看报错:

No such file or directory

优先检查目录是否存在。

回到第一个节点查询:

SHOW PARAMETER audit_file_dest;

发现审计目录:

/u01/app/oracle/admin/testdb/adump

到第二节点检查:

ls -ld /u01/app/oracle/admin/testdb/adump

目录不存在,补齐:

创建目录:

mkdir -p /u01/app/oracle/admin/testdb/adump
chmod 750 /u01/app/oracle/admin/testdb/adump

确保目录属于 Oracle 软件用户。

重新连接数据库:

sqlplus / as sysdba

连接恢复正常,继续执行:

ALTER DATABASE MOUNT;
ALTER DATABASE OPEN;

执行成功。

再查:

SELECT inst_id, instance_name, status, thread#
FROM gv$instance
ORDER BY inst_id;

INST_ID INSTANCE_NAME STATUS THREAD#
------- ------------- ------ -------
1       testdb1       OPEN   1
2       testdb2       OPEN   2

第二节点正常 OPEN,问题原因是审计目录缺失。

十、数据库最终验收

两个实例 OPEN 后,进行验收检查。

1. 检查数据库身份

SELECT name,
       db_unique_name,
       dbid,
       open_mode,
       database_role
FROM v$database;

确认数据库名称、DBID、打开状态和角色正确。

2. 检查 RAC 实例

SELECT inst_id,
       instance_name,
       host_name,
       status,
       thread#
FROM gv$instance
ORDER BY inst_id;

两个实例均为 OPEN,分别使用 Thread 1 和 Thread 2。

3. 检查数据文件

SELECT status, COUNT(*)
FROM v$datafile
GROUP BY status;

STATUS   COUNT(*)
-------- --------
ONLINE         58
SYSTEM          1

SYSTEM 为数据文件状态,属于正常结果。

4. 检查表空间

SELECT tablespace_name, status
FROM dba_tablespaces
ORDER BY tablespace_name;

34 个表空间全部 ONLINE。

5. 检查数据库组件

SELECT comp_name, status
FROM dba_registry
WHERE status <> 'VALID';

no rows selected

6. 检查监听

两个节点分别执行:

lsnrctl services

确认两个实例都注册到本地监听,并且状态为 READY。

再检查 SCAN:

srvctl config scan
srvctl status scan_listener

本地监听和 SCAN Listener 均正常,后续还需验证 SCAN 服务注册及客户端连接。

7. 完整启停测试

最后再做一次完整启停:

srvctl stop database -d testdb -o immediate

检查:

srvctl status database -d testdb

两个实例均已停止。

然后重新启动:

srvctl start database -d testdb

再次检查:

srvctl status database -d testdb

两个实例均显示 running。

登录数据库:

SELECT inst_id, instance_name, status, thread#
FROM gv$instance
ORDER BY inst_id;

INST_ID INSTANCE_NAME STATUS THREAD#
------- ------------- ------ -------
1       testdb1       OPEN   1
2       testdb2       OPEN   2

完整启停通过,两个实例均由 Clusterware 正常管理。

十一、测试环境隔离

生产库复制到测试环境后,还要检查 DB Link、定时任务和外部接口,避免误连生产系统。

先检查 DB Link:

SELECT owner, db_link, username, host
FROM dba_db_links;

这次发现测试库仍然存在连接外部数据库的 DB Link。

连接地址已脱敏,需确认是否指向生产环境。

检查 Scheduler Job:

SELECT owner, job_name, enabled, state
FROM dba_scheduler_jobs
WHERE enabled = 'TRUE';

还发现了多个已启用任务,其中包含业务相关任务。

再检查 DBMS_JOB:

SELECT schema_user, job, broken, what
FROM dba_jobs
ORDER BY schema_user, job;

因此暂时保持:

ALTER SYSTEM SET job_queue_processes=0 SCOPE=BOTH SID='*';

完成环境隔离检查前,暂不启用这些任务。

总结

本次恢复从清理原测试库开始,依次完成 RMAN DUPLICATE、共享 SPFILE 创建、RAC 参数配置及 Clusterware 注册,最终恢复双节点 RAC。

RMAN 共恢复 59 个数据文件,过程中主要遇到两个问题:

  • ORA-01565:恢复完成后,原 SPFILE 文件不存在,导致参数修改失败。通过 CREATE SPFILE FROM MEMORY 重新创建共享 ASM SPFILE,重启后恢复正常。
  • ORA-09925:第二节点启动后停留在 STARTED,排查发现 audit_file_dest 目录不存在,创建目录后正常 MOUNT、OPEN。

最后通过 srvctl 完成双节点启停验证,两个实例均正常 OPEN。

这次恢复也算再次验证了一点:RMAN DUPLICATE 完成不代表整个恢复结束,后续的 RAC 配置、监听检查和测试环境隔离同样不能少。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。