【案例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,杀掉相关数据库会话。

相关推荐
爱丶狸9 小时前
Grafana_Zabbix_ImageRenderer_部署与前端操作手册
linux·前端·zabbix·grafana·kylin
k4m7v2pz10 小时前
把 Bevy 0.14 游戏移植到 R36S 掌机:一场与“无窗口系统“的搏斗
linux·rust·bevy·r36s·rk3326·开源掌机
木子欢儿11 小时前
Intel 架构的 MacBook Pro 运行 Linux 发热量高解决
linux·运维·服务器
凌虚11 小时前
面向 MySQL 用户的 PostgreSQL 快速上手指南
数据库·后端·架构
五阿哥永琪11 小时前
MySQL中操作json的函数!
数据库·mysql·json
来者皆善11 小时前
了解Mysql优化吗?如何优化索引?
数据库·mysql
赤壁小虾14 小时前
【渲染流水线】[逐片元阶段]-[透明度测试]以UnityURP为例
java·前端·数据库
清水迎朝阳14 小时前
客户端软件 — 用户统计方案
服务器·c++·客户端·用户统计
MC皮蛋侠客14 小时前
SQLAlchemy 系列(七):高级建模与高效写入——批量 DML、方言与扩展
数据库·python
会编程的土豆14 小时前
Go 模板初识
linux·运维·服务器