Oracle11g 查詢長時間運行的SQL


一、大量的查詢

某些時候,因為SQL的問題,導致數據庫的session大量積壓,服務器的磁盤讀增大,CPU使用率劇增。一般這種SQL,都是一些全表掃描、多表關聯、報表或者排序類的SQL。這中情況很有可能,是客戶端查詢造成的。一般程序里面都會設置客戶端查詢超時時間,一旦某條SQL查詢時間超過了程序設置的超時時間,那么這個客戶端的查詢則被kill掉,但是下發到數據庫的SQL仍然還在運行,直到查詢出結果。因此,這些大量積壓的SQL就是沒用的SQL,需要我們將這些SQLkill掉。

某個session阻塞好幾個session
select 'alter system kill session '||''''||s.SID||','||s.SERIAL#||''''||';',s.SID,s.blocking_session,s.MACHINE,s.OSUSER,s.PROGRAM,
       s.USERNAME,s.last_call_et,a.SQL_ID,s.LOGON_TIME,a.SQL_TEXT,a.SQL_FULLTEXT,
        w.EVENT,a.DISK_READS,a.BUFFER_GETS
from v$process p,v$session s,v$sqlarea a,v$session_wait w
where p.ADDR = s.PADDR and s.SQL_ID = a.sql_id and s.sid = w.SID
and s.STATUS = 'ACTIVE' and s.PROGRAM !='plsqldev.exe' and s.OSUSER !='oracle'
--and a.SQL_TEXT like 'select%'
order by s.last_call_et desc;

二、大量行鎖

某些時候,session突然巨量增加,並且久久不釋放。查詢告警日志,可能發現告警中記錄由死鎖。這種情況,一般由DML語句造成(表的外鍵沒索引,程序邏輯錯亂,網絡波動)

記錄表/行鎖的監控(上面《一》中的監控SQL也可使用查看)

1.建表

-- Create table
create table DB_BLOCK_RECORD
(
  DB_USER         VARCHAR2(30),
  BK_USER         VARCHAR2(30),
  BK_SID          NUMBER not null,
  BK_SERIAL       NUMBER,
  BK_WAIT_EVENT   VARCHAR2(64),
  BK_WAIT_CLASS   VARCHAR2(64),
  BK_APP          VARCHAR2(48),
  BK_MACHINE      VARCHAR2(64),
  BK_OS_USER      VARCHAR2(30),
  BK_SQL_ID       VARCHAR2(13),
  BK_SQL_TEXT     VARCHAR2(1000),
  WT_USER         VARCHAR2(30),
  WT_SID          NUMBER not null,
  WT_SERIAL       NUMBER,
  WT_WAIT_EVENT   VARCHAR2(64),
  WT_WAIT_CLASS   VARCHAR2(64),
  WT_APP          VARCHAR2(48),
  WT_MACHINE      VARCHAR2(64),
  WT_OS_USER      VARCHAR2(30),
  WT_SQL_ID       VARCHAR2(13),
  WT_SQL_TEXT     VARCHAR2(1000),
  LOCK_TYPE       VARCHAR2(26),
  MODE_HELD       VARCHAR2(40),
  MODE_REQUESTED  VARCHAR2(40),
  LOCK_ID1        VARCHAR2(40) not null,
  LOCK_ID2        VARCHAR2(40) not null,
  BLOCKING_OTHERS VARCHAR2(40),
  BK_TIME         DATE default sysdate not null
)
tablespace DBADMIN
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  );
-- Create/Recreate primary, unique and foreign key constraints
alter table DB_BLOCK_RECORD
  add constraint PK_DB_BLOCK_RECOR primary key (BK_SID, WT_SID, LOCK_ID1, LOCK_ID2)
  using index
  tablespace DBADMIN
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  );

2.創建存儲過程

