ASH采样奥秘:Oracle性能诊断的环形缓冲区玄机

在这里插入图片描述

Oracle活动会话历史(ASH)的环形缓冲区与采样算法

一、ASH概述与核心概念

官方解释

活动会话历史(Active Session History, ASH) 是Oracle数据库提供的一种高性能诊断工具,用于捕获和存储数据库活动会话的瞬时状态信息。ASH通过每秒采样一次活动会话的状态,并将这些信息存储在内存的环形缓冲区中,为数据库性能分析提供细粒度的历史数据。

V$ACTIVE_SESSION_HISTORY 视图是ASH功能的核心接口,它提供了对内存中采样数据的实时访问能力。ASH采样专注于正在等待或消耗CPU资源的会话,为性能诊断提供关键信息。

通俗解释

可以把ASH想象成一个数据库的"黑匣子"高速摄像机

  • 它每秒拍摄一张数据库当前正在"忙碌"的会话的快照
  • 这些快照存储在一个固定大小的循环存储区(环形缓冲区)中
  • 当存储区满时,新的记录会覆盖最旧的记录
  • DBA可以回放这些快照,精确查看任何时间点数据库在做什么

二、ASH架构与内部机制

1. 环形缓冲区结构

ASH使用SGA中的固定内存区域作为环形缓冲区:

-- 查看ASH缓冲区大小和配置
SELECT * FROM V$ASH_INFO;

-- 查看ASH缓冲区使用情况
SELECT * FROM V$ASH_BUFFER_INFO;

环形缓冲区的工作方式:

  1. 缓冲区被划分为固定数量的槽位(slots)
  2. 新采样数据写入当前指针位置
  3. 当到达缓冲区末尾时,指针回到开头覆盖旧数据
  4. 这种设计确保最近的数据总是可用

2. ASH采样算法

ASH每秒钟对数据库中的活动会话进行一次采样:

-- 查看ASH采样设置
SELECT * FROM V$ACTIVE_SESS_HISTORY; -- 采样数据视图

-- 查看采样统计信息
SELECT samples, sample_seconds, sample_errors
FROM V$ASH_SAMPLING_STATS;

3. ASH采样内容

ASH采样捕获每个活动会话的丰富上下文信息:

ASH采样
会话标识信息
等待信息
SQL执行信息
对象访问信息
阻塞关系信息
SID和SERIAL#
会话类型
客户端信息
等待事件
等待时间
等待参数
SQL_ID
SQL执行计划
SQL操作类型
对象号
文件号
块号
阻塞会话
阻塞链
等待链

三、ASH采样过程详解

1. 采样触发机制

ASH采样由后台进程MMON(Manageability Monitor Process)及其从属进程Mxxx负责:

-- 查看MMON及相关进程
SELECT name, description FROM V$BGPROCESS 
WHERE name LIKE 'MMON%' OR name LIKE 'M00%';

-- 查看采样频率设置(通常为1秒,不可调整)
SELECT * FROM V$ACTIVE_SESS_HISTORY; -- 观察SAMPLE_TIME的时间间隔

2. 活动会话判定标准

ASH只采样"活动"的会话,活动会话定义为:

  • 正在等待非空闲事件(非idle事件)
  • 正在使用CPU资源
-- 查看ASH中的等待事件分布
SELECT event, COUNT(*) 
FROM V$ACTIVE_SESSION_HISTORY 
WHERE sample_time > SYSDATE - 1/24 -- 最近1小时
GROUP BY event 
ORDER BY COUNT(*) DESC;

-- 查看CPU使用情况
SELECT session_id, session_serial#, COUNT(*) AS cpu_samples
FROM V$ACTIVE_SESSION_HISTORY 
WHERE session_state = 'ON CPU'
AND sample_time > SYSDATE - 1/24
GROUP BY session_id, session_serial#
ORDER BY cpu_samples DESC;

3. 避免采样偏差

