资讯动态

Oracle 19c时区补丁p31335037实战指南:修复夏令时漂移

发布时间:2026/10/27 10:49:25 来源:尧图企业网站定制
简介本资源是 Oracle Database 19c19.0.0.0.190416DBRU专用的时区版本35补丁包专为解决 ORA-39405 错误及 TSTZTime Zone版本不匹配问题设计适用于已部署 Oracle 19.3 版本的 Linux-x86-64 环境用于将数据库时区文件升级至 TSTZ v35。补丁经官方 Bug#31335037 修复验证安装后可通过 SELECT * FROM v$timezone_file; 命令确认生效。压缩包共10个文件含6个核心 dat 数据文件承载时区定义、2个 xml 配置文件描述时区映射关系及2个 txt 说明文档含安装指引与注意事项结构精简、部署路径明确总大小仅394KB便于快速集成与验证。目前已有2567人学习下载适合 DBA 及数据库运维人员在生产环境升级、灾备同步或跨版本迁移中精准应对时区兼容性问题提供即用型修复能力与可复现的版本验证方法。1. Oracle 19c 时区补丁 P31335037装错版本或漏打补丁数据库时间就“穿越”了某高校实验室部署一套跨时区日志分析系统Oracle 19c 数据库跑在 Linux x86-64 环境下。上线第三天运维同学发现凌晨 2:15 的交易记录被写成 1:15——不是程序逻辑错也不是应用层时区设错而是SYSTIMESTAMP和CURRENT_TIMESTAMP返回值在夏令时切换窗口期集体偏移一小时。查到最后是数据库底层时区文件timezone.dat仍停留在 2019 年的旧规则而操作系统已更新至 IANA 2021a 时区数据。Oracle 官方明确要求19.0.0 基础版必须打上时区版本 35 补丁p31335037才能支持 2021 年起全球主要地区夏令时变更规则。这个补丁不依赖 OPatch 升级、不触发数据库重启但一旦跳过所有基于TIMESTAMP WITH TIME ZONE类型的审计、ETL、报表时间戳都会“玄学漂移”。它不是可选优化项而是 19.0.0 在生产环境存活的底线配置。本文专为已装好 Oracle 19.0.0 数据库、但尚未同步时区规则的 DBA 和部署工程师而写——不讲原理空话只列清该下哪个包、解压到哪、OPatch 怎么调、打完怎么验、打崩了怎么救。2. 下载与校验认准 p31335037_190000_Linux-x86-64.zip别被同名补丁带偏Oracle 补丁命名体系里“p31335037” 是补丁编号Patch Number“190000” 表示适用版本19c Release 1即 19.0.0“Linux-x86-64” 是平台标识。注意同编号补丁有多个子版本如 p31335037_191000_Linux-x86-64.zip 对应 19.10绝不能混用。19.0.0 数据库只能用 190000 后缀包否则 OPatch 会直接拒绝加载。2.1 从 Oracle Support 下载补丁包需 MOS 账号访问 https://support.oracle.com → 登录 → 搜索补丁号31335037→ 进入补丁详情页 → 找到p31335037_190000_Linux-x86-64.zip→ 下载。提示页面可能同时列出p31335037_190000_Generic.zip通用版含所有平台和p31335037_190000_Linux-x86-64.zipLinux 专用精简版。优先选后者——体积小约 12MB、解压快、无冗余文件且 Oracle 官方文档明确推荐 Linux 环境使用此包。2.2 校验 ZIP 包完整性防下载中断/传输损坏下载完成后务必校验 SHA256 值。Oracle Support 页面补丁详情区底部会提供官方校验值通常在 “Patch Information” 或 “Files” 标签页内。以当前最新发布版本为例2024 年 3 月更新$ sha256sum p31335037_190000_Linux-x86-64.zip a7e9b8c2d1f0e3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c8d9e0f1a2b3c4d5e6f7a8 p31335037_190000_Linux-x86-64.zip若输出值不匹配说明文件损坏需重新下载。这是后续所有操作的前提——补丁包损坏会导致 OPatch 解析失败报错OPatch failed with error code 73且无明确提示原因。2.3 解压到临时目录不直解到 $ORACLE_HOME将 ZIP 包解压到独立临时目录如/tmp/patch_p31335037而非直接解压到$ORACLE_HOME下$ mkdir -p /tmp/patch_p31335037 $ unzip p31335037_190000_Linux-x86-64.zip -d /tmp/patch_p31335037 $ ls -l /tmp/patch_p31335037/ total 8 drwxr-x--- 3 oracle oinstall 4096 Mar 15 10:22 31335037/ -rw-r----- 1 oracle oinstall 1234 Apr 2 09:15 README.txt解压后核心目录是31335037/数字命名内含etc/元数据、files/实际替换文件、custom/自定义脚本等子目录。关键点files/oracore/zoneinfo/下的timezone.dat文件就是本次要升级的目标——它将从旧版TZ version 32覆盖为新版TZ version 35。不直解到$ORACLE_HOME是为避免权限混乱和误删风险临时目录也方便打补丁失败后一键清理。2.4 验证补丁元数据是否匹配当前数据库版本进入解压后的补丁目录检查etc/config/actions.xml中声明的兼容版本$ grep -A 5 oraclehome /tmp/patch_p31335037/31335037/etc/config/actions.xml oraclehome version19.0.0.0.0/version min_version19.0.0.0.0/min_version max_version19.0.0.0.0/max_version /oraclehome确认version和min_version均为19.0.0.0.0。若显示19.10.0.0.0说明你误下了 19.10 补丁包必须换回 190000 后缀版本。这是新手最常踩的坑看到补丁号相同就以为通用结果 OPatch 报错Prerequisite check CheckActiveFilesAndExecutables failed卡在预检阶段。3. 打补丁前准备停监听、关实例、配 OPatch三步缺一不可时区补丁虽不重启数据库但要求$ORACLE_HOME下无活跃进程占用oracore/zoneinfo/timezone.dat文件。Linux 系统中该文件被 Oracle 后台进程如 PMON、DBW0以只读方式映射进内存若强行覆盖会导致进程异常终止。因此必须先关闭数据库实例和监听器再执行 OPatch。这不是 Oracle 官方文档的“建议”而是 Linux 文件锁机制下的硬性约束。3.1 确认当前 OPatch 版本 ≥ 12.2.0.1.24Oracle 19c 要求 OPatch 最低版本为 12.2.0.1.242020 年 10 月发布。低于此版本无法识别 19c 的补丁结构会报错OPatch failed with error code 266。检查命令$ $ORACLE_HOME/OPatch/opatch version OPatch Version: 12.2.0.1.28 OPatch succeeded.若版本过低如显示12.2.0.1.12需先升级 OPatch从 MOS 下载最新 OPatch补丁号6880880解压覆盖$ORACLE_HOME/OPatch/目录保留原目录权限验证opatch version输出 ≥12.2.0.1.24注意升级 OPatch 本身无需停库但必须确保$ORACLE_HOME下无其他 OPatch 进程运行如ps -ef | grep opatch。3.2 关闭数据库实例与监听器以 oracle 用户执行$ sqlplus / as sysdba EOF SHUTDOWN IMMEDIATE; EXIT; EOF $ lsnrctl stop LSNRCTL for Linux: Version 19.0.0.0.0 - Production on 02-APR-2024 09:30:15 Copyright (c) 1991, 2019, Oracle. All rights reserved. Connecting to (DESCRIPTION(ADDRESS(PROTOCOLIPC)(KEYEXTPROC1521))) The command completed successfully关键验证点执行ps -ef | grep -E (ora_|tnslsnr)应无任何 Oracle 进程输出。若有残留如ora_pmon_SID说明SHUTDOWN IMMEDIATE未完全生效需强制kill -9进程后再试。这是后续打补丁失败的头号原因——进程未彻底退出导致文件被锁OPatch 报错OUI-67073: Unable to lock Central Inventory。3.3 设置环境变量并验证补丁可读性确保当前 shell 已正确设置ORACLE_HOME、ORACLE_SID、PATH$ echo $ORACLE_HOME /u01/app/oracle/product/19c/dbhome_1 $ echo $ORACLE_SID orcl $ which opatch /u01/app/oracle/product/19c/dbhome_1/OPatch/opatch然后验证 OPatch 能正确读取补丁包$ $ORACLE_HOME/OPatch/opatch prereq CheckConflictAgainstOHWithDetail -phBaseDir /tmp/patch_p31335037/31335037 Oracle Interim Patch Installer version 12.2.0.1.28 Copyright (c) 2023, Oracle Corporation. All rights reserved. PREREQ session Oracle Home : /u01/app/oracle/product/19c/dbhome_1 Central Inventory : /u01/app/oraInventory from : /u01/app/oracle/product/19c/dbhome_1/oraInst.loc OPatch version : 12.2.0.1.28 OUI version : 12.2.0.7.0 Log file location : /u01/app/oracle/product/19c/dbhome_1/cfgtoollogs/opatch/opatch2024-04-02_09-35-22AM_1.log Invoking prereq checkconflictagainstohwithdetail Prereq checkConflictAgainstOHWithDetail passed. OPatch succeeded.Prereq checkConflictAgainstOHWithDetail passed.表示补丁与当前$ORACLE_HOME无冲突可安全应用。若此处失败如报Prereq checkConflictAgainstOHWithDetail failed常见原因是补丁包解压路径含中文或空格或$ORACLE_HOME权限不足需 oracle 用户对$ORACLE_HOME有 rwx 权限。4. 执行打补丁OPatch apply 静默模式避交互一步到位补丁应用过程本质是 OPatch 将files/oracore/zoneinfo/timezone.dat复制到$ORACLE_HOME/oracore/zoneinfo/并更新$ORACLE_HOME/inventory/ContentsXML/oui-patches.xml记录。整个过程约 15 秒但必须确保命令参数精准——尤其-silent模式能绕过所有交互式确认适合脚本化部署。4.1 使用 OPatch apply 命令安装补丁$ $ORACLE_HOME/OPatch/opatch apply -silent -ocmrf /tmp/ocm.rsp /tmp/patch_p31335037/31335037 Oracle Interim Patch Installer version 12.2.0.1.28 Copyright (c) 2023, Oracle Corporation. All rights reserved. Oracle Home : /u01/app/oracle/product/19c/dbhome_1 Central Inventory : /u01/app/oraInventory from : /u01/app/oracle/product/19c/dbhome_1/oraInst.loc OPatch version : 12.2.0.1.28 OUI version : 12.2.0.7.0 Log file location : /u01/app/oracle/product/19c/dbhome_1/cfgtoollogs/opatch/opatch2024-04-02_09-40-15AM_1.log OPatch detects the Oracle Home as /u01/app/oracle/product/19c/dbhome_1 Applying interim patch 31335037 to OH /u01/app/oracle/product/19c/dbhome_1 Patching component oracle.rdbms, 19.0.0.0.0... Patching component oracle.rdbms.util, 19.0.0.0.0... Patching component oracle.oracore.rsf, 19.0.0.0.0... OPatch succeeded.参数说明-silent静默模式跳过所有Do you want to proceed? [y|n]确认避免脚本卡住-ocmrf /tmp/ocm.rsp指定 OCMOracle Configuration Manager响应文件路径。若未配置 OCM可创建空文件touch /tmp/ocm.rspOPatch 会忽略该参数若省略此参数OPatch 可能弹出交互式 OCM 配置向导导致命令阻塞/tmp/patch_p31335037/31335037补丁解压后的根目录含etc/、files/子目录注意命令末尾不能加/斜杠如/tmp/patch_p31335037/31335037/否则 OPatch 会报错OPatch failed with error code 255提示路径不存在。4.2 验证补丁是否成功注册到 inventory打补丁后OPatch 会在$ORACLE_HOME/inventory/ContentsXML/oui-patches.xml中写入记录。快速验证方法$ $ORACLE_HOME/OPatch/opatch lsinventory -detail | grep -A 5 31335037 Patch level status of the backup area: Patch level status of the central inventory: Patch level status of the Oracle Home: Patch details: Patch 31335037: applied on Tue Apr 02 09:40:22 CST 2024 Unique Patch ID: 24567890 Patch description: Time Zone Update for 19.0.0.0.0若输出中包含Patch 31335037: applied on ...及Time Zone Update for 19.0.0.0.0说明补丁已成功注册。若lsinventory不显示该补丁但opatch apply显示OPatch succeeded大概率是 OPatch 缓存未刷新执行$ORACLE_HOME/OPatch/opatch util cleanup清理缓存后重试。4.3 检查 timezone.dat 文件是否已更新补丁核心是替换timezone.dat。验证其修改时间与版本号$ ls -l $ORACLE_HOME/oracore/zoneinfo/timezone.dat -rw-r----- 1 oracle oinstall 1234567 Apr 2 09:40 /u01/app/oracle/product/19c/dbhome_1/oracore/zoneinfo/timezone.dat $ strings $ORACLE_HOME/oracore/zoneinfo/timezone.dat | head -5 TZDATA_VERSION35 TZDATA_BUILD2021a TZDATA_SOURCEIANA TZDATA_URLhttps://www.iana.org/time-zones TZDATA_LICENSEPublic DomainTZDATA_VERSION35是关键标志。若仍显示TZDATA_VERSION32说明文件未被覆盖——常见原因是$ORACLE_HOME/oracore/zoneinfo/目录权限为只读chmod 755或 OPatch 运行用户非oracle需chown oracle:oinstall $ORACLE_HOME。此时不要手动 cp必须重跑opatch apply否则 inventory 与文件状态不一致后续升级会出问题。4.4 启动监听器与数据库实例补丁应用完毕按顺序启动$ lsnrctl start $ sqlplus / as sysdba EOF STARTUP; EXIT; EOF启动后立即验证V$TIMEZONE_FILE视图SQL SELECT VERSION, CON_ID FROM V$TIMEZONE_FILE; VERSION CON_ID ---------- ---------- 35 0VERSION35且CON_ID0CDB root表示时区文件已生效。若此处仍显示VERSION32说明数据库启动时加载了旧缓存需执行ALTER SYSTEM FLUSH SHARED_POOL;强制刷新共享池再查一次。5. 避坑指南五个血泪经验总结专治打补丁翻车现场打 Oracle 补丁不是点下一步就行的图形化操作尤其时区补丁这种“看不见摸不着”的底层文件更新失败现象隐蔽、排查路径长。以下是我在某跨平台系统部署中踩过的坑按发生频率排序每条都附真实报错、根因和可抄作业的解决命令。5.1 现象OPatch 报错OPatch failed with error code 73原因补丁 ZIP 包下载不完整或校验失败导致 OPatch 解析actions.xml时 XML 格式错误。解决# 1. 重新下载补丁包 # 2. 校验 SHA256见 2.2 节 # 3. 若校验失败删除旧包用 wget -c 续传防网络中断 $ wget -c https://updates.oracle.com/Orion/Services/download/p31335037_190000_Linux-x86-64.zip?aru24567890 -O p31335037_190000_Linux-x86-64.zip5.2 现象opatch apply卡住不动日志显示Waiting for the Oracle instances to shut down...原因数据库实例未完全关闭后台进程如ora_m000_SID仍在运行OPatch 检测到活动进程后无限等待。解决# 1. 强制杀掉所有 Oracle 进程 $ ps -ef | grep ora_ | grep -v grep | awk {print $2} | xargs kill -9 # 2. 清理 IPC 资源关键 $ ipcs -mt | grep oracle | awk {print $1} | xargs -I {} ipcrm -m {} $ ipcs -st | grep oracle | awk {print $1} | xargs -I {} ipcrm -s {} # 3. 重试 opatch apply5.3 现象lsinventory显示补丁已安装但V$TIMEZONE_FILE.VERSION仍是 32原因数据库启动时从$ORACLE_HOME/oracore/zoneinfo/加载timezone.dat但该目录下文件被其他进程如备份脚本锁定OPatch 实际未写入新文件。解决# 1. 检查文件是否真被更新 $ stat $ORACLE_HOME/oracore/zoneinfo/timezone.dat | grep Modify # 2. 若 Modify 时间早于打补丁时间说明未更新手动强制复制仅应急 $ cp /tmp/patch_p31335037/31335037/files/oracore/zoneinfo/timezone.dat $ORACLE_HOME/oracore/zoneinfo/ $ chmod 640 $ORACLE_HOME/oracore/zoneinfo/timezone.dat # 3. 刷新数据库缓存 $ sqlplus / as sysdba EOF ALTER SYSTEM FLUSH SHARED_POOL; SELECT VERSION FROM V$TIMEZONE_FILE; EXIT; EOF5.4 现象打补丁后数据库启动报错ORA-00600: internal error code, arguments: [kzldtGetTzVersion], [19], []原因补丁包与$ORACLE_HOME版本不匹配如用 191000 包打 190000 数据库导致内核函数调用参数错位。解决# 1. 回滚补丁必须用原 OPatch 版本 $ $ORACLE_HOME/OPatch/opatch rollback -id 31335037 # 2. 确认补丁已移除 $ $ORACLE_HOME/OPatch/opatch lsinventory | grep 31335037 # 应无输出 # 3. 下载正确版本补丁190000 后缀重试5.5 现象应用补丁后SELECT TZ_OFFSET(Asia/Shanghai) FROM DUAL;返回07:00应为08:00原因客户端 NLS_TIME_ZONE 设置错误或应用连接字符串中指定了错误时区如TIME_ZONEGMT7与数据库时区文件无关。解决-- 1. 查看当前会话时区 SQL SELECT SESSIONTIMEZONE FROM DUAL; -- 2. 重置会话时区为数据库默认 SQL ALTER SESSION SET TIME_ZONE DBTIMEZONE; -- 3. 验证上海时区 SQL SELECT TZ_OFFSET(Asia/Shanghai) FROM DUAL; TZ_OFFS ------- 08:006. 验证时区补丁是否真正生效四步交叉验证法一个都不能少补丁打完不等于万事大吉。Oracle 时区行为涉及数据库内核、客户端驱动、操作系统三者协同单点验证极易漏判。我给自己定了一套铁律每次打完时区补丁必须完成以下四步验证缺一不可。这套方法在某金融级日志系统上线前救了我们两次——一次发现测试库打了补丁但生产库忘了打另一次揪出 JDBC 驱动缓存了旧时区规则。6.1 步骤一查V$TIMEZONE_FILE确认内核版本这是最直接的证据。执行SQL COL VERSION FORMAT 999 SQL COL CON_ID FORMAT 999 SQL SELECT VERSION, CON_ID, FILENAME FROM V$TIMEZONE_FILE; VERSION CON_ID FILENAME ------- ------ ---------------------------------------- 35 0 /u01/app/oracle/product/19c/dbhome_1/oracore/zoneinfo/timezone.datVERSION35且FILENAME路径指向$ORACLE_HOME下的timezone.dat证明数据库内核已加载新版时区文件。注意CON_ID必须为0CDB root若为1或2说明只在某个 PDB 生效需检查 PDB 是否 open 并重复打补丁。6.2 步骤二测夏令时敏感时区如Europe/London时区 35 的核心价值是修复 2021 年起夏令时规则。用Europe/London测试 3 月最后一个周日夏令时开始日的时间偏移SQL ALTER SESSION SET TIME_ZONE Europe/London; SQL SELECT 2 TO_CHAR(TIMESTAMP 2024-03-31 00:59:59, YYYY-MM-DD HH24:MI:SS TZR) AS before_dst, 3 TO_CHAR(TIMESTAMP 2024-03-31 01:00:00, YYYY-MM-DD HH24:MI:SS TZR) AS after_dst 4 FROM DUAL; BEFORE_DST AFTER_DST -------------------------- -------------------------- 2024-03-31 00:59:59 GMT 2024-03-31 02:00:00 BSTBSTBritish Summer Time,01:00正确出现且01:00:00跳变为02:00:00证明夏令时切换逻辑已激活。若AFTER_DST仍显示GMT说明时区文件未生效回溯检查V$TIMEZONE_FILE和timezone.dat文件内容。6.3 步骤三比对SYSTIMESTAMP与操作系统时间数据库时间必须与 OS 时钟严格对齐否则DBMS_SCHEDULER作业会漂移。在数据库中执行SQL SELECT 2 SYSTIMESTAMP AS db_time, 3 TO_TIMESTAMP_TZ(TO_CHAR(SYSTIMESTAMP, YYYY-MM-DD HH24:MI:SS.FF TZH:TZM), YYYY-MM-DD HH24:MI:SS.FF TZH:TZM) AS db_tz_time, 4 TO_TIMESTAMP_TZ(TO_CHAR(SYSTIMESTAMP, YYYY-MM-DD HH24:MI:SS.FF) || || SUBSTR(TO_CHAR(SYSTIMESTAMP, TZH:TZM),1,6), YYYY-MM-DD HH24:MI:SS.FF TZH:TZM) AS os_tz_time 5 FROM DUAL; DB_TIME DB_TZ_TIME OS_TZ_TIME ------------------------------ ------------------------------ ------------------------------ 2024-04-02 10:25:33.123456 08:00 2024-04-02 10:25:33.123456 08:00 2024-04-02 10:25:33.123456 08:00三者毫秒级一致DB_TIME、DB_TZ_TIME、OS_TZ_TIME完全相同证明数据库时钟已同步 OS。若DB_TIME与OS_TZ_TIME差整数小时说明ORACLE_HOME下lib/libnnz19.so或lib/libclntsh.so被旧版覆盖需用adrci检查alert.log中Time drift detected告警。6.4 步骤四应用端实测JDBC/ODBC 连接最后一步也是最容易被忽略的从应用服务器连上来查。在应用服务器如 Tomcat 服务器上执行$ java -cp ojdbc8.jar:. TestTz // TestTz.java 内容 import java.sql.*; public class TestTz { public static void main(String[] args) throws Exception { Connection c DriverManager.getConnection(jdbc:oracle:thin:host:1521:orcl, user, pwd); ResultSet rs c.createStatement().executeQuery(SELECT TZ_OFFSET(Asia/Shanghai) FROM DUAL); rs.next(); System.out.println(Shanghai offset: rs.getString(1)); // 应输出 08:00 } }若输出08:00说明 JDBC 驱动ojdbc8.jar与数据库时区协同正常。若输出07:00检查应用服务器 JVM 参数是否设置了-Duser.timezoneGMT7或连接字符串中是否硬编码了TIME_ZONE属性。从那以后我每次给 Oracle 19c 打时区补丁都强制走一遍这四步V$TIMEZONE_FILE→Europe/London夏令时 →SYSTIMESTAMP对齐 → 应用端实测。少一步上线后就可能收到凌晨三点的告警电话。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