环境介绍
Oracle 11gR2 | 主库 IP:10.10.5.38 | 角色:PRIMARY | DB_UNIQUE_NAME:pay
Oracle 11gR2 | 备库 IP:10.10.5.39 | 角色:STANDBY | DB_UNIQUE_NAME:pay_standby
Oracle 11gR2 | Observer IP:10.10.5.40 | 角色:Observer
《Oracle 11g DG 主库配置 9 步走,从归档模式到 FSFO 全流程手册》上一篇把主库端的 9 步配置从头到尾走了一遍,PFILE 和密码文件也传到了备库。接下来这篇文章就是备库端的活儿——从一张白纸到 Active Data Guard 跑起来。
备库初始化最容易栽跟头的地方不是 RMAN 复制本身,而是前面的准备工作漏了一项:静态监听没配,DUPLICATE 直接报 ORA-12528;密码文件没传,RMAN 连不上;目录权限没给,NOMOUNT 起不来。每一步做完确认一步,别等 RMAN 跑了半小时才回头查。
环境参数速查(备库端):
export ORACLE_SID=pay
export ORACLE_HOME=/u01/oracle/11.2.0.3/product
export ORACLE_BASE=/u01/oracle
export PATH=$ORACLE_HOME/bin:$PATH
备库的 ORACLE_SID 和主库一样是 pay,区分主备靠的是 DB_UNIQUE_NAME,不是 SID。
前置准备:别急着敲 RMAN
0.1 网络连通性确认
主备两端的 tnsnames.ora 要互相能 ping 通,这是 RMAN FROM ACTIVE DATABASE 的前提:
tnsping pay tnsping pay_standby
两个都得通。不通就检查 tnsnames.ora 和 listener.ora,别往下走。
0.2 从主库复制文件
上一篇在主库生成了 PFILE 和密码文件,现在要把它们弄到备库:
# 密码文件(主备必须一致,否则 RMAN 远程连接失败)
scp oracle@10.10.5.38:$ORACLE_HOME/dbs/orapwpay \
$ORACLE_HOME/dbs/orapwpay
# 参数文件(主库已改过 db_unique_name=pay_standby)
scp oracle@10.10.5.38:/tmp/initpay.ora \
$ORACLE_HOME/dbs/initpay.ora
确认一下 db_unique_name 已经改过来了:
grep -i db_unique_name $ORACLE_HOME/dbs/initpay.ora
预期值:
*.db_unique_name='pay_standby'
如果还是pay,说明主库那步漏了sed替换,回去补。
0.3 创建必要目录
备库的数据文件、归档、FRA、audit 目录都得提前建好,不然 RMAN 复制到一半写不进去:
mkdir -p /u01/oracle/oradata/pay mkdir -p /u01/oracle/oradata/pay/DG_BROKER mkdir -p /u01/backup/archivelog/pay mkdir -p /u01/oracle/fast_recovery_area/pay mkdir -p /u01/oracle/admin/pay/adump chown -R oracle:oinstall /u01/oracle/oradata/pay \ /u01/backup/archivelog/pay \ /u01/oracle/fast_recovery_area/pay \ /u01/oracle/admin/pay/adump chmod 750 /u01/oracle/oradata/pay \ /u01/backup/archivelog/pay \ /u01/oracle/fast_recovery_area/pay \ /u01/oracle/admin/pay/adump
第一步:配置 listener 静态 SID 注册
为什么需要静态注册:
FROM ACTIVE DATABASE在线复制时,备库处于NOMOUNT状态,动态注册不可用。没有静态注册,RMAN 连备库时监听会拒绝连接,直接报ORA-12528。
编辑 listener.ora
文件路径:$ORACLE_HOME/network/admin/listener.ora
在文件末尾追加静态注册配置:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = pay_standby)
(SID_NAME = pay)
(ORACLE_HOME = /u01/oracle/11.2.0.3/product)
)
(SID_DESC =
(SID_NAME = pay)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)
(GLOBAL_DBNAME = pay_standby_DGMGRL)
)
)
注意:
GLOBAL_DBNAME写备库的DB_UNIQUE_NAME(pay_standby),SID_NAME写实例名(pay)。这两个容易搞反。- GLOBAL_DBNAME:11gR2 固定格式 db_unique_name_DGMGRL,必须填写 pay_standby__DGMGRL,切勿写 DGB;
- DGB 与 DGMGRL 服务完整对照说明
| 服务名称 | 来源 | 注册方式 | 作用场景 | 是否可省略 |
|---|---|---|---|---|
| pay_standby | 数据库动态注册 | 动态 | 普通DG日志传输、MRP应用 | 不可省略,常规同步依赖 |
| pay_standby_DGB | Broker内部别名 | 无注册 | 仅日志打印、内部跳转标识 | 无需手动配置 |
| pay_standby_DGMGRL | 人工监听配置 | 静态注册(必须) | Broker心跳、切换、重启实例、FSFO重建 | 11gR2必须配置 |
重载监听
lsnrctl status
# 若已启动
lsnrctl reload
# 若未启动
lsnrctl start
验证静态注册是否生效:
lsnrctl status | grep -A2 "Service"
应该能看到 pay_standby 服务状态为 UNKNOWN(这是正常的,因为实例还没启动)。
第二步:由 PFILE 创建 SPFILE
sqlplus / as sysdba
CREATE SPFILE='/u01/oracle/11.2.0.3/product/dbs/spfilepay.ora'
FROM PFILE='/u01/oracle/11.2.0.3/product/dbs/initpay.ora';
EXIT;
若
spfilepay.ora已存在且内容一致,可跳过。但第一次建备库,建议重新生成,确保参数干净。
第三步:启动备库到 NOMOUNT
sqlplus / as sysdba
-- 如果实例已是 MOUNTED/OPEN,先关闭
SHUTDOWN IMMEDIATE;
-- 启动 NOMOUNT(只读 SPFILE,不读控制文件)
STARTUP NOMOUNT;
SELECT INSTANCE_NAME, STATUS FROM V$INSTANCE;
EXIT;
预期结果:
STATUS = STARTED(即 NOMOUNT 状态)
如果报ORA-01078或LRM-00109,检查 PFILE/SPFILE 路径和参数格式。
NOMOUNT 是 RMAN DUPLICATE 的起点。备库此时只有实例进程,没有控制文件,没有数据文件——接下来交给 RMAN 从主库在线拉过来。
第四步:RMAN 在线复制备库
这是整个备库初始化最关键的一步。原理是 DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE,直接通过网络从主库拉数据文件,不需要本地备份集。
连接 RMAN
rman target="sys/oracle@pay" auxiliary="sys/oracle@pay_standby"
target:主库连接串auxiliary:备库连接串
5 个硬性前提(少一个都会失败):
- 两端密码文件一致(前面 scp 过了)
tnsnames.ora中pay、pay_standby互相 tnsping 通- auxiliary 实例必须是 NOMOUNT 状态(第三步已确认)
- 监听包含静态注册(第一步已配好)
- 两端
DB_NAME一致(都是pay),DB_UNIQUE_NAME不同(payvspay_standby)
执行复制脚本
CONFIGURE DEVICE TYPE DISK PARALLELISM 4;
RUN {
ALLOCATE CHANNEL priv1 TYPE DISK MAXPIECESIZE 2G;
ALLOCATE CHANNEL priv2 TYPE DISK MAXPIECESIZE 2G;
ALLOCATE CHANNEL priv3 TYPE DISK MAXPIECESIZE 2G;
ALLOCATE CHANNEL priv4 TYPE DISK MAXPIECESIZE 2G;
ALLOCATE AUXILIARY CHANNEL aux1 TYPE DISK MAXPIECESIZE 2G;
ALLOCATE AUXILIARY CHANNEL aux2 TYPE DISK MAXPIECESIZE 2G;
ALLOCATE AUXILIARY CHANNEL aux3 TYPE DISK MAXPIECESIZE 2G;
ALLOCATE AUXILIARY CHANNEL aux4 TYPE DISK MAXPIECESIZE 2G;
DUPLICATE TARGET DATABASE FOR STANDBY
FROM ACTIVE DATABASE
DORECOVER
NOFILENAMECHECK;
RELEASE CHANNEL priv1;
RELEASE CHANNEL priv2;
RELEASE CHANNEL priv3;
RELEASE CHANNEL priv4;
RELEASE CHANNEL aux1;
RELEASE CHANNEL aux2;
RELEASE CHANNEL aux3;
RELEASE CHANNEL aux4;
}
关键参数解读:
| 参数 | 含义 |
|---|---|
FOR STANDBY |
复制成备库(不是独立主库) |
FROM ACTIVE DATABASE |
在线从主库拉数据,不需要本地备份集 |
DORECOVER |
复制完成后自动执行 RECOVER,把归档日志追上 |
NOFILENAMECHECK |
主备路径相同时不检查文件名冲突(OVERRIDE) |
PARALLELISM 4 |
4 通道并行,加快复制速度 |
MAXPIECESIZE 2G |
限制单个备份片大小,避免大文件传输超时 |
两种 DUPLICATE 模式区别:
FROM ACTIVE DATABASE:在线直接通过网络传输,不需要本地 RMAN 备份,最适合 DG 重建- 不带
ACTIVE:依赖本地已有的 RMAN 备份集,需要先在主库备份再传过来
复制完成后,备库会自动 MOUNT,控制文件和数据文件就位,归档日志已追平。
在线复制失败的兜底方案
如果 FROM ACTIVE DATABASE 网络传输中断或超时,可以改走"备份恢复"模式:
- 在主库做 RMAN 全量备份
- 传输备份集到备库
- 手工
RESTORE CONTROLFILE、RESTORE DATABASE、RECOVER DATABASE
这个方案更慢但更稳,适合网络不稳定或主库数据量很大的场景。
第五步:配置 Flashback 和 FRA
为什么备库也要开 Flashback:FSFO 自动切换后,原主库要 reinstate 回来依赖 Flashback。主库开了还不够,备库也得开——万一备库切换成主库后,原主库要 reinstate,新主库同样需要 Flashback 支持。
5.1 设置 FRA 参数
ALTER SYSTEM SET DB_FLASHBACK_RETENTION_TARGET=1440 SCOPE=BOTH;
ALTER SYSTEM SET DB_RECOVERY_FILE_DEST='/u01/oracle/fast_recovery_area/pay' SCOPE=BOTH;
ALTER SYSTEM SET DB_RECOVERY_FILE_DEST_SIZE=100G SCOPE=BOTH;
-- 验证
SHOW PARAMETER DB_FLASHBACK_RETENTION_TARGET;
SHOW PARAMETER DB_RECOVERY_FILE_DEST;
SHOW PARAMETER DB_RECOVERY_FILE_DEST_SIZE;
5.2 检查 Flashback 状态
SELECT FLASHBACK_ON FROM V$DATABASE;
- 若
YES,跳过后续重启 - 若
NO,继续下一步
5.3 开启 Flashback(需重启到 MOUNT)
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE FLASHBACK ON;
-- 先不 OPEN,留着给下一步处理
SELECT FLASHBACK_ON FROM V$DATABASE;
预期结果:
FLASHBACK_ON = YES
Flashback 必须在 MOUNT 状态下开启,不能在 OPEN 状态直接切。
注意:FRA 大小 100G 是参考值,实际按归档量和保留时间调整。太小会导致归档写不进去,备库同步直接卡住。
第六步:启动 MRP 并启用 Active Data Guard
到这一步,备库已经是 MOUNT 状态,数据文件就位,Flashback 已开。接下来做两件事:把备库以只读模式打开,然后启动实时日志应用。
6.1 确认当前状态
SELECT STATUS FROM V$INSTANCE;
| 当前状态 | 操作 |
|---|---|
STARTED(NOMOUNT) |
ALTER DATABASE MOUNT; |
MOUNTED |
直接下一步 |
OPEN |
直接进入 MRP 步骤 |
6.2 以只读模式打开(Active Data Guard)
ALTER DATABASE OPEN READ ONLY;
Active Data Guard 允许备库在只读打开的同时继续应用归档日志,实现"边查边同步"。11g 需要额外 License,确认你有 ADG 授权。
注:至此 dg_broker 需要的前置配置已经ok,不需要手动启动MRP,后面全部由dg_broker接管,6.3步骤为DG搭建流程,可忽略
6.3 启动实时应用 MRP
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE
USING CURRENT LOGFILE
DISCONNECT FROM SESSION;
参数解读:
| 参数 | 含义 |
|---|---|
USING CURRENT LOGFILE |
实时应用(Real-Time Apply),不等归档完成,直接从 Standby Redo Log 读 |
DISCONNECT FROM SESSION |
MRP 后台运行,不占用当前会话 |
验证 MRP 进程是否启动:
SELECT PROCESS, STATUS, SEQUENCE#
FROM V$MANAGED_STANDBY
WHERE PROCESS IN ('MRP0','RFS');
预期结果:
MRP0状态为APPLYING_LOG,SEQUENCE#持续增长RFS进程存在,表示正在接收主库传来的日志
如果 MRP0 状态是 WAIT_FOR_LOG,说明 Standby Redo Log 没配好或主库没传日志过来,回去检查主库的 SRL 和 LOG_ARCHIVE_DEST_2。
第七步:检查监听状态
lsnrctl status
确认监听正常运行,且 pay_standby 服务已动态注册(实例启动后会自动注册)。
若监听未启动:
lsnrctl start
第八步:验证备库同步状态
全部配置完成,跑一遍完整检查:
sqlplus / as sysdba
SET PAGESIZE 100
SET LINESIZE 120
PROMPT ===== Database Role =====
SELECT DATABASE_ROLE, OPEN_MODE FROM V$DATABASE;
PROMPT ===== Standby Process =====
SELECT PROCESS, PID, STATUS, SEQUENCE#
FROM V$MANAGED_STANDBY;
PROMPT ===== Archived Redo Logs =====
SELECT MAX(SEQUENCE#) AS "Max Sequence"
FROM V$ARCHIVED_LOG
WHERE DELETED='NO' AND ARCHIVED='YES';
EXIT;
预期输出:
| 检查项 | 预期值 |
|---|---|
DATABASE_ROLE |
PHYSICAL STANDBY |
OPEN_MODE |
READ ONLY WITH APPLY |
MRP0 进程 |
APPLYING_LOG,SEQUENCE# 与主库一致 |
Max Sequence |
与主库 ARCHIVE LOG LIST 的序号一致 |
同步延迟排查:如果备库
SEQUENCE#落后主库,查V$DATAGUARD_STATS里的apply lag和transport lag,定位是网络传输慢还是 MRP 应用慢。
常见报错与排查
ORA-12528: TNS:listener: all appropriate instances are blocking new connections
原因:备库 NOMOUNT 时动态注册不可用,监听不知道有实例存在。
处理:
- 确认
listener.ora中已配置静态 SID 注册(见第一步) lsnrctl reload或lsnrctl start重新生效- 重新执行 RMAN 在线复制
RMAN 连接主库/备库失败
处理:
tnsping pay、tnsping pay_standby两个都得通- 检查主备两端防火墙与端口 1521
- 检查 SYS 用户口令与密码文件是否一致
- 检查主备
listener是否正常
ORA-06550 / PLS-00201: identifier ‘DBMS_RCVCAT.GETDBID’ must be declared
典型报错:
RMAN-03002: failure of Duplicate Db command
RMAN-05501: aborting duplication of target database
ORA-06550: line 1, column 17:
PLS-00201: identifier 'DBMS_RCVCAT.GETDBID' must be declared
原因:主库的 RMAN 系统包损坏或缺失。
处理(在主库执行):
-- 重建 RMAN 相关系统包
@?/rdbms/admin/dbmsrman.sql
@?/rdbms/admin/dbmsrcvcat.sql
-- 赋权
GRANT EXECUTE ON dbms_rcvcat TO PUBLIC;
GRANT EXECUTE ON dbms_rcvman TO PUBLIC;
这个问题极少遇到,但如果遇到了,上面的脚本是官方兜底方案。执行完重新跑 DUPLICATE 即可。
验收检查清单
| 项目 | 预期值 | 状态 |
|---|---|---|
DB_UNIQUE_NAME |
pay_standby |
☐ |
| 监听静态注册 | 已配置 | ☐ |
| 实例状态(复制前) | NOMOUNT / STARTED |
☐ |
DUPLICATE ... FOR STANDBY |
成功 | ☐ |
DATABASE_ROLE |
PHYSICAL STANDBY |
☐ |
OPEN_MODE |
READ ONLY WITH APPLY |
☐ |
FLASHBACK_ON |
YES |
☐ |
| MRP 进程 | MRP0 运行中 |
☐ |
| 日志序列号 | 与主库一致,持续增长 | ☐ |
逐项打勾,全绿才算备库初始化完成。
备库搞定之后
- 持续观察 MRP 应用进度(
SEQUENCE#变化) - 在主库确认归档持续传输到备库
- 执行 FSFO 启用与 Observer 部署
主库 9 步 + 备库 8 步,DG 的数据同步链路就打通了。但真正的自动化切换——FSFO(Fast-Start Failover)和 Observer——还没配。下一篇就是 Broker 配置 + FSFO 启用 + Observer 部署,把 DG 从"手动同步"升级到"自动切换"。
整套流程跑通后,SHOW CONFIGURATION 看到 SUCCESS 的那一刻,这半天没白花。
专注于 Oracle / MySQL / PostgreSQL / 达梦等主流数据库的运维实战与架构分享,欢迎关注,一起做靠谱的数据库人。
欢迎赞赏支持或留言指正





