RAC One Node 到 RAC One Node 的 Data Guard 部署

环境规划

角色 数据库名 DB_UNIQUE_NAME 活动实例 活动节点 候选节点 SCAN
主库 orcl orcl orcl_1 node1 node2 primary-scan
备库 orcl orcls orcls_1 node3 node4 standby-scan
  • Oracle 版本:19c (19.3+)
  • Grid Infrastructure:19c
  • ASM 磁盘组:+DATA、+FRA
  • RAC One Node 特征:同一时刻仅一个实例活动运行

3.1 RAC One Node 特点与 DG 注意事项

3.1.1 RAC One Node 与标准 RAC 的关键区别
特性 标准 RAC RAC One Node
同时活动实例数 多个(所有节点) 仅 1 个
Thread 数量 多个(每实例一个) 仅 1 个(与 SI 相同)
UNDO 表空间 每实例一个 仅 1 个(但每个候选节点需准备)
Online Relocation 不适用 支持(实例在线迁移到候选节点)
Redo Log Groups 每 thread 独立分组 所有日志属于 thread 1
SRL 计算 (N+1) × thread数 (N+1) × 1,与 SI 相同
srvctl add database -dbtype RAC -dbtype RACONENODE
-policy 参数 AUTOMATIC AUTOMATIC
许可证 RAC 完整许可 RAC One Node 许可(成本更低)
3.1.2 Online Relocation 对 Data Guard 的影响

Online Relocation 是 RAC One Node 的核心特性,允许在不停机的情况下将数据库实例从一个节点迁移到另一个节点。

关键行为:

  1. Relocation 期间的 Redo 传输

    • Online Relocation 期间会短暂存在两个实例(旧实例和新实例)
    • 日志传输在 relocation 期间不会中断,Oracle 自动处理 redo 传输的切换
    • 旧实例的连接会逐步迁移到新实例
  2. Relocation 期间的 Redo Apply

    • 备库的 MRP 进程不受影响,持续应用 redo
    • Relocation 完成后,新的 RFS 连接会自动建立
  3. Relocation 对 FAL 的影响

    • FAL_SERVER 使用 SCAN 地址时,relocation 透明,无需变更

最佳实践: 始终使用 SCAN 地址配置 LOG_ARCHIVE_DEST_2FAL_SERVER,这样 Online Relocation 对 Data Guard 完全透明。


3.2 RAC One Node Data Guard 部署步骤

3.2.1 主库 RAC One Node 配置

验证主库 RAC One Node 状态:

# 查看当前运行状态
srvctl status database -d orcl

# 预期输出:
# Instance orcl_1 is running on node node1

# 查看数据库配置
srvctl config database -d orcl

# 预期输出中应包含:
# Database type: RACOneNode
# Online relocation timeout: 30
# Configured nodes: node1,node2

开启归档模式(与标准 RAC 相同):

# 停止数据库
srvctl stop database -d orcl
-- 启动到 MOUNT
sqlplus / as sysdba
STARTUP MOUNT;

-- 开启归档
ALTER DATABASE ARCHIVELOG;

-- 验证
ARCHIVE LOG LIST;

SHUTDOWN IMMEDIATE;
srvctl start database -d orcl

开启 Force Logging 和 Flashback:

ALTER DATABASE FORCE LOGGING;
ALTER DATABASE FLASHBACK ON;

-- 验证
SELECT LOG_MODE, FORCE_LOGGING, FLASHBACK_ON FROM V$DATABASE;

创建 Standby Redo Log:

RAC One Node 只有 1 个 thread,SRL 计算与 SI 相同:

-- 查看当前 Online Redo Log
SELECT GROUP#, THREAD#, BYTES/1024/1024 AS SIZE_MB, STATUS
FROM V$LOG ORDER BY GROUP#;

-- 假设有 3 组 Online Redo Log,每组 1024MB
-- SRL 需要 3 + 1 = 4 组(仅 thread 1)

ALTER DATABASE ADD STANDBY LOGFILE THREAD 1
  GROUP 11 ('+DATA','+FRA') SIZE 1024M;

