1. ORACLE ASH分析会话执行状态及执行的SQL实战指南
在ORACLE数据库性能诊断领域,Active Session History (ASH)堪称DBA的"时间回溯器"。上周处理的一个生产案例让我再次体会到它的价值:某核心系统在业务高峰时段出现间歇性卡顿,通过ASH分析迅速定位到是某个报表会话执行了全表扫描。本文将分享如何利用ASH数据深度分析会话执行状态及对应SQL,这套方法已帮助我解决过数十起性能问题。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. ASH核心原理与数据采集机制
2.1 ASH采样工作原理
ASH每秒采样一次内存中的活动会话信息,采样数据存储在SGA的循环缓冲区。关键点在于:
- 采样频率固定为1秒,但只记录处于ACTIVE状态的会话(即非IDLE等待)
- 每个采样点包含会话ID、SQL_ID、等待事件、机器信息等70+个维度
- 默认保留1小时数据,通过DBA_HIST_ACTIVE_SESS_HISTORY视图可查询历史数据
注意:ASH采样会带来约2-5%的性能开销,在OLTP系统中需权衡监控粒度
2.2 关键数据字段解析
分析会话状态时最常用的字段:
sql复制SESSION_ID -- 会话标识符
SQL_ID -- 当前执行SQL的哈希值
SESSION_STATE -- 状态(WAITING/ON CPU)
EVENT -- 等待事件名称
WAIT_CLASS -- 等待类型分类
TIME_WAITED -- 等待时长(微秒)
BLOCKING_SESSION-- 阻塞会话ID
3. 会话状态分析实战步骤
3.1 实时会话监控查询
sql复制SELECT
TO_CHAR(SAMPLE_TIME, 'YYYY-MM-DD HH24:MI:SS') AS sample_time,
session_id,
session_serial#,
sql_id,
session_state,
event,
wait_class,
time_waited
FROM
v$active_session_history
WHERE
sample_time > SYSDATE - 15/1440 -- 最近15分钟
AND session_state = 'WAITING'
ORDER BY
sample_time DESC;
3.2 典型等待事件解读
常见问题与对应等待事件:
| 等待事件 | 问题类型 | 解决方案 |
|---|---|---|
| db file sequential read | 索引扫描IO等待 | 检查磁盘性能/增加缓存 |
| enq: TX - row lock | 行级锁竞争 | 定位阻塞会话并优化事务逻辑 |
| log file sync | 提交频率过高 | 批量提交优化 |
| CPU used by this session | CPU资源不足 | SQL优化或扩容 |
3.3 阻塞会话分析技巧
通过BLOCKING_HISTORY字段追踪锁等待链:
sql复制WITH block_tree AS (
SELECT
session_id,
blocking_session,
LEVEL as block_level
FROM
v$active_session_history
CONNECT BY
PRIOR session_id = blocking_session
START WITH
blocking_session IS NOT NULL
)
SELECT * FROM block_tree ORDER BY block_level;
4. SQL执行深度分析
4.1 高频SQL定位方法
统计消耗资源最多的SQL:
sql复制SELECT
sql_id,
COUNT(*) AS ash_samples,
ROUND(COUNT(*)/SUM(COUNT(*)) OVER()*100,2) AS pct
FROM
v$active_session_history
WHERE
sample_time > SYSDATE - 30/1440
GROUP BY
sql_id
ORDER BY
ash_samples DESC
FETCH FIRST 10 ROWS ONLY;
4.2 SQL执行计划关联
将ASH与AWR数据关联分析:
sql复制SELECT
h.sql_id,
s.plan_hash_value,
h.event,
COUNT(*) AS wait_count
FROM
v$active_session_history h
JOIN
v$sqlarea s ON h.sql_id = s.sql_id
WHERE
h.sample_time > SYSDATE - 60/1440
GROUP BY
h.sql_id, s.plan_hash_value, h.event
ORDER BY
wait_count DESC;
5. 高级分析技巧
5.1 时间维度分析模式
识别周期性性能问题:
sql复制SELECT
TO_CHAR(sample_time, 'HH24') AS hour,
wait_class,
COUNT(*) AS samples
FROM
v$active_session_history
WHERE
sample_time > SYSDATE - 7
GROUP BY
TO_CHAR(sample_time, 'HH24'),
wait_class
ORDER BY
1, 3 DESC;
5.2 ASH仓库数据归档
配置自动归档策略:
sql复制BEGIN
DBMS_WORKLOAD_REPOSITORY.MODIFY_SNAPSHOT_SETTINGS(
retention => 43200, -- 保留30天(分钟)
interval => 60); -- 每小时快照
END;
6. 性能问题诊断案例
最近处理的真实案例:某订单系统在每天10:00-11:00出现响应延迟。
通过ASH分析发现:
- 高峰时段"db file scattered read"等待激增
- 定位到3个SQL执行全表扫描
- 检查发现是缺失了新建索引
- 添加索引后等待事件减少82%
排查用的关键查询:
sql复制SELECT
sql_id,
event,
COUNT(*) AS wait_count
FROM
dba_hist_active_sess_history
WHERE
sample_time BETWEEN
TO_DATE('2023-05-15 10:00', 'YYYY-MM-DD HH24:MI')
AND TO_DATE('2023-05-15 11:00', 'YYYY-MM-DD HH24:MI')
AND wait_class != 'Idle'
GROUP BY
sql_id, event
ORDER BY
wait_count DESC;
7. 常见问题解决方案
7.1 ASH数据不完整
可能原因:
- STATISTICS_LEVEL未设置为TYPICAL/ALL
- 内存缓冲区过小(查看_V$ACTIVE_SESSION_HISTORY的采样率)
7.2 历史数据查询缓慢
优化技巧:
sql复制-- 创建时间分区索引
CREATE INDEX idx_ash_time ON dba_hist_active_sess_history(sample_time)
LOCAL TABLESPACE tools;
7.3 关键会话跟踪
持续监控特定会话:
sql复制SELECT * FROM (
SELECT
sample_time,
session_id,
sql_id,
event,
ROW_NUMBER() OVER(PARTITION BY session_id ORDER BY sample_time DESC) rn
FROM
v$active_session_history
WHERE
session_id = 135
)
WHERE rn <= 10;
在实际工作中,我发现结合ASH报告与SQL监控视图(v$sql_monitor)能获得最佳分析效果。对于持续时间超过5秒的SQL,Oracle会自动在v$sql_monitor中记录执行细节,这两个工具的组合使用就像给数据库装上了X光机和心电图监测仪。
