dbms_rolling仅支持active data guard+逻辑备库滚动升级,要求主备库版本差不跨大版本、启用flashback、compatible≥12.1.0、备库open read only with apply,且须停用broker、禁用手动mrp、主库sysdba调用。

DBMS_ROLLING 在 Oracle 19c Data Guard 中不支持物理备库滚动升级——它只在 Active Data Guard(ADG)+ 逻辑备库场景下可用,且要求主备库版本差不能跨大版本(如 19c → 21c 可行,19c → 23c 不行)。
DBMS_ROLLING 要求的最低环境条件
这个包不是“装了就能用”,它对底层架构有硬性依赖:
- 必须启用
FLASHBACK,且V$DATABASE.FLASHBACK_ON返回YES(主库和备库都要检查) - 数据库
COMPATIBLE参数必须 ≥12.1.0(19c 默认满足,但若从旧库升级而来可能被锁住) - 必须是 Active Data Guard 环境,即备库以
OPEN READ ONLY WITH APPLY模式运行,而非MOUNTED - 物理备库无法直接使用
DBMS_ROLLING;若当前是物理 DG,需先转换为逻辑备库(ALTER DATABASE RECOVER TO LOGICAL STANDBY),再启用 ADG - 不支持含
ROWID、UROWID、XMLTYPE、OBJECT、超长VARCHAR2(>4000)等字段的表——查DBA_LOGSTDBY_UNSUPPORTED视图确认
执行 DBMS_ROLLING 前必须停掉 Data Guard Broker
Broker 会干扰角色切换和状态同步,导致 DBMS_ROLLING.START_UPGRADE 报 ORA-16826 或卡在 INITIALIZING 状态:
- 在
DGMGRL中先执行DISABLE CONFIGURATION,不是DISABLE DATABASE - 确认
V$DATAGUARD_CONFIG中所有数据库的STATE列为TRANSPORT-ON或APPLY-ON,而非UNKNOWN - 升级过程中禁止手动启停
MRP进程(ALTER DATABASE RECOVER MANAGED STANDBY DATABASE),否则DBMS_ROLLING的内部状态元数据会错乱 - 所有操作(包括
START_UPGRADE、FINISH_UPGRADE)必须在主库上以SYSDBA身份调用,不能在备库执行
catctl.pl 升级脚本必须重设关键参数
即使 DBMS_ROLLING 启动成功,后续调用 catctl.pl 升级备库时,默认参数极易失败:
-
--n 2:强制并行度为 2,避免 shared pool latch 争用引发ORA-04031 -
--l /u01/app/oracle/cfgtoollogs/catupgrd/:指定独立日志路径,防止升级中断后残留文件污染 $ORACLE_HOME -
--p 300:组件超时设为 300 秒,避免因临时 I/O 延迟被误判失败 - 升级前确保备库处于
OPEN READ ONLY WITH APPLY,但catctl.pl执行时需先SHUTDOWN IMMEDIATE,再STARTUP UPGRADE——这步由DBMS_ROLLING自动触发,但若手动干预过,必须检查V$INSTANCE.STARTUP_TIME和V$DATABASE.OPEN_MODE是否匹配预期
升级完成后验证逻辑一致性比版本号更重要
看到 V$DATABASE.VERSION 都是 19c 并不等于升级成功。真正要盯住的是:
-
SELECT * FROM V$LOGSTDBY_PROGRESS中APPLIED_SCN和NEWEST_SCN差值应 ≤ 1000(说明 SQL Apply 实时性达标) -
SELECT STATUS, ERROR FROM V$LOGSTDBY必须全为APPLYING和NULL - 在主库执行一条带序列的 INSERT,几秒内必须能在备库 SELECT 出结果——不能只查
DBA_LOGSTDBY_EVENTS看有没有报错,得验真实数据流 - 升级后首次 Switchover 必须用 SQL*Plus 手动执行:
ALTER DATABASE COMMIT TO SWITCHOVER TO STANDBY WITH SESSION SHUTDOWN(原主库),再ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY(原备库),DGMGRL SWITCHOVER在DBMS_ROLLING流程中不可靠
DBMS_ROLLING 的自动化掩盖了很多状态细节,最容易出问题的地方不是命令输错,而是某张表没加主键、某个 schema 没开补充日志、或者 Broker 元数据残留未清——这些都不会报明确错误,但会导致升级后数据静默丢失或切换失败。











