加入收藏 | 设为首页 | 会员中心 | 我要投稿 甘南站长网 (https://www.0941zz.com/)- 科技、行业物联网、开发、云计算、云管理!
当前位置: 首页 > 数据库 > Oracle > 正文

终止正在运行的ORACLE作业

发布时间:2023-02-18 09:18:03 所属栏目:Oracle 来源:互联网
导读:图文解释 如果您曾经认为取消 oracle job很容易,那么让我向您展示让我今天头痛的事情。 我们正在测试一个使用自定义代码在数据库之间出队和传播AQ消息的应用程序。共有9个流程,所有流程都使用提交为作业DBMS_JOB。他们应该一直运行,等待消息出队。有时,
  图文解释
  如果您曾经认为取消 oracle job很容易,那么让我向您展示让我今天头痛的事情。
  我们正在测试一个使用自定义代码在数据库之间出队和传播AQ消息的应用程序。共有9个流程,所有流程都使用提交为作业DBMS_JOB。他们应该一直运行,等待消息出队。有时,我需要杀死它们以便重新编译它们正在执行的对象。
 
  这些步骤非常简单:删除/中断所有有问题的作业,终止正在运行的作业,使用新版本重新编译软件包,然后再次提交/取消中断作业。但这一次,事情进展不如我预期的顺利。我们来看一下。
 
  首先,我删除所有当前正在运行的作业:
 
  SYS@ORCL>select 'exec dbms_ijob.remove('||job||');' from dba_jobs_running;
  
  'EXECDBMS_IJOB.REMOVE('||JOB||');'
  ----------------------------------------------------------------
  exec dbms_ijob.remove(261);
  exec dbms_ijob.remove(264);
  exec dbms_ijob.remove(267);
  exec dbms_ijob.remove(262);
  exec dbms_ijob.remove(265);
  exec dbms_ijob.remove(268);
  exec dbms_ijob.remove(263);
  exec dbms_ijob.remove(266);
  exec dbms_ijob.remove(269);
  
  9 rows selected.
  
  SYS@ORCL>exec dbms_ijob.remove(261);
  PL/sql procedure successfully completed.
  
  SYS@ORCL> exec dbms_ijob.remove(264);
  PL/sql procedure successfully completed.
  
  SYS@ORCL> exec dbms_ijob.remove(267);
  PL/sql procedure successfully completed.
  
  SYS@ORCL> exec dbms_ijob.remove(262);
  PL/sql procedure successfully completed.
  
  SYS@ORCL> exec dbms_ijob.remove(265);
  PL/sql procedure successfully completed.
  
  SYS@ORCL> exec dbms_ijob.remove(268);
  PL/sql procedure successfully completed.
  
  SYS@ORCL> exec dbms_ijob.remove(263);
  PL/sql procedure successfully completed.
  
  SYS@ORCL> exec dbms_ijob.remove(266);
  PL/sql procedure successfully completed.
  
  SYS@ORCL> exec dbms_ijob.remove(269);
  PL/sql procedure successfully completed.
  下一步,我将终止正在运行的作业的会话:
 
  SYS@ORCL>select 'alter system kill session '''||sid||','||serial#||''';' from v$session where sid in (select sid from dba_jobs_running);
  
  'ALTERSYstemKILLSESSION'''||SID||','||SERIAL#||''';'
  --------------------------------------------------------------------------------
  alter system kill session '120,73';
  alter system kill session '122,111';
  alter system kill session '123,788';
  alter system kill session '136,20';
  alter system kill session '137,28';
  alter system kill session '138,143';
  alter system kill session '142,132';
  alter system kill session '144,129';
  alter system kill session '159,68';
  
  9 rows selected.
  
  SYS@ORCL>alter system kill session '120,73';
  System altered.
  
  SYS@ORCL> alter system kill session '122,111';
  System altered.
  
  SYS@ORCL> alter system kill session '123,788';
  System altered.
  
  SYS@ORCL> alter system kill session '136,20';
  System altered.
  
  SYS@ORCL> alter system kill session '137,28';
  System altered.
  
  SYS@ORCL> alter system kill session '138,143';
  System altered.
  
  SYS@ORCL> alter system kill session '142,132';
  System altered.
  
  SYS@ORCL> alter system kill session '144,129';
  System altered.
  
  SYS@ORCL> alter system kill session '159,68';
  System altered.
  并且正在运行的工作不见了:
 
  SYS@ORCL>select count(*) from dba_jobs_running;
  
    COUNT(*)
  ----------
           0
  我认为这很好,但是几秒钟后工作又回来了!
 
  SYS@ORCL> /
  
    COUNT(*)
  ----------
           9
  我发现这种行为非常有趣,因此我在网上进行搜索,并找到了一个非常不错的博客,详细解释了DBMS_JOB工作的行为。
 
  这暗示了OS进程实际上可以使数据库进程保持活动状态。因此,我认为这听起来很合理-让我们杀死OS进程。
 
  SYS@ORCL>!ps -ef | grep ora_j
  oracle   16234     1  0 12:58 ?        00:00:00 ora_j000_ORCL
  oracle   16236     1  9 12:58 ?        00:00:07 ora_j001_ORCL
  oracle   16238     1  9 12:58 ?        00:00:07 ora_j002_ORCL
  oracle   16240     1  0 12:58 ?        00:00:00 ora_j003_ORCL
  oracle   16242     1  0 12:58 ?        00:00:00 ora_j004_ORCL
  oracle   16244     1  8 12:58 ?        00:00:06 ora_j005_ORCL
  oracle   16246     1  9 12:58 ?        00:00:07 ora_j006_ORCL
  oracle   16248     1  0 12:58 ?        00:00:00 ora_j007_ORCL
  oracle   16250     1  9 12:58 ?        00:00:07 ora_j008_ORCL
  oracle   16280 15459  0 12:59 pts/0    00:00:00 /bin/bash -c ps -ef | grep ora_j
  oracle   16282 16280  0 12:59 pts/0    00:00:00 grep ora_j
  
  SYS@ORCL>!kill -9 16234 16236 16238 16240 16242 16244 16246 16248 16250 16252
  做完了!
 
  嗯,但不是真的-一段时间后,工作从死里复生。在不同的Oracle PID和不同的OS PID下。
 
  SYS@ORCL>select count(*) from dba_jobs_running;
  
    COUNT(*)
  ----------
           9
  现在,这让我感到非常困惑。我如何摆脱它们?
 
  当然!我为什么以前没有想到这个?我将设置job_queue_processes为0。终止进程,它们将不会重生。
 
  SYS@ORCL>alter system set job_queue_processes=0;
  
  System altered.
  再次杀死所有进程。
 
  SYS@ORCL>select count(*) from dba_jobs_running;
  
    COUNT(*)
  ----------
           0
  
  SYS@ORCL>alter system set job_queue_processes=10;
  
  System altered.
  
  SYS@ORCL>select count(*) from dba_jobs_running;
  
    COUNT(*)
  ----------
           9
  糟糕,他们又回来了!请注意,作业已从DBA_JOBs表中删除,正在运行的作业正在引用不存在的作业ID。他们如何重生?
 
  SYS@ORCL>select j.what,j.job,r.sid from dba_jobs j,dba_jobs_running r where j.job in (select job from dba_jobs_running) and j.job=r.job order by j.what;
  
  no rows selected
  我决定扩展我的工作知识,并阅读了James Koopmann的整个博客。然后我看到了光!在文章下的评论中提到的用户JB(感谢JB,我也学到了很难的方法),COMMIT在操作作业后必须运行该用户。

(编辑:甘南站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读