
1. 适用场景
本文适用于:
Oracle 19c 两节点 RAC 主库
↓
Active Data Guard
↓
Oracle 19c 两节点 RAC 备库
本手册基于实际 RAC→RAC 容灾环境整理,数据库版本:
Oracle Database 19c
Version 19.25.0.0.0
典型架构:
| 项目 | 主库 | 备库 |
|---|---|---|
| 架构 | 2节点 RAC | 2节点 RAC |
| DB_NAME | PRODCDB | PRODCDB |
| DB_UNIQUE_NAME | prodcdb | prodadg |
| 实例1 | prodcdb1 | prodcdb1 |
| 实例2 | prodcdb2 | prodcdb2 |
| 数据存储 | ASM +DATA | ASM +DATA |
| Redo存储 | ASM +RECO | ASM +RECO |
| Redo传输 | ASYNC | --- |
| 最终状态 | PRIMARY / READ WRITE | PHYSICAL STANDBY / READ ONLY WITH APPLY |
核心规则:
DB_NAME:主备一致
DB_UNIQUE_NAME:主备不同
四份实际文档均采用这一规划方式。3、utf8容器库容灾 2、mes容器库容灾
2. 示例网络规划
以下全部为虚拟地址。
主库 RAC
节点1:rac-pri01
Public IP:192.0.2.11
VIP:192.0.2.21
节点2:rac-pri02
Public IP:192.0.2.12
VIP:192.0.2.22
SCAN:
rac-pri-scan
192.0.2.10
备库 RAC
节点1:rac-stby01
Public IP:198.51.100.11
VIP:198.51.100.21
节点2:rac-stby02
Public IP:198.51.100.12
VIP:198.51.100.22
SCAN:
rac-stby-scan
198.51.100.10
数据库:
主库:
DB_NAME=PRODCDB
DB_UNIQUE_NAME=prodcdb
备库:
DB_NAME=PRODCDB
DB_UNIQUE_NAME=prodadg
SID:
prodcdb1
prodcdb2
3. 整体搭建流程
实际实施按以下顺序执行即可:
1. 主备4个节点配置hosts及网络解析
2. 主库开启FORCE LOGGING
3. 准备备库RAC数据库环境
4. 处理DB_DOMAIN / GLOBAL_NAME
5. 同步SYS密码文件
6. 主库创建Standby Redo Log
7. 备份主库SPFILE
8. 配置主库Data Guard参数
9. 检查备库ASM路径
10. 备库两个节点配置静态监听
11. 主备配置tnsnames.ora
12. 四个节点执行tnsping验证
13. 配置备库Data Guard参数
14. 关闭备库两个实例
15. 两个备库实例启动至NOMOUNT
16. RMAN Active Duplicate
17. 配置归档删除策略
18. 备库以只读方式打开
19. 启动Redo Apply
20. 巡检主备同步状态
21. ADGTEST表验证实际数据同步
这就是四套实际环境中反复采用的核心流程。2、mes容器库容灾
4. 配置主备 Hosts
主库、备库共 4 台服务器均配置主备 Public、VIP、SCAN 以及实际需要的私网解析。
示例:
192.0.2.11 rac-pri01
192.0.2.12 rac-pri02
192.0.2.21 rac-pri01-vip
192.0.2.22 rac-pri02-vip
192.0.2.10 rac-pri-scan
198.51.100.11 rac-stby01
198.51.100.12 rac-stby02
198.51.100.21 rac-stby01-vip
198.51.100.22 rac-stby02-vip
198.51.100.10 rac-stby-scan
四份原始实施文档均先完成主备 RAC 节点间的 hosts 解析。4、z16容器库容灾(参与搭建)
5. 主库开启强制日志
主库任一实例:
su - oracle
sqlplus / as sysdba
执行:
ALTER DATABASE FORCE LOGGING;
检查:
SELECT name,
log_mode,
force_logging
FROM v$database;
要求:
LOG_MODE = ARCHIVELOG
FORCE_LOGGING = YES
该步骤只在主库执行。四套实际环境均以此作为 DG 配置的第一项数据库操作。1、erp容器库容灾
6. 准备备库RAC数据库环境
四份实际文档采用的方式不是"仅安装软件",而是:
先在备库 RAC 环境建立同
DB_NAME、不同DB_UNIQUE_NAME的数据库环境,再通过 RMAN Active Duplicate 覆盖形成 Physical Standby。
示例:
主库:
DB_NAME=PRODCDB
DB_UNIQUE_NAME=prodcdb
备库:
DB_NAME=PRODCDB
DB_UNIQUE_NAME=prodadg
备库实例:
prodcdb1
prodcdb2
这一点要与前面的"单机→单机 RMAN Backup-Based"手册区分开。
7. 检查并处理数据库域名
四套实际搭建中均重点处理了 DB_DOMAIN / Global Name,且其中一套实际出现过因域名未清理导致归档目的端异常的问题。4、z16容器库容灾(参与搭建)
备库检查:
SHOW PARAMETER domain;
如本环境要求不使用数据库域名:
ALTER SYSTEM SET db_domain=''
SCOPE=SPFILE SID='*';
ALTER SYSTEM SET global_names=FALSE;
重启后检查:
SELECT * FROM global_name;
如果需要调整:
UPDATE global_name
SET global_name='PRODCDB';
COMMIT;
是否清除
DB_DOMAIN必须以当前环境命名规范为准;这里保留该步骤,是因为四套实际 ADG 环境均按此方式实施。
8. 同步Password File
主备必须保证 SYS 远程认证一致。
实际实施记录明确建议:
直接使用主库密码文件同步到备库,比在备库重新创建更可靠。 4、z16容器库容灾(参与搭建)
正式文档中不保存真实 SYS 密码。
检查:
SHOW PARAMETER remote_login_passwordfile;
建议:
EXCLUSIVE
密码文件完成同步后,再进行后续 TNS / RMAN 远程连接验证。
9. 主库规划Standby Redo Log
这是 RAC ADG 的核心。
先查询:
SET LINES 200
SELECT thread#,
group#,
bytes/1024/1024 size_mb
FROM v$log
ORDER BY thread#,group#;
实际四套文档中都是:
Thread 1:2组Online Redo
Thread 2:2组Online Redo
因此分别为两个 Thread 各配置:
Online Redo组数 + 1
即:
Thread 1:3组SRL
Thread 2:3组SRL
实际环境确实按照每个 Thread 3 组进行配置。2、mes容器库容灾 2、mes容器库容灾
SRL大小必须根据当前库 Online Redo 实际大小确定,不要固定照抄某个数值。
假设当前 Online Redo 为 4096M:
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1
('+RECO/PRODCDB/ONLINELOG/srl_05.log') SIZE 4096M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1
('+RECO/PRODCDB/ONLINELOG/srl_06.log') SIZE 4096M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1
('+RECO/PRODCDB/ONLINELOG/srl_07.log') SIZE 4096M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 2
('+RECO/PRODCDB/ONLINELOG/srl_08.log') SIZE 4096M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 2
('+RECO/PRODCDB/ONLINELOG/srl_09.log') SIZE 4096M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 2
('+RECO/PRODCDB/ONLINELOG/srl_10.log') SIZE 4096M;
检查:
SELECT group#,
thread#,
sequence#,
status,
bytes/1024/1024 size_mb
FROM v$standby_log
ORDER BY thread#,group#;
初建后:
STATUS = UNASSIGNED
属于正常。
10. 备份主库SPFILE
RAC 参数调整前先留备份:
SHOW PARAMETER spfile;
CREATE PFILE='/home/oracle/prodcdb_before_dg.ora'
FROM SPFILE;
实际四套环境均执行了这一动作。3、utf8容器库容灾
11. 配置主库Data Guard参数
主库执行:
ALTER SYSTEM SET
log_archive_config='DG_CONFIG=(prodcdb,prodadg)'
SCOPE=BOTH SID='*';
配置归档传输目的端:
ALTER SYSTEM SET
log_archive_dest_2=
'SERVICE=PRODADG
ASYNC
VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)
DB_UNIQUE_NAME=prodadg'
SCOPE=BOTH SID='*';
启用:
ALTER SYSTEM SET
log_archive_dest_state_2='ENABLE'
SCOPE=BOTH SID='*';
FAL:
ALTER SYSTEM SET
fal_server='PRODADG'
SCOPE=BOTH SID='*';
ALTER SYSTEM SET
fal_client='PRODCDB'
SCOPE=BOTH SID='*';
自动文件管理:
ALTER SYSTEM SET
standby_file_management='AUTO'
SCOPE=BOTH SID='*';
实际环境采用 ASYNC,对应 Maximum Performance 场景。3、utf8容器库容灾
RAC参数统一使用:
SID='*'
12. 检查ASM路径
备库检查:
SHOW PARAMETER db_create_file_dest;
SHOW PARAMETER db_create_online_log_dest;
实际四套环境采用:
db_create_file_dest = +DATA
db_create_online_log_dest_1 = +RECO
4、z16容器库容灾(参与搭建)
主备磁盘组规划一致时,RMAN Duplicate 最简单。
13. 备库配置静态监听
RMAN Duplicate 需要连接 NOMOUNT 状态下的辅助实例,因此备库两个节点均配置静态监听。
Grid 用户修改:
$GRID_HOME/network/admin/listener.ora
节点1
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = prodadg)
(ORACLE_HOME = <ORACLE_HOME>)
(SID_NAME = prodcdb1)
)
)
节点2
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = prodadg)
(ORACLE_HOME = <ORACLE_HOME>)
(SID_NAME = prodcdb2)
)
)
重新加载:
lsnrctl reload
检查:
lsnrctl status
实际四套环境均在两个备库节点分别配置静态 SID。2、mes容器库容灾
14. 配置tnsnames.ora
主备 RAC 均配置。
主库
PRODCDB =
(DESCRIPTION =
(ADDRESS=(PROTOCOL=TCP)(HOST=192.0.2.11)(PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=192.0.2.12)(PORT=1521))
(CONNECT_DATA =
(SERVER=DEDICATED)
(SERVICE_NAME=prodcdb)
)
)
备库
PRODADG =
(DESCRIPTION =
(ADDRESS=(PROTOCOL=TCP)(HOST=198.51.100.11)(PORT=1521))
(ADDRESS=(PROTOCOL=TCP)(HOST=198.51.100.12)(PORT=1521))
(CONNECT_DATA =
(SERVER=DEDICATED)
(SERVICE_NAME=prodadg)
)
)
这里保留四份实际文档中的重要经验:
RMAN Duplicate 需要连接备库静态监听,因此备库 TNS 使用 Public IP 或 VIP,不使用 SCAN IP。 1、erp容器库容灾
四台机器分别测试:
tnsping PRODCDB
tnsping PRODADG
15. 配置备库Data Guard参数
备库执行:
ALTER SYSTEM SET
log_archive_config='DG_CONFIG=(prodcdb,prodadg)'
SCOPE=BOTH SID='*';
ALTER SYSTEM SET
fal_server='PRODCDB'
SCOPE=BOTH SID='*';
ALTER SYSTEM SET
fal_client='PRODADG'
SCOPE=BOTH SID='*';
ALTER SYSTEM SET
standby_file_management='AUTO'
SCOPE=BOTH SID='*';
配置未来备库切换成 Primary 后使用的归档目的端:
ALTER SYSTEM SET
log_archive_dest_2=
'SERVICE=PRODCDB
ASYNC
VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)
DB_UNIQUE_NAME=prodcdb'
SCOPE=BOTH SID='*';
ALTER SYSTEM SET
log_archive_dest_state_2='ENABLE'
SCOPE=BOTH SID='*';
这与四套实际环境的配置方式一致。2、mes容器库容灾
16. 关闭并启动备库至NOMOUNT
分别确认当前实例:
ps -ef | grep pmon
节点1:
export ORACLE_SID=prodcdb1
sqlplus / as sysdba
节点2:
export ORACLE_SID=prodcdb2
sqlplus / as sysdba
两个备库实例先关闭:
SHUTDOWN IMMEDIATE;
然后分别启动:
STARTUP NOMOUNT;
四套实际文档统一记录为:
两个节点必须同时启动到 NOMOUNT 状态
随后进行 RMAN Duplicate。1、erp容器库容灾
17. 执行RMAN Active Duplicate
在主库 Oracle 用户下:
rman target sys@PRODCDB auxiliary sys@PRODADG
密码采用交互方式输入,禁止在正式文档中保存明文密码。
执行:
DUPLICATE TARGET DATABASE
FOR STANDBY
FROM ACTIVE DATABASE;
四套 RAC→RAC 实际环境全部采用了:
duplicate target database for standby from active database;
这一方式。3、utf8容器库容灾 2、mes容器库容灾
18. 配置主库归档删除策略
实际 ERP、MES、UTF8 环境均在 Duplicate 后设置:
rman target /
执行:
CONFIGURE ARCHIVELOG DELETION POLICY
TO APPLIED ON ALL STANDBY;
即:
归档在所有 Standby 已应用后才允许按 RMAN 策略删除。1、erp容器库容灾 2、mes容器库容灾
生产实施前仍应确认该策略与现有 RMAN 备份、归档保留要求一致。
19. 打开备库
Duplicate 完成后检查:
SELECT inst_id,
status
FROM gv$instance
ORDER BY inst_id;
如需按实际文档方式重新拉起两个实例,则分别关闭后:
STARTUP;
查看:
SELECT database_role,
protection_mode,
protection_level,
open_mode
FROM v$database;
目标角色必须:
PHYSICAL STANDBY
20. 启动Redo Apply
备库执行:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE
USING CURRENT LOGFILE
DISCONNECT FROM SESSION;
四套实际文档均采用该命令启动实时应用。4、z16容器库容灾(参与搭建)
停止时:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
最终 Active Data Guard 状态应为:
DATABASE_ROLE = PHYSICAL STANDBY
OPEN_MODE = READ ONLY WITH APPLY
21. 主库核心巡检
数据库角色
SELECT db_unique_name,
database_role,
open_mode,
protection_mode
FROM v$database;
正常:
PRIMARY
READ WRITE
两个RAC实例
SELECT inst_id,
instance_name,
status
FROM gv$instance
ORDER BY inst_id;
两个实例均应正常。
Redo传输状态
SET LINES 200
COL dest_name FOR A30
COL error FOR A70
SELECT dest_id,
dest_name,
status,
target,
error
FROM v$archive_dest
WHERE dest_id IN (1,2);
重点:
DEST_2 STATUS = VALID
ERROR = 空
如果目的端临时异常,四套实际环境中采用过刷新:
ALTER SYSTEM SET
log_archive_dest_state_2=DEFER SID='*';
ALTER SYSTEM SET
log_archive_dest_state_2=ENABLE SID='*';
3、utf8容器库容灾
22. 备库核心巡检
数据库状态
SELECT db_unique_name,
database_role,
open_mode,
protection_mode
FROM v$database;
正常:
PHYSICAL STANDBY
READ ONLY WITH APPLY
RAC实例状态
SELECT inst_id,
instance_name,
status
FROM gv$instance
ORDER BY inst_id;
MRP / RFS
SELECT process,
status,
thread#,
sequence#
FROM v$managed_standby
WHERE process IN ('MRP0','RFS')
ORDER BY process;
MRP 正常常见:
WAIT_FOR_LOG
或:
APPLYING_LOG
23. RAC必须按Thread检查日志同步
这是 RAC 巡检必须保留的一项。
SELECT thread#,
MAX(sequence#) received_seq,
MAX(CASE
WHEN applied='YES'
THEN sequence#
END) applied_seq
FROM v$archived_log
GROUP BY thread#
ORDER BY thread#;
正常例如:
THREAD# RECEIVED_SEQ APPLIED_SEQ
------- ------------ -----------
1 1580 1580
2 1492 1492
必须同时关注:
Thread 1
Thread 2
24. 检查Archive Gap
SELECT *
FROM v$archive_gap;
正常:
no rows selected
25. 检查Standby Redo Log
SELECT group#,
thread#,
sequence#,
status,
bytes/1024/1024 size_mb
FROM v$standby_log
ORDER BY thread#,group#;
重点确认:
Thread 1 SRL存在
Thread 2 SRL存在
SRL大小与Online Redo一致
26. ADG简单表测试
为了以后快速判断 ADG 是否真正同步,建议保留一张简单测试表。
选择一个业务 PDB / 测试 Schema,在主库执行:
CREATE TABLE ADGTEST (
ID NUMBER PRIMARY KEY,
TEST_TIME TIMESTAMP DEFAULT SYSTIMESTAMP
);
插入:
INSERT INTO ADGTEST (ID) VALUES (1);
COMMIT;
查询:
ALTER SESSION SET
NLS_TIMESTAMP_FORMAT='YYYY-MM-DD HH24:MI:SS.FF6';
SELECT *
FROM ADGTEST;
例如:
ID TEST_TIME
1 2026-10-07 10:30:00.123456
然后到备库相同 PDB:
ALTER SESSION SET
NLS_TIMESTAMP_FORMAT='YYYY-MM-DD HH24:MI:SS.FF6';
SELECT *
FROM ADGTEST;
能看到完全相同的数据,即可直观确认:
主库DML
↓
Redo产生
↓
RAC Redo Thread
↓
Redo Transport
↓
Standby Redo Log
↓
MRP Apply
↓
ADG查询成功
后续只需:
INSERT INTO ADGTEST (ID) VALUES (2);
COMMIT;
然后备库:
SELECT *
FROM ADGTEST
ORDER BY ID;
即可快速测试。
27. 最终验收标准
完成以下检查即可认为 RAC→RAC ADG 搭建正常:
| 检查项目 | 正常标准 |
|---|---|
| 主库角色 | PRIMARY |
| 主库状态 | READ WRITE |
| 主库两实例 | 正常运行 |
| DEST_2 | VALID |
| DEST_2 ERROR | 空 |
| 备库角色 | PHYSICAL STANDBY |
| 备库状态 | READ ONLY WITH APPLY |
| 备库两实例 | 正常运行 |
| MRP0 | WAIT_FOR_LOG / APPLYING_LOG |
| RFS | 正常 |
| Thread 1 | Received ≈ Applied |
| Thread 2 | Received ≈ Applied |
| Archive Gap | 无 |
| SRL | 两个Thread均正常 |
| ADGTEST | 主库写入、备库可查询 |
28. 下一次实施速查版
以后再搭 RAC→RAC,现场直接看这一段即可:
【规划】
1. DB_NAME主备一致
2. DB_UNIQUE_NAME主备不同
3. 确认2节点SID
4. 确认Public/VIP/SCAN/Private网络
【主库】
5. FORCE LOGGING
6. 检查ARCHIVELOG
7. 查看Thread及Online Redo
8. 每个Thread创建 Online Redo数量+1 的SRL
9. 备份SPFILE
10. 配置LOG_ARCHIVE_CONFIG
11. 配置LOG_ARCHIVE_DEST_2
12. 配置FAL_SERVER/FAL_CLIENT
13. standby_file_management=AUTO
【备库】
14. 建立相同DB_NAME、不同DB_UNIQUE_NAME的RAC环境
15. 处理DB_DOMAIN / GLOBAL_NAME
16. 同步主库Password File
17. 检查+DATA / +RECO
18. 两节点配置静态Listener
【网络】
19. 配置PRODCDB TNS
20. 配置PRODADG TNS
21. 静态监听连接使用Public/VIP,不使用SCAN
22. 四节点tnsping测试
【备库参数】
23. 配置LOG_ARCHIVE_CONFIG
24. 配置FAL_SERVER/FAL_CLIENT
25. standby_file_management=AUTO
26. 配置反向LOG_ARCHIVE_DEST_2
【Duplicate】
27. 关闭备库两实例
28. 两实例STARTUP NOMOUNT
29. RMAN连接Target/Auxiliary
30. DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE
【完成】
31. 配置APPLIED ON ALL STANDBY归档删除策略
32. 打开备库
33. 启动Redo Apply
34. 确认READ ONLY WITH APPLY
【巡检】
35. 主库DEST_2 VALID
36. 两边gv$instance正常
37. MRP/RFS正常
38. Thread 1 received≈applied
39. Thread 2 received≈applied
40. v$archive_gap无记录
41. ADGTEST主写备查成功
这版更适合作为你后续真正使用的 RAC→RAC ADG 标准 SOP:不是把 4 套 CDB 重复写 4 遍,而是把 4 次实际实施中共同且已经落地过的操作抽出来,只保留下一次搭建必须用到的步骤,同时把数据库名、IP、主机名和密码全部模板化。3、utf8容器库容灾 1、erp容器库容灾 2、mes容器库容灾 4、z16容器库容灾(参与搭建)