
简介面向Oracle数据库运维人员的一份升级实战手册核心讲解如何利用DBUA工具将Oracle 11g生产库平稳升级至19C。内容从升级前的环境评估开始覆盖备份恢复、参数文件与归档日志处理、源库与目标库目录规划、DBUA执行及升级后配置校验同时特别提醒读者留意脚本运行日志和警告信息。资源中给出升级路线对照也补充了主机版本要求、补丁检查等前置判断依据源库版本过低时需要先升至中间版本再继续升级。全文为单个PDF文档约3.18MB便于按步骤查阅目前已有1342人学习下载。对于具备一定运维能力的DBA手册既提供可落地的完整升级操作框架也整理多种异常场景下的故障解决方案强调每一步的严格顺序和命令细节能有效降低生产环境升级风险并为后续架构演进打好基础。1. 为什么 11g 必须往 19C 走这份升级手册解决的现实问题Oracle 11g 到 19C 数据库升级是很多企业躲不过的一步11.2.0.4 的扩展支持成本越来越高安全补丁更新频率也撑不起核心系统的审计要求而 19c 是目前长期支持策略下最稳的承接版本。这篇手册面向的是手里养着几套生产库、天天被业务方追着问“什么时候能升级”的 DBA也适合准备把老旧系统一起带上 19c 的运维负责人。先说一个反直觉的结论真正把升级拖垮的很少是执行脚本本身而是升级前没人认真检查环境、升级后又不知道哪些收尾动作不能省。升级脚本跑完只要几十分钟前后准备和验证却要花一周把这两头的功课做足11g 到 19c 才是一趟平稳的短途飞行而不是盲飞。2. 升级前先定方案三条路线、检查清单与备份策略2.1 三条主流路线怎么选11g 到 19c 不是只有“原地升级”一条路。常见的做法是先根据库的版本、停机窗口和数据规模选路线再开始动环境否则后面每一步都会被提前锁死。路线一原地升级。源库是 11.2.0.4目标机器和源机器是同一套硬件或同架构虚拟机直接在旁边装一个新的 19c ORACLE_HOME用 19c 的脚本把原库数据字典升级上去。这个方式最贴近“升级”的本义停机窗口通常在 1 到 2 小时dblink、ACL、directory、job 这些数据库对象大部分能原样保留回退依赖升级前的 RMAN 全备。路线二分步中转。源库低于 11.2.0.4比如 11.2.0.3 或更老一般建议先原地升到 11.2.0.4再向 19c 走。现在企业里纯 11.2.0.3 的库不多但一旦遇到别指望一条命令从 10g 直冲 19c老老实实分两步每步都做备份和验证。路线三逻辑迁移到 19c PDB。用 Data Pump 或数据库级迁移工具把 11g 的数据导入 19c 的可插拔数据库。适合目标环境已经统一规划成 CDB 结构、跨平台搬迁或者想趁升级顺手改库名、调整表空间的场景。代价是 dblink、job、ACL、目录对象、用户权限几乎都要重建一遍业务验证周期远比原地升级长坑也最多。对比一下三条路线的取舍路线适用场景停机窗口风险点回退方式原地升级 11.2.0.4 → 19c单实例/同平台核心系统1–2 小时数据字典升级失败RMAN 全备恢复分步中转源版本低于 11.2.0.4需要多次窗口每步都可能翻车每步各自全备逻辑迁移入 PDB跨平台、CDB 统一管理取决于数据量dblink/job/ACL 重建原库保留双写切换我的选择逻辑很简单能原地升级就不做逻辑迁移除非有跨平台或入库改造的硬需求。原地升级失败后恢复整库比逻辑迁移后补对象要省心得多。2.2 升级前七天必须核对的清单确定路线后立即开始环境检查不要等到维护窗口前一天才开始看机器。以下每一项都会在 preupgrade 阶段变成红字或黄字与其到时候被脚本拦住不如提前自查。OS 版本是否在 19c 认证范围内。Linux 上要注意 glibc 版本和内核参数openEuler 这类非 Oracle Linux 发行版更要逐条对照 19c 的认证矩阵环境不满足时连安装都可能失败。磁盘空间。19c 新 ORACLE_HOME 至少准备 30G升级过程中数据文件、redo、temp 都会增长建议总空闲空间不低于现有数据文件总和加 32G temp 预留。11.2.0.4 补丁情况。确认 source 库已经打到 11.2.0.4 最新 PSU 或至少是稳定的补丁基线preupgrade 脚本会检查一些已知 bug 是否已修复。无效对象数量。提前跑一遍select count(*) from dba_objects where statusINVALID;数量太大说明库本身不健康升级前要牵头清理。审计策略。检查audit_trail参数和AUDSYS.AUD$表大小19c 默认审计行为与 11g 不同升级后 SYSTEM 表空间容易被审计记录撑爆。时区文件版本。select version from v$timezone_file;如果远低于 19c 要求升级前就要规划 DST 升级。RMAN 全备是否完成并验证。这条最重要放下一节单独说。这条检查清单我会打印出来贴到机房白板上配合升级命令一步步勾选。不夸张地说清单上一半问题都是平时看不见、升级时才爆发的玄学问题。2.3 RMAN 全备才是你的后悔药升级 19c 之后跨大版本的 downgrade 支持非常有限不要指望一个命令就能回到 11g。真正可靠的后悔药是升级开始前做一次干净的一致性全备。做法是先shutdown immediate干净关闭 11g 实例然后以 mount 状态启动用 RMAN 做一次全备加归档备份。这样备份的一致性点是干净的恢复时只需 restore 后直接打开不需要做不完全恢复。命令参考rman target / shutdown immediate; startup mount; backup database plus archivelog delete input; backup current controlfile; alter database open;参数说明plus archivelog delete input是顺手把未备份的归档连同全备一起处理备份成功后删除已备份归档避免空间被旧归档占满backup current controlfile单独再备一份控制文件防止恢复时控制文件缺失。备份完成后把备份集复制到独立存储或另一台机器升级途中任何一步失败都能用这份备份在十分钟内回滚到 11g。一个血泪经验备份要保留到业务稳定之后至少一周而不是升级一成功就删。有些问题要跑到第二三天才暴露归档备份一旦提前清理那时候想回头就真的没有后悔药了。2.4 时区文件与审计最容易忽略的两个前置项时区文件是 11g 升级 19c 最常见的隐性炸弹。11g 库的时区版本通常停留在很多年前的 DST 版本而 19c 带有更新的时区文件升级后如果业务表里存了带时区的 timestamp应用查询直接报ORA-01882: timezone region not found。这个问题的危险在于 preupgrade 只会给出警告不会阻止升级但升级完成后才在业务高峰暴露。处理方式是在升级前先检查select version from v$timezone_file;再对照 19c 的要求判断是否需要在升级前执行一次 DST 升级。常见的做法是用DBMS_DST包完成 begin upgrade、执行升级脚本、end upgrade 三个阶段。注意19c 升级完成后还需要再按照 19c 的 Globalization Support Guide 做一次新的 DST 更新才能让时区版本完全匹配新版本。这一步别省否则迟早会遇到时间字段相关错误。审计策略同样要提前确认。11g 默认audit_trail可能是 NONE 或 OS19c 下审计默认行为更严格升级后系统会在 SYS.AUD$ 里写入大量审计记录。如果 SYSTEM 表空间本来就不宽裕很容易出现“升级后第一周 SYSTEM 暴涨”的故障。建议在升级前梳理应用账号把不必要的高频审计策略清理掉并准备好独立的表空间或切换audit_trail到 OS 目录避免审计日志和新系统抢空间。3. 执行原地升级跑好 preupgrade 与 catctl.pl 的关键命令3.1 新 ORACLE_HOME 与旧 home 共存原地升级的第一步不是升级而是装一个新的 19c home。11g 的 ORACLE_HOME 不要动升级完成后如果发现问题还需要它来辅助诊断或配合恢复。19c 安装时选择“仅安装软件”不建库安装完成后确认版本和 OPatch 补丁基线export ORACLE_BASE/u01/app/oracle export ORACLE_HOME/u01/app/oracle/product/19.0.0/dbhome_1 export PATH$ORACLE_HOME/bin:$PATH $ORACLE_HOME/OPatch/opatch lsinventory逻辑说明先设置 19c home 的环境变量确保后续所有命令都在新 home 下执行opatch lsinventory用来核对补丁列表确认已经打了必要的 Release Update。旧 11g home 此时不退不删只在执行 preupgrade 和升级命令时切换环境变量。这里最容易踩坑的就是环境变量混用明明想跑 19c 的 catctl结果 shell 里还留着 11g 的 ORACLE_HOME脚本直接在当前 home 找命令报一堆文件找不到。3.2 在 11g 上跑 preupgrade 并处理 fixuppreupgrade 脚本是升级前最重要的体检工具但它不是从 11g home 里跑的而是从 19c home 里找脚本、连到 11g 库上执行。先检查源库版本和健康度sqlplus / as sysdba select version from v$instance; select count(*) from dba_objects where statusINVALID; select version from v$timezone_file; exit然后切换到 19c home执行 preupgrade_dba.sqlcd $ORACLE_HOME/rdbms/admin sqlplus / as sysdba preupgrade_dba.sql输出会提示脚本在$ORACLE_BASE/cfgtoollogs/preupgrade/下生成了两样东西preupgrade_package.sql和preupgrade_fixups.sql。前者需要重新以 sysdba 身份执行用来加载辅助包后者是自动修复脚本能处理的警告会在这里自动修复掉不能处理的会列出原因和手工操作步骤。sqlplus / as sysdba $ORACLE_BASE/cfgtoollogs/preupgrade/preupgrade_package.sql $ORACLE_BASE/cfgtoollogs/preupgrade/preupgrade_fixups.sql逻辑说明preupgrade_package.sql会把 preupgrade 在目标库上运行时需要的包创建到 sys schema 里preupgrade_fixups.sql按预先规则修掉能自动处理的项比如一些过时参数、无效统计信息、遗留的回收站对象。执行完 fixup 后再看一遍生成的preupgrade.log凡是 Level 2 以上的项都不要无视逐个确认处理或记录原因别带着红字进升级窗口。3.3 切换环境并启动到 upgrade 模式检查全部通过后进入真正的维护窗口。先干净关闭 11g而不是用 abort否则下次启动要做实例恢复升级窗口会被拉长export ORACLE_HOME/u01/app/oracle/product/11.2.0/dbhome_1 export PATH$ORACLE_HOME/bin:$PATH sqlplus / as sysdba shutdown immediate; exit随后切换环境变量到 19c home以 upgrade 模式启动数据库。这一步的关键是必须使用STARTUP UPGRADE该模式会临时调整兼容性、关闭某些普通启动时的检查让数据字典升级脚本能安全运行。如果手滑用普通STARTUPcatupgrd 会直接拒绝执行或中途报错。export ORACLE_HOME/u01/app/oracle/product/19.0.0/dbhome_1 export PATH$ORACLE_HOME/bin:$PATH sqlplus / as sysdba startup upgrade;注意此时数据库以非标准模式运行dba_objects等视图访问可能异常不要在这个阶段做业务查询只允许升级脚本操作。3.4 执行核心升级脚本 catctl.pl数据库处于 upgrade 模式后最核心的一步是执行 19c 的并行升级工具catctl.pl它取代了 11g 时代串行跑 catalog.sql 的旧方式。命令如下cd $ORACLE_HOME/rdbms/admin nohup $ORACLE_HOME/perl/bin/perl catctl.pl -n 4 -l /u01/upg_log catupgrd.sql tail -f /u01/upg_log/catctl.log逻辑说明catctl.pl是 19c home 自带的 Perl 脚本catupgrd.sql是数据字典升级的总入口-n 4表示 4 个并行线程实际取值根据 CPU 核数定一般 4 到 8 足够不建议超过 16否则重做日志切换和临时表空间压力会反过来拖慢进度-l指定日志目录所有并行子任务的日志都写在这里。升级全程会有多次内部实例重启看到日志里出现数据库关闭、启动的段落是正常现象不要误判为失败去人工干预。整个 catupgrd 阶段要做的只有两件事盯着日志不要停、提前确认磁盘空间没有被打满。日志推进速度忽快忽慢很正常判断是否卡死要看最后一条日志写入时间和 CPU 占用不要因为几分钟没有新输出就手动 kill 进程。3.5 升级中的会话监控看住 sid 与等待事件catctl.pl 跑起来后通过另一个 SQL*Plus 会话观察数据库内部活动是必要的。用v$session看升级会话在做什么能快速确认脚本没有挂在某个等待上select sid, serial#, event, wait_class, sql_id from v$session where username is not null order by wait_class, event;释放说明升级会话主要会经历 CPU 密集的数据字典重编译wait_class 显示 CPU、临时段排序和日志切换如果看到大量会话卡在buffer busy wait或log buffer space大概率是并行度设置偏高或 temp/redo 空间不足需要及时调低-n或扩展临时表空间。这个监控操作就像是给升级过程装一个仪表盘能提前发现即将翻车的征兆不要等到日志报 ORA-1652 才去补空间。4. 升级收尾无效对象、参数与监听的一次性复核4.1 按顺序跑 postupgrade_fixups 与 utlrpcatctl.pl 跑完并不代表升级结束还有两个收尾脚本必须按顺序执行顺序反了会导致无效对象清理不干净。先跑 preupgrade 阶段生成的postupgrade_fixups.sql它通常也在$ORACLE_BASE/cfgtoollogs/preupgrade/目录下cd $ORACLE_BASE/cfgtoollogs/preupgrade sqlplus / as sysdba spo postupgrade.log postupgrade_fixups.sql spo off逻辑说明postupgrade fixup 处理的是升级完成后才能做的清理动作比如重置某些包的默认授权、清理失效的组件标记、补充时区相关的元数据。先跑这个再跑编译脚本能避免一部分对象因为基础元数据还没就绪而编译失败。随后执行无效对象编译sqlplus / as sysdba $ORACLE_HOME/rdbms/admin/utlrp.sql注意utlrp.sql是提交后台 job 并行编译无效对象脚本本身几分钟就返回但后台 job 可能要跑 20 分钟到一小时。跑完不要立即下结论等一会儿再查一遍invalid数量确认数量和剩余对象类型都符合预期。4.2 验证组件状态与 invalid 对象数量等待 utlrp 后台任务跑完后重新连接 19c 实例做一次系统体检。下面这组 SQL 是每次升级后我都会跑的固定项目select comp_id, comp_name, version, status from dba_registry order by comp_id; select count(*) from dba_objects where statusINVALID;预期结果dba_registry里所有核心组件状态为 VALID版本号显示 19.0.0dba_objects中 invalid 对象数量收敛到两位数以内剩余的多半是有意失效的 XDB 或 SYS 默认对象。若 invalid 数居高不下不要手动一个一个 drop 重建先检查utlrp的后台 job 是否被JOB_QUEUE_PROCESSES0挡住或者还有对象正被会话持有锁。组件验证通过后再确认参数兼容性。升级 19c 后compatible参数可能仍停留在 11.2.0.4 的设定值这是正常现象业务稳定后再手动调整到 19.0.0 并重启生效不要在一开始就强行调高否则引发回退困难。4.3 检查时区、compatible 与监听服务参数和对象都过了最后补三个容易漏的小检查。时区版本直接查视图select version from v$timezone_file;如果版本不是 19c 对应版本按照 Globalization Support Guide 再执行一次 DST 升级这项不处理业务查询时间列迟早报 ORA-01882。同时检查监听服务。升级后最常见的现象是监听“起来”了但远程客户端连不上因为 listener 进程还是从旧 11g home 拉起来的注册的服务名指向旧实例。处理方式是找到 19c home 下的listener.ora在 19c 环境下重启监听export ORACLE_HOME/u01/app/oracle/product/19.0.0/dbhome_1 export PATH$ORACLE_HOME/bin:$PATH lsnrctl stop lsnrctl start lsnrctl status tnsping PROD监听服务无法启动或状态异常时先看$ORACLE_HOME/network/log/listener.log重点确认端口是否被旧监听占用、ORACLE_HOME环境变量是否还指向旧 home。这个网络收尾动作虽小却是应用连接切到 19c 前的最后一道闸。5. 避坑从 11g 升级 19c 的 5 个高频坑与排查方法5.1 时区版本引发的 ORA-01882现象升级完成后应用查询或插入带 time zone 的时间字段时报ORA-01882: timezone region not found而且只出现在部分区域值上。原因11g 源库的时区文件版本低于 19c 需要的最低版本升级过程不会自动更新 DST 数据旧时间区域名称在新版本中不被识别。解决升级前先查v$timezone_file确认版本差距升级后用DBMS_DST按 begin upgrade、执行升级脚本、end upgrade 三步完成时区更新并在测试环境完整验证一遍带时区字段的业务不要只在查询层面抽查。5.2 catupgrd 中途报 ORA-1652 临时表空间不足现象catctl.pl 日志推进到某个阶段停滞后台报ORA-1652: unable to extend temp segment并行线程失败整个升级被拖住。原因数据字典升级过程中有大量排序、临时表重建操作11g 时期的 temp 表空间尺寸是按旧工作负载规划的升级时的瞬时需求远超日常。解决升级前提前扩 temp。进入升级窗口前用如下命令把临时表空间扩到足够水位升级完成后删掉多余临时文件即可alter tablespace temp add tempfile /u01/oradata/PROD/temp02.dbf size 16G autoextend on next 1G maxsize unlimited;参数说明autoextend on是为了防止再次触顶maxsize unlimited受文件系统空间约束实际取 32G 就能覆盖绝大多数 11g 到 19c 的升级需求。升级完成后确认 temp 使用率回落再删除这个临时文件。5.3 升级后无效对象堆到几万现象升级完成后查dba_objectsinvalid 对象数量几千到几万应用调用存储过程时报ORA-04063。原因utlrp.sql没有执行或执行前没有先跑postupgrade_fixups.sql部分对象因为依赖的元数据还没修复而编译失败另一种情况是 utlrp 的后台 job 被JOB_QUEUE_PROCESSES参数限制编译任务根本没跑起来。解决按 4.1 的顺序重跑 postupgrade fixup 和 utlrp跑完等 15 分钟再查 invalid 数量。如果仍然很多检查 job 队列参数并把job_queue_processes临时调大重新跑一次 utlrp。不要手工逐个删除重建很容易连带触发依赖对象失效。5.4 监听起来了但远程连不上现象本地sqlplus / as sysdba进库正常远程客户端报ORA-12541: TNS: no listener或ORA-12514但lsnrctl status显示监听进程存在。原因shell 环境还指向旧 11g home启动的 listener 是旧 home 的进程监听地址和服务名注册的都是旧库或者 19c listener.ora 里没有正确的SID_LIST。解决在 19c home 下重建监听配置并重启确认lsnrctl status里出现 19c 实例的服务名。如果端口被旧监听占用先杀掉旧进程再启动新的。这个坑几乎是每次升级必踩压测前务必先做一轮 tnsping。5.5 想降级回去却发现没有后悔药现象升级后业务表现异常团队立刻决定回退执行 19c 文档里的 downgrade 步骤结果脚本报不支持或走到一半失败。原因11g 到 19c 跨越的版本太多downgrade 脚本支持范围很有限更常见的是升级过程中已经执行了 DST 更新、补丁或后续 fixup这些操作会永久改变数据字典使降级路径彻底断裂。解决不要依赖降级脚本升级前做一致性 RMAN 全备并保留到业务稳定一周以上需要回退时直接 restore 整库。执行升级前就把备份放在独立存储并让团队明确回退的唯一通道是 RMAN不是 downgrade 命令。6. 多套库并行升级autoupgrade.jar 的一个最小用法如果你管理的不是一套库而是几十套手工跑 preupgrade、catctl、utlrp 这套流程会把人拖垮。19c 自带的 autoupgrade 工具可以把前面这些步骤串起来用配置文件批量管理多个实例支持断点续跑很适合分批替换存量 11g 库。一个最小配置示例如下global.autoupg_log_dir/u01/autoupgrade/logs upg1.source_home/u01/app/oracle/product/11.2.0/dbhome_1 upg1.target_home/u01/app/oracle/product/19.0.0/dbhome_1 upg1.sidPROD1 upg1.log_dir/u01/autoupgrade/logs/PROD1启动命令java -jar $ORACLE_HOME/rdbms/admin/autoupgrade.jar \ -config /u01/autoupgrade/upg.cfg -mode upgrade说明-config指向配置文件-mode upgrade表示对配置里所有实例执行升级autoupgrade 会自动完成 preupgrade 检查、fixup 执行、catctl 升级和逐步收尾每个实例都有自己的日志目录。它最实用的特性是中断后可续跑比手工脚本更抗意外。注意 autoupgrade 仍然要求升级前完成 RMAN 全备它替代的是操作流程不是备份纪律。我现在养成的习惯是再急的升级项目也先留一个完整周末备好两份全备放在不同存储然后才允许任何脚本落在生产库上。这套从 11g 到 19c 的路径跑顺之后再换别的版本升级剩下的都是细节。希望帮到你。本文还有配套的精品资源点击获取