ALTER DATABASE ADD STANDBY LOGFILE THREAD 1
  GROUP 12 ('+DATA','+FRA') SIZE 1024M;

ALTER DATABASE ADD STANDBY LOGFILE THREAD 1
  GROUP 13 ('+DATA','+FRA') SIZE 1024M;

ALTER DATABASE ADD STANDBY LOGFILE THREAD 1
  GROUP 14 ('+DATA','+FRA') SIZE 1024M;

-- 验证
SELECT GROUP#, THREAD#, BYTES/1024/1024 AS SIZE_MB, STATUS
FROM V$STANDBY_LOG ORDER BY GROUP#;

配置 Data Guard 参数:

-- RAC One Node 只需全局参数,无需实例级 thread/undo 配置
ALTER SYSTEM SET DB_UNIQUE_NAME='orcl' SCOPE=SPFILE;
ALTER SYSTEM SET LOG_ARCHIVE_CONFIG='DG_CONFIG=(orcl,orcls)' SCOPE=BOTH;
ALTER SYSTEM SET LOG_ARCHIVE_DEST_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=orcl' SCOPE=BOTH;
ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=orcls ASYNC NOAFFIRM VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=orcls COMPRESSION=ENABLE NET_TIMEOUT=30 REOPEN=15' SCOPE=BOTH;
ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_1=ENABLE SCOPE=BOTH;
ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_2=ENABLE SCOPE=BOTH;
ALTER SYSTEM SET FAL_SERVER='orcls' SCOPE=BOTH;
ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO SCOPE=BOTH;

Listener 静态注册(所有候选节点):

node1 (grid 用户) — 编辑 $GRID_HOME/network/admin/listener.ora

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = orcl_DGMGRL)
      (ORACLE_HOME = /u01/app/oracle/product/19c/db_1)
      (SID_NAME = orcl_1)
    )
    (SID_DESC =
      (GLOBAL_DBNAME = orcl)
      (ORACLE_HOME = /u01/app/oracle/product/19c/db_1)
      (SID_NAME = orcl_1)
    (SID_DESC =
      (GLOBAL_DBNAME = orcl_DGMGRL)
      (ORACLE_HOME = /u01/app/oracle/product/19c/db_1)
      (SID_NAME = orcl_2)
    )
    (SID_DESC =
      (GLOBAL_DBNAME = orcl)
      (ORACLE_HOME = /u01/app/oracle/product/19c/db_1)
      (SID_NAME = orcl_2)
    )
  )

node2 (grid 用户) — 编辑 $GRID_HOME/network/admin/listener.ora

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = orcl_DGMGRL)
      (ORACLE_HOME = /u01/app/oracle/product/19c/db_1)
      (SID_NAME = orcl_2)
    )
    (SID_DESC =
      (GLOBAL_DBNAME = orcl)
      (ORACLE_HOME = /u01/app/oracle/product/19c/db_1)
      (SID_NAME = orcl_2)
    )
    (SID_DESC =
      (GLOBAL_DBNAME = orcl_DGMGRL)
      (ORACLE_HOME = /u01/app/oracle/product/19c/db_1)
      (SID_NAME = orcl_1)
    )
    (SID_DESC =
      (GLOBAL_DBNAME = orcl)
      (ORACLE_HOME = /u01/app/oracle/product/19c/db_1)
      (SID_NAME = orcl_1)
  )

tnsnames.ora(所有节点 node1 和 node2):

orcl =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = primary-scan)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl)
    )
  )

orcls =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = standby-scan)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcls)
    )
  )
3.2.2 备库 RAC One Node 配置

备库 pfile(/tmp/initorcls.ora):

# =====================================================
# 备库 pfile - RAC One Node Data Guard Standby
# DB_UNIQUE_NAME = orcls
# =====================================================

# ---- 基本参数 ----
*.db_name='orcl'
*.db_unique_name='orcls'
*.compatible='19.0.0'

# ---- RAC One Node:首次启动时 cluster_database=FALSE ----
*.cluster_database=FALSE

