位置: 文档库 > 数据库 > Oracle job 情况的查看处理

Oracle job 情况的查看处理

VillainDragon 上传于 2022-06-07 10:50

《Oracle Job 情况的查看处理》

在Oracle数据库环境中,Job(作业)是自动化执行任务的核心机制,广泛应用于定时数据备份、统计信息收集、ETL流程调度等场景。然而,随着业务复杂度的提升,Job的异常执行(如未启动、卡死、重复执行)可能导致数据不一致、性能下降甚至系统崩溃。本文将系统阐述Oracle Job的监控方法、常见问题诊断及处理策略,帮助DBA和开发人员高效管理作业生命周期。

一、Oracle Job基础架构

Oracle Job系统包含两类核心组件:DBMS_JOB(传统作业)和DBMS_SCHEDULER(10g后引入的增强型调度器)。DBMS_JOB基于简单的定时触发机制,而DBMS_SCHEDULER支持更复杂的依赖关系、资源管理和日志记录。

Job执行流程可分为三个阶段:

  1. 调度阶段:通过时间表达式(如SYSDATE+1/24)或CALENDAR语法定义触发条件
  2. 执行阶段:由MMON进程或独立作业队列协调器(JQC)派发执行
  3. 反馈阶段:记录执行日志至DBA_SCHEDULER_JOB_RUN_DETAILS

二、Job状态监控方法

1. 基础视图查询

核心数据字典视图包括:

  • DBA_JOBS / USER_JOBS:传统Job信息(已逐渐被SCHEDULER替代)
  • DBA_SCHEDULER_JOBS:完整作业定义(包含所有者、状态、最后启动时间)
  • DBA_SCHEDULER_RUNNING_JOBS:实时运行中的作业
  • DBA_SCHEDULER_JOB_LOG:历史执行记录(含错误代码)

示例查询:

-- 查看所有异常Job
SELECT job_name, state, last_start_date, next_run_date, error# 
FROM dba_scheduler_jobs 
WHERE state IN ('FAILED', 'BROKEN', 'SCHEDULE_LIMIT');

-- 实时监控运行中的Job
SELECT job_name, session_id, running_instance, elapsed_time 
FROM dba_scheduler_running_jobs;

2. 动态性能视图辅助

结合V$视图可获取更底层信息:

-- 关联会话信息
SELECT s.sid, s.serial#, s.status, j.job_name
FROM v$session s, dba_scheduler_running_jobs j
WHERE s.sid = j.session_id;

-- 检查资源消耗
SELECT se.sql_id, se.module, se.machine, ss.value/100 cpu_seconds
FROM v$sesstat ss, v$statname sn, v$session se
WHERE ss.statistic# = sn.statistic#
AND sn.name = 'CPU used by this session'
AND se.sid = ss.sid
AND se.sid IN (SELECT session_id FROM dba_scheduler_running_jobs);

三、常见问题诊断与处理

1. Job未按时执行

原因分析

  • 调度器服务未启动(检查JOB_QUEUE_PROCESSES参数)
  • 时间表达式错误(如跨时区问题)
  • 依赖资源不可用(如表空间满、权限失效)

处理步骤

-- 1. 检查调度器进程
SELECT name, value FROM v$parameter WHERE name = 'job_queue_processes';

-- 2. 验证时间表达式
SELECT TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'Asia/Shanghai', 'YYYY-MM-DD HH24:MI:SS') 
FROM dual;

-- 3. 手动触发测试
BEGIN
  DBMS_SCHEDULER.RUN_JOB('MY_JOB', USE_CURRENT_SESSION => FALSE);
END;

2. Job执行卡死

典型表现:作业状态显示RUNNING但长时间无日志更新。

解决方案

  1. 终止异常会话:
  2. -- 获取阻塞会话ID
    SELECT session_id FROM dba_scheduler_running_jobs 
    WHERE job_name = 'STUCK_JOB';
    
    -- 终止会话(谨慎操作)
    ALTER SYSTEM KILL SESSION 'sid,serial#' IMMEDIATE;
  3. 检查锁等待:
  4. SELECT l.session_id, o.object_name, l.locked_mode
    FROM v$locked_object l, dba_objects o
    WHERE l.object_id = o.object_id
    AND l.session_id IN (SELECT session_id FROM dba_scheduler_running_jobs);

3. Job重复执行

常见原因

  • 作业定义中未设置MAX_RUNS限制
  • 窗口重叠导致多次触发
  • 程序内部未实现幂等控制

修复方法

-- 修改作业属性
BEGIN
  DBMS_SCHEDULER.SET_ATTRIBUTE(
    name      => 'DUPLICATE_JOB',
    attribute => 'max_runs',
    value     => 1
  );
END;

-- 检查窗口定义
SELECT window_name, repeat_interval FROM dba_scheduler_windows;

四、高级管理技巧

1. 作业链管理

