19C 统计信息 引发的数据库慢问题
故障描述:
某医院客户电话反馈,下午数据库出现卡顿,需要排查原因,美创 DBA 立即通过远程进行分析排查。
客户环境为 ORACLE 19C , PDB 架构运行的。
问题 分析:
通过分析发现,主要问题是故障时间段有大量 library cache lock 异常等待,这个等待原因有很多,包括存储过程对象编译,对象 DDL ,游标失效等。
对于最常见的对象(表或者存储过程) DDL 情况分析,并未发现有对象 DDL 和编译动作。
由于之前 11G 版本较多客户出现了自动统计信息调度,导致的 library cache lock 问题,所以对 19C 的统计信息进行分析,并未有人工调整:
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');

对 19C 的统计信息作业调度情况进行检查:
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;
发现调度配置时间( ACTUAL_START_DATE 列)是晚上 10 点,但是实际调度时间( ACTUAL_START_DATE_+8 列)为 13 : 03 ,与问题时间点能吻合。

在 CDB 中执行如下命令,确认 CDB 和 PDB 的当前默认时区设置:
SELECT t.CON_ID, t.ATTRIBUTE_NAME, t.VALUE
FROM CDB_SCHEDULER_GLOBAL_ATTRIBUTE t
WHERE t.ATTRIBUTE_NAME = 'DEFAULT_TIMEZONE'
ORDER BY 1;
可以看到 CDB 的时区是中国标准时间( PRC, UTC+8 ),但是 PDB 的时区设置的有误为 PST8PDT 。

通过查询相关官方文档,发现在 Oracle 19c 版本中,有一个未发布的 BUG (编号 30076391 ),导致 PDB 的统计信息任务执行时间出现错乱。这可以从表 cdb_scheduler_job_run_details 统计信息任务列表中 ACTUAL_START_DATE 列是 TIMESTAMP WITH TIMEZONE 类型看出,而在 PDT (太平洋夏令时)和 PST (太平洋标准时间)之间切换时,时区转换引起了任务执行时间的延迟。
在数据库管理中,如果 PDB 的统计信息采集任务设定在特定时间(如晚上 22 点)执行,时区转换错误可能会导致任务延迟到次日下午执行。
PRC 是指中国标准时间( China Standard Time ),也称为东八区时间( UTC+8 )。这是中国大陆、香港、澳门和台湾地区所使用的标准时间。在数据库管理中,特别是 Oracle 数据库多租户架构下(如 Oracle 19c ),时区设定对于任务调度的准确性非常重要。由于时区转换错误可能会导致
建议将 PDB 中的任务调度时间统一按照中国标准时间( PRC, UTC+8 )执行,避免由于时区转换导致的执行时间错乱问题。
问题处理
修改 PDB的时区,以解决调度窗口错乱问题。 ALTER SESSION SET CONTAINER= pdb1 ; EXEC DBMS_SCHEDULER.SET_SCHEDULER_ATTRIBUTE('default_timezone', 'PRC');
通过以上步骤,可以有效地解决 PDB统计信息任务执行时间错乱的问题,确保任务在预期的时间执行。尽管这是一个临时解决方案,但在Oracle官方发布补丁之前,这是一个可行的解决方式。
技术原理
PST8PDT 是一个组合时区名称,表示太平洋标准时间( PST )和太平洋夏令时间( PDT )的转换规则。具体来说:
PST ( Pacific Standard Time )是太平洋标准时间,通常在冬季使用。 PST 是 UTC-8 ,即比协调世界时( UTC )晚 8 小时。
PDT ( Pacific Daylight Time )是太平洋夏令时间,通常在夏季使用。 PDT 是 UTC-7 ,即比协调世界时( UTC )晚 7 小时。
当一个时区被表示为 PST8PDT 时,这意味着在该时区内,冬季使用 PST ,夏季使用 PDT 。具体转换时间为:
- 每年 3 月的第二个星期日至 11 月的第一个星期日使用 PDT ( UTC-7 )。
- 其他时间使用 PST ( UTC-8 )。
在涉及到数据库任务计划和时间戳转换时,这种时区转换需要特别注意,因为它会影响任务的执行时间。例如,在 Oracle 数据库中,将时间转换为北京时间( UTC+8 )时,需要考虑 PST 和 PDT 的差异:
PST 转换为北京时间 ** :北京时间 = PST + 16 小时
PDT 转换为北京时间 ** :北京时间 = PDT + 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)。
建议总结
1. 建议在创建 19C 数据库时,使用 DBCA 的自定义模式( Customize mode ),不要使用 General mode ,选择 PRC ,以确保后续创建的 PDB 的默认调度时区与 CDB$ROOT 相同,都是 PRC 。
2. 如果前期创建时候未注意,后期发现时区有问题不一致,可通过命令将 CDB 和 PDB 的时区都调整到一致到 PRC 。
3. MOS 相关贴, Default Scheduler Timezone Value In PDB$SEED Different Than CDB (Doc ID 2702230.1) 希望本文能够帮助数据库管理员更好地管理多租户架构中的 PDB,并提供稳定的操作环境。
