ASH必须用环形缓冲区因其设计目标是低开销、高实时性采样,不能依赖磁盘I/O或锁竞争;每秒采样若写入磁盘会拖垮高并发实例,而环形缓冲区在SGA中连续分配、无锁追加、满即覆写,天然适配“只看最近”的诊断场景。
ASH为什么必须用环形缓冲区
因为ash设计目标是低开销、高实时性采样,不能依赖磁盘i/o或锁竞争。每秒一次的采样频率下,写入磁盘或持久化表会直接拖垮高并发实例;而环形缓冲区(circular buffer)在sga中连续分配、无锁追加、满即覆写,天然适配“只看最近”的诊断场景。
V$ACTIVE_SESSION_HISTORY查不到数据的三个常见原因
不是ASH没工作,而是你没对上它的节奏:
- 没加
WHERE sample_time > SYSDATE - 1/1440—— 默认不带时间过滤会扫全缓冲区,但旧数据早被覆盖,结果为空 - 卡顿持续时间
-
SELECT * FROM v$sgastat WHERE name LIKE '%ASH%'返回bytes接近 0 或远低于_ash_size值 —— 说明MMNL进程异常或ASH内存未真正启用
_ash_size参数调大真能延长保留时间吗
能,但有硬限制和副作用:
- 最大值受SGA总量约束,Oracle文档明确说不能超过30MB;12c仍默认4194304(4MB),高并发下实际留存常不足15分钟
- 调大后需重启实例生效,且会挤占其他SGA组件(如shared pool、buffer cache)空间
- 即使设到30MB,若系统每秒产生200+活动会话,缓冲区仍可能5–10分钟就刷一遍 —— 环形本质没变,只是“跑道变长了”
什么时候该放弃内存ASH,转去查AWR持久化数据
当你需要分析的卡顿发生在1小时以前,或者想跨时段比对趋势时,V$ACTIVE_SESSION_HISTORY 已不可靠。此时应查 DBA_HIST_ACTIVE_SESS_HISTORY,它由MMNL按 _ash_disk_filter_ratio(默认1/10)从内存批量落盘,虽然粒度更粗、延迟更高,但时间跨度可达数天甚至数周。
注意:该视图依赖AWR快照正常生成,且默认只保留8天 —— 如果DBA改过 DBA_HIST_WR_CONTROL.retention,得先确认历史数据还在不在。


















