#!/usr/bin/ksh #set -x column_name_long=48 A_USERNAME=a16 USR_NOT_NULL=" and s.username != 'NULL'" HOSTNAME=`uname -n` ACTION=DEFAULT ROWNUM=30000 function help { cat < # Show info for one session sl -a # List session with active status sl -r # session actually running an sql | sl -o # list under a short form sl -c # show cpu and db time | sl -ash [nn] # show waits from active session history. sl -t # show events impact breakdown on session | # default is last 60 minutes sl -io # Show session IO | sl -cpu # Report Response time breakdown sl -siz # show session memory size | sl -lw # active session locking and waits (10g) sl -u # limit selection to session owned by | sl -f # Failed over sessions sl -i # program column length is set to | sl -m # display machine name instead of last activity Additionals: ------------ -rac # target GV\$ instead of V\$ -len # len of the column program Example : sl -l r -rn 20 # list all session order by disk reads, limits to 20 first rows Supend session: --------------- sl -sup # Suspend a session (freeze) s=suspend r=resume # Example : sl sup 45 s -->suspend session 45 # sl sup 45 r -->resume session 45 Session stats: sl -l [] # List summary stats. Optionaly order by [] p : hard parse c : sort by CPU r : physical read b : block change g : gets cc : consistent change Dumps: ------ sl -dump [ -pga |-pga_adr | -st ] # Dump session PGA stack, protion of PGA (adr) or Session process state sl -rf -pga # read dump of pga Snapper implementation: sl -p -s -n -g [t|s|l|w|e] -ulike -plike ----------------------- -g # option on snaper, can be cumulated : s - Session Statistics from v$sesstat t - Session Time model info from v$sess_time_model w - Session Wait statistics from v$session_event and v$session_wait l - instance Latch get statistics ( gets + immediate_gets ) e - instance Enqueue lock get statistics Example : sl -p 155 -s 1 -g t -g w EOF exit } FIELD7="s.last_call_et ssa" FIELD4="s.serial#," typeset -u FTYPE while [ -n "$1" ] do case $1 in -ash ) ACTION=ASH; if [ -z "$2" ];then MIN=60 else MIN=$2; shift fi ;; -a ) ACTION="ACTIVE" ;; -c ) ACTION="DB_CPU" ;; -f ) ACTION="SLF" ;; -io ) ACTION="SLIO"; SID=$2 ; shift ;; -cpu ) ACTION=CPU ;; -dump ) ACTION=DUMP ; SID=$2 ; shift ;; -st ) DUMP_VAR=ST ;; -pga ) DUMP_VAR=PGA ;; -pga_adr ) DUMP_VAR=PGA_ADR ; START_ADR=$2 ; END_ADR=$3; shift; shift ;; -g ) GATHER="$GATHER$2" ; shift ;; -i ) column_name_long=41 ;; -l ) ACTION=SLH ; if [ -n "$2" ];then case "$2" in p ) ORDER=" order by t2.value desc" ; shift ;; c ) ORDER=" order by t.value desc" ; shift ;; r ) ORDER=" order by physical_reads desc" ; shift ;; g ) ORDER=" order by consistent_gets desc" ; shift ;; cc) ORDER=" order by consistent_changes desc" ; shift ;; b ) ORDER=" order by block_changes desc" ; shift ;; esac fi ;; -len ) column_name_long=$1 ;; -lw ) ACTION="LOCK_WAIT" ;; -n ) SNAP_PAR3=$2 ; shift ;; -o ) ACTION=OVERVIEW;; -m ) FIELD7="machine " ; FIELD4=service_name,;; -p ) ACTION=SNAPER ; SID=$2; shift ;; -plike) PLIKE=$2 ;shift ;; -r ) ACTION="RUNNING" ;; -rf ) ACTION=READ_DUMP_PGA ; TRC=$2 ; shift ;; -rn ) ROWNUM=$2 ; shift ;; -rac ) G=G ; unset FIELD4; EXIT=exit; INST_ID='s.inst_id,';; -s ) SNAP_PAR2=$2 ; shift ;; -siz ) ACTION=PSIZ if [ -n "$2" ];then AND_SESSIONS=" and sid in ($2)" shift ; fi ;; -sup ) ACTION=SUSPEND; SID=$2 ; STYPE=$3; shift ; shift ;; -t ) ACTION="EV_CPU" ; SID=$2 ; shift;; -u ) unset USR_NOT_NULL ; A_USERNAME=a25 ; column_name_long=32 AND_USER=" and s.username = '$2' " ; shift ;; -ulike) ULIKE=$2 ;shift ;; -v ) set -xv ;; -h ) help;; * ) SID=$1 ; AND_SID=" and s.sid = $1" ; ACTION=SLH ;; esac shift done . $SBIN/scripts/passwd.env . ${GET_PASSWD} $S_USER $ORACLE_SID if [ "x-$CONNECT_STRING" = "x-" ];then echo "could no get a the password of $S_USER" exit 0 fi # ------------------------------------------------------------------------------ # List active sessions # ------------------------------------------------------------------------------ if [ "$ACTION" = "ACTIVE" ];then echo $NN "MACHINE $HOST - ORACLE_SID : $ORACLE_SID $NC" sqlplus -s "$CONNECT_STRING" <'' to see name of ''obj id''' from sys.dual / set term on verify off pagesize 333 linesize 150 feedback off head on col spid format 99999999 head 'Spid' col sid format 99999 head 'Sid' set lines 190 pagesize 66 col username format a16 col EVENT for a45 head 'Event' col lce for 9999999 head 'Secs in|Active' col SECONDS_IN_WAIT form 999999 head 'Secs in|Wait' justify c col bs form 9999 head 'Blk|ses' col rwo for 99999 col rwo for 999999 head 'Obj|Id' select sid, username, sql_id,WAIT_TIME, SECONDS_IN_WAIT, STATE, EVENT, LAST_CALL_ET lce, BLOCKING_SESSION bs, ROW_WAIT_OBJ# rwo from v\$session where status = 'ACTIVE' and username is not null ; EOF exit # ------------------------------------------------------------------------------ # Report Response time breakdown # ------------------------------------------------------------------------------ elif [ "$ACTION" = "SUSPEND" ];then if [ -n "$STYPE" ];then if [ "$STYPE" = 's' ];then FACTION=suspend elif [ "$STYPE" = 'r' ];then FACTION=resume else echo "$TYPE should be 's' or 'r' : Invalid suspend/resume action" exit fi else echo "No suspend/resume action" exit fi echo $NN "MACHINE $HOST - ORACLE_SID : $ORACLE_SID $NC" sqlplus -s "$CONNECT_STRING" < 0 ) b, sys.x\$ksled d where i.kslestim > 0 and b.kslesenm (+) = i.indx and nvl(b.time, 0) < i.kslestim and d.indx = i.indx and d.kslednam not in ( 'Null event', 'KXFQ: Dequeue Range Keys - Slave', 'KXFQ: Dequeuing samples', 'KXFQ: kxfqdeq - dequeue from specific qref', 'KXFQ: kxfqdeq - normal deqeue', 'KXFX: Execution Message Dequeue - Slave', 'KXFX: Parse Reply Dequeue - Query Coord', 'KXFX: Reply Message Dequeue - Query Coord', 'PAR RECOV : Dequeue msg - Slave', 'PAR RECOV : Wait for reply - Query Coord', 'Parallel Query Idle Wait - Slaves', 'PL/SQL lock timer', 'PX Deq: Execute Reply', 'PX Deq: Execution Msg', 'PX Deq: Index Merge Execute', 'PX Deq: Index Merge Reply', 'PX Deq: Par Recov Change Vector', 'PX Deq: Par Recov Execute', 'PX Deq: Par Recov Reply', 'PX Deq: Parse Reply', 'PX Deq: Table Q Get Keys', 'PX Deq: Table Q Normal', 'PX Deq: Table Q Sample', 'PX Deq: Table Q qref', 'PX Deq: Txn Recovery Reply', 'PX Deq: Txn Recovery Start', 'PX Deque wait', 'PX Idle Wait', 'Replication Dequeue', 'Replication Dequeue ', 'SQL*Net message from client', 'SQL*Net message from dblink', 'debugger command', 'parallel query dequeue wait', 'pipe get', 'queue messages', 'rdbms ipc message', 'secondary event', 'single-task message', 'slave wait' ) and d.kslednam not like 'resmgr:%' ) ) order by n_major, n_minor, time desc / EOF exit # ------------------------------------------------------------------------------ # Session IO # ------------------------------------------------------------------------------ elif [ "$ACTION" = "SLIO" ];then if [ -z "$SID" ];then echo "I need a Session ID" exit fi sqlplus -s "$CONNECT_STRING" < -- Adapted to Smenu by bpa 10:06:2009 -------------------------------------------------------- set verify off lines 190 pages 66 column tsize new_value total_size column ratio format 99.99 column ds format a20 col ctype for a30 col atype for a30 with t as ( select to_number(substr(fline, 21)) as tsize from $fname30 where regexp_like(fline, 'Total heap size') ) select sum(tsize) as tsize from t ; with c as ( select atype, csize, sum(csize) over() as t_size, &total_size as heap_size from ( select atype, sum(csize) as csize from ( select to_number(regexp_replace(fline,'.*sz=[[:space:]]+([[:digit:]]+)[[:space:]].*','\1')) csize, rtrim(regexp_replace(fline,'.*sz=[[:space:]]+[[:digit:]]+[[:space:]]+([[:alnum:]]+)[[:space:]].*','\1')) atype, rtrim(regexp_replace(fline,'.*["]+(.*)["].*','\1')) ctype, rtrim(regexp_replace(fline,'.*["]+.*["](.*)','\1')) ds from $fname30 where substr(fline, 1, 7) = ' Chunk' and rtrim(regexp_replace(fline,'.*sz=[[:space:]]+[[:digit:]]+[[:space:]]+([[:alnum:]]+)[[:space:]].*','\1')) <> 'free' ) group by atype ) ) select atype, csize, heap_size, (csize/heap_size)*100 as ratio from c union all select 'free', heap_size-t_size, heap_size, ((heap_size-t_size)/heap_size)*100 as ratio from c where rownum = 1 ; with c as ( select ctype, csize, sum(csize) over() as t_size, &total_size as heap_size from ( select ctype, sum(csize) as csize from ( select to_number(regexp_replace(fline,'.*sz=[[:space:]]+([[:digit:]]+)[[:space:]].*','\1')) csize, rtrim(regexp_replace(fline,'.*sz=[[:space:]]+[[:digit:]]+[[:space:]]+([[:alnum:]]+)[[:space:]].*','\1')) atype, rtrim(regexp_replace(fline,'.*["]+(.*)["].*','\1')) ctype, rtrim(regexp_replace(fline,'.*["]+.*["](.*)','\1')) ds from $fname30 where substr(fline, 1, 7) = ' Chunk' and rtrim(regexp_replace(fline,'.*sz=[[:space:]]+[[:digit:]]+[[:space:]]+([[:alnum:]]+)[[:space:]].*','\1')) <> 'free' ) group by ctype ) ) select ctype, csize, heap_size, (csize/heap_size)*100 as ratio from c union all select 'free', heap_size-t_size, heap_size, ((heap_size-t_size)/heap_size)*100 as ratio from c where rownum = 1 ; with c as ( select ds, csize, sum(csize) over() as t_size, &total_size as heap_size from ( select ds, sum(csize) as csize from ( select to_number(regexp_replace(fline,'.*sz=[[:space:]]+([[:digit:]]+)[[:space:]].*','\1')) csize, rtrim(regexp_replace(fline,'.*sz=[[:space:]]+[[:digit:]]+[[:space:]]+([[:alnum:]]+)[[:space:]].*','\1')) atype, rtrim(regexp_replace(fline,'.*["]+(.*)["].*','\1')) ctype, rtrim(regexp_replace(fline,'.*["]+.*["][[:space:]]+ds=(.*)','\1')) ds from $fname30 where substr(fline, 1, 7) = ' Chunk' and regexp_like(fline, 'ds=' ) ) group by ds ) ) select ds, csize, heap_size, (csize/heap_size)*100 as ratio from c union all select 'free', heap_size-t_size, heap_size, ((heap_size-t_size)/heap_size)*100 as ratio from c where rownum = 1 ; EOF # drop now the external table. var=`sqlplus -s "$CONNECT_STRING" < 0 then output(' '); output(chr(8)); output('-- Parameters used: snapper.sql '||'&snapper_options'||' '||to_char(&snapper_sleep)||' ' ||to_char(&snapper_count)||' '||'$SNAP_PAR4_C'); output(chr(8)); output(' '); end if; -- initialize statistic and event name array -- fetch statistic names with their adjusted IDs select * bulk collect into sn_tmp from ( select 'STAT' stype, statistic# - pls_adjust statistic#, name from sys.${G}v_\$statname where lv_gather like '%s%' -- union all select 'WAIT', event# + (select count(*) from sys.${G}v_\$statname) + 1 - pls_adjust, name from sys.${G}v_\$event_name where lv_gather like '%w%' -- &_IF_ORA10_OR_HIGHER union all &_IF_ORA10_OR_HIGHER select 'TIME' stype, stat_id - pls_adjust statistic#, stat_name name &_IF_ORA10_OR_HIGHER from sys.${G}v_\$sys_time_model &_IF_ORA10_OR_HIGHER where lv_gather like '%t%' -- union all select ' LAT', l.latch# + (select count(*) from sys.${G}v_\$statname) + (select count(*) from sys.${G}v_\$event_name) + 1 - pls_adjust statistic#, name from sys.${G}v_\$latch l where lv_gather like '%l%' -- union all select ' ENQ', ascii(substr(e.eq_type,1,1))*256 + ascii(substr(e.eq_type,2,1)) + (select count(*) from sys.${G}v_\$statname) + (select count(*) from sys.${G}v_\$event_name) + (select count(*) from sys.${G}v_\$latch) + 1 - pls_adjust statistic#, eq_type from ( select es.eq_type &_IF_ORA10_OR_HIGHER ||' - '||lt.name eq_type, total_req# from sys.${G}v_\$enqueue_stat es &_IF_ORA10_OR_HIGHER , V\$lock_type lt &_IF_ORA10_OR_HIGHER where es.eq_type = lt.type ) e where lv_gather like '%e%' ) order by stype, statistic#; -- store these into an index_by array organized by statistic# for fast lookup --output('sn_tmp.count='||sn_tmp.count); --output('lv_gather='||lv_gather); for i in 1..sn_tmp.count loop -- output('i='||i||' statistic#='||sn_tmp(i).statistic#); sn(sn_tmp(i).statistic#) := sn_tmp(i); end loop; -- main sampling loop for c in 1..&snapper_count loop -- print header if required if pagesize > 0 and mod(c-1, pagesize) = 0 then output(rpad('--',141,'-')); output('HEAD, SID, SNAPSHOT START , SECONDS, TYPE, ' ||rpad('STATISTIC',40,' ') ||', DELTA, D/SEC, HDELTA, HD/SEC' ); output(rpad('-',141,'-')); else if pagesize = -1 and c = 1 then output('HEAD, SID, SNAPSHOT START , SECONDS, TYPE, ' ||rpad('STATISTIC',40,' ') ||', DELTA, D/SEC, HDELTA, HD/SEC' ); end if; end if; if c = 1 then snap(d1,s1); else d1 := d2; s1 := s2; end if; -- c = 1 dbms_lock.sleep( (&snapper_sleep - (sysdate - d1)) ); -- dbms_lock.sleep( (&snapper_sleep - (sysdate - d1))*1000/1024 ); snap(d2,s2); changed_values := 0; missing_values_s1 := 0; missing_values_s2 := 0; i :=1; -- iteration counter (for debugging) a :=1; -- s1 array index b :=1; -- s2 array index while ( a <= s1.count and b <= s2.count ) loop delta := 0; -- don't print case when s1(a).sid = s2(b).sid then case when s1(a).statistic# = s2(b).statistic# then delta := s2(b).value - s1(a).value; if delta != 0 then fout(); end if; a := a + 1; b := b + 1; when s1(a).statistic# > s2(b).statistic# then delta := s2(b).value; if delta != 0 then fout(); end if; b := b + 1; when s1(a).statistic# < s2(b).statistic# then output('ERROR, s1(a).statistic# < s2(b).statistic#, a='||to_char(a)||' b='||to_char(b)||' s1.count='||s1.count||' s2.count='||s2.count||' s2.count='||s2.count); a := a + 1; b := b + 1; else output('ERROR, s1(a).statistic# ? s2(b).statistic#, a='||to_char(a)||' b='||to_char(b)||' s1.count='||s1.count||' s2.count='||s2.count||' s2.count='||s2.count); a := a + 1; b := b + 1; end case; -- s1(a).statistic# ... s2(b).statistic# when s1(a).sid > s2(b).sid then delta := s2(b).value; if delta != 0 then fout(); end if; b := b + 1; when s1(a).sid < s2(b).sid then output('WARN, Session has disappeared during snapshot, ignoring SID='||to_char(s2(b).sid)||' a='||to_char(a)||' b='||to_char(b)||' s1.count='||s1.count||' s2.count='||s2.count||' s2.count='||s2.count); a := a + 1; else output('ERROR, Should not be here, SID='||to_char(s2(b).sid)||' a='||to_char(a)||' b='||to_char(b)||' s1.count='||s1.count||' s2.count='||s2.count||' s2.count='||s2.count); end case; -- s1(a).sid ... s2(b).sid i:=i+1; if delta != 0 then changed_values := changed_values + 1; end if; -- delta != 0 end loop; -- while ( a <= s1.count and b <= s2.count ) if pagesize > 0 and changed_values > 0 then output('-- End of snap '||to_char(c)); end if; end loop; -- for c in 1..snapper_count end; / undefine snapper_oraversion undefine snapper_sleep undefine snapper_count undefine snapper_sid undefine _IF_ORA10_OR_HIGHER undefine _IF_DBMS_SYSTEM_ACCESSIBLE col snapper_oraversion clear col dbms_system_accessible clear EOF # ---------------- # Events and CPU time for a session # ---------------- elif [ "$ACTION" = "EV_CPU" ];then if [ -z "$SID" ];then echo echo echo " Error : I need an Session SID\n" echo " sl -t 1 " echo echo exit fi echo "MACHINE $HOSTNAME - ORACLE_SID : $ORACLE_SID Page: 1" sqlplus -s "$CONNECT_STRING" < 0 order by 6 desc / EOF # ---------------- # ASH # ---------------- elif [ "$ACTION" = "ASH" ];then sqlplus -s "$CONNECT_STRING" <= SYSDATE - ($MIN / 1440) -- and s.last_call_et >= 60 GROUP BY DECODE (a.session_state, 'WAITING', a.event, NULL), a.session_id, a.sql_id, s.username, a.session_state ORDER by 1; EOF # ---------------- # Size # ---------------- elif [ "$ACTION" = "PSIZ" ];then echo "MACHINE $HOSTNAME - ORACLE_SID : $ORACLE_SID Page: 1" sqlplus -s "$CONNECT_STRING" < 0 and v.sid = s. sid and row_wait_obj# = object_id (+); EOF # -------------- # Running # -------------- elif [ "$ACTION" = "RUNNING" ];then if [ -n "$G" ];then AND_INST=" and inst_id = s.inst_id " fi echo "MACHINE $HOSTNAME - ORACLE_SID : $ORACLE_SID Page: 1" sqlplus -s "$CONNECT_STRING" <