如何监控oracle进程的cpu使用率?
需求:昨天由于一个应用中的SQL写得不好,DB差点当机,占CPU 58%(朋友的描述),不理想的sql通常会导致cpu使用率过高,数据库挂起,系统变慢,进而可能引起系统的崩溃,结果很可怕,后果很严重
监控:通过shell脚本来实时监控oracle进程,若某个process的cpu使用率超过设定的阀值,则提取相关的进程信息,所运行的sql语句进行邮件或是短信报警
环境:linux as3 +oracle9i
1.监控脚本:
[oracle@localhost oracle]$ cat /home/oracle/monitor_scripts/cpu30_alter.sh
#!/bin/ksh
##########################################
# Check a single process use cpu >30% #
# Create by Jinting Xu #
# Created date:2007-3-07 #
# Modified date: #
##########################################
##########################################
# Check a single process use cpu >30% #
# Create by Jinting Xu #
# Created date:2007-3-07 #
# Modified date: #
##########################################
# Define variables
recipt='xujt@senabc.com' --邮件报警
Mon_dir=/home/oracle/monitor_scripts/log
Vpara=30 --阀值,某个进程cpu超过30%,进行报警
recipt='xujt@senabc.com' --邮件报警
Mon_dir=/home/oracle/monitor_scripts/log
Vpara=30 --阀值,某个进程cpu超过30%,进行报警
. /home/oracle/.bash_profile
cd $Mon_dir
ps aux| grep "(LOCAL=NO)"|sort +3 -r|awk '{ if ($3 > '$Vpara' ) print $2,$3,$11$12}' >cpu_alert.log --只监控oracle客户端进程
if [ -s cpu_alert.log ]; then
cat cpu_alert.log>highcpu_sql.alert.all
while read LINE
do
Vpid=`echo $LINE|awk '{print $1}'`
do
Vpid=`echo $LINE|awk '{print $1}'`
$ORACLE_HOME/bin/sqlplus "/ as sysdba"<<!
set feed off
set linesize 100
set pagesize 200
spool highcpu_sql.alert
set feed off
set linesize 100
set pagesize 200
spool highcpu_sql.alert
SELECT /*+ ORDERED */ sql_text
FROM v/$sqltext a
WHERE (a.hash_value, a.address) IN
(SELECT DECODE(sql_hash_value, 0, prev_hash_value, sql_hash_value),
DECODE(sql_hash_value, 0, prev_sql_addr, sql_address)
FROM v/$session b
WHERE b.paddr =
(SELECT addr FROM v/$process c WHERE c.spid = $Vpid))
ORDER BY piece ASC;
FROM v/$sqltext a
WHERE (a.hash_value, a.address) IN
(SELECT DECODE(sql_hash_value, 0, prev_hash_value, sql_hash_value),
DECODE(sql_hash_value, 0, prev_sql_addr, sql_address)
FROM v/$session b
WHERE b.paddr =
(SELECT addr FROM v/$process c WHERE c.spid = $Vpid))
ORDER BY piece ASC;
spool off
exit
!
exit
!
cat highcpu_sql.alert >> highcpu_sql.alert.all
done < cpu_alert.log
done < cpu_alert.log
if [ -s highcpu_sql.alert.all ]; then
cat highcpu_sql.alert.all|mail -s " ORACLE single process exceed 30%,top sql" $recipt
>highcpu_sql.alert.all
fi
cat highcpu_sql.alert.all|mail -s " ORACLE single process exceed 30%,top sql" $recipt
>highcpu_sql.alert.all
fi
fi
2.设置crontab,每5分钟监控一次
[oracle@localhost oracle]$ crontab -l
#min hour day month dayofweek command
*/5 * * * * /home/oracle/monitor_scripts/cpu30_alter.sh
#min hour day month dayofweek command
*/5 * * * * /home/oracle/monitor_scripts/cpu30_alter.sh
3.报警内容:
一封邮件报警信息,由进程信息和sql信息组成
5888 59.5 oraclesensky(LOCAL=NO) --进程
SQL>
SQL> SELECT /*+ ORDERED */ sql_text
2 FROM v$sqltext a
3 WHERE (a.hash_value, a.address) IN
4 (SELECT DECODE(sql_hash_value, 0, prev_hash_value, sql_hash_value),
5 DECODE(sql_hash_value, 0, prev_sql_addr, sql_address)
6 FROM v$session b
7 WHERE b.paddr =
8 (SELECT addr FROM v$process c WHERE c.spid = 5888))
9 ORDER BY piece ASC;
SQL>
SQL> SELECT /*+ ORDERED */ sql_text
2 FROM v$sqltext a
3 WHERE (a.hash_value, a.address) IN
4 (SELECT DECODE(sql_hash_value, 0, prev_hash_value, sql_hash_value),
5 DECODE(sql_hash_value, 0, prev_sql_addr, sql_address)
6 FROM v$session b
7 WHERE b.paddr =
8 (SELECT addr FROM v$process c WHERE c.spid = 5888))
9 ORDER BY piece ASC;
SQL_TEXT --相关sql
----------------------------------------------------------------
SELECT "TRADE_ID","SND_PHONE","SENDED_TIME","FSTATE" FROM "V_SEN
D_HISTORY_CONT" "MT" WHERE "SENDED_TIME"<:1 AND "SENDED_TIME">=:
2 AND "FSTATE"=(-127) AND :3="TRADE_ID" AND :4=TO_NUMBER("SND_PH
ONE")
SQL>
SQL> spool off
----------------------------------------------------------------
SELECT "TRADE_ID","SND_PHONE","SENDED_TIME","FSTATE" FROM "V_SEN
D_HISTORY_CONT" "MT" WHERE "SENDED_TIME"<:1 AND "SENDED_TIME">=:
2 AND "FSTATE"=(-127) AND :3="TRADE_ID" AND :4=TO_NUMBER("SND_PH
ONE")
SQL>
SQL> spool off