【案例52】oracle进程占用CPU100%分析实战

问题现象

Linux环境,数据库CPU一直处于100%。业务系统运行很慢。Top命令结果如下:

问题分析

方法1

根据上图中的oracle进程在操作系统对应的 PID号 : 如 6999,8100 等

通过下面的SQL,查询

sql 复制代码
select s.SQL_HASH_VALUE, s.SQL_ADDRESS
  from v$session s, v$process p
 where s.PADDR = p.ADDR
   and p.SPID = '6999' ---换成相关的pid值

然后,将 查询出的 SQL_HASH_VALUE ,SQL_ADDRESS 对应代入下面的sql,或者只用其中一个也可以。

sql 复制代码
select *
  from v$sqltext t
 where (t.HASH_VALUE = ' s.SQL_HASH_VALUE ' or --自行替换上述查的值
       t.ADDRESS = ' s.SQL_ADDRESS ') --自行替换上述查的值
 order by piece

方法2

通过如下SQL查询在数据库中执行缓慢的sql

sql 复制代码
SELECT /*+rule*/
 S.SQL_ID,
 S.SID,
 s.BLOCKING_SESSION,
 S.SERIAL#,
 S.USERNAME,
 W.EVENT,
 W.SECONDS_IN_WAIT,
 W.WAIT_TIME,
 S.LAST_CALL_ET,
 S.STATUS,
 S.CLIENT_INFO,
 Q.SQL_TEXT,
 Q.HASH_VALUE,
 Q.ADDRESS,
 'alter system kill session ''' || S.SID || ',' || S.SERIAL# ||
 ''' immediate;'
  FROM V$SESSION_WAIT W, V$SESSION S, V$SQL Q
 WHERE W.SID = S.SID
   AND Q.HASH_VALUE = S.SQL_HASH_VALUE
   AND W.EVENT NOT LIKE '%message from client%'
   AND S.SID >= 6
 ORDER BY LAST_CALL_ET DESC;

发现耗时sql如下

sql 复制代码
--- SQL-1  
--- 这个 SQL 语句用于获取特定用户活动会话相关的执行计划,并以一种特定的格式展示这些信息
select *
  from (select hash_value || '***' ||
               rpad('|' || substr(lpad(' ', 1 * (depth - 1)) || operation ||
                                  decode(options, null, '', ' ' || options),
                                  1,
                                  32),
                    33,
                    ' ') || '|' ||
               rpad(decode(id,
                           0,
                           '----- ' || to_char(hash_value) || ' -----',
                           substr(decode(substr(object_name, 1, 7),
                                         'SYS_LE_',
                                         null,
                                         object_name) || ' ',
                                  1,
                                  20)),
                    21,
                    ' ') || '|' ||
               lpad(decode(cardinality,
                           null,
                           ' ',
                           decode(sign(cardinality - 1000),
                                  -1,
                                  cardinality || ' ',
                                  decode(sign(cardinality - 1000000),
                                         -1,
                                         trunc(cardinality / 1000) || 'K',
                                         decode(sign(cardinality - 1000000000),
                                                -1,
                                                trunc(cardinality / 1000000) || 'M',
                                                trunc(cardinality / 1000000000) || 'G')))),
                    7,
                    ' ') || '|' ||
               lpad(decode(bytes,
                           null,
                           ' ',
                           decode(sign(bytes - 1024),
                                  -1,
                                  bytes || ' ',
                                  decode(sign(bytes - 1048576),
                                         -1,
                                         trunc(bytes / 1024) || 'K',
                                         decode(sign(bytes - 1073741824),
                                                -1,
                                                trunc(bytes / 1048576) || 'M',
                                                trunc(bytes / 1073741824) || 'G')))),
                    6,
                    ' ') || '|' ||
               lpad(decode(cost,
                           null,
                           ' ',
                           decode(sign(cost - 10000000),
                                  -1,
                                  cost || ' ',
                                  decode(sign(cost - 1000000000),
                                         -1,
                                         trunc(cost / 1000000) || 'M',
                                         trunc(cost / 1000000000) || 'G'))),
                    8,
                    ' ') || '|' as "Explain plan"
          from v$sql_plan
         where hash_value in (select s.sql_hash_value
                                from v$session s
                               where s.username = upper('[user]')
                                 and s.status = 'ACTIVE'
                                 and s.last_call_et > 10))

--- SQL-2
--- 监控和分析数据库中活动会话的执行情况
select s.client_identifier,
       s.sid,
       s.serial#,
       sql.sql_fulltext,
       s.last_call_et,
       s.event,
       sql.SQL_ID,
       child_number,
       s.sql_hash_value
  from v$session s, v$sql sql
 where s.sql_address = sql.ADDRESS
   and s.username = upper('[user]')
   and s.status = 'ACTIVE'
   and s.last_call_et > 10
 order by sid

方法3

使用AWR查看耗时SQL

sql 复制代码
Oracle>sqlplus  "/as sysdba"

SQL>@?/rdbms/admin/awrrpt.sql

查询SQL ordered by Elapsed Time

查询SQL ordered by CPU Time

相关SQL

根据awr的报告 ,也可以看出, 耗费CPU的 SQL 时 在awr中 ,可以 通过 SQL ID找到当时执行时对应的执行计划:

sql 复制代码
select * from table(dbms_xplan.display_awr('6h6zz42n9rmnw'));

解决方案

1、经过沟通,发现相关的SQL是由于NMC调用了Oracle监控脚本导致的。

nmc\server\conf\monitor.properties 文件中配置的监控脚本 。注释掉即可 。

2、停止NMC,杀掉相关数据库会话。

相关推荐
拍客圈2 分钟前
Discuz搜索报错
服务器·网络·安全
独泪了无痕3 分钟前
通过Homebrew安装Redis指南
数据库·redis·缓存
数据知道5 分钟前
PostgreSQL:如何把PostgreSQL变成时序数据库(TimescaleDB)
数据库·postgresql·时序数据库
崎岖Qiu7 分钟前
【MySQL | 第11篇】一条SQL查询语句的执行全流程简析
数据库·后端·sql·mysql
w***29851 小时前
Knife4j文档请求异常(基于SpringBoot3,查找原因并解决)
java·服务器·数据库
郝学胜-神的一滴1 小时前
深入理解TCP连接的优雅关闭:半关闭状态与四次挥手的艺术
linux·服务器·开发语言·网络·tcp/ip·程序人生
砚边数影8 小时前
运营商网管系统重构:如何解决海量投诉数据下的“查询延迟”与“写入瓶颈”?
网络·数据库·时序数据库·kingbase·kingbasees·数据库平替用金仓·金仓数据库
shsh2009 小时前
mybatis plus打印sql日志
数据库·sql·mybatis
CCPC不拿奖不改名9 小时前
虚拟机基础:在VMware WorkStation上安装Linux为容器化部署打基础
linux·运维·服务器·人工智能·milvus·知识库搭建·容器化部署
山峰哥9 小时前
数据库调优实战:索引策略与查询优化案例解析
服务器·数据库·sql·性能优化·编辑器