
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;
环形缓冲区的工作方式:
- 缓冲区被划分为固定数量的槽位(slots)
- 新采样数据写入当前指针位置
- 当到达缓冲区末尾时,指针回到开头覆盖旧数据
- 这种设计确保最近的数据总是可用
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采样过程详解
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采用系统化的采样方法避免偏差:
- 固定时间间隔:严格每秒钟采样一次
- 全系统范围:采样所有实例的所有活动会话
- 统一判定标准:使用相同的活动性判定标准
- 上下文完整:捕获完整的执行上下文信息
-- 检查采样完整性(理论上每秒样本数应≈活动会话数)
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采用覆盖策略:
- 新采样数据覆盖最旧的记录
- 系统自动将部分历史数据刷出到AWR中
- 保持最近的数据在内存中供实时查询
-- 查看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可以:
- 快速识别性能瓶颈和等待事件
- 分析SQL执行性能和资源消耗
- 诊断锁争用和阻塞问题
- 进行容量规划和性能优化
- 生成详细的性能报告和分析
ASH与其他Oracle诊断工具(如AWR、ADDM)的紧密集成,形成了一个完整的性能管理生态系统,帮助DBA确保数据库系统的高效稳定运行。
欢迎关注我的公众号《IT小Chen》

被折叠的 条评论
为什么被折叠?