# ---- 存储 ----
*.db_create_file_dest='+DATA'
*.db_recovery_file_dest='+FRA'
*.db_recovery_file_dest_size=200G
*.control_files='+DATA/orcls/controlfile/control01.ctl','+FRA/orcls/controlfile/control02.ctl'

# ---- 内存 ----
*.sga_target=8G
*.pga_aggregate_target=2G
*.sga_max_size=8G

# ---- Data Guard ----
*.log_archive_config='DG_CONFIG=(orcl,orcls)'
*.log_archive_dest_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=orcls'
*.log_archive_dest_2='SERVICE=orcl ASYNC NOAFFIRM VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=orcl COMPRESSION=ENABLE NET_TIMEOUT=30 REOPEN=15'
*.log_archive_dest_state_1=ENABLE
*.log_archive_dest_state_2=ENABLE
*.fal_server='orcl'
*.standby_file_management='AUTO'
*.remote_login_passwordfile='EXCLUSIVE'

# ---- 审计与诊断 ----
*.audit_file_dest='/u01/app/oracle/admin/orcls/adump'
*.diagnostic_dest='/u01/app/oracle'

关键差异: RAC One Node 的 pfile 中不需要实例级的 THREAD、INSTANCE_NUMBER、UNDO_TABLESPACE 参数(与 SI 类似)。

准备备库环境:

# 在 node3 和 node4 上创建目录
mkdir -p /u01/app/oracle/admin/orcls/adump
ssh node4 "mkdir -p /u01/app/oracle/admin/orcls/adump"

# 传输并放置密码文件(与 RAC 相同)
# 主备库4个节点密码文件一致
scp oracle@node1:/tmp/orapworcl /tmp/orapworcl

# 以 grid 用户放入 ASM
asmcmd pwcopy /tmp/orapworcl '+DATA/orcls/PASSWORD/pwdorcls.f' --dbuniquename orcls

启动备库到 NOMOUNT:

export ORACLE_SID=orcls_1
export ORACLE_HOME=/u01/app/oracle/product/19c/db_1
sqlplus / as sysdba
STARTUP NOMOUNT PFILE='/tmp/initorcls.ora';

SELECT INSTANCE_NAME, STATUS FROM V$INSTANCE;
-- 预期: orcls_1, STARTED

备库 Listener 静态注册(node3 和 node4):

node3 (grid 用户):

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = orcls_DGMGRL)
      (ORACLE_HOME = /u01/app/oracle/product/19c/db_1)
      (SID_NAME = orcls_1)
    )
    (SID_DESC =
      (GLOBAL_DBNAME = orcls)
      (ORACLE_HOME = /u01/app/oracle/product/19c/db_1)
      (SID_NAME = orcls_1)
    )
    (SID_DESC =
      (GLOBAL_DBNAME = orcls_DGMGRL)
      (ORACLE_HOME = /u01/app/oracle/product/19c/db_1)
      (SID_NAME = orcls_2)
    )
    (SID_DESC =
      (GLOBAL_DBNAME = orcls)
      (ORACLE_HOME = /u01/app/oracle/product/19c/db_1)
      (SID_NAME = orcls_2)
    )
  )

node4 (grid 用户):

SID_LIST_LISTENER =
  (SID_LIST =
    (SID_DESC =
      (GLOBAL_DBNAME = orcls_DGMGRL)
      (ORACLE_HOME = /u01/app/oracle/product/19c/db_1)
      (SID_NAME = orcls_2)
    )
    (SID_DESC =
      (GLOBAL_DBNAME = orcls)
      (ORACLE_HOME = /u01/app/oracle/product/19c/db_1)
      (SID_NAME = orcls_2)
    )
    (SID_DESC =
      (GLOBAL_DBNAME = orcls_DGMGRL)
      (ORACLE_HOME = /u01/app/oracle/product/19c/db_1)
      (SID_NAME = orcls_1)
    )
    (SID_DESC =
      (GLOBAL_DBNAME = orcls)
      (ORACLE_HOME = /u01/app/oracle/product/19c/db_1)
      (SID_NAME = orcls_1)
    )
  )
