必须先查SWITCHOVER_STATUS再执行VERIFY,否则切换命令易卡住或报ORA-16139/ORA-16470;主库需为TO STANDBY或SESSIONS ACTIVE,备库需为TO PRIMARY或SESSIONS ACTIVE;RAC须单实例在线;VERIFY可反复执行预检归档、MRP、逻辑阻塞等隐性问题。

必须先查 SWITCHOVER_STATUS,再跑 VERIFY,否则 DGMGRL 或 SQL*Plus 的切换命令大概率卡住或报 ORA-16139/ORA-16470。
查主备库 SWITCHOVER_STATUS 是否合规
这是所有验证里最易跳过、但决定切换能否启动的关键一步。值不匹配,后续任何操作都只是徒劳等待。
- 主库执行
SELECT SWITCHOVER_STATUS FROM V$DATABASE;—— 必须返回TO STANDBY或SESSIONS ACTIVE;若为SWITCHOVER PENDING或NOT ALLOWED,说明归档未传完、MRP 没启、或有未提交事务卡住 - 备库执行同语句 —— 必须返回
TO PRIMARY或SESSIONS ACTIVE;若为NOT ALLOWED,常见原因是LOG_ARCHIVE_CONFIG漏了主库 DB_UNIQUE_NAME,或DB_UNIQUE_NAME在 listener.ora 里没配_DGMGRL后缀 - RAC 环境下,必须确认只剩一个实例在线:
SELECT INSTANCE_NAME FROM GV$INSTANCE;,否则ALTER DATABASE COMMIT TO SWITCHOVER直接报 ORA-01105
用 VERIFY 命令触发全链路预检
Oracle 12.1+ 引入的 VERIFY 不是可选项,它是唯一能一次性暴露底层依赖缺陷的机制。它比手写 SQL 查一堆视图更准,也比 DGMGRL 的 SHOW CONFIGURATION 更贴近真实切换路径。
- 在主库执行:
ALTER DATABASE SWITCHOVER TO <standby_db_unique_name> VERIFY;</standby_db_unique_name>(例如VERIFY;) - 若报
ORA-16470: Redo Apply is not running on switchover target,说明备库 MRP 进程根本没起来,查GV$DATAGUARD_PROCESS确认TYPE = 'MRP'且STATUS = 'APPLYING_LOG' - 若报
ORA-16475: succeeded with warnings,立刻翻备库 alert.log —— 常见于STANDBY_FILE_MANAGEMENT为 MANUAL 时建表空间失败,或DB_BLOCK_CHECKING开启导致日志应用慢 - 该命令不改状态、不启事务,只做只读校验,可反复执行,适合在维护窗口前高频验证
确认归档传输与应用无 GAP
即使 SWITCHOVER_STATUS 和 VERIFY 都过,仍可能因归档积压导致切换超时或切出“假主库”。物理 DG 的同步粒度是归档日志文件,不是 SCN,必须对齐序列号。
- 主库查最新归档:
SELECT THREAD#, MAX(SEQUENCE#) FROM V$ARCHIVED_LOG GROUP BY THREAD#; - 备库查已接收并应用的归档:
SELECT THREAD#, MAX(SEQUENCE#) FROM V$ARCHIVED_LOG WHERE APPLIED = 'YES' GROUP BY THREAD#; - 两结果必须完全一致;若有差值,用
SELECT * FROM V$ARCHIVE_GAP;定位缺失范围,手动拷贝补上 - 避免依赖
V$DATAGUARD_STATS的apply lag:该值可能为 0,但实际有未应用的归档文件(尤其在异步传输 + 大事务场景下)
检查逻辑层阻塞点(常被忽略)
很多环境在物理层一切正常,却在切换瞬间 hang 住 —— 往往是逻辑捕获进程或分布式事务没清理干净。
- 停掉所有
DBA_CAPTURE中的状态为ENABLED的捕获进程:EXEC DBMS_CAPTURE_ADM.STOP_CAPTURE('<capture_name>');</capture_name> - 查是否有未提交的分布式事务:
SELECT * FROM DBA_2PC_PENDING;,如有,必须在主库执行COMMIT FORCE '<local_tran_id>';</local_tran_id>或ROLLBACK FORCE - 逻辑 DG 场景下,额外检查
DBA_LOGSTDBY_PROGRESS.APPLIED_SCN与主库V$DATABASE.CURRENT_SCN差值 —— 超过 10 万需暂停 SQL Apply 并人工干预
真正影响切换成败的,往往不是命令本身,而是那些不报错但让状态“悬停”的隐性条件:GLOBAL_DBNAME 少个 _DGMGRL、LOG_ARCHIVE_CONFIG 少写一个名字、MRP 启动后又意外中断却没被监控捕获……这些点不会出现在官方 checklist 里,但每次翻车基本都栽在这儿。


















