上月底的一天刚好在休假,突然收到通知说,系统快挂了,赶紧上线【十万火急】
一看,好家伙,CPU爆满,在崩溃的边沿都快拉直了,怎么呢?我们来具体看看
1. 问题分析
看到CPU这样,首先想到的是,查看故障时间,快速登录服务器,导出这段时间的AWR报告
sqlplus / as sysdba @?rdbms/admin/awrrpt
AWR导出说明:
1)互动操作1:导出报告的格式,直接回车,默认html
2)互动操作1:查询的天数,输入1表示近一天
3)然后根据镜像ID对应的时间范围,输入开始和结束时间对应的ID
4)最后导出完会提示导出的文件名及存放路径,下载
查看AWR报告
由于已知CPU问题,快速先翻到“”SQL ordered by CPU Time”
问题马上呈现出来了,第一条SQL cpu占了总体的73% ,那其他都可以不看了,直接定位这条SQL是怎么回事

查看这条SQL的执行计划,发现执行计划有问题

再具体看,发现是这是张近期新建的表,由于当时无数据,未提前预制索引,该表数据上来后与亿级大表关联查询,造成如今形式
2. 解决方案
既然问题已经找到,马上对该表对应字段建立索引(脱敏:表名和列名用测试代替)
create index idx_tablename_col on test_tab(col) <parallel 4> ;
习惯性带上并行加快建立索引的速度,突然想起,CPU都要爆了,还加并行做啥,赶紧将(parallel 4)去掉,执行,0.5s 完成。
再收集下该表的统计信息
BEGIN
DBMS_STATS.GATHER_TABLE_STATS(OWNNAME => 'USER1',
TABNAME => 'TEST_TAB',
ESTIMATE_PERCENT => 1,
METHOD_OPT => 'FOR ALL COLUMNS SIZE 1',
NO_INVALIDATE=> FALSE,
FORCE=>TRUE,
CASCADE => TRUE,
DEGREE => 10);
END;
/
再查看CPU,呃。。还没降下来
可能是还有再跑sql,去看看
SELECT b.sid oracleID,
b.username 登录Oracle用户名,
b.SID,b.serial#,
spid 操作系统ID,
paddr,c.sql_id,
sql_text 正在执行的SQL,
b.machine 计算机名,c.SQL_FULLTEXT,b.PREV_EXEC_START,b.STATUS,b.OSUSER,b.PROGRAM
FROM v$process a, v$session b, v$sqlarea c
WHERE a.addr = b.paddr
AND b.sql_hash_value = c.hash_value
and b.status='ACTIVE'
and c.SQL_ID='1txxxxxxxw1'
嗯,没错,还有一批再跑着,最长的已经跑了俩小时了。经评估,可以结束掉
查杀会话 (对应放查询到的id)
alter system kill session '<sid>,<serial#>';
3. 再次查看CPU,自由落体

「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




