适用版本:Oracle 11gR2 / 12c / 19c
工作模式:Physical Standby(物理备库)
核心场景:Data Guard 环境下的四种主备切换模式(Switchover / Failover / Snapshot Standby / Activate)
1. 环境说明
| 角色 | 说明 |
|---|---|
| 主库(Primary) | 提供读写服务的生产库 |
| 备库(Standby) | 接收并应用日志的物理备库 |
| MRP 进程 | Managed Recovery Process,备库日志应用进程 |
| ARCn/FAL | 日志归档与日志获取进程 |
重要前提:操作前务必确认主备日志同步状态正常,无日志间隙(gap),否则切换可能失败。
-- 主库:检查日志传输状态
SELECT DEST_ID, STATUS, TARGET, ARCHIVER, SCHEDULE, DESTINATION
FROM V$ARCHIVE_DEST
WHERE STATUS = 'VALID' AND TARGET = 'STANDBY';
-- 主库:检查是否有 gap
SELECT * FROM V$ARCHIVE_GAP;
-- 备库:检查 MRP 应用进度
SELECT PROCESS, STATUS, SEQUENCE# FROM V$MANAGED_STANDBY WHERE PROCESS = 'MRP0';
2. Switchover —— 主备正常切换
适用场景: 计划内维护(如主机打补丁、硬件升级),主备两端均正常运行。
特点: 无数据丢失,切换后原主库自动变为备库,可再次切换回来。
2.1 切换前状态检查
-- 主库执行(确认 SWITCHOVER_STATUS 为 TO STANDBY 或 SESSIONS ACTIVE)
SELECT OPEN_MODE, PROTECTION_MODE, PROTECTION_LEVEL, SWITCHOVER_STATUS
FROM V$DATABASE;
| SWITCHOVER_STATUS 值 | 含义 |
|---|---|
TO STANDBY |
可以直接切换 |
SESSIONS ACTIVE |
有活跃会话,需加 WITH SESSION SHUTDOWN |
NOT ALLOWED |
不满足切换条件,需排查 |
-- 备库执行(确认 SWITCHOVER_STATUS 为 NOT ALLOWED 或 TO PRIMARY)
SELECT OPEN_MODE, PROTECTION_MODE, PROTECTION_LEVEL, SWITCHOVER_STATUS
FROM V$DATABASE;
2.2 主库切换为备库
-- 步骤1:主库执行切换命令
-- 如有活跃会话,使用 WITH SESSION SHUTDOWN 参数
ALTER DATABASE COMMIT TO SWITCHOVER TO PHYSICAL STANDBY;
-- 或(有活跃会话时):
-- ALTER DATABASE COMMIT TO SWITCHOVER TO PHYSICAL STANDBY WITH SESSION SHUTDOWN;
-- 步骤2:重启进入 Standby 状态
SHUTDOWN IMMEDIATE;
STARTUP NOMOUNT;
ALTER DATABASE MOUNT STANDBY DATABASE;
-- 步骤3:启动 MRP 日志应用
-- 方式A:普通模式——MOUNTED 状态下应用日志(默认)
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;
-- 方式B:Active Data Guard 模式——OPEN READ ONLY 状态下同时应用日志
-- 需要额外购买 Active Data Guard License
-- ALTER DATABASE OPEN READ ONLY;
-- ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
MOUNTED vs OPEN READ ONLY 的选择:
模式 备库状态 MRP 前提 普通 Physical Standby MOUNTED 运行 无额外 License Active Data Guard OPEN READ ONLY 运行 需 Active Data Guard License 如果备库仅做灾备、不需要读查询,保持 MOUNTED 即可;如果需要读写分离分担主库读压力,使用 Active Data Guard 模式。
版本差异说明:
- Oracle 12c+:
USING CURRENT LOGFILE为默认实时应用,可省略。- Oracle 11g:建议显式写
USING CURRENT LOGFILE启用 Real-Time Apply。
2.3 备库切换为主库
-- 步骤1:备库执行(确认 SWITCHOVER_STATUS 为 TO PRIMARY)
SELECT OPEN_MODE, PROTECTION_MODE, PROTECTION_LEVEL, SWITCHOVER_STATUS
FROM V$DATABASE;
-- 步骤2:切换备库为主库
ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY;
-- 或(有活跃会话时):
-- ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN;
-- 步骤3:重启进入 Primary 读写模式
SHUTDOWN IMMEDIATE;
STARTUP;
2.4 切换后验证
-- 两端均执行,确认角色已互换
SELECT DB_UNIQUE_NAME, DATABASE_ROLE, OPEN_MODE, SWITCHOVER_STATUS
FROM V$DATABASE;
-- 新主库确认日志在传输
SELECT DEST_ID, STATUS, TARGET FROM V$ARCHIVE_DEST WHERE TARGET='STANDBY';
-- 新备库确认 MRP 在运行
SELECT PROCESS, STATUS, SEQUENCE# FROM V$MANAGED_STANDBY WHERE PROCESS='MRP0';
3. Failover —— 主备非正常切换
适用场景: 主库宕机或不可恢复,备库紧急接管,单向不可逆操作。
⚠️ 警告: Failover 操作不可逆!完成后原主库不能直接重新加入 Data Guard,需重建为备库(通过 RMAN DUPLICATE 或 DBMS_RMAN 重新克隆)。
3.1 Failover 前确认
-- 确认本库角色为 PHYSICAL STANDBY(防止误在主库操作)
SELECT DATABASE_ROLE, OPEN_MODE FROM V$DATABASE;
-- 检查是否有未应用的日志间隙(gap)
-- 主库宕机无法对比最新序号,但 gap 信息仍有助于评估数据丢失量
SELECT * FROM V$ARCHIVE_GAP;
说明: 主库已宕机,备库侧无法精确判断数据丢失量。
V$ARCHIVE_GAP仅能发现备库已知但未接收的归档日志间隙;若主库在线 Redo Log 中还有未归档的事务,这部分丢失在 failover 前无法评估。
3.2 执行 Failover
-- 步骤1:完成所有已接收日志的应用(推荐方式)
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH FORCE DISCONNECT FROM SESSION;
-- 步骤2:激活备库为主库(两种方式)
-- 方式A(标准方式,等待当前事务完成):
ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY;
-- 方式B(强制方式,直接结束所有会话):
-- ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN;
-- 步骤3:重启进入 Primary 读写模式(必须步骤)
SHUTDOWN IMMEDIATE;
STARTUP;
3.3 Failover 后验证
-- 确认角色已变为 PRIMARY
SELECT DB_UNIQUE_NAME, DATABASE_ROLE, OPEN_MODE FROM V$DATABASE;
-- 检查数据完整性(确认业务关键表记录数)
SELECT COUNT(*) FROM [关键业务表];
3.4 原主库重建为备库(Failover 后必须操作)
Failover 后原主库不能直接加回 DG,必须通过以下方式之一重建:
- RMAN DUPLICATE FROM ACTIVE DATABASE(在线克隆,推荐)
- 从新主库备份恢复,再注册为 Standby
4. Snapshot Standby —— 备库快照模式
适用场景: 需要在备库上执行测试、压测或临时读写操作,测试完成后还原为物理备库继续同步。
特点: 切换为 Snapshot 模式后,备库进入读写状态,但原主库日志仍会被接收(暂存);恢复为 Physical Standby 后,快照期间的变更被丢弃,继续应用主库日志。
前置要求:
- 必须配置 Flash Recovery Area(FRA)
- 闪回日志空间需足以存放 Snapshot 期间所有变更
4.1 配置 FRA(如未配置)
-- 在备库执行(根据实际规划调整路径和大小)
ALTER SYSTEM SET DB_RECOVERY_FILE_DEST_SIZE = 100G;
ALTER SYSTEM SET DB_RECOVERY_FILE_DEST = '/orcldata/fra';
-- ⚠️ 注意:路径需提前创建,且 Oracle 用户有写权限
4.2 备库转换为 Snapshot Standby
-- 步骤1:停止 MRP 日志应用
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
-- 步骤2:确认当前角色
SELECT DATABASE_ROLE, OPEN_MODE FROM V$DATABASE;
-- 预期结果:PHYSICAL STANDBY | MOUNTED 或 READ ONLY
-- 步骤3:转换为 Snapshot Standby
-- 官方文档要求在 MOUNTED 状态下执行;实测 OPEN READ ONLY 状态也可成功执行
-- 但 OPEN READ WRITE 状态下绝对不行,会报 ORA-38784
ALTER DATABASE CONVERT TO SNAPSHOT STANDBY;
-- 步骤4:确认转换成功
SELECT DATABASE_ROLE, OPEN_MODE FROM V$DATABASE;
-- 预期结果:SNAPSHOT STANDBY | MOUNTED
-- 步骤5:确认闪回已自动开启(Oracle 自动启用)
SELECT FLASHBACK_ON FROM V$DATABASE;
-- 预期结果:YES
-- 步骤6:打开数据库(读写模式)
ALTER DATABASE OPEN;
4.3 测试完成后恢复为 Physical Standby
-- 步骤1:关闭数据库
SHUTDOWN IMMEDIATE;
-- 步骤2:挂载进入 mount 状态
STARTUP MOUNT;
-- 步骤3:转换回 Physical Standby(此操作会丢弃 Snapshot 期间所有变更)
ALTER DATABASE CONVERT TO PHYSICAL STANDBY;
-- 步骤4:再次重启到 mount 状态(转换后需重启生效)
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
-- 步骤5:确认角色已恢复
SELECT DATABASE_ROLE, OPEN_MODE FROM V$DATABASE;
-- 预期结果:PHYSICAL STANDBY | MOUNTED
-- 步骤6:启动 MRP 恢复日志应用
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
版本差异说明:
- Oracle 11g:
USING CURRENT LOGFILE为实时应用(Real-Time Apply),需显式指定。- Oracle 12c+:
USING CURRENT LOGFILE已为默认行为,可省略。
4.4 Snapshot 模式延迟保护(可选)
-- 取消 MRP 后重新启动带延迟的应用(delay 单位为分钟)
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
ALTER DATABASE OPEN;
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DELAY 1440 DISCONNECT FROM SESSION;
-- ⚠️ DELAY 1440 = 延迟24小时应用,防止误操作传播到备库
4.5 查看 Data Guard 统计信息
-- 查看同步延迟、传输延迟等统计指标
SELECT NAME, VALUE FROM V$DATAGUARD_STATS;
| 常见 NAME 字段 | 含义 |
|---|---|
apply lag |
备库应用落后主库的时间 |
transport lag |
日志传输落后主库的时间 |
estimated startup time |
估计的主备切换时间 |
5. Activate Standby —— 强制激活备库
适用场景: 主库彻底不可用,且无法正常执行 Failover(如无法连接备库执行 FINISH),需强制激活备库。
⚠️ 警告:
- Activate 操作不可逆,激活后原备库成为新的独立 Primary,与原 DG 配置脱离。
- 该操作可能导致数据丢失(取决于激活时已接收的日志量)。
- 激活后必须重启数据库才能进入读写模式。
-- 步骤1:先确认日志文件状态(确认已接收哪些日志)
SELECT MEMBER FROM V$LOGFILE;
-- 步骤2:确认当前数据库角色
SELECT DATABASE_ROLE, OPEN_MODE FROM V$DATABASE;
-- 预期:PHYSICAL STANDBY | MOUNTED
-- 步骤3:强制激活备库
ALTER DATABASE ACTIVATE STANDBY DATABASE;
-- ⚠️ 修正说明:
-- 此语句适用于 Physical Standby;
-- Logical Standby 使用:ALTER DATABASE ACTIVATE LOGICAL STANDBY DATABASE;
-- 激活后数据库仍处于 MOUNTED 状态,必须执行后续重启步骤
-- 步骤4:重启进入读写模式(激活后必须执行)
SHUTDOWN IMMEDIATE;
STARTUP;
-- 步骤5:验证已成为 Primary
SELECT DB_UNIQUE_NAME, DATABASE_ROLE, OPEN_MODE FROM V$DATABASE;
-- 预期:PRIMARY | READ WRITE
6. 四种切换模式对比
| 维度 | Switchover | Failover | Snapshot Standby | Activate |
|---|---|---|---|---|
| 场景 | 计划内切换 | 主库故障应急 | 备库临时读写测试 | 主库彻底不可用 |
| 是否可逆 | ✅ 可逆 | ❌ 不可逆 | ✅ 可逆 | ❌ 不可逆 |
| 数据丢失风险 | 无 | 可能有(取决于gap) | 快照期间变更丢弃 | 可能有 |
| 原主库处理 | 自动变为备库 | 需重建才能加入DG | 不影响主库 | 需重建才能加入DG |
| MRP 状态 | 需停止再启动 | 执行 FINISH | 取消→转换→恢复 | 不需要 |
| FRA 要求 | 无 | 无 | 必须配置 | 无 |
| 生产推荐度 | ⭐⭐⭐⭐⭐ 首选 | ⭐⭐⭐⭐ 应急 | ⭐⭐⭐ 测试场景 | ⭐⭐ 最后手段 |
7. 常见问题与排查
Q1:Switchover 时 SWITCHOVER_STATUS 显示 NOT ALLOWED
-- 检查是否有未传输的归档日志
SELECT * FROM V$ARCHIVE_GAP;
-- 检查 FAL 进程状态
SELECT PROCESS, STATUS FROM V$MANAGED_STANDBY;
-- 检查 DG 配置参数
SELECT NAME, VALUE FROM V$DATAGUARD_CONFIG;
Q2:Failover 后如何重建原主库为备库
# 使用 RMAN 从新主库在线克隆(推荐)
rman target sys/[密码]@新主库 auxiliary sys/[密码]@原主库
# RMAN 内执行
DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE
DORECOVER
USING COMPRESSED BACKUPSET
NOFILENAMECHECK;
Q3:Snapshot Standby 转换失败(ORA-38706)
常见原因:FRA 未配置或空间不足。
-- 检查 FRA 配置
SHOW PARAMETER DB_RECOVERY_FILE_DEST;
SHOW PARAMETER DB_RECOVERY_FILE_DEST_SIZE;
-- 检查 FRA 使用情况
SELECT * FROM V$RECOVERY_FILE_DEST;
8. 总结 & 注意事项
-
优先使用 Switchover:计划内维护场景务必使用 Switchover,可完整保留 DG 配置,无数据丢失风险。
-
Failover 前先执行 FINISH:强制完成已接收日志的应用,最大限度减少数据丢失。推荐带
FORCE DISCONNECT FROM SESSION参数,避免卡住。 -
Snapshot Standby 必须提前规划 FRA:FRA 大小需足以存储测试期间产生的所有 Redo,否则 Snapshot 期间主库日志无法持续接收。
-
Activate 是最后手段:仅在主库彻底宕机且 Failover 无法正常执行时使用,激活后必须重启才能进入读写模式,且无法直接回切。
-
切换后必须验证:无论哪种切换方式,操作完成后必须执行验证 SQL,确认角色、OPEN_MODE 符合预期,并检查业务连通性。
-
DG Broker 可简化切换:生产环境推荐使用 Data Guard Broker(DGMGRL)管理切换,命令更简洁,内置状态检查:
DGMGRL> SWITCHOVER TO standby_db_name; DGMGRL> FAILOVER TO standby_db_name;
参考文档
| 文档 | 来源 |
|---|---|
| Oracle Data Guard Concepts and Administration | Oracle 官方文档 |
| Oracle Database Backup and Recovery User’s Guide | Oracle 官方文档(FRA 配置) |
| MOS Doc ID 1304939.1 | Oracle Data Guard Switchover Best Practices |
| MOS Doc ID 1305019.1 | Oracle Data Guard Failover Best Practices |




