大家好,想请教一个问题:
我想问一下,当我用sqlplus命令发出一个比较消耗cpu的sql语句时,我发现对同样的pid,在ps aux与topas下看到的占用cpu大小并不相同。
我的目的是这样的:
由于在晚上时,某些oracle 的batch job在运行时会突然占用比较多的cpu,我们知道,根据这个pid可以获得这个进程所发出的sql语句。因此,我希望写一个脚本获取pid的信息。
如:对在某一时期内持续占用cpu某个百分比的进程(如在3分钟内该进程持续占用cpu5%),将其进程号取出插入到一张表中,然后我利用这个进程号获取sql语句。
在脚本中,我用的是ps aux来获取进程信息,但当我做测试时,发现ps aux取出的结果与topas相差停大的。
因此,我想知道,到底用什么命令可以真实反应进程占用cpu呢?
我的脚本如下:(测试环境,比例为1%,持续时间为3秒)
#!/usr/bin/ksh
#----------------------------------------------------------------------------
#Enviroment setting
#----------------------------------------------------------------------------
export ORACLE_SID=abcd
export ORACLE_HOME=/u01/app/oracle/product/9.2.0
export PATH=$ORACLE_HOME/bin:$PATH
export HOME=/u79/home/oracle
#----------------------------------------------------------------------------
#Find out pid that cpu usage > 1% and keeping time >3 seconds and insert the values
#into table system.abcd_pid
for i in `ps aux |grep oracle | awk '{if ($3 ~/[0-9]/ && $3 > 1) print $2}'` ##i = PID
do
if [ `ps aux |grep $i | awk '{printf "%d", $3}'` -gt "1" ]
then
sleep 3 #sleep 3 = 3 seconds
if [ `ps aux |grep $i | awk '{printf "%d", $3}'` -gt "1" ]
then
echo $i >test1
./aa
fi
fi
done
aa脚本的内容:
export ORACLE_SID=abcd
cat test1| awk '{print $1}'| while read PID
do
$ORACLE_HOME/bin/sqlplus system/testmanager <<EOF
insert into abcd_pid values(sysdate,$PID);
commit;
exit
EOF
done
对AIX不大熟,感谢大家帮忙。
yanbing 回复于:2007-11-27 21:10:51
还真没注意ps aux和topas的输出关于cpu%有什么不同的,不过,你说的差距挺大具体是什么情况呢?是按比例有增减还是完全不靠谱的那种不同,连顺序都不一样呢?
如果是前者,大可继续你的思路,只不过以ps aux为准就好了,如果是后者,还没想到什么好办法。
有熟悉这方面的兄弟么?一起讨论讨论啊!这可是解决日常进程监控的好办法呢!
chinadns 回复于:2007-11-27 23:03:41
topas 中的cpu
% CPU Utilization
The average processor use of the process over the monitoring interval. The first time a process is shown, this value is the average processor use over the lifetime of the process.
ps aux中的cpu
The ps command, run periodically, displays the CPU time under the TIME column and the ratio of CPU time to real time under the %CPU column. Look for the processes that dominate usage. The au and v options give similar information on user processes. The options aux and vg display both user and system processes.
kennyblues 回复于:2007-11-28 10:35:36
主要是这样的,我在client发出一些sql语句。然后:
1.topas的结果:
Name PID CPU% PgSp Owner
oracle 688292 14.3 4.1 oracle
2.ps aux| grep 688292的结果:
oracle 688292 2.1 1.0 50360 47540 - A 10:07:11 0:12 oracledrmsp (LO
cpu的比较一个是14.3%,一个是2.1%。因此我提出了以上疑问。
从3楼的解释看,ps 所反映的是某个时刻cpu所使用的百分比。10:07:11--是进程开始时间,0:12 -是进程运行时间。
从监控的角度看,应从实时的角度出发进行,因此,是否可以认为用ps命令就可以真实反映进程对cpu的使用?
我将对脚本进行修改,届时发上来跟大家讨论。
再次感谢回复。
kennyblues 回复于:2007-12-05 12:11:29
我写这个脚本的思路是:
1.环境设定:
在oracle用户的$HOME目录下,创建cpu_alarm,pid,output三个目录。
1.1 考虑到有些主机上可能有多个sid的情况,因此,以oracle用户登陆主机,先通过以下命令:
$ps -ef | grep ora_smon
获取当前主机上所安装的oracle。并将sid名称放在ora.txt文件中。
2.脚本内容 cpu_monitor.ksh:
#!/usr/bin/ksh
#----------------------------------------------------------------------------
#Enviroment setting
#----------------------------------------------------------------------------
export ORACLE_HOME=/u01/app/oracle/product/9.2.0
export PATH=$ORACLE_HOME/bin:$PATH
export HOME=/u79/home/oracle
#----------------------------------------------------------------------------
for j in `cat $HOME/cpu_alarm/ora.txt` ##在ora.txt中循环获取sid名字
do
##判断cpu的百分比是否>1,如果>1将其取出
for i in `ps aux |grep -E "^oracle|' oracle'"| grep $j | awk '{if ($3 ~/[0-9]/ && $3 > 1) print $2}'`
do
##找到cpu>1的进程后,过30秒看进程cpu是否仍然>1
if [ `ps aux|grep $i| awk '{printf "%d", $3}'` -gt "1" ]
then
sleep 30 #sleep 30 =》 30 seconds
if [ `ps aux |grep $i | awk '{printf "%d", $3}'` -gt "0.5" ]
then
echo $i > $HOME/cpu_alarm/pid/$j ##若30s后仍然>1,将进程号写入$HOME/cpu_alarm/pid目录下以sid命名的文件中。
fi
fi
done
done
cd $HOME/cpu_alarm/pid
##$HOME/cpu_alarm/pid目录下,列出所有sid名,并将这些文件名中的sid号循环代入根据pid号获得sql的sql语句中,并将所产生的sql语句产生到<sid>.sql文件中,同时,将结果spool到一个html文件,最后发送出来。
for k in `ls -1`
do
echo "export ORACLE_SID=${k}"
echo "set markup html on spool on" >> $HOME/cpu_alarm/output/$k.sql
TIME=`date +%Y%m%d%H%M`
echo "spool $HOME/cpu_alarm/output/${k}_${TIME}.html" >> $HOME/cpu_alarm/output/$k.sql
for t in `cat $k`
do
echo "SELECT to_char(a.logon_time,'yyyy-mm-dd hh24:mi:ss') as "LONGON_TIME",a.username,a.machine,a.program,a.sid,a.serial#,a.sta
tus,c.piece,c.sql_text FROM v$session a,v$process b,v$sqltext c WHERE b.spid=$t AND b.addr=a.paddr AND a.sql_address=c.address(+)
ORDER BY a.sid,c.piece;" >> $HOME/cpu_alarm/output/$k.sql
echo "set markup html off spool off" >> $HOME/cpu_alarm/output/$k.sql
export ORACLE_SID=${k}
echo "exit" >> $HOME/cpu_alarm/output/$k.sql
sqlplus "/ as sysdba" @$HOME/cpu_alarm/output/${k}.sql
rm $HOME/cpu_alarm/output/*.sql
uuencode $HOME/cpu_alarm/output/${k}_${TIME}.html $HOME/cpu_alarm/output/${k}_${TIME}.html | mail -s "${k}_cpu_alarm" [email]abc@abc.com[/email]
##注意:由于spool出来的结果是html文件,因此,要用uuencode file1 file1 |mail -s ...的格式去发附件。
chinadns 回复于:2007-12-05 20:05:49
加精
yanbing 回复于:2007-12-05 20:41:27
支持! :)
kennyblues 回复于:2007-12-08 10:28:56
感谢大家支持
jtw 回复于:2007-12-10 15:03:02
我认为topas才是实时反映进程占用cpu使用率,而ps不是,所以你这个脚本好象不能实现你的需求。
如果ps是,那么在业务高峰期,你看到的CPU使用率,应该更大,但实际上不是。你可以去观察你的系统,如果系统运行得越久,使用ps看到的进程CPU使用率好象会越小。
[ 本帖最后由 jtw 于 2007-12-10 15:07 编辑 ]
snowbow 回复于:2008-02-16 20:51:47
lz脚本可以写的简单点
返回sql语句执行结果可以直接写 echo "语句1 \n 语句2"|sqlplus " / as sysdba" 如果是linux环境 echo记得加-e
|