switchover成功前提必须是switchover_status为to standby或to primary,若为not allowed或sessions active则不可执行;需先查v$archive_gap、v$managed_standby确认无日志缺口且传输应用正常,再按主库切备库、备库切主库顺序执行带with session shutdown的命令并验证监听与归档目标配置。

Switchover 能成功,不等于执行计划内切换就安全 —— 最容易卡在 switchover_status 为 NOT ALLOWED 或 SESSIONS ACTIVE,而不是报错才叫失败。
检查 switchover_status 是否允许切换
这是所有操作前必须确认的第一步,跳过它 90% 会失败。直接查:
SELECT db_unique_name, database_role, open_mode, switchover_status FROM v$database;
重点关注 switchover_status 字段,合法值只有几种:
-
TO STANDBY:主库可切为备库(正常) -
SWITCHOVER PENDING:备库已收到切换请求、但主库尚未确认(少见,多见于中断重试后) -
NOT ALLOWED:常见原因包括——主库未开启归档、备库日志未应用完、LOG_ARCHIVE_CONFIG配置不一致、或备库监听未启动导致主库无法验证其状态 -
SESSIONS ACTIVE:有活跃会话(如未断开的 SQL*Plus、应用连接、JOB 进程),不是“没人连”,而是“有未提交/未释放的 session”
若为 NOT ALLOWED,别急着切,先查 v$archive_gap 和 v$managed_standby;若为 SESSIONS ACTIVE,用 ALTER SYSTEM KILL SESSION 清理,或等应用侧优雅断连。
确保归档传输与应用已同步
Switchover 不要求零延迟,但要求“无 GAP + 无阻塞”。三步快速验证:
- 查 GAP:
SELECT * FROM v$archive_gap;—— 返回空集才安全 - 查传输进程:
SELECT process, status, sequence# FROM v$managed_standby WHERE process = 'LNS';—— 主库上LNS必须是WRITING或IDLE,不能是ERROR - 查应用进程:
SELECT process, status, sequence# FROM v$managed_standby WHERE process = 'MRP0';—— 备库上MRP0必须是APPLYING_LOG,且sequence#接近主库当前归档序号(差 ≤ 2 即可)
注意:v$dataguard_stats 中的 apply lag 值受统计刷新频率影响,不可信;以 v$managed_standby 的实时 sequence# 为准。
执行 Switchover 的最小安全命令序列
不要依赖图形化工具或脚本封装,手敲最可控。按顺序执行(主库 → 备库):
- 主库上执行:
ALTER DATABASE COMMIT TO SWITCHOVER TO STANDBY WITH SESSION SHUTDOWN;
(加WITH SESSION SHUTDOWN是关键,它自动处理SESSIONS ACTIVE状态,避免手动 kill) - 立即关闭并重启主库(此时已是逻辑备库):
SHUTDOWN IMMEDIATE; STARTUP MOUNT; - 备库上执行:
ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY; - 重启备库(现为主库):
SHUTDOWN IMMEDIATE; STARTUP;
如果第 1 步报错,说明前置检查没过;如果第 3 步卡住,大概率是备库控制文件不是最新(比如从旧备份恢复而来),需确认 STANDBY CONTROLFILE 是通过 ALTER DATABASE CREATE STANDBY CONTROLFILE 生成的。
切换后验证角色与服务可用性
别只看 v$database,要立刻验证业务路径是否通:
- 新主库上跑:
SELECT MAX(sequence#) FROM v$log_history;和SELECT MAX(sequence#) FROM v$archived_log WHERE applied='YES';—— 两者应基本一致 - 新主库监听是否注册:用
lsnrctl status看服务名是否出现在SERVICE_NAME列,否则应用连不上 - TNS 名称是否更新:如果客户端用的是
tnsnames.ora,确保其中CONNECT_DATA下的SERVICE_NAME指向新主库的db_unique_name,而非旧名
最容易被忽略的是:切换后旧主库(现备库)的 LOG_ARCHIVE_DEST_2 目标仍指向“原主库地址”,若未及时修改,下次日志切换就会触发归档失败告警 —— 这个坑不会阻断本次 Switchover,但会埋下下次故障的种子。











