当前位置:首页>Linux>Linux CPU 飙高时,如何从 OS PID 快速定位 Oracle SQL

Linux CPU 飙高时,如何从 OS PID 快速定位 Oracle SQL

  • 2026-10-11 05:43:17
Linux CPU 飙高时,如何从 OS PID 快速定位 Oracle SQL

Oracle 数据库服务器 CPU 突然升高时,最有效的方法之一,是先从操作系统找到真正占 CPU 的 Oracle 进程,再通过 V$PROCESS 和 V$SESSION 映射到具体数据库会话。

直接寻找高 CPU 的 Oracle 进程 PID。

1. 在 Linux 找到高 CPU Oracle 进程

可以先使用:

top
CSS

按:

P
CSS

按照 CPU 使用率排序。

也可以直接执行:

ps -eo pid,ppid,user,pcpu,pmem,etime,args \
  --sort=-pcpu | head -20
BASH

针对 Oracle 用户:

ps -u oracle \
  -o pid,ppid,pcpu,pmem,etime,args \
  --sort=-pcpu | head -20
BASH

例如:

PID      %CPU   COMMAND
2367898.5   oracleORCL (LOCAL=NO)
1821112.3   ora_lgwr_ORCL
181925.6   ora_dbw0_ORCL
SQL

这里首先要区分两种情况:

oracleORCL (LOCAL=NO)
SQL

通常是前台 server process,可以继续映射到 Session 和 SQL。

而:

ora_lgwr_ORCL
ora_dbw0_ORCL
ora_ckpt_ORCL

属于后台进程,应从 redo、I/O、checkpoint 等方向继续分析,而不是寻找业务 SQL。Oracle 官方的进程架构文档也将服务器进程和后台进程作为不同角色分别描述。

2. 根据 OS PID 定位 Oracle Session

假设发现:

PID = 23678

执行:

SELECT
    s.sid,
    s.serial#,
    s.username,
    s.status,
    s.sql_id,
    s.event,
    s.state,
    s.seconds_in_wait,
    p.spid,
    s.machine,
    s.program
FROM v$session s
JOIN v$process p
ON s.paddr = p.addr
WHERE p.spid ='23678';
SQL

例如返回:

SID             125
SERIAL#         4812
USERNAME        TRADE
STATUS          ACTIVE
SQL_ID          7abc123xyz890
EVENT           ON CPU
SPID            23678
PYTHON

这时已经完成:

Linux PID
    ↓
Oracle Process
    ↓
Session
    ↓
SQL_ID
MARKDOWN

的完整映射。

3. 获取 SQL 和实际执行计划

拿到 SQL_ID 后查看 SQL:

SELECT
    sql_id,
    child_number,
    plan_hash_value,
    executions,
    buffer_gets,
    disk_reads,
    cpu_time /1000000AS cpu_sec,
    elapsed_time /1000000AS elapsed_sec,
    sql_text
FROM v$sql
WHERE sql_id ='7abc123xyz890';
SQL

查看执行计划:

SELECT*
FROMTABLE(
    dbms_xplan.display_cursor(
'7abc123xyz890',
NULL,
'ALLSTATS LAST'
    )
);
SQL

重点关注:

A-Rows
Buffers
Reads
Starts
SQL

例如:

E-Rows=10
A-Rows=5000000
SQL

通常说明优化器估算严重偏差,可以进一步检查:

  • 统计信息是否过期;
  • 是否存在数据倾斜;
  • Bind Peeking;
  • 执行计划发生变化;
  • 索引选择错误。

4. 如果高 CPU 的是 Oracle 后台进程

不能看到 Oracle PID CPU 高,就全部按 SQL 问题处理。

例如:

ora_lgwr_ORCL

CPU 或系统调用异常时,可以检查:

SELECT
    event,
    total_waits,
    time_waited_micro /1000000AS time_waited_sec
FROM v$system_event
WHERE event LIKE'log file%';
SQL

如果是:

ora_dbw0_ORCL

可以重点观察:

SELECT
    event,
    total_waits,
    time_waited_micro /1000000AS time_waited_sec
FROM v$system_event
WHERE event LIKE'db file parallel write%'
OR event LIKE'free buffer waits%';
SQL

因此完整判断流程应该是:

CPU 高
 │
 ├─ 前台 oracleORCL (LOCAL=NO)
 │      ↓
 │   V$PROCESS → V$SESSION → SQL_ID
 │
 └─ 后台 ora_xxxx_ORCL
        ↓
     根据后台进程职责分析
     LGWR → redo
     DBWR → datafile I/O
     ARCn → archive
     LMS → RAC Cache Fusion
PHP

最新文章

随机文章