news 2026/11/4 21:52:03

Oracle 19c DSTv35补丁:OPatch成功不等于时区生效

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Oracle 19c DSTv35补丁:OPatch成功不等于时区生效

简介:这份补丁包面向需要处理 Oracle 19c 时区版本问题的 DBA 与数据库运维人员,核心用于把 TSTZ 时区文件升级到 35 版本,以规避 ORA-39405 报错。需要特别留意:该补丁仅适用于 Oracle 19.3 环境,其他 19c 版本直接使用可能报错,作者另提供适配全部 19c 版本的 35 时区补丁。压缩包共 10 个文件,以 6 个 dat 数据文件、2 个 xml 配置文件和 2 个 txt 说明文件为主,整体约 394KB,体积小巧但组成清晰,便于按说明完成补丁应用与版本核对。补丁包已有 2570 人学习下载,读者可据此排查当前时区版本、理解补丁文件构成,并获取针对 ORA-39405 的排错思路;结合 v$timezone_file 查询结果,也能更清晰地判断数据库时区状态与后续升级路径。

1. Oracle 19c 时区 35 补丁 p31335037:为什么 opatch 成功不等于 DSTv35 生效

某开发在 Linux x86-64 上给 Oracle 19c 19.0.0 打时区版本 35 补丁,zip 包是 p31335037_190000_Linux-x86-64.zip。opatch apply 返回成功,datapatch 也跑完了,结果一查V$TIMEZONE_FILE还是 32,应用里写America/New_York照样报 ORA-01882。这个场景太常见:补丁只把$ORACLE_HOME/oracore/zoneinfo下的文件换成了 35,数据库当前使用的时区版本并没有自动跟过去。装不好不会立刻崩库,但跨时区业务、TSTZ 字段、调度任务会陆续翻车。这套流程适合正在给 19c 单实例或 CDB 环境补 DSTv35 的读者,也适合需要把补丁步骤写进变更单的运维。

2. 装前核对:19.0.0 的 ORACLE_HOME、OPatch 版本和补丁包里的 zoneinfo 文件

2.1 先查 V$TIMEZONE_FILE 和 DST_UPGRADE_STATE,别急着解压

时区补丁和普通 RU 的差别在于:它有两层版本。一层是$ORACLE_HOME/oracore/zoneinfo里的时区文件版本,另一层是数据库属性里记录的当前时区版本。只打补丁不升级数据库时区,文件版本会变,数据库属性不一定变。装前先把这两层都看清楚,后面才知道自己到底停在哪一步。

-- 查看每个容器的时区文件版本;CDB 环境下会多行 SELECT con_id, filename, version FROM v$timezone_file ORDER BY con_id; -- 查看数据库当前使用的时区版本和升级状态 SELECT property_name, property_value FROM database_properties WHERE property_name IN ( 'DST_UPGRADE_STATE', 'DST_PRIMARY_TT_VERSION', 'DST_SECONDARY_TT_VERSION' );

第一段查询里VERSION是文件版本,常见值是 32、34、35;FILENAME能看到当前加载的是timezone_32.dat还是timezlrg_35.dat。第二段查询里DST_PRIMARY_TT_VERSION才是数据库当前使用的时区版本,DST_UPGRADE_STATE为NONE表示没有处于升级中间态。如果V$TIMEZONE_FILE已经是 35,但DST_PRIMARY_TT_VERSION还是 32,说明补丁文件装上了,数据库时区没有升级,后面必须走DBMS_DST。

提示:CDB 环境不要只在 CDB$ROOT 看。切到每个 PDB 执行一次同样的查询,PDB 的时区版本可能和根容器不一致。

2.2 核对 OPatch 版本与 ORACLE_HOME,别让系统 PATH 抢跑

Oracle 补丁最怕调错 OPatch。机器上可能同时存在 Grid 的 OPatch、旧版 Oracle Home 的 OPatch,甚至/usr/local/bin下有一个同名脚本。应用前先把环境变量钉死,所有命令都用绝对路径或确认$ORACLE_HOME/OPatch在 PATH 前面。

# 按实际路径修改,不要直接照抄生产路径 export ORACLE_BASE=/u01/app/oracle export ORACLE_HOME=$ORACLE_BASE/product/19.0.0/dbhome_1 export ORACLE_SID=ORCLCDB export PATH=$ORACLE_HOME/bin:$ORACLE_HOME/OPatch:$PATH export LD_LIBRARY_PATH=$ORACLE_HOME/lib:$LD_LIBRARY_PATH # 确认当前会话用的是目标 Home echo $ORACLE_HOME which opatch opatch version

echo $ORACLE_HOME用来确认没有切错 Home,which opatch必须指向$ORACLE_HOME/OPatch/opatch。opatch version低于 12.2.0.1.17 时,19c 的部分补丁会报格式不支持,常见做法是先升级 OPatch 再打补丁,不要硬上。环境变量表可以按下面这样核对:

变量作用常见错误
ORACLE_HOME指定要打补丁的 19c Home指到 Grid Home 或旧版本 Home
ORACLE_SID指定要启动的实例CDB 环境写成 PDB 名
PATH决定 opatch、sqlplus 走哪个版本系统 PATH 抢先
LD_LIBRARY_PATH决定动态库加载顺序混入其他 Home 的 lib

2.3 补丁包解压后先读 README,确认是否需要 datapatch

拿到p31335037_190000_Linux-x86-64.zip后,不要直接opatch apply。先测试压缩包完整性,再解压到独立目录,读补丁自带的 README。README 会写清楚这是纯时区文件补丁,还是包含 SQL 变更、需要datapatch的补丁。两类补丁的收尾动作不一样,跳过 README 最容易在最后一步踩坑。

# 建立独立补丁目录,避免和旧补丁混在一起 mkdir -p /u01/patches/31335037 cd /u01/patches/31335037 # 测试 zip 完整性并解压 unzip -t /path/to/p31335037_190000_Linux-x86-64.zip unzip -q /path/to/p31335037_190000_Linux-x86-64.zip # 进入补丁目录,先看 README 和文件清单 cd 31335037 ls -l cat README.txt

unzip -t只做完整性检查,不解压;unzip -q静默解压到当前目录。进入31335037后重点看README.txt里的 “Patch Installation” 和 “Post Installation” 两段。如果 README 明确写了要跑datapatch,就在opatch apply之后执行;如果只要求更新 zoneinfo 文件,就不要额外跑不必要的 SQL 补丁。补丁目录里通常能看到files/oracore/zoneinfo/timezone_35.dat、timezlrg_35.dat这类文件,确认目标版本是 35 再往下走。

2.4 备份与回退窗口:RMAN 全备和 opatch rollback 的边界

时区补丁本身可以opatch rollback,但数据库时区数据一旦升级到 35,回退就不是一条命令的事。装前至少做一次 RMAN 全备,并确认归档日志可用。不要用“补丁很小”来省这一步,时区升级涉及 TSTZ 数据扫描,出问题再找备份就被动了。

# 在数据库打开状态下做一次全备,归档日志也要保留 rman target / RMAN> backup database plus archivelog; RMAN> backup current controlfile;

backup database plus archivelog会备份数据文件和归档日志,backup current controlfile单独保留控制文件。回退边界要记清楚:opatch rollback -id 31335037只能回退 Oracle Home 里的二进制和文件,回退不了已经通过DBMS_DST升级的数据库时区数据。所以要么在升级数据库时区之前做好快照,要么把备份恢复方案写进变更单。

3. 应用 p31335037:opatch apply、datapatch 与 DBMS_DST 升级 35 的完整链路

3.1 停实例与监听:单实例和 RAC 的停法不一样

应用时区补丁前要不要停库,以补丁 README 为准。独立时区补丁常见做法是关闭所有实例和监听,避免文件被占用。单实例可以用shutdown immediate,RAC 用srvctl按节点停。不要凭“上次没停也能过”的经验硬来,时区文件被进程持有的时候,opatch apply可能报文件忙,回滚也麻烦。

# 单实例:用 sysdba 关闭数据库 sqlplus -s / as sysdba <<'SQL' shutdown immediate; exit SQL # RAC:按数据库和监听停,具体节点名按实际环境改 srvctl stop database -d ORCLCDB srvctl stop listener

单实例的shutdown immediate会干净关闭实例,避免带事务强杀。RAC 的srvctl stop database -d ORCLCDB会停整个数据库,如果 README 允许滚动,再按节点单独停实例、打补丁、启动。停监听是为了避免客户端在补丁过程中连进来,减少文件句柄占用。停完用ps -ef | grep pmon确认没有残留 Oracle 进程。

