ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 数据库恢复状态可能导致JOB无法自动运行

数据库恢复状态可能导致JOB无法自动运行

原创 Linux操作系统 作者:yangtingkun 时间:2010-05-21 22:06:49 0 删除 编辑

碰到一个有意思的情况,一个11gr2的数据库的JOB无法自动运行。

 

 

这是一个测试数据库。前一段时间运行了一个建立分区表的SQL语句,目的是测试最大分区数,因此设置的分区数是1048575。关于这个测试的详细信息可以参考:http://yangtingkun.itpub.net/post/468/499902

这个SQL运行时间超过了一个星期,由于是测试数据库,我也没有在意,本打算看看是否能最终跑完。没想到前两天测试机房断电,于是这个服务器就异常关闭了。

尝试启动数据库,并未发现异常,数据库的启动也不算太慢。不过当用户访问TAB同义词的时候,出现了长时间的等待,显然Oracle运用了快速恢复启动的技术,由于前面的CREATE TABLE已经建立了大量的分区信息,而这些信息由于没有最终提交因此都需要进行回滚。可以想象,这个运行时间超过1个星期的SQL,在回滚的时候显然也会需要很长的时间,Oracle为了避免数据库长时间无法打开,采用了延迟回滚的技术。数据库的日志一旦恢复完成,就可以打开使用,回滚并不会马上进行。如果用户触发到需要回滚的数据,则会发生等待,直到数据库处理完需要回滚的操作为止。

正是这种技术,使得Oracle可以快速的打开并使用,而后台会继续处理这些回滚的操作,除非用户访问到需要回滚的数据,否则不会意识到数据库的操作。

不过除了上面提到的访问TAB等视图被锁之外,还发现了一个奇怪的现象,数据库的JOB无法自动运行:

SQL> conn yangtk/yangtk
已连接。
SQL> create table t_id (id number);

表已创建。

SQL> select * from user_jobs;

未选定行

SQL> show parameter job

NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
job_queue_processes                  integer     100
SQL> declare
  2  v_job number;
  3  begin
  4  dbms_job.submit(v_job, 'begin insert into t_id values (1); commit; end;', sysdate, 'sysdate + 1');
  5  commit;
  6  end;
  7  /

PL/SQL 过程已成功完成。

SQL> select * from t_id;

未选定行

SQL> select job, this_date, next_date, total_time, broken, failures
  2  from user_jobs;

       JOB THIS_DATE      NEXT_DATE      TOTAL_TIME B   FAILURES
---------- -------------- -------------- ---------- - ----------
        63                20-5
月 -10              0 N

可以看到,JOB并未自动运行,手工运行JOB则没有问题:

SQL> exec dbms_job.interval(63, 'sysdate + 1/1440');

PL/SQL 过程已成功完成。

SQL> commit;

提交完成。

SQL> exec dbms_job.run(63)

PL/SQL 过程已成功完成。

SQL> select * from t_id;

        ID
----------
         1

SQL> alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss';

会话已更改。

SQL> select job, this_date, next_date, total_time, broken, failures
  2  from user_jobs;

       JOB THIS_DATE           NEXT_DATE           TOTAL_TIME B   FAILURES
---------- ------------------- ------------------- ---------- - ----------
        63                     2010-05-20 02:18:13          0 N          0

SQL> select sysdate from dual;

SYSDATE
-------------------
2010-05-20 02:19:12

SQL> select * from t_id;   

        ID
----------
         1

SQL> select job, this_date, next_date, total_time, broken, failures
  2  from user_jobs;

       JOB THIS_DATE           NEXT_DATE           TOTAL_TIME B   FAILURES
---------- ------------------- ------------------- ---------- - ----------
        63                     2010-05-20 02:18:13          0 N          0

但是运行JOB后,这个JOB并没有继续自动运行,而是停了下来。检查操作系统发现cjq0进程存在,但是不存在J00N进程。检查alert文件,没有发现JOB相关的错误。

尝试通过设置JOB_QUEUE_PROCESSES为0,然后在设置一个非0值,来重新唤起JOB进程:

SQL> alter system set job_queue_processes = 0;

系统已更改。

SQL> alter system set job_queue_processes = 20;

系统已更改。

正常情况下,设置JOB_QUEUE_PROCESSES参数为0,会导致CJQ0进程推出,但是等待了很长时间发现CJQ0进程并未退出,只好重新设置JOB_QUEUE_PROCESSES为非零值。

通过DBMS_IJOB.ENABLE检查数据库的JOB是否正常:

SQL> CONN / AS SYSDBA
已连接。
SQL> SET SERVEROUT ON
SQL> BEGIN
  2  IF DBMS_IJOB.ENABLED THEN
  3  DBMS_OUTPUT.PUT_LINE('TRUE');
  4  ELSE
  5  DBMS_OUTPUT.PUT_LINE('FALSE');
  6  END IF;
  7  END;
  8  /
TRUE

PL/SQL 过程已成功完成。

强制关闭JOB,然后在启用,问题依旧:

SQL> EXEC DBMS_IJOB.SET_ENABLED(FALSE)

PL/SQL 过程已成功完成。

SQL> EXEC DBMS_IJOB.SET_ENABLED(TRUE)

PL/SQL 过程已成功完成。

登陆目标用户,JOB仍然没有运行:

SQL> conn yangtk/yangtk
已连接。
SQL> select * from t_id;   

        ID
----------
         1

SQL> select job, this_date, next_date, total_time, broken, failures
  2  from user_jobs;

       JOB THIS_DATE           NEXT_DATE           TOTAL_TIME B   FAILURES
---------- ------------------- ------------------- ---------- - ----------
        63                     2010-05-20 02:18:13          0 N          0

由于时间比较晚,没有再继续追查下去。而随后一天比较忙,也没有来得及看

等到第三天准备继续检查这个问题的时候,发现JOB已经开始自动运行了:

SQL> select job, this_date, next_date, total_time, broken, failures
  2  from user_jobs;
       JOB THIS_DATE           NEXT_DATE           TOTAL_TIME B   FAILURES
---------- ------------------- ------------------- ---------- - ----------
        63 21-5
月 -10          21-5月 -10                  42 N          0

SQL> select * from t_id;

        ID
----------
         1
         1
.
.
.
         1
         1
         1
         1

已选择2113行。

和JOB没有启动时唯一的区别在于,Oracle后台的回滚操作已经完成。

存在两种可能性,一种是Oracle在自动回滚的过程中禁止JOB的运行,避免冲突的发生;另一种可能是尝试启动JOB的时候,Oracle访问了数据字典,但是被自动回滚任务锁住。

 

 

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/4227/viewspace-663399/ ,如需转载,请注明出处,否则将追究法律责任。

下一篇: RMAN用户手册总结
请登录后发表评论 登录
全部评论
暂无介绍

注册时间:2007-12-29

  • 博文量
    1964
  • 访问量
    11077131