这是最常见的调度程序问题之一。
在这里,我们列出了一些常见问题及其解决方案。
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');