3.2 opatch apply 的静默参数与输出判读

补丁目录里执行opatch apply时,建议显式带-oh $ORACLE_HOME,避免 OPatch 从环境推断错 Home。-silent只是减少交互,不是跳过检查;输出里仍然要看到 “OPatch succeeded”。如果出现 conflict,先看冲突补丁号,不要直接加-force。

cd /u01/patches/31335037/31335037 # 显式指定 ORACLE_HOME,静默应用补丁 $ORACLE_HOME/OPatch/opatch apply -oh $ORACLE_HOME -silent # 应用后确认补丁已注册 $ORACLE_HOME/OPatch/opatch lspatches | grep -i 31335037

-oh指定目标 Oracle Home,-silent让 OPatch 不逐项询问。输出里重点看三处:补丁号是否为 31335037、是否有 “Patch is already applied”、最后是否为 “OPatch succeeded”。opatch lspatches能确认补丁进入 inventory。如果这里报 “Patch 31335037 conflicts with patch ...”,常见原因是之前打过包含时区文件的 RU,需要按 README 判断是覆盖还是先回退,不要用-force把冲突压过去。

3.3 datapatch -verbose 在 CDB$ROOT 下跑,PDB 怎么办

补丁 README 要求跑datapatch时,先把数据库启动到 OPEN 状态,再在 CDB$ROOT 下执行。datapatch会扫描补丁里的 SQL,注册到数据库,CDB 环境会处理容器。不要在每个 PDB 里重复跑,也不要在数据库 MOUNT 状态跑,否则容易报 ORA-00604 或 ORA-56927。

# 启动监听和数据库,确认状态是 OPEN srvctl start listener srvctl start database -d ORCLCDB sqlplus -s / as sysdba <<'SQL' SELECT name, open_mode FROM v$database; SELECT con_id, name, open_mode FROM v$containers; exit SQL # 在 CDB$ROOT 下执行 datapatch cd $ORACLE_HOME/OPatch ./datapatch -verbose

datapatch -verbose会输出每个 SQL 补丁的应用结果,重点看最后是否有 “done” 和 “CDB$ROOT” 相关记录。数据库必须是 OPEN,PDB 也要处于 READ WRITE 或至少 OPEN 状态,否则补丁 SQL 可能跳过某个容器。-verbose不是必填,但排错时没有它很难定位是哪个容器失败。如果 README 明确说这是纯时区文件补丁、不需要 datapatch,这一步可以跳过,直接进入DBMS_DST。

3.4 DBMS_DST 升级到 35:PREPARE、BEGIN_UPGRADE、END_UPGRADE

补丁文件装好后,数据库默认还在旧时区版本。要让DST_PRIMARY_TT_VERSION变成 35,需要走DBMS_DST。常见顺序是先BEGIN_PREPARE(35)做预检查,再END_PREPARE,然后BEGIN_UPGRADE(35),最后END_UPGRADE(35)。如果表多、TSTZ 列多,PREPARE 会花时间,但能提前暴露受影响对象,不要省。

-- 在 CDB$ROOT 执行;每个 PDB 也需要单独执行 BEGIN DBMS_DST.BEGIN_PREPARE(35); END; / -- 查看准备状态和当前时区版本 SELECT property_name, property_value FROM database_properties WHERE property_name IN ( 'DST_UPGRADE_STATE', 'DST_PRIMARY_TT_VERSION', 'DST_SECONDARY_TT_VERSION' ); BEGIN DBMS_DST.END_PREPARE; END; /

BEGIN_PREPARE(35)的35是目标时区版本,不是数据库版本。准备阶段会扫描可能受时区规则影响的表,DST_UPGRADE_STATE可能从NONE变成PREPARE。END_PREPARE结束准备。确认没有异常后,再执行升级:

BEGIN DBMS_DST.BEGIN_UPGRADE(35); END; / -- 升级后确认主版本和状态 SELECT property_name, property_value FROM database_properties WHERE property_name IN ( 'DST_UPGRADE_STATE', 'DST_PRIMARY_TT_VERSION' ); BEGIN DBMS_DST.END_UPGRADE(35); END; /

