上一期生成了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分钟)
);