srvctl stop listener -l LISTENER -n node3 && srvctl start listener -l LISTENER -n node3
srvctl stop listener -l LISTENER -n node4 && srvctl start listener -l LISTENER -n node4

备库 tnsnames.ora(node3 和 node4):

与主库端 tnsnames.ora 内容相同(使用 SCAN 地址的 orcl 和 orcls 条目)。

3.2.3 RMAN Active Duplicate(RAC One Node 场景)
# 在 node3 上执行
rman TARGET sys/密码@orcl AUXILIARY sys/密码@orcls
RUN {
  ALLOCATE CHANNEL prmy1 DEVICE TYPE DISK;
  ALLOCATE CHANNEL prmy2 DEVICE TYPE DISK;
  ALLOCATE AUXILIARY CHANNEL stby1 DEVICE TYPE DISK;
  ALLOCATE AUXILIARY CHANNEL stby2 DEVICE TYPE DISK;

  DUPLICATE TARGET DATABASE
    FOR STANDBY
    FROM ACTIVE DATABASE
    DORECOVER
    SPFILE
      SET DB_UNIQUE_NAME='orcls'
      SET CLUSTER_DATABASE='TRUE'
      SET LOG_ARCHIVE_CONFIG='DG_CONFIG=(orcl,orcls)'
      SET LOG_ARCHIVE_DEST_1='LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=orcls'
      SET LOG_ARCHIVE_DEST_2='SERVICE=orcl ASYNC NOAFFIRM VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=orcl COMPRESSION=ENABLE NET_TIMEOUT=30 REOPEN=15'
      SET FAL_SERVER='orcl'
      SET STANDBY_FILE_MANAGEMENT='AUTO'
      SET CONTROL_FILES='+DATA/orcls/controlfile/control01.ctl','+FRA/orcls/controlfile/control02.ctl'
      SET DB_CREATE_FILE_DEST='+DATA'
      SET DB_RECOVERY_FILE_DEST='+FRA'
      SET DB_RECOVERY_FILE_DEST_SIZE='200G'
      SET AUDIT_FILE_DEST='/u01/app/oracle/admin/orcls/adump'
      SET DIAGNOSTIC_DEST='/u01/app/oracle'
      SET REMOTE_LOGIN_PASSWORDFILE='EXCLUSIVE'
    NOFILENAMECHECK
  ;
}

与标准 RAC 的差异: 不需要设置实例级的 INSTANCE_NUMBER、THREAD、UNDO_TABLESPACE 等 SID 级参数。SET CLUSTER_DATABASE='TRUE' 仍然必须设置,因为 RAC One Node 底层仍是 RAC 架构。

3.2.4 注册到 CRS(关键差异)
# 关闭当前实例
sqlplus / as sysdba <<EOF
SHUTDOWN IMMEDIATE;
EOF

# 创建指向 ASM SPFILE 的 init 文件(两个节点)
echo "SPFILE='+DATA/orcls/spfileorcls.ora'" > $ORACLE_HOME/dbs/initorcls_1.ora
ssh node4 "echo \"SPFILE='+DATA/orcls/spfileorcls.ora'\" > $ORACLE_HOME/dbs/initorcls_2.ora"

# ============================================
# 关键差异:使用 -dbtype RACONENODE 注册
# ============================================
srvctl add database \
  -db orcls \
  -oraclehome /u01/app/oracle/product/19c/db_1 \
  -dbtype RACONENODE \
  -dbname orcl \
  -spfile '+DATA/orcls/spfileorcls.ora' \
  -role PHYSICAL_STANDBY \
  -startoption MOUNT \
  -diskgroup "DATA,FRA" \
  -policy AUTOMATIC \
  -node node3,node4

# ============================================
# 关键差异:RAC One Node 只添加一个活动实例
# 候选节点由 -node 参数指定
# ============================================
srvctl add instance -db orcls -instance orcls_1 -node node3

# 验证
srvctl config database -d orcls
# 输出中应包含:
# Database type: RACOneNode
# Configured nodes: node3,node4

