Switchover是唯一保证零数据丢失的主备切换方式,前提为switchover_status合规、归档传输无gap、日志应用无延迟、transport lag与apply lag均为零。

能用 Switchover 就别碰 Failover —— 零丢失只在 Switchover 中成立,且必须满足四个硬性前提。
确认 switchover_status 是否真正允许切换
这是最容易被跳过的一步,但直接决定能否零丢失。不能只看 SELECT switchover_status FROM v$database 返回 TO STANDBY 就动手。
常见错误现象:返回 SESSIONS ACTIVE 却没处理会话,或返回 NOT ALLOWED 却强行执行 ALTER DATABASE COMMIT TO SWITCHOVER,结果卡住甚至报 ORA-16470。
实操建议:
- 主库上先查活跃会话:
SELECT COUNT(*) FROM v$session WHERE type = 'USER',非零则需清理或加WITH SESSION SHUTDOWN - 备库上同步检查:
SELECT switchover_status FROM v$database必须是TO PRIMARY或SESSIONS ACTIVE,否则说明 Redo 传输中断或应用滞后 - 若为
NOT ALLOWED,立刻查v$archive_dest_status的error列和gap_status,90% 是归档未传到备库或备库未应用
验证 transport lag 和 apply lag 是否真为零
很多人只看 v$dataguard_stats 里显示 +00 00:00:00 就以为没问题,但这个值可能缓存、延迟更新,或仅反映某一时点状态。
真实同步状态要看三处:
- 主库执行:
SELECT MAX(sequence#) FROM v$archived_log WHERE dest_id = 2 AND applied = 'YES',对比备库当前SELECT MAX(sequence#) FROM v$archived_log - 备库执行:
SELECT MIN(flushed_scn), MAX(flushed_scn) FROM v$archived_log,确保与主库v$database.current_scn差距在可接受范围(通常 - 运行
SELECT name, value FROM v$dataguard_stats WHERE name IN ('transport lag', 'apply lag'),两次查询间隔 5 秒,确认值稳定为+00 00:00:00
注意:transport lag 不为零,说明 LGWR/ARCn 还没把日志发过去;apply lag 不为零,说明 MRP 进程还没重放完——两者任一不为零,Switchover 后都可能丢事务。
执行切换时的命令细节与顺序不可颠倒
Switchover 不是“两边各跑一条命令”那么简单。顺序错、状态没等稳、实例没 mount,都会导致角色混乱或启动失败。
主库操作必须严格按此序列:
-
ALTER DATABASE COMMIT TO SWITCHOVER TO PHYSICAL STANDBY WITH SESSION SHUTDOWN(加WITH SESSION SHUTDOWN避免卡死) -
SHUTDOWN IMMEDIATE(不是ABORT) -
STARTUP MOUNT(不能OPEN,否则变成只读库,无法再接收日志)
备库操作也必须同步跟上:
- 确认主库已
MOUNT后,再执行ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN -
ALTER DATABASE OPEN(此时才是新主库上线) - 立刻在新主库上执行
ALTER SYSTEM SWITCH LOGFILE,触发日志切换,验证新主库是否正常生成归档
坑:RAC 环境下,备库切换前必须确认 MRP 进程所在实例(查 GV$MANAGED_STANDBY),切换命令只能在该节点执行,否则报 ORA-16139。
切换后原主库重入 DG 配置的关键动作
很多人以为切换完成就结束了,其实真正的风险在“回切”准备阶段。原主库(现备库)若没正确加入新 DG 链路,下次 Switchover 就无法进行。
必须立刻做三件事:
- 在新主库上检查
v$archive_dest,确认dest_id = 2指向的是原主库的db_unique_name,且status = VALID - 在原主库(现备库)上启动日志应用:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION - 验证是否开始接收新主库的日志:
SELECT process, status, sequence# FROM v$managed_standby WHERE process = 'RFS',有记录且status = IDLE表示接收正常
容易被忽略的点:如果原主库之前启用了 Flashback Database,切换后必须重新启用(ALTER DATABASE FLASHBACK ON),否则后续 Fast-Start Failover 无法使用闪回快速回退。