ASH采用系统化的采样方法避免偏差:

  1. 固定时间间隔:严格每秒钟采样一次
  2. 全系统范围:采样所有实例的所有活动会话
  3. 统一判定标准:使用相同的活动性判定标准
  4. 上下文完整:捕获完整的执行上下文信息
-- 检查采样完整性(理论上每秒样本数应≈活动会话数)
SELECT TO_CHAR(sample_time, 'YYYY-MM-DD HH24:MI:SS') sample_second,
       COUNT(*) samples_per_second
FROM V$ACTIVE_SESSION_HISTORY 
WHERE sample_time > SYSDATE - 5/1440 -- 最近5分钟
GROUP BY TO_CHAR(sample_time, 'YYYY-MM-DD HH24:MI:SS')
ORDER BY sample_second DESC;

四、环形缓冲区管理

1. 缓冲区工作原理

ASH环形缓冲区采用先进先出(FIFO)的覆盖策略:

-- 查看缓冲区大小和使用情况
SELECT * FROM V$ASH_BUFFER_INFO;

-- 估算缓冲区可存储的时间范围
SELECT MIN(sample_time) oldest_sample, MAX(sample_time) newest_sample,
       (MAX(sample_time) - MIN(sample_time)) * 24 * 60 retention_minutes
FROM V$ACTIVE_SESSION_HISTORY;

2. 内存管理与溢出处理

当缓冲区满时,ASH采用覆盖策略:

  1. 新采样数据覆盖最旧的记录
  2. 系统自动将部分历史数据刷出到AWR中
  3. 保持最近的数据在内存中供实时查询
-- 查看ASH到AWR的刷新情况
SELECT snap_id, begin_interval_time, end_interval_time,
       ash_flush_elapsed_time, ash_flush_size
FROM DBA_HIST_ASH_SNAPSHOT
ORDER BY snap_id DESC;

五、ASH数据解读与分析

1. 关键数据字段解读

-- ASH关键字段示例查询
SELECT 
    sample_time,           -- 采样时间
    session_id,            -- 会话ID
    session_serial#,       -- 会话序列号
    session_state,         -- 会话状态(ON CPU/WAITING)
    event,                 -- 等待事件
    sql_id,                -- 当前SQL ID
    sql_plan_hash_value,   -- SQL计划哈希值
    current_obj#,          -- 当前访问对象
    block#,                -- 访问的块号
    time_waited,           -- 等待时间
    blocking_session,      -- 阻塞会话
    blocking_session_serial# -- 阻塞会话序列号
FROM V$ACTIVE_SESSION_HISTORY 
WHERE sample_time > SYSDATE - 5/1440 -- 最近5分钟
ORDER BY sample_time DESC;

2. 等待事件分析

-- 分析等待事件分布
SELECT event, session_state, COUNT(*) samples,
       ROUND(COUNT(*) * 100 / SUM(COUNT(*)) OVER(), 2) pct
FROM V$ACTIVE_SESSION_HISTORY 
WHERE sample_time > SYSDATE - 1/24 -- 最近1小时
GROUP BY event, session_state
ORDER BY samples DESC;

-- 识别顶级等待事件
SELECT * FROM (
    SELECT event, COUNT(*) samples,
           ROUND(RATIO_TO_REPORT(COUNT(*)) OVER() * 100, 2) pct
    FROM V$ACTIVE_SESSION_HISTORY 
    WHERE session_state = 'WAITING'
    AND sample_time > SYSDATE - 1/24
    GROUP BY event
    ORDER BY samples DESC
) WHERE ROWNUM <= 10;

3. SQL性能分析

-- 识别高负载SQL
SELECT sql_id, COUNT(*) samples,
       ROUND(COUNT(*) * 100 / SUM(COUNT(*)) OVER(), 2) pct,
       MAX(sample_time) last_seen
FROM V$ACTIVE_SESSION_HISTORY 
WHERE sample_time > SYSDATE - 1/24
AND sql_id IS NOT NULL
GROUP BY sql_id
ORDER BY samples DESC;

-- 关联SQL文本
SELECT ash.sql_id, sql.sql_text, COUNT(*) samples,
       SUM(ash.time_waited) total_wait_time
FROM V$ACTIVE_SESSION_HISTORY ash
JOIN V$SQLAREA sql ON ash.sql_id = sql.sql_id
WHERE ash.sample_time > SYSDATE - 1/24
GROUP BY ash.sql_id, sql.sql_text
ORDER BY total_wait_time DESC;

六、常见问题与排查方法

1. ASH数据不完整或缺失

问题现象:ASH历史数据时间范围过短或部分时间段缺失

排查方法

-- 检查ASH缓冲区大小是否足够
SELECT * FROM V$ASH_INFO;

-- 检查MMON进程状态
SELECT process_name, status FROM V$MANAGED_PROCESS 
WHERE process_name LIKE 'MMON%';

-- 检查采样是否正常工作
SELECT COUNT(*) samples_per_min,
       TO_CHAR(sample_time, 'YYYY-MM-DD HH24:MI') sample_minute
FROM V$ACTIVE_SESSION_HISTORY 
WHERE sample_time > SYSDATE - 1/24
GROUP BY TO_CHAR(sample_time, 'YYYY-MM-DD HH24:MI')
ORDER BY sample_minute DESC;

2. 性能问题诊断

问题现象:数据库响应时间变慢

排查方法

-- 分析特定时间段的性能问题
SELECT *
FROM V$ACTIVE_SESSION_HISTORY 
WHERE sample_time BETWEEN 
    TO_DATE('2023-06-15 14:00:00', 'YYYY-MM-DD HH24:MI:SS') AND
    TO_DATE('2023-06-15 14:10:00', 'YYYY-MM-DD HH24:MI:SS')
ORDER BY sample_time, session_id;

-- 使用ASH报告生成详细分析
-- 通过OEM或以下SQL生成ASH报告
SELECT * FROM TABLE(DBMS_WORKLOAD_REPOSITORY.ASH_REPORT_HTML(
    dbid => (SELECT dbid FROM V$DATABASE),
    inst_num => 1,
    l_btime => SYSDATE - 30/1440, -- 开始时间(30分钟前)
    l_etime => SYSDATE            -- 结束时间
));

3. 阻塞和锁争用分析

问题现象:会话阻塞或锁等待

排查方法

-- 查找阻塞链
SELECT sample_time, session_id, session_serial#, 
       blocking_session, blocking_session_serial#,
       event, current_obj#
FROM V$ACTIVE_SESSION_HISTORY 
WHERE blocking_session IS NOT NULL
AND sample_time > SYSDATE - 5/1440
ORDER BY sample_time DESC;

-- 分析锁等待详情
SELECT ash.sample_time, ash.session_id, ash.event,
       o.owner, o.object_name, o.object_type
FROM V$ACTIVE_SESSION_HISTORY ash
JOIN DBA_OBJECTS o ON ash.current_obj# = o.object_id
WHERE ash.event LIKE '%enq%'
AND ash.sample_time > SYSDATE - 1/24;

七、ASH与相关技术集成

1. ASH与AWR集成

ASH数据会自动刷新到AWR中,用于长期历史分析:

-- 查看AWR中的ASH数据
SELECT snap_id, begin_interval_time, ash_sample_count
FROM DBA_HIST_ASH_SNAPSHOT
ORDER BY snap_id DESC;

-- 比较两个时间段的性能差异
SELECT * FROM TABLE(DBMS_WORKLOAD_REPOSITORY.ASH_REPORT_DIFF_HTML(
    dbid => (SELECT dbid FROM V$DATABASE),
    inst_num => 1,
    l_btime1 => SYSDATE - 60/1440, -- 时间段1开始
    l_etime1 => SYSDATE - 30/1440, -- 时间段1结束
    l_btime2 => SYSDATE - 30/1440, -- 时间段2开始
    l_etime2 => SYSDATE            -- 时间段2结束
));

2. ASH与ADDM集成

ADDM(自动数据库诊断监控)使用ASH数据进行根本原因分析:

-- 查看ADDM分析结果
SELECT task_id, task_name, finding_name, impact, message
FROM DBA_ADVISOR_FINDINGS
WHERE task_id = (SELECT MAX(task_id) FROM DBA_ADVISOR_TASKS 
                 WHERE advisor_name = 'ADDM')
ORDER BY impact DESC;

八、最佳实践与管理建议

1. 监控配置建议

-- 定期检查ASH缓冲区状态
SELECT * FROM V$ASH_INFO;

-- 监控ASH采样率
SELECT samples, sample_seconds,
       ROUND(samples/sample_seconds, 2) samples_per_second
FROM V$ASH_SAMPLING_STATS;

-- 检查ASH到AWR的刷新情况
SELECT snap_id, ash_flush_size, ash_flush_elapsed_time
FROM DBA_HIST_ASH_SNAPSHOT
ORDER BY snap_id DESC;

2. 性能优化建议

-- 识别频繁等待的对象
SELECT o.owner, o.object_name, o.object_type,
       COUNT(*) wait_samples,
       ROUND(COUNT(*) * 100 / SUM(COUNT(*)) OVER(), 2) pct
FROM V$ACTIVE_SESSION_HISTORY ash
JOIN DBA_OBJECTS o ON ash.current_obj# = o.object_id
WHERE ash.session_state = 'WAITING'
AND ash.sample_time > SYSDATE - 1/24
GROUP BY o.owner, o.object_name, o.object_type
ORDER BY wait_samples DESC;

-- 分析SQL执行模式
SELECT sql_id, 
       SUM(CASE WHEN session_state = 'ON CPU' THEN 1 ELSE 0 END) cpu_samples,
       SUM(CASE WHEN session_state = 'WAITING' THEN 1 ELSE 0 END) wait_samples,
       COUNT(*) total_samples
FROM V$ACTIVE_SESSION_HISTORY 
WHERE sql_id IS NOT NULL
AND sample_time > SYSDATE - 1/24
GROUP BY sql_id
ORDER BY total_samples DESC;

3. 容量规划建议

-- 评估ASH缓冲区需求
SELECT 
    -- 当前活动会话数峰值
    (SELECT MAX(sessions) FROM (
        SELECT COUNT(*) sessions
        FROM V$ACTIVE_SESSION_HISTORY
        GROUP BY sample_time
    )) max_concurrent_sessions,
    
    -- 当前缓冲区保留时间
    (SELECT (MAX(sample_time) - MIN(sample_time)) * 24 * 60
     FROM V$ACTIVE_SESSION_HISTORY) retention_minutes,
     
    -- 建议缓冲区大小(基于峰值会话数)
    (SELECT MAX(sessions) * 120 * 60 FROM (
        SELECT COUNT(*) sessions
        FROM V$ACTIVE_SESSION_HISTORY
        GROUP BY sample_time
    )) suggested_buffer_size
FROM DUAL;

总结

Oracle ASH是一个强大的性能诊断工具,它通过每秒采样活动会话状态,为DBA提供了细粒度的性能分析能力。理解ASH的环形缓冲区机制、采样算法和数据解读方法,对于快速诊断和解决数据库性能问题至关重要。

通过合理利用ASH数据,DBA可以:

  1. 快速识别性能瓶颈和等待事件
  2. 分析SQL执行性能和资源消耗
  3. 诊断锁争用和阻塞问题
  4. 进行容量规划和性能优化
  5. 生成详细的性能报告和分析

ASH与其他Oracle诊断工具(如AWR、ADDM)的紧密集成,形成了一个完整的性能管理生态系统,帮助DBA确保数据库系统的高效稳定运行。

欢迎关注我的公众号《IT小Chen

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值