【问题标题】:How to schedule an Oracle dbms_scheduler Job timezone and DST safely如何安全地安排 Oracle dbms_scheduler 作业时区和 DST
【发布时间】:2014-02-04 03:47:20
【问题描述】:

我正在尝试将 DBMS_SCHEDULER 作业设置为在 Oracle 11g 上每年 1 月 1 日凌晨 1 点准确运行。由于时区差异或夏令时,如何设置其属性以绝对确保它不会在错误的时间执行。

我花了很多时间浏览 Oracle 文档,但我仍然没有达到确定的程度。

顺便说一句,以下是我发现并认为与主题相关的规则:

职位属性

start_date 此属性指定此作业计划开始的第一个日期。如果 start_date 和 repeat_interval 保留为空,则作业将在作业启用后立即运行。 对于使用日历表达式指定重复间隔的重复作业,start_date 用作参考日期。作业将被安排运行的第一次时间是当前日期当天或之后的日历表达式的第一个匹配项。 调度器不能保证作业会在准确的时间执行,因为系统可能会过载,从而导致资源不可用。

repeat_interval 此属性指定作业应重复的频率。您可以使用日历或 PL/SQL 表达式指定重复间隔。 对指定的表达式求值以确定下次作业应该运行的时间。如果未指定 repeat_interval,则作业将在指定的开始日期仅运行一次。有关详细信息,请参阅“日历语法”。

日历语法中的规则

  • 日历语法不允许您指定时区。 相反,调度程序从 start_date 检索时区 争论。如果作业必须遵循夏令时调整,您必须 确保为该时区指定区域名称 开始日期。例如将 start_date 时区指定为 纽约的“美国/东部”将确保夏令时 自动应用调整。如果改为时区 start_date 设置为绝对偏移量,例如'-5:00', 不遵循夏令时调整,您的工作执行 将在半年中关闭一个小时。
  • 当 start_date 为 NULL 时,调度程序将确定重复间隔的时区,如下所示:
  • 会检查会话时区是否为区域名称。会话时区可以通过以下任一方式设置: 发出 ALTER SESSION 语句,例如:SQL> ALTER SESSION SET time_zone = '亚洲/上海';设置 ORA_SDTZ 环境 变量。
  • 如果会话时区是绝对偏移量而不是区域名称,调度程序将使用 DEFAULT_TIMEZONE 调度程序属性的值。有关详细信息,请参阅 SET_SCHEDULER_ATTRIBUTE 过程。
  • 如果 DEFAULT_TIMEZONE 属性为 NULL,则调度程序将在启用作业或窗口时使用 systimestamp 的时区。

【问题讨论】:

  • 您不会在数据库服务器的本地“时钟”时间安排 01/01/20xx 01:00 吗?您是否尝试过运行测试?
  • 说实话,这对我来说太模糊了。本地时钟调度是什么意思?属性应该如何设置?不,我还没有进行太多测试,因为我发现测试时区更改、DST 更改有点太复杂,并且仍然不能确定它是否正确。
  • @OldProgrammer:不幸的是,这样做不考虑DST。 Oracle 会将您的工作安排在非 DST 时间,如果您处于 DST 时间,那将不是您想要的时间。

标签: oracle11g timezone dst job-scheduling dbms-scheduler


【解决方案1】:

您可以使用它来确保传递带有时区的时间戳,并且开始日期将具有时区名称(美国/东部)而不是偏移量(例如:+5:00)。这样,正如上述来自 oracle 文档的片段所提到的,调度程序将跟踪 DST。

-- 创建一个时间表

declare 
 v_start_date timestamp with time zone;
BEGIN 

select localtimestamp at time zone 'US/Eastern' into v_start_date from dual; --US/Eastern

DBMS_SCHEDULER.CREATE_SCHEDULE(
      schedule_name => 'SAMPLE_SCHEDULE',
      start_date => v_start_date,
      repeat_interval => 'FREQ=DAILY; BYHOUR=10; BYMINUTE= 15',
      comments => 'Runs daily at the specified hour.'); 
END;

为确保您已正确设置它,您可以运行以下命令: ALTER SESSION SET nls_timestamp_tz_format = 'MM-DD-YYYY HH24:MI:SS tzr tzd';

现在,创建两个计划,一个如上所述,一个使用 sysdate 作为 start_date 参数并执行下面的查询。

-- Check the TIMEZONE 
select * from USER_SCHEDULER_SCHEDULES;


v1:
27-MAR-14 11.44.24.929282 AM **US/EASTERN**

v2:

27-MAR-14 05.44.54.000000 PM **+05:00**

【讨论】:

    【解决方案2】:

    我不确定这个答案是否真的通过了这个网站上的答案规则,但是在花了很多时间谷歌搜索之后,我想出了以下解决方案:

    start_date      => CAST(trunc(sysdate, 'YEAR')+2/24 AS TIMESTAMP) at time zone 'Europe/Berlin'
    

    我相信这是最安全的解决方案,因为:

    • 它使用时间戳而不是日期 - 我相信它会强制作业在给定时区的给定时间真正执行,同时忽略 DMBS_SCHEDULER default_timezone。我还发现一些建议说直接使用时间戳也是不安全的,只有这个演员是安全的
    • 我手动选择了我需要的时区,希望它不会与本地设置发生冲突。尽管我不清楚它现在是否真的与 SESSIONTIMEZONE 或 DBTIMEZONE 无关,以及它是否会影响正确的运行时间。
    • 我使用了一个小技巧,即使请求应该在午夜之后开始工作,我也将它设置为凌晨 2 点,希望即使在时区和夏令时不好的情况下,它也会被最大移动+-2 小时。

    如果我能完全清楚地知道作业何时在服务器的本地时间、SESSIONTIMEZONE、DBTIMEZONE、start_date 时区和 DBMS_SCHEDULER 时区方面实际执行,我会对解决方案感到满意。

    我也对时区规范不满意,因为它有 4 个与之相关的缩写 - LMT、CET、CEST、CEMT,在我看来,CEST 完全错误。我的目标是在夏令时使用 CET(冬天!=夏天)。

    【讨论】:

      【解决方案3】:

      实际上我从未尝试过使用.CREATE_SCHEDULE 方法,但.CREATE_JOB 也有 start_date 参数,对我有用的只是简单的

      start_date => TO_TIMESTAMP_TZ('00:10 Europe/Rome','hh24:mi tzr'
      

      当我查询 dba_scheduler_jobs 时,它会保留“欧洲/罗马”:

      SELECT job_name, TO_CHAR(start_date) start_date,
                       TO_CHAR(next_run_date) next_run_date
          FROM dba_scheduler_jobs;
      

      【讨论】:

        【解决方案4】:

        当您想检查修改是否成功时,添加更多信息。 运行查询:select * from all_scheduler_jobs where owner='schema_name'。 您可以在 start_date 字段中看到,它具有带时区的时间戳类型,它包含如下数据:2017-12-05 01:55:00,000000000 EUROPE/YOUR_CITY 最后有时区信息确认它已正确保存用于作业。 然后,next_run_date 也与 start_date 对齐,它还应该显示时区详细信息。

        【讨论】:

          【解决方案5】:
          SELECT DBMS_SCHEDULER.STIME FROM DUAL;
          

          Reference

          【讨论】:

          • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
          猜你喜欢
          • 1970-01-01
          • 2018-02-17
          • 1970-01-01
          • 2016-10-09
          • 2014-11-24
          • 1970-01-01
          • 2017-09-20
          • 2018-03-18
          • 2021-01-21
          相关资源
          最近更新 更多