Oracle DBMS 作业未运行

en *_*pes 3 sql oracle plsql dbms-scheduler oracle12c

我定义了一个从周二到周日每 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;
/
Run Code Online (Sandbox Code Playgroud)

但这项工作并没有运行检查

SELECT *
FROM USER_SCHEDULER_JOB_RUN_DETAILS 
ORDER BY LOG_DATE DESC
Run Code Online (Sandbox Code Playgroud)

检查工作似乎没问题:

在此处输入图片说明

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

Nuñ*_*ada 11

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

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

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

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

如果数字太接近,您可以使用 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> select logins from 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> select value from dba_scheduler_global_attribute where 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) 可能达到上述限制之一的一个可能原因是维护窗口可能已经生效。维护窗口是属于名为 MAINTENANCE_WINDOW_GROUP 的窗口组的 Oracle 调度程序窗口。在计划的维护窗口期间,使用作业运行多个维护任务。这可能会导致达到上面列出的限制之一并延迟用户作业。有关更多信息,请参阅管理指南(第 24 章)。

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

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

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

诊断其他问题

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

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

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');
Run Code Online (Sandbox Code Playgroud)

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';
Run Code Online (Sandbox Code Playgroud)

6) 如果一个简单的 run-once 作业没有运行,您可以尝试重新启动调度程序,如下所示。

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');
Run Code Online (Sandbox Code Playgroud)