Oracle Data Guard 容灾实战:从搭建到切换,一篇讲透 Oracle Data Guard 是 Oracle 企业级容灾方案的核心,通过维护一个或多个备库来保护主库数据安全。本文从架构原理到搭建实战,从 Switchover 到 Failover,从监控到故障处理,一篇文章让你彻底掌握 Data Guard。
一句话总结 Oracle Data Guard 通过Redo 日志传输 + 应用 实现主备数据库同步,提供最大保护、最大可用、最大性能 三种保护模式,支持物理备库、逻辑备库、快照备库 ,是 Oracle 数据库异地容灾的首选方案。
一、Data Guard 架构与核心概念 1.1 Data Guard 能解决什么问题? 场景 解决方案 主库宕机(服务器故障) 备库接管,快速切换 机房灾难(火灾/断电) 异地备库恢复 读写分离(报表查询) Active Data Guard 备库只读 备份卸载 在备库执行 RMAN 备份 升级测试 快照备库测试,回退无影响
1.2 Data Guard 架构图 ┌─────────────────────────────────────────────────────────────┐ │ Primary Database (主库) │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ LGWR → Online Redo Log → (传输) → Standby Redo Log │ │ │ │ (主库) │ │ │ └──────────────────────────────────────────────────────┘ │ │ │ │ │ LNS / ARCn │ │ (Redo 传输) │ └─────────────────────────┬───────────────────────────────────┘ │ ┌───────────▼───────────┐ │ 网络传输 (TCP) │ │ (可选加密/压缩) │ └───────────┬───────────┘ │ ┌─────────────────────────▼───────────────────────────────────┐ │ Standby Database (备库) │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ Standby Redo Log → (应用) → Datafiles │ │ │ │ ↓ │ │ │ │ Archivelog (归档日志) │ │ │ └──────────────────────────────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘1.3 核心术语 术语 含义 Primary Database 主库,生产数据库 Standby Database 备库,与主库保持同步 Physical Standby 物理备库,块级复制,与主库完全一致 Logical Standby 逻辑备库,通过 SQL 应用,备库可有不同结构 Snapshot Standby 快照备库,物理备库临时转为可读写,用于测试 Active Data Guard (ADG) 备库在 Redo Apply 的同时以只读模式打开 Redo Transport Redo 日志传输服务 Apply Mode 备库应用模式(Redo Apply / SQL Apply)
1.4 三种保护模式 模式 数据安全性 性能 传输方式 RPO Maximum Protection (最大保护)最高 影响最大 SYNC + AFFIRM 0(绝对不丢) Maximum Availability (最大可用)高 影响较小 SYNC(正常)/ ASYNC(异常) 正常情况下 0 Maximum Performance (最大性能)中 影响最小 ASYNC 可能丢少量数据
生产建议 :金融系统用Maximum Protection 或Maximum Availability ;一般业务用Maximum Performance 。
二、搭建 Physical Standby 2.1 环境准备 项目 主库 备库 主机名 primary-db standby-db IP 192.168.1.101 192.168.1.102 ORACLE_SID orcl orcl_stby DB_UNIQUE_NAME primary standby 数据库版本 19c 19c(必须相同)
2.2 主库配置 -- 1. 开启归档模式 SHUTDOWN IMMEDIATE; STARTUP MOUNT; ALTER DATABASE ARCHIVELOG; ALTER DATABASE OPEN ; -- 验证 ARCHIVE LOG LIST; -- 2. 开启 Force Logging ALTER DATABASE FORCE LOGGING; -- 验证 SELECT FORCE_LOGGINGFROM V$DATABASE ; -- 3. 创建 Standby Redo Log(比 Online Redo Log 多一组) -- 查看当前 Redo Log 大小和组数 SELECT GROUP #, BYTES/1024/1024 AS SIZE_MB FROM V$LOG; -- 添加 Standby Redo Log(建议与 Online Redo Log 大小一致,多 1-2 组) ALTER DATABASE ADD STANDBY LOGFILE THREAD1 GROUP 4 ( '/u01/oradata/orcl/srl04.log' ) SIZE200 M; ALTER DATABASE ADD STANDBY LOGFILE THREAD1 GROUP 5 ( '/u01/oradata/orcl/srl05.log' ) SIZE200 M; ALTER DATABASE ADD STANDBY LOGFILE THREAD1 GROUP 6 ( '/u01/oradata/orcl/srl06.log' ) SIZE200 M; ALTER DATABASE ADD STANDBY LOGFILE THREAD1 GROUP 7 ( '/u01/oradata/orcl/srl07.log' ) SIZE200 M; -- 验证 SELECT GROUP #, THREAD#, BYTES/1024/1024 AS SIZE_MB, STATUS FROM V$STANDBY_LOG; -- 4. 配置 Redo 传输参数 ALTER SYSTEMSET LOG_ARCHIVE_CONFIG= 'DG_CONFIG=(primary,standby)' SCOPE= BOTH; -- 本地归档 ALTER SYSTEMSET LOG_ARCHIVE_DEST_1= 'LOCATION=USE_DB_RECOVERY_FILE_DEST VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=primary' SCOPE= BOTH; -- 传输到备库 ALTER SYSTEMSET LOG_ARCHIVE_DEST_2= 'SERVICE=standby LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=standby' SCOPE= BOTH; -- 5. 配置 FAL(自动缺口解决) ALTER SYSTEMSET FAL_SERVER= 'standby' SCOPE= BOTH; ALTER SYSTEMSET FAL_CLIENT= 'primary' SCOPE= BOTH; -- 6. 配置文件路径转换(主备目录不同时) ALTER SYSTEMSET STANDBY_FILE_MANAGEMENT= 'AUTO' SCOPE= BOTH; ALTER SYSTEMSET DB_FILE_NAME_CONVERT= '/u01/oradata/orcl/' , '/u01/oradata/orcl_stby/' SCOPE= BOTH; ALTER SYSTEMSET LOG_FILE_NAME_CONVERT= '/u01/oradata/orcl/' , '/u01/oradata/orcl_stby/' SCOPE= BOTH; 2.3 配置 TNS 主库 tnsnames.ora :
PRIMARY = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = primary-db)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = primary) ) ) STANDBY = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = standby-db)(PORT = 1521)) (CONNECT_DATA = (SERVER = DEDICATED) (SERVICE_NAME = standby) ) )备库 tnsnames.ora :同上,拷贝过去即可。
2.4 密码文件同步 # 主库生成密码文件 orapwdfile = $ORACLE_HOME /dbs/orapworclpassword = xxxxxentries = 10 # 拷贝到备库(文件名改为备库 SID) scp $ORACLE_HOME /dbs/orapworcl standby-db:$ORACLE_HOME /dbs/orapworcl_stby2.5 创建备库(RMAN 方法) # 在主库执行 rman target sys/xxxxx@primary# 1. 备份主库(包含备库控制文件) RMAN> BACKUP DATABASE PLUS ARCHIVELOG; RMAN> BACKUP CURRENT CONTROLFILE FOR STANDBY FORMAT'/u01/backup/stby_ctrl_%U' ; # 2. 将备份传到备库服务器 scp -r /u01/backup/* standby-db:/u01/backup/# 在备库执行 rman target sys/xxxxx@standby_stby# 3. 恢复备库 RMAN> RESTORE STANDBY CONTROLFILE FROM'/u01/backup/stby_ctrl_01' ; RMAN> ALTER DATABASE MOUNT; RMAN> RESTORE DATABASE; RMAN> RECOVER DATABASE NOREDO; -- 没有归档日志需要应用或者用 DUPLICATE 从活动数据库直接复制(更简单) :
# 在备库服务器执行 rman target sys/xxxxx@primary auxiliary sys/xxxxx@standby_stby RMAN> DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE NOFILENAMECHECK; 2.6 启动 Redo Apply -- 在备库启动 Redo Apply ALTER DATABASE RECOVER MANAGED STANDBYDATABASE DISCONNECTFROM SESSION ; -- 验证同步状态 SELECT PROCESS, STATUS , THREAD#, SEQUENCE#, BLOCK#, BLOCKS FROM V$MANAGED_STANDBY; -- 验证传输延迟 SELECT NAME, VALUE , DATUM_TIMEFROM V$DATAGUARD_STATSWHERE NAMEIN ( 'transport lag' , 'apply lag' ) ; 2.7 开启 Active Data Guard(可选) -- 备库以只读模式打开,同时应用 Redo ALTER DATABASE RECOVER MANAGED STANDBYDATABASE CANCEL; ALTER DATABASE OPEN READ ONLY; ALTER DATABASE RECOVER MANAGED STANDBYDATABASE USING CURRENT LOGFILE DISCONNECT; -- 验证 SELECT OPEN_MODE, DATABASE_ROLEFROM V$DATABASE ; -- 应显示: READ ONLY WITH APPLY | PHYSICAL STANDBY 三、Data Guard Broker(简化运维) 3.1 启用 Broker -- 主库和备库都要执行 ALTER SYSTEMSET DG_BROKER_START= TRUE SCOPE= BOTH; 3.2 配置 Broker # 连接 Broker dgmgrl sys/xxxxx@primary DGMGRL> CREATE CONFIGURATION dg_config AS PRIMARY DATABASE IS primary CONNECT IDENTIFIER IS primary; DGMGRL> ADD DATABASE standby AS CONNECT IDENTIFIER IS standby MAINTAINED AS PHYSICAL; DGMGRL> ENABLE CONFIGURATION; DGMGRL> SHOW CONFIGURATION; -- 查看详细信息 DGMGRL> SHOW DATABASE VERBOSE primary; DGMGRL> SHOW DATABASE VERBOSE standby; 3.3 用 Broker 切换 DGMGRL> SWITCHOVER TO standby; -- Switchover(计划切换) DGMGRL> FAILOVER TO standby; -- Failover(故障切换) DGMGRL> REINSTATE DATABASE primary; -- 恢复原主库为新备库四、Switchover 与 Failover 4.1 Switchover(计划性切换) -- Switchover:主备角色互换,无数据丢失 -- 适用场景:维护、升级、测试 -- 1. 在主库执行 ALTER DATABASE COMMIT TO SWITCHOVERTO STANDBY; -- 2. 在备库执行 ALTER DATABASE COMMIT TO SWITCHOVERTO PRIMARY ; ALTER DATABASE OPEN ; -- 3. 在新备库(原主库)启动 Redo Apply ALTER DATABASE RECOVER MANAGED STANDBYDATABASE DISCONNECTFROM SESSION ; 4.2 Failover(故障切换) -- Failover:备库提升为主库,主库已不可用 -- 适用场景:主库崩溃、机房灾难 -- 1. 在备库执行 ALTER DATABASE RECOVER MANAGED STANDBYDATABASE FINISH; ALTER DATABASE COMMIT TO SWITCHOVERTO PRIMARY ; ALTER DATABASE OPEN ; -- 2. 如果原主库恢复后,需要重建为新备库 -- 用 RMAN 从新主库重建备库 RMAN> DUPLICATE TARGETDATABASE FOR STANDBYFROM ACTIVEDATABASE NOFILENAMECHECK; 4.3 切换对比 操作 前提条件 数据丢失 后续操作 Switchover 主库和备库都正常 无 原主库自动变备库 Failover 主库不可用 可能丢失未传输的 Redo 需要重建原主库为新备库
五、监控与告警 5.1 关键监控指标 -- 1. 检查 Redo 传输延迟 SELECT NAME, VALUE , DATUM_TIMEFROM V$DATAGUARD_STATSWHERE NAMEIN ( 'transport lag' , 'apply lag' ) ; -- transport lag:传输延迟(主库到备库) -- apply lag:应用延迟(备库应用进度) -- 2. 检查归档传输状态 SELECT DEST_ID, STATUS , ERRORFROM V$ARCHIVE_DEST_STATUSWHERE DEST_IDIN ( 1 , 2 ) ; -- STATUS 应该是 VALID,ERROR 应该为空 -- 3. 查看 Redo Apply 进度 SELECT PROCESS, STATUS , THREAD#, SEQUENCE#, BLOCK#, BLOCKS FROM V$MANAGED_STANDBY; -- 4. 检查 GAP(归档缺口) SELECT * FROM V$ARCHIVE_GAP; -- 如果有 GAP,说明备库缺失归档日志,需要手动传输 -- 5. 查看 Redo 日志序列号(主备对比) -- 主库 SELECT THREAD#, MAX(SEQUENCE#) FROM V$ARCHIVED_LOG GROUP BY THREAD#; -- 备库 SELECT THREAD#, MAX(SEQUENCE#) FROM V$ARCHIVED_LOG GROUP BY THREAD#; -- 差值就是 GAP 5.2 告警脚本示例 #!/bin/bash # dg_monitor.sh - Data Guard 监控脚本 export ORACLE_HOME = /u01/app/oracle/product/19c/dbhome_1export ORACLE_SID = orclexport PATH = $ORACLE_HOME /bin:$PATH # 检查传输延迟 TRANSPORT_LAG = $( sqlplus-s sys/xxxxx@primary<< EOF SET HEADING OFF FEEDBACK OFF SELECT VALUE FROM V\$DATAGUARD_STATS WHERE NAME='transport lag'; EXIT; EOF ) # 检查应用延迟 APPLY_LAG = $( sqlplus-s sys/xxxxx@standby<< EOF SET HEADING OFF FEEDBACK OFF SELECT VALUE FROM V\$DATAGUARD_STATS WHERE NAME='apply lag'; EXIT; EOF ) # 检查 GAP GAP_COUNT = $( sqlplus-s sys/xxxxx@standby<< EOF SET HEADING OFF FEEDBACK OFF SELECT COUNT(*) FROM V\$ARCHIVE_GAP ; EXIT; EOF ) # 告警阈值(秒) LAG_THRESHOLD = 300 # 5 分钟 # 解析延迟(格式:+00 00:05:30) parse_lag ( ) { local lag = $1 echo $lag | awk -F'[+ :]' '{print $2*3600 + $3*60 + $4}' } transport_seconds = $( parse_lag"$TRANSPORT_LAG " ) apply_seconds = $( parse_lag"$APPLY_LAG " ) if [ "$transport_seconds " -gt "$LAG_THRESHOLD " ] || [ "$GAP_COUNT " -gt 0 ] ; then echo "[ALERT] Data Guard Lag! Transport:${transport_seconds} s, Apply:${apply_seconds} s, GAP:${GAP_COUNT} " | \ mail-s "Oracle Data Guard Alert" dba@company.comfi echo "[$( date ) ] DG Monitor: Transport=${transport_seconds} s, Apply=${apply_seconds} s, GAP=${GAP_COUNT} " 5.3 Broker 监控 DGMGRL> SHOW CONFIGURATION; -- 输出示例: -- Configuration - dg_config -- Protection Mode: MaxPerformance -- Members: -- primary - Primary database -- standby - Physical standby database -- -- Fast-Start Failover: DISABLED -- -- Configuration Status: -- SUCCESS DGMGRL> SHOW DATABASE standby; -- 检查各成员状态 DGMGRL> SHOW DATABASE VERBOSE standby; 六、故障处理 6.1 Redo 传输失败 -- 现象:备库接收不到 Redo -- 1. 检查错误 SELECT DEST_ID, STATUS , ERRORFROM V$ARCHIVE_DEST_STATUSWHERE DEST_ID= 2 ; -- 2. 常见原因和解决方案 -- 原因 1:网络不通 -- 解决:检查防火墙和 TNS 连通性 -- $ tnsping standby -- 原因 2:密码文件不同步 -- 解决:重新生成并拷贝密码文件 -- $ orapwd file=$ORACLE_HOME/dbs/orapworcl password=xxxxx entries=10 -- $ scp orapworcl standby-db:$ORACLE_HOME/dbs/orapworcl_stby -- 原因 3:备库未启动 -- 解决:启动备库 -- $ sqlplus sys/xxxxx@standby_stby -- SQL> STARTUP MOUNT; -- 原因 4:LOG_ARCHIVE_DEST_2 配置错误 -- 解决:检查参数 -- SQL> SHOW PARAMETER LOG_ARCHIVE_DEST_2; 6.2 GAP(归档缺口) -- 现象:备库缺失部分归档日志 -- 1. 检查 GAP SELECT * FROM V$ARCHIVE_GAP; -- 2. 查看缺失的归档日志 SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP; -- 3. 在主库找到缺失的归档日志 SELECT NAMEFROM V$ARCHIVED_LOGWHERE THREAD# = 1 AND SEQUENCE# BETWEEN 100 AND 105; -- 4. 手动传输到备库 scp/ u01/ fast_recovery_area/ orcl/ archivelog/ 2026 _08_14/ o1_mf_1_100_xxx. arc standby- db:/ u01/ arch/ -- 5. 在备库注册 ALTER DATABASE REGISTER LOGFILE'/u01/arch/o1_mf_1_100_xxx.arc' ; -- 6. 重新启动 Redo Apply ALTER DATABASE RECOVER MANAGED STANDBYDATABASE DISCONNECTFROM SESSION ; 6.3 Redo Apply 失败 -- 现象:备库 Redo Apply 停止 -- 1. 检查错误 SELECT MESSAGEFROM V$DATAGUARD_STATUSWHERE SEVERITY= 'Error' ORDER BY TIMESTAMP DESC ; -- 2. 常见原因 -- - 备库数据文件丢失 → RESTORE DATAFILE -- - 备库空间不足 → 扩展磁盘 -- - 数据文件路径错误 → 修改 STANDBY_FILE_MANAGEMENT -- 3. 重新启动 Apply ALTER DATABASE RECOVER MANAGED STANDBYDATABASE DISCONNECTFROM SESSION ; 6.4 备库数据文件丢失 -- 1. 在备库还原数据文件 ALTER DATABASE RECOVER MANAGED STANDBYDATABASE CANCEL; RESTORE DATAFILE5 ; RECOVER DATAFILE5 ; -- 2. 重新启动 Apply ALTER DATABASE RECOVER MANAGED STANDBYDATABASE DISCONNECTFROM SESSION ; 七、Fast-Start Failover(自动故障切换) 7.1 配置 FSFO # 需要 Oracle Observer(观察进程) # 1. 启用 FSFO DGMGRL> ENABLE FAST_START FAILOVER; # 2. 启动 Observer(在第三方机器运行) DGMGRL> START OBSERVER; -- Observer 会持续监控主库,如果主库不可用,自动触发 Failover7.2 FSFO 工作原理 Observer(第三方机器) │ ├── 监控主库(心跳检测) │ │ │ ├── 主库正常 → 不干预 │ │ │ └── 主库超时 → 触发自动 Failover │ │ │ └── 备库提升为主库 │ └── 通知应用切换连接八、快照备库(Snapshot Standby) -- 快照备库:物理备库临时转为可读写,用于测试 -- 1. 转换为快照备库 ALTER DATABASE CONVERT TO SNAPSHOT STANDBY; ALTER DATABASE OPEN ; -- 此时备库可读写,用于升级测试、数据验证等 -- 2. 测试完成后,转回物理备库 -- 注意:所有测试数据都会被丢弃! SHUTDOWN IMMEDIATE; STARTUP MOUNT; ALTER DATABASE CONVERT TO PHYSICAL STANDBY; -- 3. 重新启动 Redo Apply ALTER DATABASE RECOVER MANAGED STANDBYDATABASE DISCONNECTFROM SESSION ; 九、Logical Standby(逻辑备库) -- 逻辑备库:通过 SQL Apply,备库可有不同结构 -- 1. 在主库创建 LogMiner 字典 ALTER DATABASE ADD SUPPLEMENTAL LOGDATA ( PRIMARY KEY , UNIQUE INDEX ) COLUMNS ; EXECUTE LOGSTDBY. BUILD; -- 2. 在备库转换为逻辑备库 ALTER DATABASE RECOVERTO LOGICAL standby_logical; ALTER DATABASE OPEN ; -- 3. 启动 SQL Apply ALTER DATABASE START LOGICAL STANDBYAPPLY IMMEDIATE; -- 4. 在逻辑备库创建额外对象(主库没有的) CREATE TABLE extra_data( id NUMBER, data VARCHAR2( 100 ) ) ; -- 5. 跳过某些表的同步 EXECUTE DBMS_LOGSTDBY. SKIP( 'SCHEMA_DDL' , 'HR' , 'TEMP_TABLES' ) ; EXECUTE DBMS_LOGSTDBY. SKIP_STMT( 'DML' , 'HR' , 'TEMP_TABLES' ) ; 十、Data Guard 最佳实践 10.1 架构设计 场景 推荐方案 单机容灾 Primary + Physical Standby 读写分离 Primary + Physical Standby + ADG 高可用 + 容灾 RAC + Data Guard 自动故障切换 Data Guard + FSFO 异构同步 Data Guard + GoldenGate
10.2 运维要点 监控告警 :设置 transport lag、apply lag 阈值告警定期演练 :每季度做一次 Switchover 演练密码同步 :主库密码修改后同步到备库归档管理 :及时清理备库已应用的归档日志网络稳定 :Redo 传输对网络质量敏感,建议使用专线版本一致 :主备库 Oracle 版本必须一致补丁同步 :主库打补丁后,备库也要同步10.3 性能优化 -- 1. 使用异步传输(MAXIMUM PERFORMANCE) ALTER SYSTEMSET LOG_ARCHIVE_DEST_2= 'SERVICE=standby LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=standby' ; -- 2. 开启 Redo 传输压缩 ALTER SYSTEMSET LOG_ARCHIVE_DEST_2= 'SERVICE=standby LGWR ASYNC COMPRESSION=ENABLE VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=standby' ; -- 3. 增加并行传输(19c+) ALTER SYSTEMSET LOG_ARCHIVE_DEST_2= 'SERVICE=standby LGWR SYNC PARALLEL=64 VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=standby' ; 十一、总结 备库类型 一致性 可用性 适用场景 Physical Standby 块级一致 只读(ADG)或不可用 核心业务容灾 Logical Standby 逻辑一致 可读写(部分表) 异构同步、报表 Snapshot Standby 物理一致 可读写(测试) 升级测试、验证
操作 数据丢失 停机时间 后续操作 Switchover 无 分钟级 自动变备库 Failover 可能丢失 分钟级 需要重建 FSFO 无 秒级 自动切换
系列文章 ORA-01017 故障排查 Oracle 高可用教程 Oracle RMAN 备份恢复教程 总结 :Data Guard 不是搭完就完了,没有演练过的灾备等于没有灾备 。每季度做一次 Switchover 演练,每次 5 分钟,换来的是主库宕机时的 5 分钟快速恢复。这笔账,怎么算都划算。