在数据库的世界里,Oracle 数据库一直以其强大的性能和稳定性著称。而今天,我们要介绍一个堪称数据库性能“黑匣子”的神秘角色 —— DBA_HIST_ACTIVE_SESS_HISTORY 视图。它就像飞机上的黑匣子一样,默默记录着数据库运行过程中的各种活动会话信息,是数据库管理员(DBA)监控和优化数据库性能的得力助手。
DBA_HIST_ACTIVE_SESS_HISTORY:数据库的“行车记录仪”
DBA_HIST_ACTIVE_SESS_HISTORY 是 Oracle 数据库中用于存储活动会话历史信息的视图。想象一下,数据库就像一辆高速行驶的汽车,而这个视图就是车上的行车记录仪。它每隔一段时间(通常是 1 秒),就会对数据库中所有活跃的会话进行一次“快照”抓拍,把每个会话当时正在执行的操作记录下来。
这些记录包含了丰富的信息,比如会话正在执行的 SQL 语句、等待的事件(比如等待磁盘 I/O、等待锁)、消耗的资源(CPU、内存等)以及发生的具体时间等。通过这些历史记录,我们可以像回放行车记录仪视频一样,回顾数据库过去一段时间内的运行状况,了解它在每一个时刻的表现。
举个形象的例子:假设数据库是一架飞机,那么 DBA_HIST_ACTIVE_SESS_HISTORY 就相当于飞机上的黑匣子,持续记录着飞机(数据库)飞行(运行)过程中的各种参数和操作。当数据库出现性能问题时,我们就可以通过这个“黑匣子”来追查过去发生了什么,找出问题的根源所在。
解密 DBA_HIST_ACTIVE_SESS_HISTORY:黑匣子中的关键信息
既然是“黑匣子”,那里面自然记录了很多关键信息,这些信息通过一个个字段展现出来,帮助我们深入了解数据库的运行情况。下面是一些主要字段及其含义:
SNAP_ID(快照 ID) :每次抓拍的编号。Oracle 会定期生成快照,每个快照都有唯一的 ID,用来标识这一时刻的记录批次。简单来说,这就像是给数据库拍的一张张“集体照”的编号,方便我们区分不同的时间点。 SAMPLE_TIME(采样时间) :具体的采样时间点,精确到秒,让我们知道某个事件是在几点几分发生的。它为我们提供了时间维度的参考,使我们能够将不同的记录定位到特定的时刻。 SESSION_ID(会话 ID)和 SESSION_SERIAL#(会话序列号) :这两个字段一起用来唯一标识一个会话。SESSION_ID 是会话的 ID 号,而 SERIAL# 相当于会话的序列号,防止 ID 重复。可以把它们想象成会话的“身份证号”,通过这对组合,我们就能区分不同的用户连接,了解每个用户在数据库中的具体操作。 SQL_ID(SQL 标识符) :当前会话正在执行的 SQL 语句的唯一标识。SQL_ID 就好比是 SQL 语句的“车牌号”,通过它我们可以快速定位到具体是哪条 SQL 在运行,从而进一步分析这条 SQL 的性能情况。 EVENT(等待事件) :如果当前会话在等待某些资源,这里会记录它在等什么事件。例如,可能是在等待磁盘读取数据(db file sequential read),或者等待锁(enq: TX - row lock contention)等等。如果会话没有在等待,而是正在使用 CPU 执行任务,那么 EVENT 字段可能为空或者显示为“CPU”。
除此之外,还有 DBID(数据库 ID,标识是哪个数据库)、INSTANCE_NUMBER(实例编号,用于集群环境区分不同实例)、SESSION_TYPE(会话类型,比如是用户会话还是后台进程)等辅助信息。这些字段帮助我们在复杂环境下更准确地定位问题。
通过这些字段的组合,DBA_HIST_ACTIVE_SESS_HISTORY 详细记录了“在什么时候、哪个用户会话、执行了哪条 SQL、遇到了什么等待”等关键信息。把这些记录按时间顺序连起来看,就像是一部数据库的“监控录像”,让我们对数据库的运行过程了如指掌。
DBA_HIST_ACTIVE_SESS_HISTORY 的强大用途:解锁数据库性能优化的关键
DBA_HIST_ACTIVE_SESS_HISTORY 视图的用途非常广泛,主要用于监控数据库性能和诊断问题。以下是几个典型的使用场景:
监控历史活动:回溯数据库的过去
通过查询这个视图,我们可以回顾数据库过去一段时间内的会话活动情况。比如,想知道昨天下午 3 点到 4 点之间,数据库有多少用户在操作,他们主要在执行哪些 SQL,或者有没有长时间等待的情况。这时候,我们可以从 DBA_HIST_ACTIVE_SESS_HISTORY 中提取那段时间的记录,统计分析每个时间点的会话数量、活跃的 SQL 以及常见的等待事件。
举个例子,假设我们想了解某一小时内每分钟有多少不同的会话在运行,以及这些会话主要在执行哪些 SQL 或等待什么事件。可以编写类似下面的查询:
select trunc(sample_time, 'mi') tm, sql_id, nvl(event,'CPU'),count(distinct session_id) cnt from dba_hist_active_sess_history where sample_time>=to_date('2023-5-26 09:00:00','yyyy-mm-dd hh24:mi:ss') and sample_time<=to_date('2023-5-26 10:00:00','yyyy-mm-dd hh24:mi:ss') group by trunc(sample_time, 'mi'), sql_id,nvl(event,'CPU') order by cnt desc;
分析性能瓶颈:找出数据库变慢的“罪魁祸首”
DBA_HIST_ACTIVE_SESS_HISTORY 最强大的功能之一,就是帮助诊断性能问题。当数据库出现变慢、响应延迟或者用户抱怨查询慢的时候,DBA 通常会借助这个视图来找出背后的原因。具体可以从以下几个方面入手:
识别高负载 SQL :通过分析视图中记录的 SQL_ID 和出现的频率,我们可以发现哪些 SQL 语句在历史上执行得最频繁或者占用了最多资源。如果某个 SQL_ID 在大量的采样记录中出现,说明这条 SQL 在那段时间内非常活跃,可能就是导致系统繁忙的“罪魁祸首”。进一步查询该 SQL_ID 对应的具体 SQL 文本和执行计划,就能评估是否需要对这条 SQL 进行优化。 定位等待事件 :如果发现很多会话长时间处于等待状态,查看 EVENT 字段就能找出它们在等什么。常见的等待事件比如等待磁盘 I/O(可能是存储慢或者 SQL 需要大量读取)、等待锁(可能是有事务长时间未提交阻塞了其他会话)、等待内存(可能 PGA 或 SGA 配置不足)等等。通过统计不同等待事件的出现次数和时长,我们能判断系统的瓶颈类型,到底是 CPU 不够用,还是 I/O 太慢,或是并发争用导致的问题。 追踪会话行为 :对于特定的问题会话(比如某个用户报告他的查询特别慢),可以根据 SESSION_ID 在这个视图中找到该会话的历史采样记录,查看它在不同时间点在执行什么 SQL、等待什么事件。这相当于给这个会话“放电影”,通过观察它的执行轨迹,找到慢的原因。例如,可能发现这个会话在某个时间点执行了一条复杂查询,之后一直卡在等待某个事件上。 关联 AWR 报告 :DBA_HIST_ACTIVE_SESS_HISTORY 是 Oracle 自动工作负载信息库(AWR)的一部分,Oracle 会定期将其内容保存到历史表中。DBA 经常结合 AWR 报告来使用这个视图。AWR 报告提供了宏观的性能指标,而通过直接查询 DBA_HIST_ACTIVE_SESS_HISTORY 可以深入细节。例如,AWR 可能指出某段时间 CPU 利用率很高,那么可以查询对应的 HISTORY 记录看看是不是某几条 SQL 在疯狂消耗 CPU。又或者 AWR 发现平均等待时间变长,可以通过 HISTORY 记录找出具体是哪个等待事件变多了。
举个实际的例子:某天中午,数据库突然变慢,用户感觉查询响应明显变迟钝。DBA 查看 AWR 报告发现那段时间“db file sequential read”等待事件显著增加,平均等待时间变长。于是进一步查询 DBA_HIST_ACTIVE_SESS_HISTORY,发现在问题时间段内,大量会话都在等待读取同一张表的数据,且关联的 SQL_ID 指向一条特定的查询。进一步分析这条 SQL,发现它缺少索引,导致全表扫描产生了大量磁盘 I/O 请求。找到原因后,DBA 为该表添加了索引,问题顺利解决。这就是利用历史会话信息诊断性能瓶颈的典型过程。

DBA_HIST_ACTIVE_SESS_HISTORY 作为 Oracle 数据库的“性能黑匣子”,忠实地记录着数据库运行过程中每个活跃会话的详细活动。它就像数据库的“行车记录仪”和“监控摄像头”,持续记录着数据库的运行轨迹。对于数据库管理员来说,这个视图是排查问题、优化性能的利器;即使对普通用户而言,理解它的作用也有助于明白数据库是如何记录和反映其行为的。
当数据库出现性能问题时,DBA_HIST_ACTIVE_SESS_HISTORY 能够帮助我们透过现象看本质,不再只是看到表面的慢,而是可以深入历史记录,找到是哪些操作、哪些会话在“拖后腿”,从而有针对性地进行优化和调整。下次如果有人提到 Oracle 的性能调优,不妨提起这个“黑匣子”,它可是解决问题的关键线索来源呢!




