1#! /bin/sh 2# $Id$ 3# 4# Display environment's deadlocks based on "db_stat -Co" output. 5 6t1=__a 7t2=__b 8 9trap 'rm -f $t1 $t2; exit 0' 0 1 2 3 13 15 10 11if [ $# -ne 1 ]; then 12 echo "Usage: dd.sh [db_stat -Co output]" 13 exit 1 14fi 15 16if `egrep '\<WAIT\>.*\<page\>' $1 > /dev/null`; then 17 n=`egrep '\<WAIT\>.*\<page\>' $1 | wc -l | awk '{print $1}'` 18 echo "dd.sh: $1: $n page locks in a WAIT state." 19else 20 echo "dd.sh: $1: No page locks in a WAIT state found." 21 exit 1 22fi 23 24# Print out list of node wait states, and output cycles in the graph. 25egrep '\<WAIT\>.*\<page\>' $1 | awk '{print $1 " " $5 " " $7}' | 26while read l f p; do 27 for i in `egrep "\<HELD\>.*\<$f\>.*\<page\>.*\<$p\>" $1 | 28 awk '{print $1}'`; do 29 echo "$l $i" 30 done 31done | tsort > /dev/null 2>$t1 32 33# Display the locks in a single cycle. 34c=1 35display_one() { 36 if [ -s $1 ]; then 37 echo "Deadlock #$c ============" 38 c=`expr $c + 1` 39 cat $1 | sort -n +6 40 :> $1 41 fi 42} 43 44# Display the locks in all of the cycles. 45# 46# Requires tsort output some text before each list of nodes in the cycle, 47# and the actual node displayed on the line be the second (white-space) 48# separated item on the line. For example: 49# 50# tsort: cycle in data 51# tsort: 8000177f 52# tsort: 80001792 53# tsort: 80001774 54# tsort: cycle in data 55# tsort: 80001776 56# tsort: 80001793 57# tsort: cycle in data 58# tsort: 8000176a 59# tsort: 8000178a 60# 61# XXX 62# Currently, db_stat doesn't display the implicit wait relationship between 63# parent and child transactions, where the parent won't release a lock until 64# the child commits/aborts. This means the deadlock where parent holds a 65# lock, thread A waits on parent, child waits on thread A won't be shown. 66if [ -s $t1 ]; then 67 :>$t2 68 while read a b; do 69 case $b in 70 [0-9]*) 71 egrep $b $1 >> $t2;; 72 *) 73 display_one $t2;; 74 esac 75 done < $t1 76 display_one $t2 77else 78 echo 'No deadlocks found.' 79fi 80 81exit 0 82