适用版本:Oracle 11.2.0.4 → 19.23
工作模式:DataGuard 备库先行升级 + 主备 Switchover
核心场景:基于物理 DataGuard 的生产数据库从 11G R2 平滑升级至 19C,最小化停机窗口
1. 升级概述
1.1 升级策略
本次升级的核心思路是 “备库先行、主备切换、原地升级、搭建新备库、切回”,整体流程如下:
- 停止业务应用 — 停机窗口起点
- 主备 Switchover — 原备库切换为新主库
- 新主库原地升级 — 在备库环境完成 11G → 19C 数据字典升级(与步骤 4 同步进行)
- 新节点重装部署 — 原主库节点重装操作系统、安装 19C GI 集群及数据库软件
- 搭建 DataGuard — 在新节点上通过 RMAN Duplicate 搭建备库并同步数据
- 主备 Switchover — 切回新节点为主库,完成整个升级流程
设计要点:步骤 3 和步骤 4 并行执行,最大化缩短停机时间。
1.2 环境信息
| 项目 | 信息 |
|---|---|
| 硬件平台 | 物理服务器 |
| 操作系统 | Linux 7.x |
| 源数据库版本 | Oracle 11.2.0.4 |
| 目标数据库版本 | Oracle 19.3 + RU 19.23 |
| 数据库名 | PRODDB |
| 高可用方案 | RAC ONE NODE + DataGuard |
| 数据库角色 | 主库 + 物理备库 |
2. 升级前环境准备
2.1 操作系统层面检查清单
在正式升级前,需对操作系统进行全面检查,确保升级后环境一致:
| 序号 | 检查项 | 说明 | 风险等级 |
|---|---|---|---|
| 1 | /etc/fstab |
单独挂载卷(数据卷、归档卷、备份卷) | 高 |
| 2 | crontab 及对应脚本 |
定时任务是否完整迁移 | 高 |
| 3 | /etc/sysctl.conf |
内核参数、大页内存配置 | 高 |
| 4 | /etc/rc.local |
开机自启动脚本 | 中 |
| 5 | /etc/security/limits.conf |
Oracle 及应用用户的资源限制 | 高 |
| 6 | 环境变量 bash_profile |
Oracle 及应用用户的环境变量 | 高 |
| 7 | /home/oracle 下的 Shell/SQL 脚本 |
所有运维脚本同步至新机器 | 高 |
| 8 | 归档日志清理脚本 | 防止归档目录写满 | 高 |
⚠️ 特别注意:19C 与 11G 在操作系统内核参数方面的核心差异主要有以下三项:
- 透明大页(THP)必须关闭:
/sys/kernel/mm/transparent_hugepage/enabled设为never,19C 安装检查工具会显式检测此项- RAC/GI 环境:
net.ipv4.conf.all.rp_filter建议从0改为2,解决多路由场景下私网心跳包被 drop 的问题- 大内存机器:
vm.min_free_kbytes建议 ≥524288,并合理配置vm.nr_hugepages其余
shmmax、shmall、sem、fs.file-max等参数与 11G 要求基本一致,无需额外调整。详见 MOS Doc ID 2532998.1。
2.2 Oracle 19c 软件安装
# 在备库节点完成操作系统升级后,安装 Oracle 19.3 软件
# 并将 RU 版本升级至 19.23
# Oracle 19c 安装目录结构
export ORACLE_BASE=/oracle/app/oracle
export ORACLE_HOME=/oracle/app/oracle/product/19c/db_1
版本差异说明:
- 11.2.0.4:GI 和 DB 软件独立安装,Oracle Restart 管理单实例 ASM
- 19C:GI 包含 ASM 和集群件,建议使用 RU 19.23 以上版本以包含最新的优化器修复
⚠️ 版本适配建议: 涉及 RAC 集群升级时,需同步升级 OCR/Voting Disk 所在的 ASM 磁盘组兼容性属性。
3. 升级方案详解
3.1 停止业务应用
这是停机窗口的起点,需要与应用管理员密切配合:
操作流程:
- 协调应用管理员停止所有连接该数据库的生产应用
- 在数据库层面持续检查活跃会话,确认所有业务用户会话已断开
- 如有残留会话,通过
kill -9操作系统层面强制终止
-- oracle-19c / 11g
-- 检查生产库业务用户会话情况
SELECT inst_id, username, COUNT(*)
FROM gv$session
WHERE username IN (SELECT username
FROM dba_users
WHERE TO_CHAR(created, 'YYYY-MM-DD HH24:MI:SS') > '<业务用户最早创建日期>')
GROUP BY inst_id, username;
-- 生成 kill session 命令(操作系统层面)
SELECT 'ho kill -9 ' || spid
FROM v$session s, v$process p
WHERE p.addr = s.paddr
AND s.username IN (SELECT username
FROM dba_users
WHERE TO_CHAR(created, 'YYYY-MM-DD') > '<业务用户最早创建日期>'
AND account_status = 'OPEN');
⚠️ 注意事项:
kill -9是最后手段,先试ALTER SYSTEM KILL SESSION或ALTER SYSTEM DISCONNECT SESSION- 确保所有 dblink 连接和远程会话也断开了
- 主库会话断开后,确认备库 MRP 进程已应用完所有日志
3.2 备库切换为主库(Switchover)
升级采用先在原备库原地升级的策略。首先执行主库到备库的 Switchover 切换(这是计划内切换,不是故障切换 Failover)。
3.2.1 主库端操作 — 中断日志传输
-- oracle-11g 主库 — 暂停日志传输至备库
-- ⚠️ 请先通过 SHOW PARAMETER log_archive_dest 确认备库对应的 dest 编号后再执行!
-- 以下 _3 和 _4 为示例,实际编号以环境为准
ALTER SYSTEM SET log_archive_dest_state_3 = 'defer';
ALTER SYSTEM SET log_archive_dest_state_4 = 'defer';
3.2.2 备库端操作 — 检查同步状态并停止应用
-- oracle-11g 备库 — 检查同步状态
SET LINES 999
SELECT name, value FROM v$dataguard_stats;
-- 停止 MRP 日志应用进程
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
3.2.2 中用
v$dataguard_stats检查同步状态,11.2.0.4 下该视图需要 MRP 在跑才有数据。可以同时查归档序列号差距:SELECT thread#, low_seq#, high_seq# FROM v$archive_gap;
3.2.3 执行 Switchover
-- oracle-11g 备库 — 确认可转换状态
SELECT switchover_status FROM v$database;
-- 期望输出:TO PRIMARY 或 SESSIONS ACTIVE
-- 完成日志应用(计划内 Switchover 用 FINISH,故障切换 Failover 用 FINISH FORCE)
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH;
-- 将备库转换为主库
ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN;
-- 确认数据库角色
SELECT name, open_mode, database_role FROM v$database;
-- 期望:READ WRITE / PRIMARY
-- 重启数据库使用 11.2.0.4 软件打开
SHUTDOWN IMMEDIATE;
STARTUP;
SELECT open_mode, database_role FROM v$database;
版本差异说明:
- 11.2.0.4:
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH在有 GAP 的情况下会报错- 19C:
RECOVER ... FINISH的语义与 11g 一致,但 19C 中 DataGuard Broker 的DGMGRL提供了更便捷的VALIDATE DATABASE前置检查命令版本适配建议: 如果使用了 DataGuard Broker(
DGMGRL),建议通过 Broker 执行 Switchover/Failover,自动处理日志 GAP 检测和角色转换。
3.3 新节点重装部署(同步进行)
在本步骤中,原主库节点重新安装操作系统并部署 Oracle 19C GI 集群和数据库软件,为后续搭建 DataGuard 备库做准备。
具体操作包括:
- 操作系统重新安装
- 19C Grid Infrastructure 集群软件安装
- 19C 数据库软件安装及 RU 19.23 补丁应用
- ASM 磁盘组配置
本步骤与下面的「目标环境升级数据库至 19.23」同步执行,有效缩减停机窗口。
3.4 目标环境升级数据库至 19.23
这是整个升级流程的核心环节,在原备库(已切换为新主库)上完成 11.2.0.4 到 19.23 的数据字典升级。
⚠️ 前置要求:升级前必须执行 RMAN 全库备份
即使有 DataGuard 备库作为数据副本,升级前仍需做一次 RMAN 全备。万一升级过程中出现不可恢复的错误,全备是最后的兜底手段。# 升级前全备示例 rman target / <<EOF BACKUP AS COMPRESSED BACKUPSET DATABASE FORMAT '/backup/full_%U'; BACKUP AS COMPRESSED BACKUPSET ARCHIVELOG ALL FORMAT '/backup/arc_%U'; EOF备份应存放于与升级环境分离的存储上,确保即使原节点重建也不丢失。
Step 1 — 检查并停止 Job
-- oracle-11g
-- 检查所有 Job 状态
ALTER SESSION SET nls_date_format = 'yyyy-mm-dd hh24:mi:ss';
SET LINES 188 PAGES 1000
COL INTERVAL FOR a25
COL what FOR a33
COL log_user FOR a11
SELECT job, log_user, last_date, next_date, interval, failures, broken, what
FROM dba_jobs;
-- 暂停 Job 队列,防止升级过程中自动触发 Job
ALTER SYSTEM SET job_queue_processes = 0 SCOPE = BOTH;
job_queue_processes=0只是停了调度,正在跑的 Job 不会被杀。升级前看一眼dba_jobs_running,有还在跑的就等它结束或者手动 kill。
Step 2 — 检查数据库组件版本和状态
-- oracle-11g
COL comp_id FOR a30
COL comp_name FOR a40
SET LINE 200
SELECT comp_id, comp_name, version, status FROM dba_registry;
确认所有组件状态为 VALID。如有 INVALID 或 OPTION OFF 组件,需评估其影响。
Step 3 — 检查失效对象
-- oracle-11g
SET LINESIZE 200 PAGESIZE 200
COL object_name FOR a40
COL owner FOR a20
SELECT owner, object_type, object_name
FROM dba_objects
WHERE status = 'INVALID';
升级前失效对象先跑一遍
utlrp.sql编译,19C 升级脚本对失效对象校验更严格,建议控制在 100 个以内。
Step 4 — 清空回收站
-- oracle-11g
SELECT COUNT(*) FROM dba_recyclebin;
PURGE DBA_RECYCLEBIN;
⚠️ 回收站不清空可能导致升级卡死,
PURGE DBA_RECYCLEBIN升级前必做,不要省略。
Step 5 — 执行升级预检查(preupgrade.jar)
这是 Oracle 官方推荐的关键步骤,使用 19C 自带的 preupgrade.jar 工具对 11G 数据库进行全面诊断:
# ⚠️ 重要说明:preupgrade.jar 从 19c 的 ORACLE_HOME 路径执行,
# 但数据库本身仍在 11.2.0.4 软件下运行!
# ORACLE_SID 指向 11g 的实例,Java 使用 19c 的 jdk,sqlplus 连接用的是 11g 进程
export ORACLE_HOME=/oracle/app/oracle/product/19c/db_1
export ORACLE_BASE=/oracle/app/oracle
export ORACLE_SID=PRODDB
/oracle/app/oracle/product/19c/db_1/jdk/bin/java \
-jar /oracle/app/oracle/product/19c/db_1/rdbms/admin/preupgrade.jar \
TERMINAL TEXT FILE
预检查常见输出及处理:
| 检查项 | 处理方式 |
|---|---|
| Remove the EM repository | 手动清理 Database Control 仓库(11G 的 EM 不再被 19C 支持) |
(AUTOFIXUP) Drop sys.enabled$indexes |
由 preupgrade_fixups.sql 自动处理 |
Run utlrp.sql recompile invalid objects |
手动执行 @?/rdbms/admin/utlrp.sql |
Remove OLAP Catalog (catnoamd.sql) |
手动执行 @?/olap/admin/catnoamd.sql |
| Upgrade Oracle Application Express (APEX) | 手动升级 APEX 或移除 |
| Remove EXF and RUL | 手动移除 Expression Filter 和 Rules Manager |
(AUTOFIXUP) Gather stale dictionary statistics |
由 preupgrade_fixups.sql 自动处理 |
(AUTOFIXUP) Gather fixed objects statistics |
由 preupgrade_fixups.sql 自动处理 |
前置条件补充:
- 确保 19C
$ORACLE_HOME/jdk目录存在且 Java 版本正确- 预检查脚本的输出文件默认保存在
$ORACLE_BASE/cfgtoollogs/$ORACLE_SID/preupgrade/下- 执行预检查时数据库需处于 OPEN 状态
Step 6 — 执行修复脚本
⚠️ 执行环境说明:此脚本由 Step 5 的
preupgrade.jar生成,存放在 19c 目录下,但必须在 11g 环境的 sqlplus 中以 SYSDBA 身份执行(数据库仍在 11g 软件下运行)。
-- 在 11g 环境的 sqlplus 中执行 preupgrade 生成的自动修复脚本
SQL> @/oracle/app/oracle/product/19c/db_1/cfgtoollogs/PRODDB/preupgrade/preupgrade_fixups.sql
-- 关闭数据库,准备以 upgrade 模式启动
SQL> SHUTDOWN IMMEDIATE;
Step 7 — 拷贝 11G 参数到 19C 环境
# 将 11g 环境的 spfile 和密码文件拷贝至 19c $ORACLE_HOME/dbs 目录
# 具体路径以实际环境为准
cp /oracle/app/oracle/product/11.2.0.4/dbhome_1/dbs/spfilePRODDB.ora \
/oracle/app/oracle/product/19c/db_1/dbs/
cp /oracle/app/oracle/product/11.2.0.4/dbhome_1/dbs/orapwPRODDB \
/oracle/app/oracle/product/19c/db_1/dbs/
⚠️ 补充说明:
- 如果使用 pfile 而非 spfile,需将 pfile 文件一并拷贝
- 密码文件格式在 19C 中为 12.2 格式,升级启动后 Oracle 会自动转换
- 拷贝后检查文件权限(属主
oracle:oinstall,权限 640)
⚠️ 关于 11g 废弃参数:从 11g 拷贝的 spfile 中可能包含
background_dump_dest、user_dump_dest、core_dump_dest等 19C 已废弃的参数。这些参数不会阻止STARTUP UPGRADE,19C 会将相关告警写入 alert 日志。升级完成后根据 alert 日志提示逐项清理即可:ALTER SYSTEM RESET background_dump_dest SCOPE=SPFILE SID='*',同理处理user_dump_dest和core_dump_dest;audit_file_dest如路径含 11g ORACLE_HOME 则需改为 19c 路径。
# source 19c 环境变量
source bash_19c
# 以 upgrade 模式启动数据库
sqlplus / as sysdba
SQL> STARTUP UPGRADE;
Step 8 — 执行数据字典升级脚本
# 19c 环境执行,-n 8 表示 8 个并行进程
cd $ORACLE_HOME/rdbms/admin
$ORACLE_HOME/perl/bin/perl catctl.pl -n 8 $ORACLE_HOME/rdbms/admin/catupgrd.sql
版本差异说明:
- 11g 升级使用
catupgrd.sql直接串行执行- 19C 使用
catctl.pl包装器支持并行升级,-n参数建议设置为 CPU 核心数的 1/2 ~ 1/4- 升级日志输出在
$ORACLE_HOME/cfgtoollogs/$ORACLE_SID/upgrade/目录下版本适配建议: 如果数据库对象数量极为庞大(百万级以上),建议
-n不超过 8,避免字典升级期间出现 enq: TM contention。
Step 8.1 — 确认 catupgrd.sql 执行完成
升级脚本执行完毕后,必须确认升级本身是否成功完成,再继续后续步骤:
# 检查升级日志尾部,确认是否成功
tail -50 $ORACLE_HOME/cfgtoollogs/$ORACLE_SID/upgrade/catupgrd*.log
# 日志末尾应出现类似 "Upgrade completed successfully" 的信息
-- 在 sqlplus 中确认核心组件状态
SELECT comp_id, version, status FROM dba_registry WHERE comp_id IN ('CATALOG', 'CATPROC');
-- 必须为 VALID 才能继续
Step 9 — 编译失效对象并检查组件状态
-- 编译所有失效对象
@?/rdbms/admin/utlrp.sql
-- 检查组件状态(需全部为 VALID)
SELECT comp_id, version, status FROM dba_registry;
⚠️ CATALOG、CATPROC、JAVAVM、XML、OWM 这几个核心组件必须为 VALID,有 INVALID 的查 MOS 找对应修复脚本。
Step 10 — 更新 Timezone 时区文件
-- 先关闭数据库(Step 9 之后数据库是 OPEN 状态)
SHUTDOWN IMMEDIATE;
-- 以 upgrade 模式重新启动
STARTUP UPGRADE;
-- 查看当前时区文件版本
SELECT * FROM v$timezone_file;
SET SERVEROUTPUT ON
DECLARE
l_tz_version PLS_INTEGER;
BEGIN
l_tz_version := DBMS_DST.get_latest_timezone_version;
DBMS_OUTPUT.put_line('l_tz_version=' || l_tz_version);
DBMS_DST.begin_upgrade(l_tz_version);
END;
/
-- 重启数据库
SHUTDOWN IMMEDIATE;
STARTUP;
-- 完成时区升级
SET SERVEROUTPUT ON
DECLARE
l_failures PLS_INTEGER;
BEGIN
DBMS_DST.upgrade_database(l_failures);
DBMS_OUTPUT.put_line('DBMS_DST.upgrade_database : l_failures=' || l_failures);
DBMS_DST.end_upgrade(l_failures);
DBMS_OUTPUT.put_line('DBMS_DST.end_upgrade : l_failures=' || l_failures);
END;
/
-- 确认时区文件版本已更新
SELECT * FROM v$timezone_file;
-- ⚠️ 时区升级后必须重启数据库,使更改完全生效
SHUTDOWN IMMEDIATE;
STARTUP;
版本差异说明:
- 11G 默认时区文件版本通常为 14 或更低
- 19.23 对应时区文件版本通常为 32+
- 时区升级涉及
TIMESTAMP WITH TIME ZONE类型列的检查,耗时与表中此类列的数量成正比补充步骤: 在
DBMS_DST.begin_upgrade之前建议先执行:-- 检查受影响的表 SELECT owner, table_name, column_name FROM dba_tab_columns WHERE data_type LIKE 'TIMESTAMP%WITH TIME ZONE';
Step 11 — 创建 19C 默认 Directory
-- 创建 19c 新增的默认目录对象
SQL> @?/rdbms/admin/utldirsymlink.sql
此脚本会创建如 ORACLE_BASE、ORACLE_HOME、DATA_PUMP_DIR 等 19C 新引入的默认目录对象。
Step 12 — 修改 COMPATIBLE 参数
-- 改完就回不去了,升级完直接改就行
SQL> SHOW PARAMETER compatible;
SQL> ALTER SYSTEM SET compatible = '19.0.0' SCOPE = SPFILE;
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP;
Step 13 — 执行升级后检测脚本
SQL> @/oracle/app/oracle/product/19c/db_1/cfgtoollogs/PRODDB/preupgrade/postupgrade_fixups.sql
结果解读: 脚本输出通常为 “No manual actions needed”,如有需手动处理的项目,逐项确认。
3.5 19C 数据库参数调优
升级完成后,根据生产环境特点调整以下参数。这些参数的调整目标是稳定优先、性能次之,确保从 11G 到 19C 的执行计划不发生重大退化。
3.5.1 优化器相关参数
-- oracle-19c
-- 关闭 19C 新增的优化器特性,保持与 11G 执行计划一致
ALTER SYSTEM SET "_optimizer_adaptive_cursor_sharing" = FALSE SCOPE = SPFILE;
ALTER SYSTEM SET "_optimizer_extended_cursor_sharing_rel" = NONE SCOPE = SPFILE;
ALTER SYSTEM SET "_optimizer_extended_cursor_sharing" = NONE SCOPE = SPFILE;
ALTER SYSTEM SET "_optimizer_gather_feedback" = FALSE SCOPE = SPFILE;
ALTER SYSTEM SET "_optimizer_use_feedback" = FALSE SCOPE = SPFILE;
ALTER SYSTEM SET "_optimizer_dsdir_usage_control" = 0 SCOPE = SPFILE;
ALTER SYSTEM SET "_optimizer_mjc_enabled" = FALSE SCOPE = SPFILE;
ALTER SYSTEM SET "_optimizer_cbqt_or_expansion" = OFF SCOPE = SPFILE;
ALTER SYSTEM SET "_optimizer_reduce_groupby_key" = FALSE SCOPE = SPFILE;
ALTER SYSTEM SET "_optimizer_null_accepting_semijoin" = FALSE SCOPE = SPFILE;
ALTER SYSTEM SET "_optimizer_aggr_groupby_elim" = FALSE SCOPE = SPFILE;
ALTER SYSTEM SET "_sql_plan_directive_mgmt_control" = 0 SCOPE = SPFILE;
| 参数 | 作用 | 关闭原因 |
|---|---|---|
_optimizer_adaptive_cursor_sharing |
自适应游标共享 | 11G 升级后避免游标频繁失效 |
_optimizer_gather_feedback |
统计信息反馈 | 避免因反馈导致执行计划不稳定 |
_optimizer_cbqt_or_expansion |
基于成本的 OR 扩展 | 关闭后与 11G 行为一致 |
_sql_plan_directive_mgmt_control |
SQL 计划指令管理 | 避免自动创建 SQL Plan Directive |
3.5.2 内存与 I/O 相关参数
-- oracle-19c
ALTER SYSTEM SET "_serial_direct_read" = NEVER SCOPE = SPFILE;
ALTER SYSTEM SET "_PX_use_large_pool" = TRUE SCOPE = SPFILE;
ALTER SYSTEM SET "_use_single_log_writer" = TRUE SCOPE = SPFILE;
ALTER SYSTEM SET "_max_outstanding_log_writes" = 1 SCOPE = SPFILE;
ALTER SYSTEM SET "_use_adaptive_log_file_sync" = FALSE SCOPE = SPFILE;
| 参数 | 说明 |
|---|---|
_serial_direct_read = NEVER |
禁用串行直接路径读,避免小表全扫走 Direct Read 影响 Buffer Cache 效率 |
_use_single_log_writer + _max_outstanding_log_writes=1 |
使用单一 LGWR 进程,降低 Redo 写入延迟抖动 |
_use_adaptive_log_file_sync=FALSE |
关闭自适应日志同步,避免高频提交场景下日志同步策略切换 |
3.5.3 其他关键参数
-- oracle-19c
-- 基础参数
ALTER SYSTEM SET "_b_tree_bitmap_plans" = FALSE SCOPE = SPFILE;
ALTER SYSTEM SET "_simple_view_merging" = TRUE SCOPE = SPFILE;
ALTER SYSTEM SET "_sort_elimination_cost_ratio" = 1 SCOPE = SPFILE;
ALTER SYSTEM SET undo_retention = 1800 SCOPE = SPFILE;
ALTER SYSTEM SET db_files = 2000 SCOPE = SPFILE;
ALTER SYSTEM SET deferred_segment_creation = FALSE SCOPE = SPFILE;
-- 审计关闭(减少系统开销)
ALTER SYSTEM SET audit_trail = NONE SCOPE = SPFILE;
ALTER SYSTEM SET audit_sys_operations = FALSE SCOPE = SPFILE;
-- 资源管理
ALTER SYSTEM SET resource_manager_plan = 'FORCE:' SCOPE = SPFILE;
-- DDL 日志(便于审计)
ALTER SYSTEM SET enable_ddl_logging = TRUE SCOPE = SPFILE;
-- SCN 相关保护参数
ALTER SYSTEM SET "_external_scn_logging_threshold_seconds" = 21600 SCOPE = SPFILE;
ALTER SYSTEM SET "_external_scn_rejection_threshold_hours" = 720 SCOPE = SPFILE;
-- 游标相关
ALTER SYSTEM SET "_cursor_obsolete_threshold" = 128 SCOPE = SPFILE;
ALTER SYSTEM SET "_kks_obsolete_dump_threshold" = 0 SCOPE = SPFILE;
-- UNDO 调优
ALTER SYSTEM SET "_undo_autotune" = FALSE SCOPE = SPFILE;
ALTER SYSTEM SET "_rollback_segment_count" = 6000 SCOPE = SPFILE;
-- 分区、分布式事务
ALTER SYSTEM SET "_partition_large_extents" = FALSE SCOPE = SPFILE;
ALTER SYSTEM SET "_clusterwide_global_transactions" = FALSE SCOPE = SPFILE;
-- dblink 相关
ALTER SYSTEM SET "_keep_remote_column_size" = TRUE SCOPE = SPFILE;
-- 其他
ALTER SYSTEM SET "_drop_stat_segment" = 1 SCOPE = SPFILE;
ALTER SYSTEM SET "_sys_logon_delay" = 0 SCOPE = SPFILE;
ALTER SYSTEM SET "_report_capture_cycle_time" = 0 SCOPE = SPFILE;
3.5.4 关闭自动维护任务
-- oracle-19c
-- 关闭 OCM 配置任务
EXEC dbms_scheduler.disable('ORACLE_OCM.MGMT_CONFIG_JOB');
EXEC dbms_scheduler.disable('ORACLE_OCM.MGMT_STATS_CONFIG_JOB');
-- 关闭自动任务(空间顾问、SQL 调优顾问、自动统计信息收集)
BEGIN
DBMS_AUTO_TASK_ADMIN.DISABLE(
client_name => 'auto space advisor',
operation => NULL,
window_name => NULL);
END;
/
BEGIN
DBMS_AUTO_TASK_ADMIN.DISABLE(
client_name => 'sql tuning advisor',
operation => NULL,
window_name => NULL);
END;
/
BEGIN
DBMS_AUTO_TASK_ADMIN.DISABLE(
client_name => 'auto optimizer stats collection',
operation => NULL,
window_name => NULL);
END;
/
-- 确认状态均为 DISABLED
SELECT client_name, status FROM DBA_AUTOTASK_CLIENT;
版本差异说明:
- 11G 中自动维护任务窗口默认为周一到周五 22:00,周末全天
- 19C 中增加了更多自动任务(如
auto index advisor),默认同样在维护窗口执行- 建议由应用侧或定制脚本控制统计信息收集,而非依赖 Oracle 自动任务
3.6 PROFILE 策略调整
-- oracle-19c
-- 解除密码策略限制,避免应用连接因密码过期而中断
ALTER PROFILE DEFAULT LIMIT FAILED_LOGIN_ATTEMPTS UNLIMITED;
ALTER PROFILE DEFAULT LIMIT PASSWORD_LIFE_TIME UNLIMITED;
ALTER PROFILE DEFAULT LIMIT PASSWORD_REUSE_TIME UNLIMITED;
ALTER PROFILE DEFAULT LIMIT PASSWORD_REUSE_MAX UNLIMITED;
ALTER PROFILE DEFAULT LIMIT PASSWORD_LOCK_TIME UNLIMITED;
ALTER PROFILE DEFAULT LIMIT PASSWORD_GRACE_TIME UNLIMITED;
ALTER PROFILE DEFAULT LIMIT PASSWORD_VERIFY_FUNCTION NULL;
-- 验证配置
SELECT * FROM dba_profiles WHERE profile = 'DEFAULT';
风险提示: 解除密码策略仅适用于内部受控环境,生产环境应按安全规范设置密码复杂度和过期策略。
3.7 重建 WM_CONCAT 行列转化函数
WM_CONCAT 是 Oracle 内部未公开的函数,从 12C 起被官方废弃(desupported)。如果 11G 应用代码中使用了该函数,需要在 19C 中重新创建。
-- oracle-19c — 重建 WM_CONCAT 函数
-- ⚠️ 19C 升级后 WMSYS 用户已被移除,需要先创建
CREATE USER WMSYS IDENTIFIED BY VALUES 'AC98877DE1297363A8CB7D7F085B3646'
DEFAULT TABLESPACE SYSAUX
QUOTA UNLIMITED ON SYSAUX
ACCOUNT LOCK;
-- 创建 Type
CREATE OR REPLACE TYPE WMSYS.WM_CONCAT_IMPL AS OBJECT
(
CURR_STR VARCHAR2(32767),
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT WM_CONCAT_IMPL) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT WM_CONCAT_IMPL,
P1 IN VARCHAR2) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN WM_CONCAT_IMPL,
RETURNVALUE OUT VARCHAR2,
FLAGS IN NUMBER) RETURN NUMBER,
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT WM_CONCAT_IMPL,
SCTX2 IN WM_CONCAT_IMPL) RETURN NUMBER
);
/
-- 创建 Type Body
CREATE OR REPLACE TYPE BODY WMSYS.WM_CONCAT_IMPL IS
STATIC FUNCTION ODCIAGGREGATEINITIALIZE(SCTX IN OUT WM_CONCAT_IMPL) RETURN NUMBER IS
BEGIN
SCTX := WM_CONCAT_IMPL(NULL);
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEITERATE(SELF IN OUT WM_CONCAT_IMPL,
P1 IN VARCHAR2) RETURN NUMBER IS
BEGIN
IF (CURR_STR IS NOT NULL) THEN
CURR_STR := CURR_STR || ',' || P1;
ELSE
CURR_STR := P1;
END IF;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATETERMINATE(SELF IN WM_CONCAT_IMPL,
RETURNVALUE OUT VARCHAR2,
FLAGS IN NUMBER) RETURN NUMBER IS
BEGIN
RETURNVALUE := CURR_STR;
RETURN ODCICONST.SUCCESS;
END;
MEMBER FUNCTION ODCIAGGREGATEMERGE(SELF IN OUT WM_CONCAT_IMPL,
SCTX2 IN WM_CONCAT_IMPL) RETURN NUMBER IS
BEGIN
IF (SCTX2.CURR_STR IS NOT NULL) THEN
SELF.CURR_STR := SELF.CURR_STR || ',' || SCTX2.CURR_STR;
END IF;
RETURN ODCICONST.SUCCESS;
END;
END;
/
-- 创建聚合函数及同义词
CREATE OR REPLACE FUNCTION WMSYS.wm_concat(P1 VARCHAR2)
RETURN VARCHAR2 AGGREGATE USING WMSYS.WM_CONCAT_IMPL;
/
CREATE PUBLIC SYNONYM WM_CONCAT_IMPL FOR WMSYS.WM_CONCAT_IMPL;
CREATE PUBLIC SYNONYM wm_concat FOR WMSYS.wm_concat;
GRANT EXECUTE ON WM_CONCAT_IMPL TO PUBLIC;
GRANT EXECUTE ON wm_concat TO PUBLIC;
版本差异说明:
- 11G:
WM_CONCAT作为内部函数存在,但从未被官方文档化- 12C/18C/19C:
WM_CONCAT被移除,需手动重建- 官方推荐使用
LISTAGG函数替代(Oracle 11g R2 起支持)版本适配建议: 优先推动应用代码将
WM_CONCAT替换为标准的LISTAGG。如需保留兼容性,使用上述手工方式重建:
-- Oracle 官方推荐替代方案
SELECT deptno, LISTAGG(ename, ',') WITHIN GROUP (ORDER BY ename) AS employees
FROM emp
GROUP BY deptno;
3.8 监听参数与兼容性配置
在 $ORACLE_HOME/network/admin/sqlnet.ora 中添加以下配置(注意:sqlnet.ora 的注释符是 #,不是 SQL 的 --):
# 允许低版本客户端连接 19C 数据库
SQLNET.ALLOWED_LOGON_VERSION_SERVER = 8
SQLNET.ALLOWED_LOGON_VERSION_CLIENT = 8
# 如果应用与数据库之间有防火墙,设置 DCD(Dead Connection Detection)
# 检测时间为 10 分钟
SQLNET.EXPIRE_TIME = 10
| 参数 | 默认值 | 建议值 | 说明 |
|---|---|---|---|
ALLOWED_LOGON_VERSION_SERVER |
12 | 8 | 允许 11G 及更低版本客户端连接 |
ALLOWED_LOGON_VERSION_CLIENT |
12 | 8 | 允许使用低版本密码验证协议 |
SQLNET.EXPIRE_TIME |
0(禁用) | 10(分钟) | 检测死连接,防止僵尸会话占用资源 |
版本差异说明:
- 11G 默认使用
ALLOWED_LOGON_VERSION=8(密码验证协议 8i 兼容)- 19C 默认最小版本为 12,需显式降低以兼容旧客户端
- 从安全角度,建议逐步升级客户端并恢复较高的
ALLOWED_LOGON_VERSION
3.9 恢复 Job 队列并做 19C 适应性调整
-- oracle-19c
-- 正式对外提供服务后,恢复 Job 队列进程
ALTER SYSTEM SET job_queue_processes = 1000 SCOPE = BOTH;
3.10 搭建 DataGuard 备库并 Switchover
升级完成后的新主库(原备库)与新部署的节点之间搭建 DataGuard。
说明:DataGuard 备库搭建(RMAN Duplicate)是整个升级流程的重要环节,涉及 listener.ora / tnsnames.ora 配置、备库参数文件准备、RMAN Duplicate 命令执行及同步验证等多个步骤。由于篇幅限制,本文聚焦于 Switchover 操作,RMAN Duplicate 的详细步骤请参考 Oracle 官方文档或另行整理。
3.10.1 RMAN Duplicate 搭建备库 — 关键配置要点
# 主库端 — 配置 tnsnames.ora 连接串
# 备库端 — 准备备库参数文件(pfile),核心参数包括:
# db_name=PRODDB, db_unique_name=PRODDBS
# log_archive_config='DG_CONFIG=(PRODDB,PRODDBS)'
# log_archive_dest_2='service=PRODDB ...'
# 执行 RMAN Duplicate
rman target sys/password@PRODDB auxiliary sys/password@PRODDBS <<EOF
DUPLICATE TARGET DATABASE
FOR STANDBY
FROM ACTIVE DATABASE
DORECOVER
NOFILENAMECHECK;
EOF
3.10.2 主备库 Switchover 操作
-- oracle-19c
-- ========== 主库端(新主库,即原备库升级后的库) ==========
-- 检查可切换状态
SELECT switchover_status FROM v$database;
-- TO STANDBY:可正常切换
-- SESSIONS ACTIVE:有活动会话,需 WITH SESSION SHUTDOWN
-- 开始切换
ALTER DATABASE COMMIT TO SWITCHOVER TO PHYSICAL STANDBY WITH SESSION SHUTDOWN;
-- 重启原主库为备库角色
SHUTDOWN IMMEDIATE;
STARTUP MOUNT;
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT;
-- ========== 新节点备库端 ==========
-- 验证可切换状态
SELECT switchover_status FROM v$database;
-- TO PRIMARY:可切换为主库
-- 切换为主库
ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY;
-- 重启
SHUTDOWN IMMEDIATE;
STARTUP;
-- ========== 验证角色 ==========
SELECT switchover_status, database_role FROM v$database;
3.11 监听及网络配置检查
确认 sqlnet.ora 和 listener.ora 在新主库节点上已正确配置。具体检查项:
# 确认监听状态
lsnrctl status
# 检查 listener.ora 中 STATIC_SERVICE 是否正确指向 19c 实例
cat $ORACLE_HOME/network/admin/listener.ora
# 检查 tnsnames.ora 连接串是否指向新主库
cat $ORACLE_HOME/network/admin/tnsnames.ora
# 测试连接
sqlplus sys/password@PRODDB as sysdba
4. 升级后操作与验证
4.1 升级后检查清单
| 类别 | 检查项 | 说明 |
|---|---|---|
| 操作系统 | /etc/fstab |
确认文件系统挂载正确 |
| crontab | 检查定时任务及对应脚本是否完整 | |
/etc/sysctl.conf |
检查内核参数和大页内存 | |
/etc/security/limits.conf |
Oracle 及应用用户资源限制 | |
环境变量 bash_profile |
各用户的环境变量是否更新到 19C | |
| 归档清理脚本 | 同步至新机器并确认正常运行 | |
| 数据库 | sqlnet.ora 兼容性配置 | ALLOWED_LOGON_VERSION 参数 |
| tnsnames.ora / listener.ora | 连接串完整性检查 | |
| Oracle Directory 目录 | 确认业务需要的 Directory 对象均已创建 | |
| 初始化参数比对 | 与 11G 参数对比,确认隐含参数和业务参数一致性 | |
| 密码文件同步 | 主备库密码文件一致性 | |
| One-off Patch / PSU | 确认补丁清单完整 | |
| Public 同义词、dblink | 确认业务相关对象无缺失 | |
| Profile、密码策略 | 确认策略与业务需求匹配 | |
| 归档模式、FORCE LOGGING | 确认 DataGuard 前置要求 | |
| 失效对象 | 确认核心业务 Schema 中无失效对象 | |
| COMPATIBLE 参数 | 确认已设为 19.0.0 |
|
| 其他 | 监控系统(Zabbix / Splunk) | 确认采集正常 |
| 备份系统(NBU / CDM) | 确认备份脚本适配 19C 并测试备份 |
4.2 crontab 部署
# oracle 用户 crontab
4 5 6 * * /home/oracle/monitor/sql/gather_stats.sh
*/1 * * * * /usr/bin/find /tadata/arclogs -type f -mmin +600 | xargs -r rm -f
⚠️ 升级后务必检查 crontab 中脚本是否适配了 19C 的
$ORACLE_HOME路径。
4.3 通知应用组启动
在确认数据库升级无异常后,通知应用组启动应用程序,并在应用启动后监控数据库会话和性能指标至少 30 分钟,确认无异常。
5. 回退方案
5.1 升级过程中操作失败的回退
如果升级操作(数据字典升级、参数调整等)在执行过程中失败:
- 尚未修改 COMPATIBLE 参数 — 数据库仍可回退到 11G 版本
- 回退操作步骤:
- 放弃当前升级操作
- 用升级前的 RMAN 全备恢复原备库节点上的 11G 数据库
- 在原主库上以 11G 软件打开,恢复业务
- 重建 DataGuard 同步关系
⚠️ 如果已完成
STARTUP UPGRADE且catupgrd.sql已部分执行,数据库可能处于中间态,不一定能用 11G 软件重新打开。最安全的做法是从 RMAN 全备恢复。
5.2 升级成功但后期出现问题的回退
如果升级完成且业务已上线,但后续出现严重性能问题或功能故障:
- 保留原主库数据 — 在升级流程中,原主库节点已被重装操作系统,11G 环境已不存在,但升级前的 RMAN 全备数据仍然可用
- 优先解决问题 — 通过参数调整、补丁应用等手段尝试在 19C 上解决
- 极端情况回退 — 使用升级前的 RMAN 全备将数据库恢复至 11G 版本(耗时较长,需预留充足恢复时间)
风险提示:
- 原主库节点已重装,11G 环境不存在,回退需重新装 11G + RMAN 恢复,代价极高
- 升级前 RMAN 全备是唯一的兜底,务必确保可用且已验证可恢复
6. 总结与注意事项
核心要点
- 升级策略选择:备库先行升级 + 主备切换的方式最大程度缩短了停机窗口,同时保留了完整回退能力
- 并行执行:数据字典升级与新节点部署同步进行,是缩短停机时间的关键
- 升级前 RMAN 全备:必须执行,是升级失败时唯一的兜底手段,备份应存放在与升级环境分离的存储上
- PREUPGRADE 预检查:必须执行,不可跳过。它能提前发现大量潜在问题并生成自动修复脚本
- SPFILE 废弃参数清理:11g 拷贝到 19c 后
background_dump_dest、user_dump_dest、core_dump_dest等废弃参数不影响启动,升级完成后根据 alert 日志提示逐项清理 - COMPATIBLE 参数:升级完直接改,改完回不去
- 优化器参数:19C 引入了大量新的优化器特性,从 11G 升级后务必关闭可能导致执行计划突变的特性
- WM_CONCAT 函数:11G 中广泛使用的未公开函数,升级后需手工重建或推动代码迁移至
LISTAGG - 客户端兼容性:务必配置
ALLOWED_LOGON_VERSION使旧客户端能连接 19C
常见避坑指南
| 坑点 | 规避措施 |
|---|---|
| 回收站未清空导致升级卡死 | PURGE DBA_RECYCLEBIN,升级前必做 |
| 升级前未做 RMAN 全备导致无法回退 | 升级前必须做全备,存放在与升级环境分离的存储上 |
| spfile 含 11g 废弃参数 | 升级完成后看 alert 日志,逐项 reset background_dump_dest、user_dump_dest、core_dump_dest |
| 时区升级未执行导致 TIMESTAMP 类型异常 | 完整执行 DBMS_DST 三步流程(begin → upgrade → end),完成后重启数据库 |
| 未关闭自动维护任务导致升级后资源争抢 | 关闭 auto space/sql/stats 三大自动任务 |
COMPATIBLE 改完回不去 |
升级完直接改就行,清楚后果就行 |
| 密码策略导致应用连接失败 | 升级后第一时间调整 DEFAULT PROFILE 密码策略 |
| 监听未配置兼容参数导致客户端连接报错 | sqlnet.ora 中配置 ALLOWED_LOGON_VERSION=8 |
| 19C 自适应游标共享导致执行计划漂移 | 关闭 _optimizer_adaptive_cursor_sharing 等优化器参数 |
_serial_direct_read 默认为 AUTO 导致 Buffer Cache 命中率下降 |
设为 NEVER,适合 OLTP 为主的系统 |
参考文档
- 本文基于 Oracle 11.2.0.4 至 19.23 升级实践经验整理
- Oracle Database Upgrade Guide 19c
- MOS Doc ID 2532998.1 — Oracle Database 19c Upgrade Guide and Checklist
- MOS Doc ID 884522.1 — Complete Checklist for Manual Upgrades to 19c
- Oracle 19c SQL Language Reference — LISTAGG 函数文档
- Oracle 19c Net Services Reference — SQLNET.ALLOWED_LOGON_VERSION 参数




