一、故障背景与现象
某医院客户反馈,某日下午数据库出现明显卡顿,业务操作响应缓慢。接到报障后,立即通过远程连接介入,对故障进行紧急排查。
客户数据库环境信息如下:
- 数据库版本: 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 多租户环境中,时区一致性是保障任务调度准确性的基础 —— 尤其对于统计信息、备份等关键运维任务,需在部署和运维阶段严格检查,避免因时间偏差引发业务影响。