BEGIN_UPGRADE(35)会把数据库当前时区版本切到 35,END_UPGRADE(35)做收尾。升级完成后DST_UPGRADE_STATE应回到NONE,DST_PRIMARY_TT_VERSION应为 35。CDB 环境要在 CDB$ROOT 和每个 PDB 分别确认,PDB 不会因为根容器升级就自动完成。升级期间不要跑大批量 TSTZ 写入,避免把业务问题和时区升级问题混在一起。

4. 避坑排查:时区补丁装完常见 ORA-56927、ORA-01882 与版本不涨的现场

4.1 现象:opatch apply 报 “Patch 31335037 conflicts with patch ...”

现象是opatch apply刚跑就退出,提示补丁冲突,或者报 “OPatch failed with error code 73”。原因通常是目标 Home 里已经存在包含时区文件的 RU 或其他时区补丁,inventory 认为文件会被覆盖;也可能是ORACLE_HOME指到了另一个 Home。解决时先用opatch lspatches看现有补丁,再读 p31335037 的 README 确认是否允许共存。不要直接加-force,先判断冲突补丁是否已经带了 DSTv35 文件;如果只是 OPatch 版本太旧,升级 OPatch 后重跑。冲突解决不了就回退冲突补丁或换维护窗口,别在 production Home 上反复试。

4.2 现象:datapatch 报 ORA-56927 或 ORA-00604

现象是datapatch -verbose跑到一半报 ORA-56927,或者 ORA-00604 带 ORA-06512 堆栈。原因常见于数据库没有 OPEN、PDB 没有打开、或者datapatch在错误容器里执行。解决时先查v$database.open_mode和v$containers.open_mode,确保 CDB 和 PDB 都是 OPEN;然后在 CDB$ROOT 下重跑datapatch -verbose,不要在每个 PDB 里重复执行。如果报错指向某个具体 SQL,去看$ORACLE_HOME/OPatch/datapatch日志,确认是补丁 SQL 不适用还是权限问题。已经部分应用时不要强行重跑,先看dba_registry_sqlpatch状态。

4.3 现象:补丁应用成功,V$TIMEZONE_FILE 仍是 32

现象是opatch lspatches能看到 31335037,但V$TIMEZONE_FILE还是 32,DST_PRIMARY_TT_VERSION也没变。原因是只应用了补丁文件,没有执行DBMS_DST升级数据库时区。解决时先确认$ORACLE_HOME/oracore/zoneinfo/timezlrg_35.dat存在,再按BEGIN_PREPARE(35)、BEGIN_UPGRADE(35)、END_UPGRADE(35)走一遍。注意V$TIMEZONE_FILE是文件版本,DST_PRIMARY_TT_VERSION是数据库使用版本,两个都要看。只改文件不升级数据库,应用里仍然可能报时区区域问题。

4.4 现象:RAC 另一个节点查不到补丁

现象是节点一opatch lspatches有 31335037,节点二没有,或者节点二启动后报时区文件不一致。原因是 RAC 的 Oracle Home 如果是本地盘,每个节点都要单独opatch apply;如果是共享 Home,才可能只打一次。解决时先确认 Home 是共享还是本地,本地 Home 按节点停实例、apply、启动,最后只在一个节点跑datapatch。不要在一个节点打完后直接启动另一个节点,文件版本不一致会让时区行为看起来像“玄学”。滚动顺序和停库范围以 README 为准,README 要求全停就全停。

4.5 现象:升级时区时报 ORA-01882 时区区域未找到

现象是应用连接数据库后写America/New_York报 ORA-01882,或者DBMS_DST升级过程中报时区区域找不到。原因是客户端或数据库端加载的时区文件还是旧版本,也可能是 OJVM 或客户端 Home 没有同步更新。解决时先在数据库端查V$TIMEZONE_FILE和DST_PRIMARY_TT_VERSION,确认数据库已经是 35;再查客户端$ORACLE_HOME/oracore/zoneinfo是否有 35 文件。JDBC 客户端要确认驱动和orai18n.jar的版本,别只换数据库端。升级后重启客户端连接池,避免旧会话继续用旧时区缓存。

5. 验证 DSTv35:V$TIMEZONE_FILE、DST_UPGRADE_STATE 和一条 TSTZ 写入测试

装完不要只看opatch lspatches。先查文件版本和数据库属性,再写一条 TSTZ 数据做冒烟。下面三条查询能覆盖大多数现场:

-- 文件版本:应为 35 SELECT con_id, filename, version FROM v$timezone_file ORDER BY con_id; -- 数据库当前时区版本:应为 35,状态应为 NONE SELECT property_name, property_value FROM database_properties WHERE property_name IN ( 'DST_UPGRADE_STATE', 'DST_PRIMARY_TT_VERSION' ); -- 写一条带时区的时间戳,验证区域名可识别 CREATE TABLE tz_check ( id NUMBER, ts TIMESTAMP WITH TIME ZONE ); INSERT INTO tz_check VALUES ( 1, TIMESTAMP '2024-07-01 12:00:00 America/New_York' ); SELECT id, ts, TZ_OFFSET('America/New_York') FROM tz_check;

第一条查询里VERSION为 35 只代表文件到位;第二条查询里DST_PRIMARY_TT_VERSION为 35 且DST_UPGRADE_STATE为NONE,才代表数据库时区升级收尾完成。第三条插入语句如果不再报 ORA-01882,说明区域名解析正常。CDB 环境把这三条在 CDB$ROOT 和每个 PDB 各跑一次,别只看根容器。

检查点期望值看什么
V$TIMEZONE_FILE.VERSION35文件是否到位
DST_PRIMARY_TT_VERSION35数据库是否真正升级
DST_UPGRADE_STATENONE是否还在升级中间态
TSTZ 插入成功区域名是否可解析

血泪经验是:opatch apply成功只说明文件进了 Home,datapatch成功只说明 SQL 补丁注册了,这两个都不等于 DSTv35 已经生效。从那以后我每次打时区补丁都强制走一遍“查文件版本、查数据库属性、写一条 TSTZ”的流程,不把 OPatch 的成功输出当终点,也不给自己留“以为装好了”的后悔药。需要复现这套流程的,直接取p31335037_190000_Linux-x86-64.zip,按上面的顺序走一遍。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/11/4 21:47:24

Windows下WSL2搭建Node.js与pnpm前端开发环境指南

1. 项目概述 最近在Windows环境下折腾本地网页开发环境时&#xff0c;发现很多前端开发者都会遇到一个典型问题&#xff1a;如何在Windows系统上快速搭建完整的Linux开发环境&#xff0c;并顺利运行基于Node.js的前端项目&#xff1f;这个问题看似简单&#xff0c;但实际上涉及…

作者头像 李华
网站建设 2026/11/4 21:42:58

Moo0工具箱:轻量化效率工具的核心功能与应用场景

1. 工具类软件的价值与选择逻辑在数字化工作场景中&#xff0c;效率工具的选择往往决定了我们的生产力天花板。不同于大型专业软件的笨重&#xff0c;轻量化工具箱类产品以其模块化设计、即开即用的特性&#xff0c;成为许多从业者的日常必备。Moo0工具箱正是这类产品中的典型代…

作者头像 李华
网站建设 2026/11/4 21:42:35

规格驱动开发:用Markdown让AI写代码不再“抽卡”

1. 当AI写代码开始“抽卡”&#xff0c;问题到底出在哪用AI写代码这件事&#xff0c;很多人应该都有类似的体验&#xff1a;同一个需求&#xff0c;早上问它给你生成一版能跑的&#xff0c;下午再问一遍&#xff0c;它给你换了个架构、换了个命名风格&#xff0c;甚至把之前明确…

作者头像 李华
网站建设 2026/11/4 21:39:27

MATLAB二维点云配准:ICP+kd-tree+SVD实现

简介&#xff1a;这份面向点云配准初学者与MATLAB实践者的学习材料&#xff0c;围绕二维点云配准中传统ICP匹配不准、易受异常点干扰以及容易陷入局部最优等问题&#xff0c;给出结合kd-tree、指派问题、动态阈值与Delaunay三角剖分的改进思路。内容以LaTeX生成的论文式说明为主…

作者头像 李华
网站建设 2026/11/4 21:37:11

AI Agent 知识获取之道:RAG 索引、检索与生成全解析

做 AI Agent 应用&#xff0c;最难的不是让大模型会聊天&#xff0c;而是让它知道业务知识从哪里来。我见过太多 Agent 项目&#xff0c;前面意图识别、工具调用都跑通了&#xff0c;一到真实业务问题就翻车——模型训练时没见过你们公司的产品目录&#xff0c;也没读过你们最新…

作者头像 李华