94 lines
2.9 KiB
Bash
94 lines
2.9 KiB
Bash
#!/bin/ksh
|
|
|
|
#--------------------------------------------------------------------------------
|
|
#--
|
|
#-- File name: enq_trace.sh
|
|
#-- Purpose: Trace specific enqueue lock gets and process activity during
|
|
#-- lock holding to find out why exactly was a lock taken and why
|
|
#-- hasn't it been released fast enough. This script should be used
|
|
#-- only when conventional troubleshooting mechanisms
|
|
#-- (v$ views, ASH, hanganalyze, systemstate dumps) do not give
|
|
#-- enough relevant details about the hang
|
|
#--
|
|
#-- Author: Tanel Poder
|
|
#-- Copyright: (c) http://www.tanelpoder.com
|
|
#--
|
|
#-- Other: EXPERIMENTAL! This script needs reviewinng and adjustment,
|
|
#-- case by case. It's meant for diagnosing very specific hangs
|
|
#-- and you need to know what you're doing before running it in
|
|
#-- production
|
|
#--
|
|
#--------------------------------------------------------------------------------
|
|
|
|
|
|
# Set the lock type# we want to trace (should be 22 for CF enqueue on 11.1.0.7 and 18 on 10.2.0.3)
|
|
LOCK_TYPE=18
|
|
|
|
# ---------------------------------------------------------------
|
|
# -- You can verify what's the correct lock type# for CF enqueue
|
|
# -- using this query (run as SYS). Set the LOCK_TYPE variable
|
|
# -- above to match the result of the query
|
|
# ---------------------------------------------------------------
|
|
# select
|
|
# i
|
|
# from
|
|
# (
|
|
# select
|
|
# rest.indx i,
|
|
# rest.resname type
|
|
# from X$KSIRESTYP rest, X$KSQEQTYP eqt
|
|
# where (rest.inst_id = eqt.inst_id)
|
|
# and (rest.indx = eqt.indx)
|
|
# and (rest.indx > 0)
|
|
# )
|
|
# where
|
|
# type = 'CF'
|
|
# /
|
|
# ---------------------------------------------------------------
|
|
|
|
|
|
dtrace $LOCK_TYPE -qn '
|
|
/* ring buffer policy probably not needed due low trace volume so its commented out
|
|
#pragma D option bufpolicy=ring
|
|
#pragma D option bufsize=256k
|
|
*/
|
|
|
|
pid*:oracle:ksqgtlctx:entry
|
|
/arg4 == $1/
|
|
{
|
|
gettime=timestamp;
|
|
enqHolder = pid;
|
|
enqAddress = arg0;
|
|
printf("%d [%Y] getting enqueue: pid=%d enqAddress=0x%x locktype#=%d get_stack={", gettime, walltimestamp, pid, enqAddress, arg4);
|
|
ustack(50);
|
|
printf("}\n");
|
|
}
|
|
|
|
pid*:oracle:ksqrcl:entry
|
|
/arg0 == enqAddress/ {
|
|
printf("%d [%Y] releasing enqueue: pid=%d enqAddress=0x%x usec_held=%d\n", timestamp, walltimestamp, pid, arg0, (timestamp-gettime)/1000);
|
|
enqAddress = 0;
|
|
}
|
|
|
|
pid*:oracle:kslwtb_tm:entry
|
|
/enqAddress && enqHolder == pid/ {
|
|
currentWait = arg0;
|
|
}
|
|
|
|
pid*:oracle:kslwte_tm:return
|
|
/enqAddress && enqHolder == pid/ {
|
|
currentWait = 0;
|
|
}
|
|
|
|
tick-1sec
|
|
/enqAddress/
|
|
{
|
|
printf("%d [%Y] still holding enqueue: pid=%d enqAddress=0x%x current_wait=%d current_stack={", timestamp, walltimestamp, pid, enqAddress, currentWait);
|
|
stack(50);
|
|
ustack(50);
|
|
printf("}\n");
|
|
}
|
|
'
|
|
|
|
|