\_ash\_sampling\_interval 决定ash采样时间粒度而非精度,设为200ms虽可捕获亚秒级事件但会加剧mmnl负载、加速ash缓冲区覆盖;仅当已怀疑特定瞬时问题时才临时调低,且须同步调整\_ash\_disk\_filter\_ratio并及时恢复默认值。
_ash_sampling_interval 不是“越高越准”,而是决定了你能在多大时间粒度上捕获会话状态变化。设为 1000(默认)时,每秒最多一个样本;设为 200,理论上每 200ms 采一次——但代价是内存、cpu 和 mmnl 负载同步升高,反而可能干扰真实问题。
为什么 1 秒采样可能错过关键事件
ASH 只记录当时处于 ON CPU 或非空闲等待状态的会话。若某次锁等待仅持续 300ms,而两次采样刚好卡在它开始前和结束后(比如 14:00:00.8 和 14:00:01.8),该事件就完全漏掉。
- 亚秒级阻塞(如
enq: TX - row lock contention)、短 SQL 执行、瞬时 latch 竞争,都容易被默认频率跳过 -
event字段为空或为NULL的样本,不表示“没事”,只表示那刻没被采到活跃态 - 在 RAC 环境下,不同节点采样时间点不严格对齐,叠加默认间隔,跨节点阻塞链更难拼合
调高 _ash_sampling_interval 的实际限制
把参数改成 500 或 200 并不等于“诊断能力翻倍”。MMNL 进程每轮都要遍历所有前台会话,检查 session_state、event、sql_id 等字段,并写入 SGA 循环缓冲区。
- 并发会话数 > 2000 时,MMNL 周期性扫描本身就会吃掉可观 CPU,尤其在系统已接近饱和时
-
_ash_size默认约 1–30MB,高频采样会更快填满缓冲区,导致旧样本被覆盖得更早,反缩短可观测窗口 - 设为 0 或负值会禁用 ASH,等于关掉实时诊断入口,
v$active_session_history将无数据可查
什么时候真需要调低间隔?
不是为了“更准”,而是为了验证某个已怀疑的亚秒级现象。比如你从 AWR 报告看到 db file sequential read 平均时间突增,但 v$sql 里对应 SQL 的 elapsed_time 却不高——这时才值得临时把 _ash_sampling_interval 改成 200,配合 sample_time 精确到毫秒的查询,确认是否大量小 I/O 被密集触发。
- 必须有
ALTER SYSTEM权限,且修改是实例级的,无法按 PDB 或会话隔离 - 改完立刻生效,但不要长期维持;观察完就切回 1000,避免拖慢 MMNL
- 务必同步检查
_ash_disk_filter_ratio(默认 1/10),否则高频采样进内存,却只存 10% 到历史表,dba_hist_active_sess_history仍看不出细节
真正影响诊断成败的,往往不是采样多密,而是你有没有在问题刚发生时,第一时间盯住 v$active_session_history,并用 trunc(sample_time, 'hh24') 和 sql_id 做小时级聚合比对——因为大多数“突增”不是靠单点精度,而是靠趋势偏移暴露出来的。











