1. 项目背景与核心挑战
作为Oracle DBA,数据库版本升级是职业生涯中绕不开的关键任务。最近我主导完成了生产环境Oracle 11g到19c的ADG架构升级,整个过程采用dbua工具静默模式执行。与常规单实例升级不同,ADG环境下的升级需要同时考虑主备库的协同、停机窗口控制以及回退方案设计等复杂因素。
这次升级的源环境是Oracle 11.2.0.4 RAC+单实例ADG的架构,目标版本为19.17.0.0。选择dbua静默模式而非GUI方式,主要基于以下考量:
- 生产环境通常不允许直接图形界面操作
- 静默模式可通过脚本精确控制每个步骤
- 便于记录完整的操作日志用于审计
- 出现异常时可快速定位问题点
关键决策点:在ADG环境下,必须先升级Standby库再升级Primary库,这个顺序与常规认知相反。因为19c的ADG机制要求Standby库必须先兼容新版本的数据格式。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与预检工作
2.1 系统兼容性验证
在正式升级前,我们花费两周时间进行环境验证。使用Oracle提供的preupgrade.jar工具生成详细的检查报告:
bash复制java -jar $ORACLE_HOME/rdbms/admin/preupgrade.jar -c "preupgrade_dir" -l "preupgrade.log"
检查重点包括:
- 表空间剩余空间(SYSTEM至少需要1.5GB空闲)
- 无效对象数量(需提前编译或记录)
- 过时参数检查(如_optimizer_join_sel_sanity_check)
- 字符集兼容性(AL32UTF8与ZHS16GBK的转换策略)
2.2 ADG状态确认
通过以下SQL确认ADG同步状态正常:
sql复制SELECT PROCESS, STATUS, THREAD#, SEQUENCE#, BLOCK#, BLOCKS
FROM V$MANAGED_STANDBY
WHERE PROCESS LIKE 'MRP%';
特别需要注意:
- 确保没有延迟的归档日志(V$ARCHIVED_LOG.APPLIED='NO'的记录)
- 检查传输延迟时间(V$DATAGUARD_STATS)
- 确认备库当前SCN与主库差值在可接受范围
2.3 备份策略强化
尽管dbua会自动备份,但我们仍额外执行了:
- 全库RMAN备份(包含归档日志)
rman复制RMAN> BACKUP DATABASE PLUS ARCHIVELOG DELETE INPUT;
- 关键参数文件导出
sql复制CREATE PFILE='/backup/initORCL.ora' FROM SPFILE;
- 控制文件备份
sql复制ALTER DATABASE BACKUP CONTROLFILE TO TRACE;
3. Standby库升级实战
3.1 停止同步进程
首先停止ADG同步进程:
sql复制ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
然后检查确保没有活跃的redo应用:
sql复制SELECT PROCESS, STATUS FROM V$MANAGED_STANDBY;
3.2 执行静默升级
使用dbua的静默模式命令示例:
bash复制dbua -silent \
-oracleHome $ORACLE_HOME \
-sid ORCL \
-databaseConfigType SINGLE \
-upgradeOption DB \
-recompile_invalid_objects true \
-emConfiguration NONE \
-autoSpaceCheck false \
-ignorePrereqFailure true \
-moveFilesManually false \
-backupLocation /oracle/backup \
-logfile /tmp/dbua_standby_upgrade.log
关键参数说明:
-ignorePrereqFailure true:跳过非致命性检查错误-recompile_invalid_objects true:自动重编译无效对象-moveFilesManually false:允许工具自动处理文件位置变更
3.3 升级后处理
升级完成后需要:
- 重建standby控制文件(主库生成后传输到备库)
sql复制ALTER DATABASE CREATE STANDBY CONTROLFILE AS '/tmp/standby_control.ctl';
- 更新监听配置(19c需要静态注册)
bash复制lsnrctl stop
lsnrctl start
- 检查数据库状态
sql复制SELECT STATUS, OPEN_MODE, DATABASE_ROLE FROM V$DATABASE;
4. Primary库升级与ADG重建
4.1 主库升级步骤
主库升级流程与备库类似,但需特别注意:
- 确保所有应用连接已断开
- 停用Oracle集群服务(如使用RAC)
bash复制crsctl stop has
- 执行dbua时增加RAC相关参数:
bash复制dbua -silent \
-oracleHome $ORACLE_HOME \
-sid ORCL \
-databaseConfigType RAC \
-clusterNodes "node1,node2" \
...
4.2 ADG重新配置
升级完成后重建ADG的关键步骤:
- 主库生成新的密码文件并传输到备库
bash复制orapwd file=$ORACLE_HOME/dbs/orapw$ORACLE_SID entries=10 force=y
- 备库更新参数文件:
sql复制ALTER SYSTEM SET log_archive_config='DG_CONFIG=(ORCL,ORCL_STBY)' SCOPE=BOTH;
ALTER SYSTEM SET fal_server='ORCL' SCOPE=BOTH;
- 启动同步进程
sql复制ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT;
5. 验证与性能调优
5.1 功能验证矩阵
我们设计了完整的验证checklist:
- 基础功能验证
sql复制-- 检查数据库角色
SELECT DATABASE_ROLE FROM V$DATABASE;
-- 验证ADG同步延迟
SELECT NAME, VALUE, TIME_COMPUTED FROM V$DATAGUARD_STATS
WHERE NAME LIKE 'apply lag';
- 业务SQL回放测试
使用SQL Performance Analyzer对比升级前后执行计划:
sql复制EXEC DBMS_SQLTUNE.CREATE_SQLSET('UPGRADE_TEST');
EXEC DBMS_SQLPA.EXECUTE_COMPARISON_TASK(...);
5.2 19c新特性适配
针对19c的新特性调整:
- 自动索引管理
sql复制ALTER SYSTEM SET "_optimizer_auto_index_allow"=TRUE SCOPE=BOTH;
- 内存管理优化
sql复制ALTER SYSTEM SET MEMORY_TARGET=8G SCOPE=SPFILE;
- 统计信息收集策略
sql复制EXEC DBMS_STATS.SET_GLOBAL_PREFS('CONCURRENT','TRUE');
6. 回退方案设计
尽管升级过程顺利,但我们仍准备了完整的回退方案:
- 时间点恢复(当升级后运行时间<24小时)
rman复制RMAN> RUN {
SET UNTIL TIME "TO_DATE('2023-07-20 14:00:00','YYYY-MM-DD HH24:MI:SS')";
RESTORE DATABASE;
RECOVER DATABASE;
}
- 全库恢复(严重故障时)
rman复制RMAN> STARTUP FORCE MOUNT;
RMAN> RESTORE DATABASE FROM TAG "PRE_UPGRADE";
RMAN> RECOVER DATABASE;
- ADG回退特别注意事项:
- 需要先将主库降级再恢复备库
- 确保所有节点同时回退到相同版本
- 回退后必须重建ADG关系
整个升级过程中最耗时的环节是无效对象重编译,我们通过以下命令提前识别并处理:
sql复制SELECT OWNER, OBJECT_NAME, OBJECT_TYPE
FROM DBA_OBJECTS
WHERE STATUS='INVALID'
ORDER BY OWNER, OBJECT_TYPE;
对于大型PL/SQL包,采用并行编译提升效率:
sql复制ALTER SESSION SET PLSQL_OPTIMIZE_LEVEL=3;
ALTER SESSION SET PLSQL_CODE_TYPE='NATIVE';
@?/rdbms/admin/utlrp.sql
在19c中,DBMS_UTILITY.COMPILE_SCHEMA的并行度设置更为关键:
sql复制BEGIN
DBMS_UTILITY.COMPILE_SCHEMA(
SCHEMA => 'APP_USER',
COMPILE_ALL => TRUE,
REUSE_SETTINGS => FALSE,
PARALLEL => 8
);
END;