通过DBMS_SCHEDULER.CREATE_CHAIN实现复杂依赖:

BEGIN
  DBMS_SCHEDULER.CREATE_CHAIN(
    chain_name => 'DATA_PROCESS_CHAIN',
    rule_set_name => NULL,
    evaluation_interval => NULL,
    comments => 'Daily data processing chain'
  );
  
  -- 添加步骤
  DBMS_SCHEDULER.DEFINE_CHAIN_STEP(
    chain_name => 'DATA_PROCESS_CHAIN',
    step_name => 'EXTRACT_STEP',
    program_name => 'EXTRACT_PROG'
  );
  
  -- 定义规则
  DBMS_SCHEDULER.DEFINE_CHAIN_RULE(
    chain_name => 'DATA_PROCESS_CHAIN',
    condition => 'TRUE',
    action => 'START EXTRACT_STEP',
    rule_name => 'INIT_RULE'
  );
END;

2. 资源计划分配

通过资源管理器控制Job的CPU/IO使用:

-- 创建资源计划
BEGIN
  DBMS_RESOURCE_MANAGER.CREATE_PENDING_AREA();
  DBMS_RESOURCE_MANAGER.CREATE_PLAN_DIRECTIVE(
    plan => 'JOB_PLAN',
    group_or_subplan => 'JOB_GROUP',
    comment => 'Priority for scheduler jobs',
    mgmt_p1 => 50  -- 分配50%资源
  );
  DBMS_RESOURCE_MANAGER.VALIDATE_PENDING_AREA();
  DBMS_RESOURCE_MANAGER.SUBMIT_PENDING_AREA();
END;

-- 关联到作业
BEGIN
  DBMS_SCHEDULER.SET_ATTRIBUTE(
    name => 'CRITICAL_JOB',
    attribute => 'resource_consumer_group',
    value => 'JOB_GROUP'
  );
END;

3. 外部作业集成

调用操作系统命令或脚本:

BEGIN
  DBMS_SCHEDULER.CREATE_PROGRAM(
    program_name => 'BACKUP_PROG',
    program_type => 'EXECUTABLE',
    program_action => '/bin/bash /backup/script.sh',
    enabled => TRUE,
    number_of_arguments => 0
  );
  
  DBMS_SCHEDULER.CREATE_JOB(
    job_name => 'DAILY_BACKUP',
    program_name => 'BACKUP_PROG',
    schedule_name => 'EVERY_NIGHT',
    enabled => FALSE
  );
END;

五、最佳实践建议

1. 命名规范:采用"模块_功能_周期"格式(如FIN_REPORT_DAILY)

2. 日志管理:配置作业输出重定向至审计表

BEGIN
  DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE(
    job_name => 'LOG_PROCESSOR',
    argument_position => 1,
    argument_value => 'LOG_TABLE'
  );
END;

3. 高可用设计:在RAC环境中配置作业实例亲和性

BEGIN
  DBMS_SCHEDULER.SET_ATTRIBUTE(
    name => 'CLUSTER_JOB',
    attribute => 'instance_affinity',
    value => 'INSTANCE1,INSTANCE2'
  );
END;

4. 版本兼容性:12c及以上版本优先使用DBMS_SCHEDULER替代DBMS_JOB

六、自动化监控方案

构建Job健康检查脚本(示例):

DECLARE
  v_count NUMBER;
  v_alert VARCHAR2(4000);
BEGIN
  -- 检查失败作业
  SELECT COUNT(*) INTO v_count 
  FROM dba_scheduler_jobs 
  WHERE state = 'FAILED' AND enabled = 'TRUE';
  
  IF v_count > 0 THEN
    v_alert := '发现'||v_count||'个失败作业,请检查DBA_SCHEDULER_JOB_LOG';
    -- 此处可添加邮件通知逻辑
    DBMS_OUTPUT.PUT_LINE(v_alert);
  END IF;
  
  -- 检查长时间运行作业
  FOR rec IN (
    SELECT job_name, elapsed_time/3600 hours 
    FROM dba_scheduler_running_jobs 
    WHERE elapsed_time > 3600  -- 超过1小时
  ) LOOP
    DBMS_OUTPUT.PUT_LINE('作业'||rec.job_name||'已运行'||rec.hours||'小时');
  END LOOP;
END;

关键词:Oracle Job调度器管理作业监控、DBMS_SCHEDULER、故障诊断资源控制、作业链

简介:本文详细介绍了Oracle数据库中Job系统的架构原理、监控方法及常见问题处理策略。内容涵盖传统DBMS_JOB与增强型DBMS_SCHEDULER的对比分析,通过数据字典视图和动态性能视图的组合查询实现作业状态实时监控,针对未执行、卡死、重复执行等典型故障提供系统化解决方案,并介绍了作业链管理、资源计划分配等高级功能。最后给出自动化监控脚本示例和最佳实践建议,帮助运维人员构建高效的作业管理体系。