当 Oracle 19C 在午后 “走神”:PDB 时区里藏着的隐形推手

来源:这里教程网 时间:2026-03-03 22:24:45 作者:

 一、故障背景与现象

某医院客户反馈,某日下午数据库出现明显卡顿,业务操作响应缓慢。接到报障后,立即通过远程连接介入,对故障进行紧急排查。

客户数据库环境信息如下:

数据库版本: Oracle 19C

架构模式:多租户( PDB )架构

核心问题:业务高峰期(下午)出现数据库卡顿,需定位根因并解决

  二、问题分析过程

(一)初步锁定异常等待事件

通过对数据库实时性能数据及日志的分析,发现故障时间段内存在大量 **library cache lock** 异常等待。该等待事件的常见触发场景包括:

1 、存储过程、函数等对象的编译操作

2 、表、索引等对象的 DDL (数据定义语言)操作

3 、游标失效导致的重新解析

经进一步排查,排除了 对象 DDL”“ 存储过程编译 等常见场景 —— 未发现故障时段有相关操作记录。

(二)聚焦统计信息调度问题

结合历史经验: Oracle 11G 版本曾多次出现 自动统计信息调度引发 library cache lock” 的案例。因此将排查重点转向 19C 的自动统计信息任务。

 1.  检查统计信息调度配置

通过如下 SQL 查询统计信息任务的调度配置(默认属于维护窗口组):

sql

select t1.window_name,t1.repeat_interval,t1.duration 

from dba_scheduler_windows t1,dba_scheduler_wingroup_members t2

where t1.window_name=t2.window_name 

  and t2.window_group_name in ('MAINTENANCE_WINDOW_GROUP','BSLN_MAINTAIN_STATS_SCHED');

编辑

结果显示:配置的执行时间为晚上 22:00 (符合常规运维窗口设置)。

 2.  核查实际执行时间

通过查询统计信息任务的运行日志( cdb_scheduler_job_run_details ),确认实际执行时间:

sql

select t.log_id, t.LOG_DATE, t.JOB_NAME, t.STATUS, 

       t.ACTUAL_START_DATE, 

       to_char((to_timestamp_tz(ACTUAL_START_DATE) at time zone '+08:00'), 'yyyy-mm-dd hh24:mi:ss') "ACTUAL_START_DATE_+8", 

       t.RUN_DURATION, t.con_id 

from cdb_scheduler_job_run_details t 

where job_name LIKE 'ORA$AT_OS%' and con_id = 3 

order by log_date;

关键发现:

1 、配置时间( ACTUAL_START_DATE 列,带时区的时间戳)显示为 晚上 10

2 、转换为北京时间后( ACTUAL_START_DATE_+8 列),实际执行时间为 13:03 (与故障时间完全吻合)

编辑

(三)定位时区配置异常

为确认时间错乱原因,检查 CDB PDB 的默认时区设置:

sql

SELECT t.CON_ID, t.ATTRIBUTE_NAME, t.VALUE 

FROM CDB_SCHEDULER_GLOBAL_ATTRIBUTE t 

WHERE t.ATTRIBUTE_NAME = 'DEFAULT_TIMEZONE' 

ORDER BY 1;

查询结果显示:

1 CDB (容器数据库)时区: **PRC UTC+8 ,中国标准时间) ** (正确)

2 PDB (可插拔数据库)时区: **PST8PDT (太平洋时间,含夏令时转换) ** (错误)

编辑

(四)根因:时区转换与未公开BUG

 1.  时区转换逻辑冲突

PST8PDT 是太平洋时区(含夏令时)的缩写,其与北京时间( UTC+8 )的转换规则为:

1 、太平洋标准时间( PST ): UTC-8 →  比北京时间晚 16 小时

2 、太平洋夏令时( PDT ): UTC-7 →  比北京时间晚 15 小时

举例说明:

- 2022 10 2 07:00 PDT = 2022 10 2 22:00  北京时间( 07:00 + 15 小时  = 22:00 )。

- 2022 10 2 07:00 PST = 2022 10 2 23:00  北京时间( 07:00 + 16 小时  = 23:00 )。

PDB 时区为 PST8PDT CDB PRC 时,统计信息任务的 配置时间 (基于 CDB 时区的 22:00 )会因时区转换错误,实际执行时间偏移至下午(与故障时间匹配)。

 2.  官方 BUG 确认

查询 Oracle 官方文档得知: 19C 存在未发布 BUG (编号 30076391 ),在 PDB 时区与 CDB 不一致时,会导致统计信息任务的时间戳( TIMESTAMP WITH TIMEZONE 类型)转换错乱 —— 尤其在 PST/PDT 切换时,执行时间偏差问题更明显。

  三、问题解决方案

(一)核心修复:统一PDB时区

通过如下操作将 PDB 的时区修改为 PRC (与 CDB 保持一致):

sql

--  切换到目标 PDB

ALTER SESSION SET CONTAINER=pdb1;

--  修改调度器默认时区为中国标准时间

EXEC DBMS_SCHEDULER.SET_SCHEDULER_ATTRIBUTE('default_timezone', 'PRC');

(二)效果验证

修改后再次查询 PDB 时区( CDB_SCHEDULER_GLOBAL_ATTRIBUTE ),确认已更新为 PRC ;后续统计信息任务执行时间恢复正常(按配置的 22:00 执行),数据库卡顿问题未再出现。

  四、预防建议与最佳实践

(一)部署阶段规范

1 、创建 19C 数据库时,使用 DBCA (数据库配置助手)的 ** 自定义模式( Customize mode ** ,而非默认的 “General mode”

2 、在配置步骤中明确指定时区为 “PRC UTC+8 ,确保 PDB$SEED PDB 模板)与 CDB 的时区一致。

(二)运维阶段检查

1 、定期通过如下 SQL 检查 CDB 与所有 PDB 的时区配置:

  sql

  SELECT t.CON_ID, t.NAME, t.ATTRIBUTE_NAME, t.VALUE 

  FROM CDB_SCHEDULER_GLOBAL_ATTRIBUTE t 

       JOIN V$PDBS t2 ON t.CON_ID = t2.CON_ID

  WHERE t.ATTRIBUTE_NAME = 'DEFAULT_TIMEZONE' 

  ORDER BY 1;

  

2 、若发现时区不一致,及时通过 `DBMS_SCHEDULER.SET_SCHEDULER_ATTRIBUTE` 统一为 PRC

(三)参考官方文档

Oracle MOS 文档《 Default Scheduler Timezone Value In PDB$SEED Different Than CDB (Doc ID 2702230.1) 》详细说明了多租户架构下时区配置的注意事项,建议数据库管理员参考。

  五、总结

本次故障的核心是 “PDB CDB 时区不一致 ”+“Oracle 19C BUG 30076391” 导致统计信息任务执行时间错乱,进而引发 library cache lock 和数据库卡顿。通过统一时区配置,可有效解决该问题。

Oracle 19C 多租户环境中,时区一致性是保障任务调度准确性的基础 —— 尤其对于统计信息、备份等关键运维任务,需在部署和运维阶段严格检查,避免因时间偏差引发业务影响。

相关推荐