首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

Oracle 高 CPU 消耗 SQL 定位實戰:從 OS 進程到具體 SQL 文本全鏈路追踪

     編輯:MySQL 資料庫相關知識

生產環境 Oracle 數據庫 CPU 飆升至 100%,業務響應嚴重延遲。本文記錄一次真實排查案例,演示從操作系統層面定位高消耗進程,層層關聯至具體 SQL 文本的標準化排查鏈路,適用於 Oracle 10g/11g/12c/19c 等主流版本。

排查鏈路總覽

  1. OS 層:top/pidstat 找出高 CPU 進程 PID(如 1217)。
  2. Oracle 進程視圖:V$PROCESS 以 SPID = PID 查得 ADDR(進程地址)。
  3. 會話視圖:V$SESSION 以 PADDR = ADDR 查得 SID、SERIAL#、SQL_HASH_VALUE。
  4. SQL 文本視圖:V$SQLTEXT/V$SQL/V$SQLAREA 以 HASH_VALUE 取得完整 SQL_TEXT。

實戰腳本:一鍵定位 Top SQL

-- 保存為 find_top_sql.sql,SQL*Plus 執行 @find_top_sql <OS_PID>
SET LINESIZE 300 PAGESIZE 1000 LONG 1000000
COL SQL_TEXT FOR A120

VAR v_pid NUMBER
EXEC :v_pid := &1;

SELECT s.SID, s.SERIAL#, s.USERNAME, s.OSUSER, s.MACHINE, s.PROGRAM,
       s.PROCESS, s.LOGON_TIME, s.SQL_HASH_VALUE,
       sq.SQL_TEXT
FROM   V$SESSION s
JOIN   V$PROCESS p ON s.PADDR = p.ADDR
JOIN   V$SQL sq ON s.SQL_HASH_VALUE = sq.HASH_VALUE
WHERE  p.SPID = :v_pid
AND    s.STATUS = 'ACTIVE';

案例實錄

$ top -bn1 | head -20
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 6799 oracle    20   0  1.200g  1.100g  1.000g R  99.7 12.3  12:34.56 oracle

$ sqlplus / as sysdba @find_top_sql 6799

SID  SERIAL# USERNAME OSUSER MACHINE   PROGRAM           PROCESS  LOGON_TIME      SQL_HASH_VALUE
---- ------- -------- ------ --------- ----------------- -------- --------------- --------------
 483    1224 PORTAL   www16  bj_wap03  JDBC Thin Client  6799     2024-01-15 02:21  3141592653

SQL_TEXT
--------------------------------------------------------------------------------
SELECT * FROM SPINFO WHERE SPID = :1

深度分析:為什麼這條 SQL 佔用高 CPU?

可能原因驗證方法優化方向
缺少索引/全表掃描EXPLAIN PLAN FOR ...; SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY);在 SPID 列建立索引
綁定變量窺探導致計劃失效V$SQL_CS_HISTOGRAM 檢查多計劃使用 /*+ BIND_AWARE */ 或修正統計信息
高頻調用(如循環單行查詢)V$SQLAREA.EXECUTIONS 對比 ELAPSED_TIME應用層批量化、緩存、改為 JOIN
統計信息過期DBA_TAB_STATISTICS.LAST_ANALYZEDDBMS_STATS.GATHER_TABLE_STATS

自動化監控建議

  • 部署 DBMS_SCHEDULER 定時任務,每 5 分鐘採集 V$SESSION_WAIT、V$SQLAREA Top 10 CPU SQL,寫入歷史表。
  • 設置閾值告警:CPU_TIME > 1000000 (微秒) 或 EXECUTIONS > 10000/分鐘 觸發郵件/釘釘通知 DBA。
  • 配合 ASH(Active Session History)報告:DBMS_WORKLOAD_REPOSITORY.ASH_REPORT_TEXT 事後根因分析。

工具箱速查

工具/視圖用途典型命令
top / pidstatOS 級進程 CPU 佔用pidstat -p <PID> 1 10
V$PROCESSOracle 後台/前台進程映射SELECT ADDR, SPID FROM V$PROCESS WHERE SPID=1217
V$SESSION用戶會話狀態、當前 SQLSELECT SID, SQL_HASH_VALUE FROM V$SESSION WHERE PADDR=...
V$SQL / V$SQLAREASQL 文本、執行計劃、統計SELECT SQL_FULLTEXT FROM V$SQL WHERE HASH_VALUE=...
DBMS_XPLAN執行計劃格式化顯示SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(sql_id))
SQL Trace / TKPROF會話級詳細追踪ALTER SESSION SET EVENTS '10046 TRACE NAME CONTEXT FOREVER, LEVEL 12'

總結

「OS PID → V$PROCESS → V$SESSION → V$SQL」四步關聯法是 Oracle 性能排查的基礎功夫。關鍵在於熟練掌握視圖關聯鍵(SPID→ADDR→PADDR→HASH_VALUE),並建立自動化採集機制,將「事後排查」轉化為「事前預警」。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved