dbaai 发表于 2026-8-28 07:49:26

Oracle Data Guard 物理备库容灾配置实战

Oracle Data Guard 物理备库容灾配置实战

一、具体要解决的问题

很多小团队的 Oracle 跑在单机上,每天只做 expdp 逻辑备份。一旦机器磁盘坏掉、机房断电,或者有人误删了数据文件,最近一次备份到故障点之间的数据就彻底没了——RPO(恢复点目标)可能高达一整天。真正稳妥的做法是建一套物理备库(Physical Standby),让重做日志(redo)实时传过去、在备机持续应用,主库一倒,备库能在分钟级接管。本文聚焦一个最常被问到的落地问题:从零把一套单实例主库,配成"主库 + 物理备库"的容灾架构,每一步怎么做、踩了哪些坑。

二、核心原理先讲清

Data Guard 的本质就是"重做日志的传输与应用"。主库产生 redo,通过网络传到备库的 Standby Redo Log(SRL),备库的托管恢复进程(MRP)把这些 redo 应用到数据文件上,于是备库的数据就和主库保持同步。

三个关键概念必须分清:

[*]保护模式:最大性能(默认,主库提交不等备库确认,性能最好、极端情况可能丢少量数据)、最大可用(主库提交等至少一个备库收到 redo,网络断了自动降级为最大性能)、最大保护(主库提交必须等备库落盘,备库挂了主库也跟着停写,最严格)。
[*]redo 传输:通过 log_archive_dest_2 指向备库的 TNS 服务名,用 LGWR ASYNC 异步或 LGWR SYNC 同步。
[*]应用方式:物理备用 Redo Apply(MRP 逐条应用 redo);备库以只读打开时称为 Active Data Guard,此时还能对外提供报表查询,把主库压力分流出去。


三、实例参考(动手步骤)

下面以一套最简化的 19c 单实例主库为例,给出可照做的命令链。假设主库唯一名 orcl_pri,备库 orcl_stby,两台主机网络互通、SID 均为 orcl。

第 1 步:主库开启归档与强制日志(缺了这步,备库永远追不上主库)

SELECT log_mode, force_logging FROM v$database;
-- 若 LOG_MODE 不是 ARCHIVELOG:
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE ARCHIVELOG;
ALTER DATABASE FORCE LOGGING;
ALTER DATABASE OPEN;


第 2 步:主库加 Standby Redo Log(SRL),大小和在线日志一致,组数 = 在线日志组数 + 1

ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 11
('/u01/oradata/orcl/srl11.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 12
('/u01/oradata/orcl/srl12.log') SIZE 200M;
ALTER DATABASE ADD STANDBY LOGFILE THREAD 1 GROUP 13
('/u01/oradata/orcl/srl13.log') SIZE 200M;


第 3 步:主库设置 DG 关键参数(db_unique_name 主备必须不同;log_archive_config 把两边成员都列全)

ALTER SYSTEM SET LOG_ARCHIVE_CONFIG='DG_CONFIG=(orcl_pri,orcl_stby)' SCOPE=BOTH;
ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=orcl_stby LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=orcl_stby' SCOPE=BOTH;
ALTER SYSTEM SET FAL_SERVER=orcl_stby SCOPE=BOTH;
ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO SCOPE=BOTH;


第 4 步:把主库的密码文件、listener.ora、tnsnames.ora **到备库(DG 要求主备 SYS 密码一致,直接拷 orapw 文件最省事);备库以 NOMOUNT 启动,用 RMAN 从主库"活动**":

# 在备库机器上执行
rman target sys/@orcl_pri auxiliary sys/@orcl_stby
DUPLICATE TARGET DATABASE FOR STANDBY
FROM ACTIVE DATABASE
DORECOVER
NOFILENAMECHECK;


第 5 步:备库启动托管恢复,让 MRP 持续应用重做

ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;


第 6 步:验证同步(主备两边分别查)

-- 主库:看归档是否成功发往备库
SELECT dest_id, status, error FROM v$archive_dest_status WHERE dest_id=2;
-- 备库:看 MRP 进程与已应用的日志序列
SELECT process, status, thread#, sequence# FROM v$managed_standby;
SELECT * FROM v$archive_gap;   -- 有返回行说明存在缺口,需补传归档


前后对比:改造前,一台机器挂掉 = 业务停摆 + 最坏丢一天数据(只能拿前晚的 expdp 恢复);改造后,主库宕机时备库已实时同步到故障前最后一笔已提交事务,RPO 降到秒级(最大可用模式)甚至零丢失(最大保护模式)。DBA 只需做一次 switchover 或 failover 即可恢复对外服务,从发现故障到切到备用通常十几分钟,而不是数小时的备份恢复。

四、实操检查清单


[*]主备库的 db_unique_name 必须不同,且两边都写进对方的 LOG_ARCHIVE_CONFIG。
[*]主库 FORCE LOGGING 必须开启,否则带有 nologging 的操作会在备库报"缺损的数据块"。
[*]备库的 Standby Redo Log 组数 = 主库在线日志组数 + 1,单组大小必须和在线日志一致。
[*]主备 SYS 密码必须一致(直接拷 orapw 密码文件,别手敲,敲错一个字符**就失败)。
[*]listener.ora 里为备库配置静态注册(SID_LIST),否则 NOMOUNT 状态下 RMAN 连不上备库。
[*]**前先打通主备 TNS 互连,用 tnsping 双向验证都能通。
[*]DUPLICATE 用 FROM ACTIVE DATABASE 时,主库必须处于 OPEN 或 MOUNT 状态,且归档模式已开启。
[*]备库启动 MRP 后,务必查 v$managed_standby,确认 MRP0 进程状态是 APPLYING_LOG 而非 WAIT_FOR_LOG。
[*]每次主库切日志(ALTER SYSTEM SWITCH LOGFILE)后,到备库确认 sequence 在递增,证明传输链路真的通。
[*]定期做一次真实 failover 演练,把"以为有容灾"变成"真的会用容灾"。


五、一个常被忽略的坑

很多人配完 MRP 就以为万事大吉,却从不在备库测只读查询,也不做 switchover 演练。结果真出事时才发现:备库的临时表空间、DBLINK、外部表这些对象根本不会随 redo 同步过去,切过去服务立刻报错。教训很直接:Data Guard 保的是"数据",不保"配置"。账号、DBLINK、定时作业、外部依赖都要另写脚本在主备两边对齐。把上面的清单过一遍,再跑一次真实演练,这套容灾才算真正落地,而不是躺在参数里的一句空话。
页: [1]
查看完整版本: Oracle Data Guard 物理备库容灾配置实战