上一期生成了ASH報告后,就需要解讀報告關鍵信息。ASH的使用可以快速定位瞬時性能問題。生產環境的場景時間緊、任務重,但是必須要結合具體業務分析,同時借助其他工具做報告做趨勢分析。
一、ASH 技術原理?
?1. 核心機制?
- ?采樣原理?:ASH 每秒采樣一次活動會話(狀態為 ACTIVE,非空閑等待),由后臺進程 ?MMNL?(Memory Monitor Light)執行
- ?數據存儲?:
- ?內存?:采樣數據存儲在 SGA 的循環緩沖區(V$ACTIVE_SESSION_HISTORY),緩沖區大小由隱含參數 _ash_size 控制(默認約 1MB~30MB)
- ?持久化?:MMNL 定期將內存數據寫入 AWR 表 WRH$_ACTIVE_SESSION_HISTORY(視圖為 DBA_HIST_ACTIVE_SESS_HISTORY),持久化比例由 _ash_disk_filter_ratio 控制(默認 1/10)
2. 核心術語?
?術語? | ?解釋? | ?分析意義? |
?DB Time? | 所有活動會話消耗的總時間(CPU + 等待時間) | 衡量系統負載強度,高 DB Time 表明性能瓶頸 |
?Top Events? | 排名前幾的等待事件(如db file sequential read, enq: TX - row lock contention) | 定位系統級瓶頸(事件占比 >30% 需優先處理) |
?Load Profile? | 活動會話數、邏輯讀/秒、物理讀/秒等負載指標 | 判斷資源壓力(如物理讀 >500/秒需優化 I/O) |
?SQL ID? | 消耗資源最多的 SQL 唯一標識 | 關聯高負載 SQL 與等待事件 |
?Blocking Session? | 阻塞其他會話的源頭會話 ID | 診斷鎖爭用問題(如行鎖阻塞鏈) |
?3. 關鍵隱含參數?
?參數名? | ?默認值? | ?作用? |
_ash_sampling_interval | 1000ms | 采樣間隔(毫秒) |
_ash_enable | TRUE | 啟用/禁用 ASH 采樣 |
_ash_sample_all | FALSE | 是否采樣空閑等待會話(通常僅ACTIVE會話) |
_ash_disk_write_enable | TRUE | 控制是否持久化到磁盤 |
4. ?頂級等待事件(Top User Events)??
識別系統級瓶頸的核心區域
- ?單事件占比 > 30%??:需要立即處理
- ?累計等待時間 > 50%??:系統級瓶頸
5. ?高負載SQL(Top SQL with Top Events)??
?字段? | ?診斷意義? | ?優化閾值? |
SQL ID | SQL唯一標識 | - |
% Activity | SQL影響范圍 | >5%需優先優化 |
Executions | 執行頻率 | >100/分鐘需關注 |
Buffer Gets | 邏輯讀消耗 | 單次>10,000需優化 |
Scan Type | 掃描方式 | FTS(全表掃描)需建索引 |
關聯等待事件 | SQL瓶頸類型 | 關聯Top Events分析 |
- 高頻全表掃描 → 創建缺失索引
- 高邏輯讀SQL → SQL重寫/綁定變量
- 長時鎖等待SQL → 業務邏輯優化
6. ?活動會話時間分布(Activity Over Time)??
- ?時段突增?:關聯具體SQL/事件(如時段3的db file sequential read)
- ?持續高峰?:系統容量不足
- ?周期性波動?:定時任務影響
7. ?阻塞會話分析(Blocking Sessions)??
- BLOCKING_SESSION:阻塞源會話ID
- WAIT_TIME:等待時間(>1秒需關注)
- EVENT:等待事件類型
- SQL_ID:阻塞源SQL
二、ASH報告診斷四步法
分析流程?
定位核心瓶頸?:
- 查看?Top Events,篩選占比 >30% 的等待事件(如行鎖、I/O 等待)
- 檢查?Load Profile 中的活動會話數:若持續超過 CPU 核數 × 1.5,表明資源爭用
關聯資源消耗?:
- 在?Top SQL with Top Events 中,找到高 % Activity(>5%)的 SQL,分析其執行計劃與資源消耗
- 示例 SQL(查找高邏輯讀 SQL):
--注意參數 SELECT sql_id, SUM(buffer_gets) total_gets FROM dba_hist_active_sess_history WHERE sample_time BETWEEN :start AND :end GROUP BY sql_id ORDER BY total_gets DESC;
追溯阻塞鏈?:
- 通過?Blocking Sessions 定位鎖源頭會話,結合 DBA_HIST_ACTIVE_SESS_HISTORY 分析鎖類型(如 enq: TX - row lock contention)
時段負載分析?:
- 使用?Activity Over Time 圖表定位突增時段(如 10:05-10:08),關聯該時段內的 SQL 與事件
?三、關鍵性能問題速查表
?現象? | ?可能原因? | ?驗證方法? |
?log file sync > 30%? | redo寫入延遲 | 檢查redo日志文件性能 |
?enq: TX - row lock contention? | 行鎖爭用 | 分析阻塞會話鏈 |
?db file sequential read? | 索引掃描I/O慢 | 檢查磁盤IOPS/延遲 |
?buffer busy waits? | 熱塊爭用 | 檢查對象訪問模式 |
?CPU used when call started? | SQL效率低下 | 分析Top SQL邏輯讀 |
四、案例解析?
?案例 1:Oracle 11g 行鎖阻塞(enq: TX - row lock contention)??
- ?問題現象?:ASH 報告中 enq: TX - row lock contention 占比 87.62%
- 在 Top Events 中確認行鎖為頂級事件。
- 通過關聯的 SQL_ID 找到UPDATE 卡事務的 SQL:
--更新業務側,等待很久 UPDATE HIS.FEI_ACCOUNT SET SHYUEDU = SHYUEDU - 1000 WHERE HUANGZHE_ID = 9028;
- 溯源 BLOCKING_SESSION,發現未提交的事務持有行鎖
- 解決方案?:
- 優化事務提交邏輯,避免長事務。
- 添加索引減少行鎖競爭范圍
?
案例 2:Oracle 19c RAC 全局 I/O 瓶頸?
- ?問題現象?:gc buffer busy 和 db file sequential read 等待事件在多個實例同時出現。
- ?分析過程?:
- a.RAC ASH 報告顯示跨實例的高 gc buffer busy。
- 關聯 SQL 發現全表掃描頻繁,導致全局緩存爭用。
- 檢查?Buffer Activity 部分,Consistent Gets 異常高
- ?解決方案?:
- 為高頻查詢字段添加索引,減少全表掃描。
- 調整?db_cache_size 和 inmemory_size,優化緩沖區命中率
案例 3:短時 CPU 高負載(11g 單機)??
- ?問題現象?:用戶反饋系統在 14:00-14:05 卡頓,但 AWR 未捕獲異常。
- ?分析過程?:
- 生成精確時段的 ASH 報告(14:00-14:05)。
- 發現?CPU used when call started 占比 95%,關聯 SQL 為低效聚合查詢。
- 該 SQL 執行計劃使用全表掃描而非索引
- ?解決方案?:
- 優化 SQL,添加復合索引。
- 調整?cursor_sharing 減少硬解析
五、ASH 的局限和最佳實踐?
1. ?數據覆蓋風險?:
- 內存緩沖區僅保留約 1 小時數據,高并發時可能被覆蓋,需及時捕獲
2. ?RAC 環境要點?:
- 使用?ashrpti.sql 生成全局報告,分析跨實例等待事件(如 gc buffer busy)
ASH報告分析最佳實踐
采樣時間選擇?:
- 問題發生期精確分析:5-15分鐘
- 趨勢分析:30-60分鐘
對比分析?:
-- 比如工作日 vs 周末,注意時間參數
SELECT event, COUNT(*)
FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN <高負載期間> AND <低負載期間>
GROUP BY event;
關聯工具使用?:
- 瞬時問題:ASH + SQL Monitor
- 歷史分析:ASH + AWR
- 實時監控:ASH + OEM
保存策略優化?:
-- 延長ASH保留時間(單位:分鐘)
EXEC DBMS_WORKLOAD_REPOSITORY.modify_snapshot_settings(retention => 4320 -- 3天保留期(默認=4320分鐘)
);