
Oracle 19c V$ACTIVE_SESSION_HISTORY (ASH) 动态性能视图详解
核心作用
V$ACTIVE_SESSION_HISTORY (ASH) 是 Oracle 数据库性能诊断的核心工具,主要提供:
- 实时性能监控:每秒采样活动会话状态
- 历史性能分析:保留最近会话活动历史
- 瓶颈诊断:识别 SQL、对象、等待事件等性能瓶颈
- 低开销采样:轻量级数据收集机制
- AWR 基础:为自动工作负载仓库提供原始数据
关键特性
- 每秒采样:每秒钟收集一次活动会话数据
- 活动会话聚焦:仅采样非空闲状态的会话
- 内存存储:数据存储在 SGA 的循环缓冲区中
- 历史保留:默认保留约1小时(取决于内存大小)
- 多维分析:支持 SQL、会话、对象、事件等多维度分析
- 自动刷新:采样过程完全自动化
字段详解(Oracle 19c)
基础标识字段
| 字段名 | 数据类型 | 描述 |
|---|---|---|
SAMPLE_ID | NUMBER | 采样记录的唯一标识符 |
SAMPLE_TIME | TIMESTAMP | 采样的精确时间(包含毫秒) |
SESSION_ID | NUMBER | 会话标识符 (SID) |
SESSION_SERIAL# | NUMBER | 会话序列号(与SID组合唯一标识会话) |
USER_ID | NUMBER | Oracle 用户 ID |
SQL_ID | VARCHAR2(13) | 正在执行的 SQL 语句 ID |
SQL_CHILD_NUMBER | NUMBER | SQL 子游标编号 |
SQL_OPCODE | NUMBER | SQL 操作代码(2=INSERT, 3=SELECT, 6=UPDATE, 7=DELETE 等) |
PLSQL_ENTRY_OBJECT_ID | NUMBER | 调用的 PL/SQL 对象 ID |
PLSQL_ENTRY_SUBPROGRAM_ID | NUMBER | PL/SQL 子程序 ID |
会话状态字段
| 字段名 | 数据类型 | 描述 |
|---|---|---|
SESSION_STATE | VARCHAR2(7) | 会话状态: - ON CPU:消耗 CPU- WAITING:等待事件 |
EVENT | VARCHAR2(128) | 等待事件名称(当状态为 WAITING 时) |
EVENT_ID | NUMBER | 等待事件的唯一标识符 |
SEQ# | NUMBER | 等待事件序列号 |
P1TEXT | VARCHAR2(64) | 等待事件参数1描述 |
P1 | NUMBER | 等待事件参数1值 |
P2TEXT | VARCHAR2(64) | 等待事件参数2描述 |
P2 | NUMBER | 等待事件参数2值 |
P3TEXT | VARCHAR2(64) | 等待事件参数3描述 |
P3 | NUMBER | 等待事件参数3值 |
WAIT_CLASS | VARCHAR2(64) | 等待事件类别(Concurrency, User I/O, System I/O 等) |
WAIT_TIME | NUMBER | 等待时间(毫秒) |
TIME_WAITED | NUMBER | 本次等待已耗时(毫秒) |
对象与执行字段
| 字段名 | 数据类型 | 描述 |
|---|---|---|
CURRENT_OBJ# | NUMBER | 当前访问的对象 ID |
CURRENT_FILE# | NUMBER | 当前访问的文件号 |
CURRENT_BLOCK# | NUMBER | 当前访问的块号 |
PROGRAM | VARCHAR2(48) | 客户端程序名称 |
MODULE | VARCHAR2(48) | 应用模块名称 |
ACTION | VARCHAR2(32) | 应用操作名称 |
CLIENT_ID | VARCHAR2(64) | 客户端标识符 |
MACHINE | VARCHAR2(64) | 客户端机器名称 |
PORT | NUMBER | 客户端端口号 |
并行与高级字段
| 字段名 | 数据类型 | 描述 |
|---|---|---|
QC_SESSION_ID | NUMBER | 并行查询协调器会话 ID |
QC_INSTANCE_ID | NUMBER | 并行查询协调器实例 ID(RAC) |
BLOCKING_SESSION | NUMBER | 阻塞当前会话的会话 ID |
BLOCKING_SESSION_STATUS | VARCHAR2(11) | 阻塞会话状态(VALID, NO HOLDER, UNKNOWN) |
BLOCKING_INST_ID | NUMBER | 阻塞会话所在实例 ID(RAC) |
XID | RAW(8) | 事务标识符 |
基表与底层原理
底层结构:
WRH$_ACTIVE_SESSION_HISTORY(AWR 持久化存储)- SGA 中的循环缓冲区(实时数据)
数据来源:
- 活动会话采样器:每秒扫描 V$SESSION 视图
- 会话状态检测:识别 ON CPU 或 WAITING 状态
- 等待事件捕获:记录等待事件详情
- SQL 执行跟踪:关联当前执行的 SQL 语句
工作原理:
- 每秒钟采样器检查所有活动会话
- 对于每个活动会话,记录关键性能数据
- 数据写入 SGA 的循环缓冲区(ASH 缓冲区)
- MMON 进程定期将内存数据刷新到磁盘(AWR)
- 当 ASH 缓冲区满时,覆盖最旧的数据
数据生命周期:
- 内存保留:约1小时(默认)
- 磁盘保留:8天(默认 AWR 保留策略)
核心使用场景
1. 实时性能诊断
SELECT sample_time, session_id, sql_id, event, time_waited
FROM v$active_session_history
WHERE session_state = 'WAITING'
ORDER BY sample_time DESC;
2. SQL 性能分析
SELECT sql_id, COUNT(*) AS samples
FROM v$active_session_history
WHERE sample_time > SYSDATE - 15/1440 -- 最近15分钟
GROUP BY sql_id
ORDER BY samples DESC;
3. 等待事件分析
SELECT event, wait_class, COUNT(*) AS total_waits
FROM v$active_session_history
WHERE sample_time > SYSDATE - 30/1440 -- 最近30分钟
GROUP BY event, wait_class
ORDER BY total_waits DESC;
4. 对象争用检测
SELECT o.object_name, o.object_type, COUNT(*) AS access_count
FROM v$active_session_history ash
JOIN dba_objects o ON ash.current_obj# = o.object_id
WHERE ash.sample_time > SYSDATE - 60/1440 -- 最近60分钟
GROUP BY o.object_name, o.object_type
ORDER BY access_count DESC;
5. 阻塞会话分析
SELECT blocking_session, event, COUNT(*) AS block_count
FROM v$active_session_history
WHERE blocking_session IS NOT NULL
AND sample_time > SYSDATE - 10/1440 -- 最近10分钟
GROUP BY blocking_session, event
ORDER BY block_count DESC;
常用查询 SQL 示例
1. 最近10分钟性能概览
SELECT
TO_CHAR(sample_time, 'HH24:MI:SS') AS time,
session_state,
wait_class,
COUNT(*) AS sessions
FROM v$active_session_history
WHERE sample_time > SYSDATE - 10/1440
GROUP BY
TO_CHAR(sample_time, 'HH24:MI:SS'),
session_state,
wait_class
ORDER BY time;
2. TOP SQL 识别
SELECT
sql_id,
sql_opname,
COUNT(*) AS total_samples,
SUM(CASE WHEN session_state = 'ON CPU' THEN 1 ELSE 0 END) AS cpu_samples,
SUM(CASE WHEN session_state = 'WAITING' THEN 1 ELSE 0 END) AS wait_samples
FROM v$active_session_history
WHERE sample_time > SYSDATE - 30/1440
GROUP BY sql_id, sql_opname
ORDER BY total_samples DESC
FETCH FIRST 10 ROWS ONLY;
3. 文件 I/O 分析
SELECT
current_obj#,
current_file#,
event,
COUNT(*) AS wait_count,
SUM(time_waited) AS total_wait_time
FROM v$active_session_history
WHERE wait_class = 'User I/O'
AND sample_time > SYSDATE - 60/1440
GROUP BY current_obj#, current_file#, event
ORDER BY total_wait_time DESC;
4. 阻塞链分析
SELECT
session_id,
blocking_session,
event,
sample_time
FROM v$active_session_history
WHERE blocking_session IS NOT NULL
AND sample_time > SYSDATE - 5/1440
ORDER BY sample_time DESC;
5. 应用模块性能分析
SELECT
module,
action,
wait_class,
COUNT(*) AS total_samples,
ROUND(100 * RATIO_TO_REPORT(COUNT(*)) OVER (), 2) AS pct
FROM v$active_session_history
WHERE sample_time > SYSDATE - 60/1440
GROUP BY module, action, wait_class
ORDER BY total_samples DESC;
6. 生成 ASH 报告(命令行)
-- 生成文本报告
@?/rdbms/admin/ashrpt.sql
-- 生成 HTML 报告
@?/rdbms/admin/ashrpti.sql
高级使用技巧
1. 结合 AWR 历史数据
SELECT * FROM dba_hist_active_sess_history
WHERE sample_time BETWEEN TO_TIMESTAMP('2023-01-01 10:00', 'YYYY-MM-DD HH24:MI')
AND TO_TIMESTAMP('2023-01-01 11:00', 'YYYY-MM-DD HH24:MI');
2. 时间模型分析
SELECT
session_state,
wait_class,
SUM(time_waited)/1000 AS time_sec
FROM v$active_session_history
WHERE sample_time > SYSDATE - 30/1440
GROUP BY session_state, wait_class
ORDER BY time_sec DESC;
3. 活动会话趋势分析
SELECT
TO_CHAR(sample_time, 'YYYY-MM-DD HH24:MI') AS minute,
COUNT(*) AS active_sessions
FROM v$active_session_history
WHERE sample_time > SYSDATE - 24/24 -- 最近24小时
GROUP BY TO_CHAR(sample_time, 'YYYY-MM-DD HH24:MI')
ORDER BY minute;
重要注意事项
- 权限要求:需要 SELECT ANY DICTIONARY 或特定权限
- 内存限制:ASH 缓冲区大小由
_ash_size参数控制 - RAC 环境:使用 GV$ACTIVE_SESSION_HISTORY 查看集群范围数据
- 历史数据:超过1小时的数据需查询 DBA_HIST_ACTIVE_SESS_HISTORY
- 采样限制:
- 仅捕获活动会话(非空闲)
- 高并发系统可能无法捕获所有活动会话
- 性能影响:通常 <1% 的 CPU 开销,但极端情况下可能达到 2-5%
相关参数
-- ASH 缓冲区大小(默认自动管理)
SELECT * FROM v$sgastat WHERE name = 'ASH buffers';
-- ASH 采样设置
SELECT * FROM v$sysstat WHERE name LIKE '%ASH%';
通过 V$ACTIVE_SESSION_HISTORY,DBA 可以快速诊断性能问题,识别资源瓶颈,优化 SQL 语句,并全面了解数据库工作负载特征。结合 AWR 和 ADDM,ASH 构成了 Oracle 性能诊断体系的核心。
欢迎关注我的公众号《IT小Chen》
1399

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



