【问题标题】:Oracle DBMS Job not runningOracle DBMS 作业未运行
【发布时间】:2018-03-19 23:07:12
【问题描述】:

我将工作定义为从周二到周日每 5 分钟运行一次。从上午 9:00 到下午 22:00

BEGIN
DBMS_SCHEDULER.CREATE_JOB (
job_name => 'GET_INVOICES_JOB',
job_type => 'PLSQL_BLOCK',
job_action => 'BEGIN LOPES.GET_INVOICES; END;',
repeat_interval =>'FREQ=MINUTELY; INTERVAL=5; BYHOUR=9,22; BYDAY=TUE,WED,THU,FRI,SAT,SUN', 
enabled => TRUE,
comments => 'GET_INVOICES');
END;
/

但是作业不运行检查

SELECT *
FROM USER_SCHEDULER_JOB_RUN_DETAILS 
ORDER BY LOG_DATE DESC

检查作业似乎没问题:

并手动运行作业,它会执行该过程,但不是每 5 分钟一次

【问题讨论】:

    标签: sql oracle plsql oracle12c dbms-scheduler


    【解决方案1】:

    这是最常见的调度程序问题之一。 在这里,我们列出了一些常见问题及其解决方案。

    1) job_queue_processes 可能太低(这是最常见的问题) job_queue_processes 的值限制了 dbms_scheduler 的总数 和可以在给定时间运行的 dbms_job 作业。 要检查是否是这种情况,请检查的当前值 job_queue_processes 与 SQL> select value from v$parameter where name='job_queue_processes'; 然后检查正在运行的作业数 SQL> select count() from dba_scheduler_running_jobs; SQL> select count() from dba_jobs_running;

    如果这是问题,您可以使用增加参数 SQL> alter system set job_queue_processes=1000;

    2) max_job_slave_processes 可能太低 如果此参数不为 NULL,则它限制了 dbms_scheduler 作业的数量 一次运行。要检查这是否是问题,请检查当前 使用价值 SQL> 从 dba_scheduler_global_attribute 中选择值 其中attribute_name='MAX_JOB_SLAVE_PROCESSES'; 然后检查正在运行的作业数 SQL> select count(*) from dba_scheduler_running_jobs;

    如果这是问题,您可以增加数字或将其设为 NULL 使用 SQL> exec dbms_scheduler.set_scheduler_attribute('max_job_slave_processes',null)

    3) 会话可能太少 此参数随时限制会话数。每个调度程序作业 需要2个会话。要检查这是否是问题,请检查当前 使用价值 SQL> select value from v$parameter where name='sessions'; 然后使用检查当前会话数 SQL> 从 v$session 中选择 count(*) ;

    如果数字太接近,您可以使用 SQL> alter system set job_queue_processes=200;

    4) 您最近是否应用了时区更新补丁或升级了数据库 到具有更新时区信息的版本?如果您跳过任何步骤 更新时区信息,作业可能无法运行。检查这是否 是这样吗? SQL> select * from sys.scheduler$_job; 和 SQL> select * from sys.scheduler$_window; 并确保它们完成时没有错误。

    如果它引发时区警告,请重新应用升级或 时区补丁确保遵循所有步骤。

    5) 数据库是否在受限模式下运行? 如果数据库以受限模式运行,则不会运行任何作业(除非 您正在使用 11g 并使用 ALLOW_RUNS_IN_RESTRICTED_MODE 属性)。 检查此用途 SQL> 从 v$instance 中选择登录;

    如果登录受到限制,您可以使用以下方法禁用限制模式 SQL> ALTER SYSTEM DISABLE RESTRICTED SESSION;

    6) 作业是否计划在已关闭的实例上运行?

    您可以通过查看是否为作业设置了 instance_id 来检查这一点(检查 dba_scheduler_jobs 视图),如果是,则应检查该实例是否已启动。

    7) 作业是否计划在尚未在任何实例上启动的服务上运行?

    您可以通过检查作业指向的 job_class,然后检查该类是否指向服务来检查这一点。如果是,请确保该服务已在至少一个正在运行的实例上启动。您可以使用 dbms_service.start_service 在实例上启动服务。

    8) 资源管理器是否具有限制性资源计划?

    如果限制性资源计划生效,调度程序作业可能没有分配足够的资源,因此它们可能无法运行。您可以通过以下方式检查有效的资源计划

    SQL> 从 V$RSRC_PLAN 中选择名称;

    如果没有有效的计划或有效的计划是 INTERNAL_PLAN,则资源管理器无效。如果资源管理器有效,您可以通过执行禁用它

    SQL>alter system set resource_manager_plan = '';

    9) 调度程序是否被禁用?这不是受支持的操作 但有可能有人已经这样做了。要检查这个 SQL> 从 dba_scheduler_global_attribute 中选择值,其中 attribute_name='SCHEDULER_DISABLED'

    如果此查询返回 TRUE,那么您可以使用以下方法解决此问题 SQL> exec dbms_scheduler.set_scheduler_attribute('scheduler_disabled','false');

    作业延迟的原因

    1) 首先要检查的是作业安排的时区 SQL> select owner, job_name, next_run_date from dba_scheduler_jobs ;

    如果作业位于错误的时区,它们可能无法按预期运行 时间。如果 next_run_date 使用的是绝对时区偏移量(例如 +08:00) 而不是命名的时区(如 US/PACIFIC),那么作业可能不会 如果夏令时生效,则按预期运行 - 它们可能会运行一个小时 早晚。

    2) 可能在计划运行作业时,几个 可能已暂时达到上述限制,导致作业延迟。 检查上述限制是否足够高,并在可能的情况下检查它们 作业被延迟的时间。

    3) 可能会达到上述限制之一的一个可能原因是 维护窗口可能已经生效。维护窗口是 Oracle 属于名为的窗口组的调度程序窗口 MAINTENANCE_WINDOW_GROUP。在计划的维护窗口期间,几个 维护任务使用作业运行。这可能会导致列出的限制之一 以上被击中,用户作业被延迟。有关更多信息,请参阅管理员指南 关于这个(第 24 章)。

    要获取维护时段列表,请使用 SQL> select * from dba_scheduler_wingroup_members;

    要查看 Windows 何时运行,请使用 SQL> select * from dba_scheduler_windows;

    要解决此问题,您可以增加限制或重新安排维护时间 windows 在更方便的时候运行。

    诊断其他问题

    如果这些都不起作用,您可以采取以下进一步的步骤来尝试 弄清楚发生了什么。

    1) 检查alert log中是否有错误。如果数据库是 无法分配内存或磁盘空间不足或任何其他 发生了灾难性错误,您应该首先解决这些错误。你可以 使用查找警报日志的位置 SQL> 从 v$parameter 中选择值 where name = 'background_dump_dest'; 警报日志将在此目录中,名称以“alert”开头。

    2) 检查是否有作业协调器跟踪文件,如果有,检查是否有 包含任何错误。如果存在,它将位于 'background_dump_dest' 目录,您可以在上面找到并且看起来 类似 SID-cjq0_nnnn.trc 的东西。如果这里有任何错误,他们可能会 提示为什么作业没有运行。

    3) 如果上述任一情况表明 SYSAUX 表空间(调度程序存储其日志记录表的位置)已满,您可以使用 dbms_scheduler.purge_log 过程清除旧的日志条目。

    4) 查看当前是否有打开的窗口。如果有,您可以尝试关闭它,看看是否有帮助。

    SQL> select * from DBA_SCHEDULER_GLOBAL_ATTRIBUTE where 
    attribute_name='CURRENT_OPEN_WINDOW';
    SQL> exec DBMS_SCHEDULER.close_window ('WEEKNIGHT_WINDOW');
    

    5)尝试运行一个简单的一次性作业,看看它是否运行

    SQL>begin
    dbms_scheduler.create_job (
    job_name => 'test_job',
    job_type => 'plsql_block',
    job_action => 'null;',
    enabled => true);
    end;
    /
    SQL> -- wait a while
    SQL> select * from user_scheduler_job_run_details where job_name='TEST_JOB';
    

    6) 如果一个简单的一次性作业没有运行,您可以尝试如下重启调度器。

    SQL> exec dbms_scheduler.set_scheduler_attribute('SCHEDULER_DISABLED', 'TRUE');
    SQL> alter system set job_queue_processes=0;
    SQL> exec dbms_ijob.set_enabled(FALSE);
    SQL> 
    SQL> alter system flush shared_pool;
    SQL> alter system flush shared_pool;
    SQL>
    SQL> exec dbms_ijob.set_enabled(TRUE);
    SQL> alter system set job_queue_processes=99;
    SQL> exec dbms_scheduler.set_scheduler_attribute('SCHEDULER_DISABLED', 'FALSE');
    

    【讨论】:

      【解决方案2】:

      在多租户环境中,容器还必须具有正确的 job_queue_processes 值。

      【讨论】:

      猜你喜欢
      • 2022-09-26
      • 1970-01-01
      • 2017-03-22
      • 2018-03-18
      • 2020-04-30
      • 1970-01-01
      • 2014-11-02
      • 1970-01-01
      相关资源
      最近更新 更多