ablog

不器用で落着きのない技術者のメモ

続・門外不出のOracle現場ワザの v$session_wait から情報収集するスクリプト

続・門外不出のOracle現場ワザ (DB SELECTION) で紹介されているスクリプト*1は v$session_wait から情報収集するスクリプトがあるけど、不要な情報が出力される。

$ ./session_wait.sh|sqlplus

SQL*Plus: Release 9.2.0.7.0 - Production on Fri Jul 31 22:51:10 2009

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.

Enter user-name:
Connected to:
Oracle9i Enterprise Edition Release 9.2.0.7.0 - 64bit Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.7.0 - Production

SQL> SQL> SQL> SQL> SQL>
0731225110,1,db01,,0,ACTIVE,oracle@db01 (PMON),00,0,00,0,0716080621,pmon timer, 300,0,0,0,1349084
0731225110,2,db01,,0,ACTIVE,oracle@db01 (DBW0),00,0,00,0,0716080621,rdbms ipc message, 300,0,0,0,84
...

とこんな具合なので、Perl ワンライナーでフィルタしてやると、

$ ./session_wait9.sh|sqlplus|perl -F, -lane 'print if($#F==17)'
0731225252,1,db01,,0,ACTIVE,oracle@db01 (PMON),00,0,00,0,0716080621,pmon timer, 300,0,0,0,1349184
0731225252,2,db01,,0,ACTIVE,oracle@db01 (DBW0),00,0,00,0,0716080621,rdbms ipc message, 300,0,0,0,184
...

必要な情報のみ出力されるようになった。


[ソースコード]

#!/bin/sh

#本スクリプトはDBマガジンの記事に添付されているものです。
#SLEEP_SECが3に設定されていますが、必要に応じて調整してください。
#LOOP_MAXも必要に応じて調整してください。

#本スクリプトおよびSQLの内容、
#および利用したことによって生じた損害等について、
#株式会社翔泳社、日本オラクルおよび著者は
#一切の責任を負いません。自己責任でご使用ください。
#また、筆者個人のノウハウであるため、
#お問い合わせもご遠慮ください。
#
#特に、スクリプトやSQLを改変した場合の性能へのインパクト、
#データを取得したことによるディスクフル、
#パスワードのセキュリティ漏洩などにはご注意ください。

SLEEP_SEC=3
LOOP_MAX=1200
COUNT=0

echo "/"
echo "set heading off"
echo "set feedback off"
echo "set pagesize 9999"
echo "set linesize 2000"

while [ $COUNT -lt $LOOP_MAX ]
do
 echo "@seswait.sql"
 sleep $SLEEP_SEC
 COUNT=`expr $COUNT + 1`
done
SELECT /*+ INDEX (s) INDEX (w) */
to_char(sysdate, 'MMDDHH24MISS')||','||s.SID||','||s.MACHINE||','||s.USERNAME||
','||s.COMMAND||','||s.STATUS||','||s.PROGRAM||','||s.SQL_ADDRESS||','||
s.SQL_HASH_VALUE||','||s.PREV_SQL_ADDR||','||s.PREV_HASH_VALUE||','||
to_char(s.LOGON_TIME,'MMDDHH24MISS')||','||w.EVENT||', '||w.P1||','||
w.P2||','||w.P3||','||w.WAIT_TIME||','||w.SECONDS_IN_WAIT
FROM V$SESSION s, V$SESSION_WAIT w
WHERE s.SID = w.SID
AND (s.STATUS = 'ACTIVE'
OR w.EVENT NOT IN ('SQL*Net message to client','SQL*Net message from client'));

*1:ダウンロード|翔泳社の本 からダウンロードできる。