Linux下Oracle进程CPU使用率过高处理方式

问题现象:Linux下Oracle进程CPU使用率过高处理方式
问题分析:一般cpu占用效高都是排序、sql解析和全表扫描,这里首先需要找出占用cpu最高的sql,然后查看他的执行计划,比如:看执行计划是走索引还是全表扫描(刚开始查看top发现占用同样多的CPU的进程很多,还以为是oracle 的bug, 后来发现不是)
处理过程
1、登陆Linux,free -m查询内存使用情况、

[oracle@oracledb trace]$ free -m
total used free shared buffers cached
Mem: 16049 15930 118 0 1 15334
-/+ buffers/cache: 595 15454
Swap: 8015 298 7717
[oracle@oracledb trace]$ cat /etc/redhat-release
Red Hat Enterprise Linux Server release 6.5 (Santiago)

2、使用top工具查看进程信息
[oracle@oracledb trace]$ top
top - 12:32:24 up 4:48, 2 users, load average: 2.11, 2.25, 2.31
Tasks: 223 total, 4 running, 219 sleeping, 0 stopped, 0 zombie
Cpu(s): 15.0%us, 1.3%sy, 0.0%ni, 73.1%id, 10.5%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 16434548k total, 16344300k used, 90248k free, 776k buffers
Swap: 8208380k total, 305664k used, 7902716k free, 15732832k cached

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
9201 oracle 20 0 4261m 2.0g 2.0g R 61.2 12.8 28:27.35 oracle
9940 oracle 20 0 4262m 2.0g 2.0g R 27.3 13.1 8:15.49 oracle
6913 oracle 20 0 4261m 2.0g 2.0g D 18.3 13.0 50:53.39 oracle
10925 oracle 20 0 4261m 2.0g 2.0g R 12.6 12.9 1:28.16 oracle
8898 oracle 20 0 4260m 2.0g 2.0g S 5.7 12.7 26:37.53 oracle

从中可以看出,进程号为9201的oracle进程占用CPU资源是最多的

三、查看9201这个oracle进程对应的会话信息
SELECT sql_text FROM v s q l t e x t a W H E R E ( a . h a s h v a l u e , a . a d d r e s s ) I N ( S E L E C T D E C O D E ( s q l h a s h v a l u e , 0 , p r e v h a s h v a l u e , s q l h a s h v a l u e ) , D E C O D E ( s q l h a s h v a l u e , 0 , p r e v s q l a d d r , s q l a d d r e s s ) F R O M 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 sqltextaWHERE(a.hashvalue,a.address)IN(SELECTDECODE(sqlhashvalue,0,prevhashvalue,sqlhashvalue),DECODE(sqlhashvalue,0,prevsqladdr,sqladdress)FROMvsession b WHERE b.paddr =(SELECT addr FROM v p r o c e s s c W H E R E c . s p i d = ′ 920 1 ′ ) ) O R D E R B Y p i e c e A S C ; 或 S E L E C T s q l t e x t F R O M v process c WHERE c.spid = '9201')) ORDER BY piece ASC; 或 SELECT sql_text FROM v processcWHEREc.spid=9201))ORDERBYpieceASC;SELECTsqltextFROMvsqltext 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 s e s s i o n b W H E R E b . p a d d r = ( S E L E C T a d d r F R O M v session b WHERE b.paddr =(SELECT addr FROM v sessionbWHEREb.paddr=(SELECTaddrFROMvprocess c WHERE c.spid = ‘&pid’)) ORDER BY piece ASC;
查询结果如下:
SQL> SELECT sql_text FROM v s q l t e x t a W H E R E ( a . h a s h v a l u e , a . a d d r e s s ) I N ( S E L E C T D E C O D E ( s q l h a s h v a l u e , 0 , p r e v h a s h v a l u e , s q l h a s h v a l u e ) , D E C O D E ( s q l h a s h v a l u e , 0 , p r e v s q l a d d r , s q l a d d r e s s ) F R O M 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 sqltextaWHERE(a.hashvalue,a.address)IN(SELECTDECODE(sqlhashvalue,0,prevhashvalue,sqlhashvalue),DECODE(sqlhashvalue,0,prevsqladdr,sqladdress)FROMvsession b WHERE b.paddr =(SELECT addr FROM v$process c WHERE c.spid = ‘9201’)) ORDER BY piece ASC;

SQL_TEXT

UPDATE ID_GRANT A SET A.ISTOTERM = 1 WHERE A.TERMID = :B4 AND A.
EXTENDID = :B3 AND A.DPID = :B2 AND A.VER <= :B1 AND A.ISTOTERM
= 0

结果显示SQL语句就是我们之前构建的SQL。
在执行如下SQL语句,找出相应的会话信息:
select sid,serial# ,username,osuser,machine,program,process,to_char(logon_time,‘yyyy-mm-dd hh24:mi:ss’) logon from
v s e s s i o n w h e r e p a d d r i n ( s e l e c t a d d r f r o m v session where paddr in ( select addr from v sessionwherepaddrin(selectaddrfromvprocess where spid in(‘9201’));
或者
select id,serial# ,username,osuser,machine,program,process,to_char(logon_time,‘yyyy-mm-dd hh24:mi:ss’) logon
from v s e s s i o n w h e r e p a d d r i n ( s e l e c t a d d r f r o m v session where paddr in ( select addr from v sessionwherepaddrin(selectaddrfromvprocess where spid in(’&pid’));
执行的结果如下:
SID SERIAL# USERNAME OSUSER MACHINE PROGRAM PROCESS LOGON
228 7259 CCENSE SYSTEM WORKGROUP\ECARDYINGYONG AutoDealService.exe 8932:5828 2020-04-10 10:59:00
到这里,就可以根据SID和SERIAL#来杀掉用户会话了。
SQL> alter system kill session ‘228,7259’ immediate;
System altered.
但是,这要是通过PMON进程来定期清除会话的,因此会有一定的时间间隔,如果情况很紧急,需要立即释放资源,那么就要杀操作系统进程了。

四、找出操作系统进程
select PADDR from v$session where SID=228 and SERIAL#=7259;
找出拥有会话的进程地址

然后通过PAAD号找出系统进程号

然后在操作系统上kill -9 9201即可。

扩展补充:查询的where 条件字段没有在索引里面,导致查询慢。经过重建并增加相关字段到索引解决,但有点疑惑的是原来库上查询语句里where条件字段也没有在索引里面(新库是使用expdp导出再导入到新库的),查询还正常,CPU也不高,oracle数据库真是博大精深,好多问题还有待研究。

另外复合索引一定要匹配查询的where条件,不然oracle不会走引索。

你可能感兴趣的:(oracle)