srvctl status database -d orcls
3.2.5 启动备库并开启 Redo Apply
# 启动备库
srvctl start database -d orcls

# 验证
srvctl status database -d orcls
# 预期: Instance orcls_1 is running on node node3
-- 启动 MRP
sqlplus / as sysdba
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;

-- 验证
SELECT PROCESS, STATUS, THREAD#, SEQUENCE#
FROM V$MANAGED_STANDBY
WHERE PROCESS IN ('MRP0','RFS');

3.3 Online Relocation 期间的 Data Guard 行为

3.3.1 执行 Online Relocation
# 将主库从 node1 迁移到 node2
srvctl relocate database -d orcl -n node2

# 或指定超时时间(分钟)
srvctl relocate database -d orcl -n node2 -timeout 60

# 监控 relocation 进度
srvctl status database -d orcl -v
3.3.2 Relocation 过程中的详细行为

阶段1:新实例启动

-- 在 relocation 进行中,可以看到两个实例短暂共存
SELECT INSTANCE_NAME, HOST_NAME, STATUS FROM GV$INSTANCE;
-- 可能看到:
-- orcl_1  node1  OPEN
-- orcl_2  node2  OPEN (RESTRICTED)  -- 新实例短暂以 RESTRICTED 模式存在

阶段2:会话迁移

  • 会话从旧实例逐步迁移到新实例
  • Data Guard 的 LGWR/ARCn 传输自动切换到新实例
  • 备库端的 RFS 进程自动与新实例建立连接

阶段3:旧实例关闭

-- relocation 完成后
SELECT INSTANCE_NAME, HOST_NAME, STATUS FROM GV$INSTANCE;
-- 预期:
-- orcl_2  node2  OPEN
3.3.3 Relocation 期间的 Data Guard 监控
-- 在备库持续监控传输状态
SELECT PROCESS, STATUS, THREAD#, SEQUENCE#, BLOCK#, BLOCKS
FROM V$MANAGED_STANDBY;

-- 监控是否有传输中断
SELECT NAME, VALUE, DATUM_TIME FROM V$DATAGUARD_STATS;

-- 检查归档日志连续性
SELECT THREAD#, SEQUENCE#, FIRST_TIME, NEXT_TIME, APPLIED
FROM V$ARCHIVED_LOG
WHERE FIRST_TIME > SYSDATE - 1/24
ORDER BY SEQUENCE#;
3.3.4 Online Relocation 最佳实践
  1. SCAN 地址是关键: LOG_ARCHIVE_DEST_2FAL_SERVER 必须使用 SCAN 地址,否则 relocation 后日志传输会断开

  2. 所有候选节点的 listener 必须配置静态注册: 确保 relocation 目标节点的 listener 已配置对应 SID 的静态注册

  3. 避免在高负载时 relocate: Relocation 期间虽然 Data Guard 不中断,但会增加短暂的系统负载

  4. 监控脚本要适配: 监控脚本应使用 SCAN 地址连接,避免使用固定的 VIP 或节点名

  5. relocation 后验证:

# relocation 完成后,验证 Data Guard 状态
srvctl status database -d orcl
-- 在备库验证日志是否持续同步
SELECT THREAD#, MAX(SEQUENCE#) AS LAST_APPLIED
FROM V$ARCHIVED_LOG
WHERE APPLIED='YES'
GROUP BY THREAD#;
3.3.5 备库 Online Relocation

备库同样支持 Online Relocation:

# 将备库从 node3 迁移到 node4
srvctl relocate database -d orcls -n node4

备库 relocation 期间的行为:

  • MRP 进程会自动在新实例上重新启动
  • Redo Apply 会有短暂中断(通常几秒到几十秒),之后自动恢复
  • 无需人工干预
-- relocation 完成后验证 MRP 状态
SELECT PROCESS, STATUS, THREAD#, SEQUENCE#
FROM V$MANAGED_STANDBY
WHERE PROCESS = 'MRP0';

-- 如果 MRP 未自动恢复(极少数情况),手动启动:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