oracle创建job:定时杀死慢查询

本文是记一次运维过程中实际发生的一个案例

背景介绍

应用这边运行缓慢,卡顿严重,查看数据库所在服务器,CPU100%,怀疑有大量查询占用资源导致。故查询DB中的慢sql,发现确实有耗时相当长的sql。
用kill 命令杀掉该进程之后,还是过一段时间后产生,但一时半会没法定位sql的产生来源,故只能想办法先定时处理掉这部分慢sql。
这里想到了 利用oracle 创建存储过程,循环查找慢sql,并kill session,并用oracle的job来定时执行该存储过程。

操作过程(基本可以复制粘贴使用)
以下是进入sqlplus进行的操作

1 创建表,用于记录被kill的sql;

--CREATE LOG TABLE 
CREATE TABLE KILL_SESS_HIST   AS 
SELECT S.*,T.START_TIME
      FROM V$TRANSACTION T,V$SESSION S 
           WHERE S.TADDR=T.ADDR AND T.START_TIME<TO_CHAR((SYSDATE-1/1440),'YY/HH/DD HH24:MI:SS')
                     
alter table KILL_SESS_HIST    add (kill_time date default sysdate);

2 创建存储过程;

CREATE 	OR REPLACE PROCEDURE  P_KILL_SES_BEF1S
  IS
BEGIN
  FOR
   REC_ACT_SESS IN (SELECT S.SID,
                           S.SERIAL#,
                           S.MACHINE,
                           S.LAST_CALL_ET,
                           S.STATUS,
                           S.USERNAME,
                           S.TYPE,
                           S.SQL_ID,
                           S.EVENT,
                           T.START_TIME
                      FROM V$TRANSACTION T, V$SESSION S
                     WHERE S.TADDR = T.ADDR
                       AND T.START_TIME <
                           TO_CHAR((SYSDATE - 1 / 1440), 'YY/HH/DD HH24:MI:SS'))

   LOOP
    INSERT INTO KILL_SESS_HIST
      (SID,
       SERIAL#,
       MACHINE,
       LAST_CALL_ET,
       USERNAME,
       TYPE,
       SQL_ID,
       START_TIME,
       EVENT)
    VALUES
      (REC_ACT_SESS.SID,
       REC_ACT_SESS.SERIAL#,
       REC_ACT_SESS.MACHINE,
       REC_ACT_SESS.LAST_CALL_ET,
       REC_ACT_SESS.USERNAME,
       REC_ACT_SESS.TYPE,
       REC_ACT_SESS.SQL_ID,
       REC_ACT_SESS.START_TIME,
       REC_ACT_SESS.EVENT);
    EXECUTE immediate 'ALTER SYSTEM KILL SESSION ' || CHR(39) ||
                      REC_ACT_SESS.SID || ',' || REC_ACT_SESS.SERIAL# ||
                      CHR(39);
    dbms_output.put_line('ALTER SYSTEM KILL SESSION ' || CHR(39) ||
                         REC_ACT_SESS.SID || ',' || REC_ACT_SESS.SERIAL# ||
                         CHR(39));
    COMMIT;
  END LOOP;
END;
/

注意末尾要以“/”结尾,命令行才能执行
下图标志表示成功
在这里插入图片描述

3 调用存储过程;

set serveroutput on
call P_KILL_SES_BEF1S();

在这里插入图片描述
4 创建job;

 DECLARE
     n number;
    begin
      dba_job.submit(n=>n,
                      'P_KILL_SES_BEF1S;',
                      to_date('22-02-2020 14:47:00', 'dd-mm-yyyy hh24:mi:ss'),
                      'sysdate+1/1440');
      commit;
    end;
    .

在这里插入图片描述
注意最后一行是一个英文句号,表示代码编辑完毕。用英文斜杠,执行该代码

结果如图所示job运行成功在这里插入图片描述
关于存储过程介绍、job创建的其它指令,有很多,感兴趣可以自行百度了解。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值