关于oracle服务器cpu爆满,从而导致程序运行缓慢,甚至直接白屏,各类连接超时,在生产环境中必须快速排查定位和紧急处理。
希望下面的处理步骤能够帮到大家。
1. 服务器中使用 top 命令观察当前服务器各项指标使用情况, 通过下面sql耗费CPU大的sql语句是哪些
select a.username,a.command,a.status,a.program,a.machine,a.client_identifier,b.sql_text,b.cpu_time,b.sharable_mem,
round((b.disk_reads + b.buffer_gets) / b.executions) as resource_cost
from v$session a, v$sqlstats b
where a.sql_id = b.sql_id
and b.executions > 0
and a.wait_class <> 'idle'
order by resource_cost desc;
2. 快速查询正在运行的慢sql语句,从而定位到程序中具体哪些sql语句有问题(比如程序中带条件的sql,当请求参数不满足某个条件时,sql条件也不会带上,最后造成无条件sql的全表扫描)
select *
from (select sa.SQL_TEXT,
sa.SQL_FULLTEXT,
sa.EXECUTIONS "执行次数",
round(sa.ELAPSED_TIME / 1000000, 2) "总执行时间",
round(sa.ELAPSED_TIME / 1000000 / sa.EXECUTIONS, 2) "平均执行时间",
sa.COMMAND_TYPE,
sa.PARSING_USER_ID "用户ID",
u.username "用户名",
sa.HASH_VALUE
from v$sqlarea sa
left join all_users u
on sa.PARSING_USER_ID = u.user_id
where sa.EXECUTIONS > 0
order by (sa.ELAPSED_TIME / sa.EXECUTIONS) desc)
where rownum <= 50;
到此分析上面1 2 执行后的结果,导出excel来具体分析优化代码或者sql即可。但是优化需要时间,必须再进行下面的操作,让数据库快速恢复正常.
3. 查询正在执行中的select会话(用处是把查询出来的select会话手动杀掉,从而是CPU快速下降-只针对查询)
select v$session.SID,
v$session.SERIAL#,
v$session.MACHINE,
v$sqlarea.SQL_FULLTEXT,
v$sqlarea.SQL_TEXT,
'alter system kill session ' || '''' || v$session.SID || ',' || v$session.SERIAL# ||
''' immediate;'
from v$sqlarea, v$session
where v$sqlarea.ADDRESS = v$session.SQL_ADDRESS
and v$sqlarea.HASH_VALUE = v$session.SQL_HASH_VALUE
and v$session.STATUS = 'ACTIVE'
--and v$session.PROGRAM = 'JDBC Thin Client'
and UPPER(v$sqlarea.SQL_TEXT) like 'SELECT %';