在Oracle数据库中,一般人们可能只会关注数据库的时区或会话的时区,但是很少有人会关注Scheduler的时区设置,因为Scheduler的时区设置一般只会影响作业的scheduler和Windows的运行,很多时候,人们往往没有注意到它。这里简单总结一下这个知识点。

在Oracle 10g/11g中,数据库的scheduler的时区是全局统一的,但是从Oracle 12c开始,多租户架构中,CDB和各个PDB的scheduler的时区设置是分开的。我们一般可以通过下面几种方法查看数据库的scheduler时区信息

方法1:

selectdbms_scheduler.stimefromdual;

方法2:

setlinesize680
colattribute_namefora20
colvaluefora30
select*fromdba_scheduler_global_attribute
whereattribute_namelike'%TIMEZONE%';

方法3:

get_scheduler_attributes.sql脚本

SETSERVEROUTPUTON
showcon_name;
EXECDBMS_OUTPUT.put_line(RPAD('-',60,'-'));
DECLARE
PROCEDUREdisplay(p_paramINVARCHAR2)AS
l_resultVARCHAR2(50);
BEGIN
DBMS_SCHEDULER.get_scheduler_attribute(
attribute=>p_param,
value=>l_result);
DBMS_OUTPUT.put_line(RPAD(p_param,30,'')||':'||l_result);
END;
BEGIN
display('current_open_window');
display('default_timezone');
display('email_sender');
display('email_server');
display('event_expiry_time');
display('log_history');
display('max_job_slave_processes');
END;
/

如下所示,我们在CDB容器下,查看数据库的Scheduler时区信息,如下所示,第一个SQL可以判断为东八区设置,其它两个SQL的值为null,表示使用systimestamp的时区。而当前systimestamp的时区为东八区

SQL>selectdbms_scheduler.stimefromdual;

STIME
---------------------------------------------------------------------------
11-SEP-2310.04.37.395374000PM+08:00

SQL>setlinesize680
SQL>colattribute_namefora20
SQL>colvaluefora30
SQL>select*fromdba_scheduler_global_attribute
2whereattribute_namelike'%TIMEZONE%';

ATTRIBUTE_NAMEVALUE
--------------------------------------------------
DEFAULT_TIMEZONE

SQL>@get_scheduler_attributes.sql

CON_NAME
------------------------------
CDB$ROOT
------------------------------------------------------------

PL/SQLproceduresuccessfullycompleted.

current_open_window:MONDAY_WINDOW
default_timezone:
email_sender:
email_server:
event_expiry_time:
log_history:30
max_job_slave_processes:

PL/SQLproceduresuccessfullycompleted.

SQL>

官方文档[1]中的介绍如下

Whenstart_dateisNULL,theSchedulerdeterminesthetimezonefortherepeatintervalasfollows:

Itcheckswhetherornotthesessiontimezoneisaregionname.Thesessiontimezonecanbesetbyeither:

IssuinganALTERSESSIONstatement,forexample:

SQL>ALTERSESSIONSETtime_zone='Asia/Shanghai';



SettingtheORA_SDTZenvironmentvariable.

Ifthesessiontimezoneisanabsoluteoffsetinsteadofaregionname,theSchedulerusesthevalueoftheDEFAULT_TIMEZONESchedulerattribute.Formoreinformation,seetheSET_SCHEDULER_ATTRIBUTEProcedure.

IftheDEFAULT_TIMEZONEattributeisNULL,theSchedulerusesthetimezoneofsystimestampwhenthejoborwindowisenabled.

在Oracle 19c中,一般用DBCA创建的PDB数据库,它的scheduler时区默认为PST8PDT, 如下所示,PST8PDT其实是美国的太平洋标准时间,是美国西部城市的主要计时制度。就和我们的北京时间类似。中国是统一使用北京时间,但是美国东西部使用不同的时间制度。美国东部有西5区,西6区等,PST8PDT就是西8区的时间。

关于这个问题,其实官方文档Default Scheduler Timezone Value In PDB$SEED Different Than CDB (Doc ID 2702230.1)[2]有阐述这个现象。

On12C,18cand19c,usingDBCAGeneralmodecreateDB,thedefaulttimezoneofschedulerofPDBisdifferentwithCDB$ROOT.
ThedefaulttimezoneoftheschedulerofPDBisPST8PDTon19candEtc/UTCon12C&18cnomatterwhatthetimezoneoftheschedulerisinCDB$ROOT.
ButusingcreatedatabasecommandorusingDBCAcustomizemode,thedefaulttimezoneoftheschedulerofPDBissamewithCDB$ROOT.
Itisexpectedbehavior.
Pleaserefertothebelowbugraisedanenhancementrequest.
UnpublishedBug30076391:DIFFERENTTIMEZONESOFSCHEDULERINCDB$ROOTANDPDBUSINGDBCAGENERALMODECREATEDB

这个现象,如果你没有注意到,可能Scheduler的运行时间跟你所预期的不一样。例如,数据库采集、更新统计信息的时间,这个影响说大其实影响也蛮大的。可能导致在白天业务高峰期,数据库正在收集统计信息。所以,一般你在创建对应的PDB数据库时,就必须检查/设置Scheduler的时区。

设置scheduler的时区

execdbms_scheduler.set_scheduler_attribute('default_timezone','Asia/Shanghai');

参考资料

[1]

1: https://docs.oracle.com/en/database/oracle/oracle-database/19/arpls/DBMS_SCHEDULER.html#GUID-2D8930DD-1042-4FA9-A0C0-2E4C7A7BFE9B

[2]

2: https://support.oracle.com/epmos/faces/DocumentDisplay?_afrLoop=122259819987503&id=2702230.1&_afrWindowMode=0&_adf.ctrl-state=bngoz01qg_129

扫描上面二维码关注我如果你真心觉得文章写得不错,而且对你有所帮助,那就不妨帮忙“推荐”一下,您的“推荐”和”打赏“将是我最大的写作动力!本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接.