create or replace procedure proc_DB_BLOCK_RECORD as
  v_num            number;
  v_ROWS           number;
  v_count          number;
  cursor v_CURSOR is
    SELECT  bs.username DB_User,
          bs.username BK_User,bs.SID BK_SID,bs.SERIAL# BK_SERIAL,
          bs.EVENT BK_WAIT_EVENT,bs.WAIT_CLASS BK_WAIT_CLASS,bs.program BK_App,bs.machine BK_Machine,
          bs.osuser BK_OS_User,
          bs.SQL_ID BK_SQL_ID,sa.SQL_TEXT BK_SQL_TEXT,
          ws.username WT_User,ws.SID WT_SID,ws.SERIAL# WT_SERIAL,
          ws.EVENT   WT_WAIT_EVENT,ws.WAIT_CLASS WT_WAIT_CLASS,ws.program WT_App,ws.machine WT_Machine,
          ws.osuser WT_OS_User,
          sa.SQL_ID WT_SQL_ID,sa.SQL_TEXT WT_SQL_TEXT,
          DECODE (wk.TYPE,
                  'MR', 'Media Recovery',
                  'RT', 'Redo Thread',
                  'UN', 'USER Name',
                  'TX', 'Row Locks',
                  'TM', 'Table Locks',
                  'UL', 'PL/SQL USER LOCK',
                  'DX', 'Distributed Xaction',
                  'CF', 'Control FILE',
                  'IS', 'Instance State',
                  'FS', 'FILE SET',
                  'IR', 'Instance Recovery',
                  'ST', 'Disk SPACE Transaction',
                  'TS', 'Temp Segment',
                  'IV', 'Library Cache Invalidation',
                  'LS', 'LOG START OR Switch',
                  'RW', 'ROW Wait',
                  'SQ', 'Sequence Number',
                  'TE', 'Extend TABLE',
                  'TT', 'Temp TABLE',
                  wk.TYPE
                 ) lock_type,
          DECODE (hk.lmode,
                  0, 'None',
                  1, 'NULL',
                  2, 'ROW-S (SS)',
                  3, 'ROW-X (SX)',
                  4, 'SHARE',
                  5, 'S/ROW-X (SSX)',
                  6, 'EXCLUSIVE',
                  TO_CHAR (hk.lmode)
                 ) mode_held,
          DECODE (wk.request,
                  0, 'None',
                  1, 'NULL',
                  2, 'ROW-S (SS)',
                  3, 'ROW-X (SX)',
                  4, 'SHARE',
                  5, 'S/ROW-X (SSX)',
                  6, 'EXCLUSIVE',
                  TO_CHAR (wk.request)
                 ) mode_requested,
          TO_CHAR (hk.id1) lock_id1, TO_CHAR (hk.id2) lock_id2,
          DECODE
             (hk.BLOCK,
              0, 'NOT Blocking',          /**//* Not blocking any other processes */
              1, 'Blocking',              /**//* This lock blocks other processes */
              2, 'Global',           /**//* This lock is global, so we can't tell */
              TO_CHAR (hk.BLOCK)
             ) blocking_others  ,sysdate
     FROM v$lock hk, v$session bs, v$lock wk, v$session ws,v$sqlarea sa
    WHERE hk.BLOCK = 1
      AND hk.lmode != 0
      AND hk.lmode != 1
      AND wk.request != 0
      AND wk.TYPE(+) = hk.TYPE
      AND wk.id1(+) = hk.id1
      AND wk.id2(+) = hk.id2
      AND hk.SID = bs.SID(+)
      AND wk.SID = ws.SID(+)
      AND (bs.username IS NOT NULL)
      AND (bs.username <> 'SYSTEM')
      AND (bs.username <> 'SYS')
      and ws.SQL_ID=sa.SQL_ID
ORDER BY 4,11,23,24;
begin
  select count(1) into v_num from dba_blockers;
  v_rows := 0;
  if v_num > 0 then
    for varA in v_CURSOR loop
      insert /*+  IGNORE_ROW_ON_DUPKEY_INDEX(DB_BLOCK_RECORD,PK_DB_BLOCK_RECOR) */
      into DBADMIN.DB_BLOCK_RECORD
      values
        (
         varA.DB_User,varA.BK_User,varA.BK_SID,varA.BK_SERIAL,varA.BK_WAIT_EVENT,varA.BK_WAIT_CLASS,varA.BK_App,
         varA.BK_Machine,varA.BK_OS_User,varA.BK_SQL_ID,varA.BK_SQL_TEXT,
         varA.WT_User,varA.WT_SID,varA.WT_SERIAL,varA.WT_WAIT_EVENT,varA.WT_WAIT_CLASS,
         varA.WT_App,varA.WT_Machine,varA.WT_OS_User,varA.WT_SQL_ID,varA.WT_SQL_TEXT,
         varA.lock_type,varA.mode_held,
         varA.mode_requested,varA.lock_id1,varA.lock_id2,varA.blocking_others,varA.sysdate
           );
       --insert into DBADMIN.DB_BLOCK_RECORD_temp
       --values(varA.BK_SID,varA.BK_SERIAL,varA.WT_SID,varA.WT_SERIAL,varA.lock_id1,varA.lock_id2);
       v_rows := v_rows+1;
    end loop;
    commit;
    ---select  from DBADMIN.DB_BLOCK_RECORD_temp where rownum<=v_rows;
    --DBMS_OUTPUT.PUT_LINE(v_ROWS);
    DBMS_OUTPUT.PUT_LINE(v_ROWS);
  else
    DBMS_OUTPUT.PUT_LINE(0);
  end if;
end;

3.定時任務

cat db_block_record.sh
#!/bin/bash
source /home/oracle/.bash_profile
while true
  do
    sleep 1
    v_log=/u01/dba_scripts/db_block_record/log/db_block_record.log
    v_date=`date +"%Y-%m-%d %H:%M:%S"`
    v_out=`sqlplus -s dbadmin/QazWsx12  <<EOF
    set colsep' ';
    set feedback off;
    set heading off;
    set pagesize 0;
    set termout off;
    set trimout on;
    set trimspool on;
    set serveroutput on;
    exec dbadmin.proc_DB_BLOCK_RECORD
EOF`
    echo "$v_out"
    if [ "$v_out" -gt 0 ]
      then
        echo "$v_date "----" $v_out"" waiter,please check!" >> "$v_log"
    fi
done

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM