方法一:
方法二:
我们可以首先使用top等工具,找到最好资源的进程(记住进程号),例如,操作系统进程号为2796,然后根据这个进程号(v$process.spid)在v$process中找到进程地址(v$process.addr),然后根据这个地址在v$session中找到相应的sid(v$session.sid),然后根据这个sid找到相应的hash alue(v$session. sql_hash_value),然后根据这个hash alue在v$sqltext,$sql,v$sqlarea等视图中找到对应的sql语句(sql_text)。
比如:我用top工具看到最消耗CPU的PID为26337,即V$PROCESS里面的字段SPID为26337
SQL> SELECT a.pid,a.spid,a.username,b.sid,b.serial#,c.hash_value,c.sql_text
FROM v$process a,v$session b,v$sqltext c
WHERE a.addr=b.paddr
AND b.sql_hash_value=c.hash_value
and A.spid=26337
PID SPID USERNAME SID SERIAL# HASH_VALUE
---------- ------------ --------------- ---------- ---------- ----------
SQL_TEXT
----------------------------------------------------------------
17 26337 oracle 160 361 474876535
i); EXIT WHEN 1>2; i:=i+1; END LOOP; END;
17 26337 oracle 160 361 474876535
DECLARE i number:=1; BEGIN LOOP INSERT INTO test(id) VALUES(
原来这个sql语句发生了死循环。
解决办法:查询这个会话的SID,SERIAL#,杀死这个会话,若杀不掉,在OS下将该进程杀掉。再把PL/SQL程序改为正确的即可。
如:
SQL> alter system kill session '160,361';
alter system kill session '160,361'
*
ERROR at line 1:
ORA-00031: session marked for kill
但发现报错,并且还没有杀死。
在os下杀死该进程:
kill -9 26337
会话终止了。
此时,再运行该sql语句,查询结果为空了。:
SQL> SELECT a.pid,a.spid,a.username,b.sid,b.serial#,c.hash_value,c.sql_text
2 FROM v$process a,v$session b,v$sqltext c
3 WHERE a.addr=b.paddr
4 AND b.sql_hash_value=c.hash_value
5* and A.spid=26337
no rows selected