
故障可以过去,证据不能随之消失。ASH把时间与参与者重新连在一起,让监控从汇总结果走向重建现场,让优化有据可循。
在之前的「等待事件革命——数据库到底把时间花在了哪里」一文中,我们把CPU与非空闲等待放进DB Time这本时间总账,终于知道数据库为什么慢。但最棘手的性能故障往往只有几分钟:DBA赶到时,锁已经释放,SQL已经结束,系统级统计只留下一笔区间汇总后的总账,参与者却已经散了。ASH(Active Session History,活动会话历史)的突破,是把时间、会话、SQL、等待和对象一起留下,让事后的诊断仍有现场可查。
尽管时间总账可以为“数据库为什么慢”指明方向,但单看系统级汇总有一个天然限制:它会抹平参与者之间的差异。同样是600秒User I/O,可能是同一条SQL的并发执行在一分钟内集中制造,也可能是几百条SQL零散累积。这两种情况的调优动作完全不同。
¹ 汤姆·凯特(Tom Kyte)是Oracle数据库技术专家,创办Ask Tom问答网站并长期解答开发与性能问题,著有《Expert Oracle Database Architecture》《Effective Oracle by Design》等。他通过问答、示例和著作推广以证据验证数据库行为的方法,帮助开发者与DBA理解数据库内部机制及性能诊断。

一种朴素办法,是频繁读取所有会话的V$SESSTAT和V$SESSION_EVENT,再抓SQL、对象与文件统计。数据库性能监控与可视化专家凯尔·海利(Kyle Hailey)曾在一场演讲里给出示例:假设150个会话各有800个等待事件和200项统计,那么仅会话层就有15万个组合;SQL可能上万、对象可能上千,将继续放大采集量。轮询越密,采集器自己越可能成为负担。

图1:为所有会话、SQL、对象和文件持续读取计数器,采集规模与竞争开销都会迅速膨胀。
更麻烦的是拼接。会话统计在10:00:01读取,SQL数据到10:00:03才采集,对象数据采集又晚两秒,所得“现场”其实来自不同时间。Oracle 10g的性能指南明确区分累计增量、区间平均指标与活动采样,并指出AWR并不按会话层保存那些累计统计。前后快照适合看一个区间的增量和Top Events,却难以指出秒级尖峰中的参与者。采得全,不等于拼得准。
Oracle的ASH每秒采样一次活动会话。这里的“活动”有明确边界:会话正在使用CPU,或正在等待非Idle类事件;连接着但没干活的会话不会写入样本。数据量因此跟实际工作量相关,而不是跟允许连接多少会话相关。
一行ASH样本至少把采样时间、会话、SQL、会话状态和等待事件放在一起,还可以关联执行计划、模块与动作、服务、程序、对象、文件、块以及阻塞会话。样本先进入SGA的循环缓冲区,负载越高,内存里能保留的会话数据时间通常越短;后台进程再把其中一部分持久化到AWR,以供更长时间范围的历史分析。

图2:ASH按固定时刻记录活动会话;CPU与非空闲等待入样本,空闲会话被过滤。
2012年,凯特把ASH比作“模糊的TKPROF”:它不如SQL跟踪汇总精细,却能从系统总量下钻到某个会话、一条或一组SQL,观察它们当时在做什么。也就是说,采样保存的是观察瞬间,不是期间发生的全部事件。一个20毫秒等待可能落在两次采样之间;持续8秒的锁等待则很可能连续留下多行。样本适合估计时间分布,单行不能被武断地解释为“准确消耗了一秒”,更不能拿它证明某个极短调用必然发生过或没有发生过。
但在足够多的会话和样本上,某类状态被采到的比例会逐渐接近它占用活动时间的比例。在内存视图V$ACTIVE_SESSION_HISTORY中,ASH通常每秒采样一次,因此1000行User I/O样本大致对应1000个数据库活动秒;写入DBA_HIST_ACTIVE_SESS_HISTORY的历史数据通常经过降采样,典型采样间隔约为10秒,同样1000行样本对应的活动时间量级约为10000秒。实际分析时仍应根据数据库版本和采样字段确认间隔,Oracle 12.2及以后版本还可以参考USECS_PER_ROW。ASH提供的是统计估计,不是审计流水。
今天,zCloud承接的已不只是把ASH数据保存得更久,而是把“持续观察活动会话”的方法从Oracle内核扩展到异构数据库。对于具备原生ASH能力的数据库,zCloud周期性读取并持久化已有样本;对于不提供ASH或ASH不可用的数据库,则以秒级频率采集系统视图,把会话、SQL、运行状态和等待事件组织成可追溯的活动样本。由此,即使某些国产数据库没有Oracle式的内核ASH,DBA仍能在统一的时间轴上观察活动会话趋势,按时间窗口计算AAS,并继续下钻Top SQL、Top Event和Top Session。
需要注意的是,不同数据库的采样来源和精度并不完全相同,分析时仍要核对实际采集间隔、汇总粒度和保留策略;但ASH与AAS所代表的诊断方法,已经不再依赖某一种数据库的内核实现。

图3:zCloud将异构数据库的活动会话数据统一为ASH/AAS诊断视角。
AAS(Average Active Sessions,平均活跃会话数)的定义很简单:某个窗口内的DB Time除以墙钟时间(自然流逝时间)。60秒累计720秒DB Time,AAS就是12,表示这段时间平均有12个前台会话在数据库调用中消耗CPU时间或非Idle等待时间。Oracle在2011年的ASH Analytics材料中仍以这一公式解释负载。它相当于把时间总量变成了可以画在纵轴上的并发强度。
AAS高不等于CPU一定忙。如图4所示,AAS同为12,一种情况可能有7.5个会话处于CPU类活动状态,已经贴近8核主机的处理能力;另一种情况可能只有3个会话处于CPU类活动状态,7个会话等待User I/O,其余2个会话等待其他非Idle事件。前者先查高CPU SQL和调度,后者则先查SQL访问路径与存储延迟。还要注意:ASH中的CPU样本既可能正在CPU上运行,也可能位于操作系统运行队列中。因此,CPU类AAS与CPU能力的比较只是线索,仍需结合主机CPU利用率和运行队列验证。

图4:AAS = DB Time 墙钟时间;相同的AAS可能对应完全不同的CPU与等待结构。
同一批ASH样本可以沿等待、SQL、计划、会话和对象等维度反复切换。先按等待类别看User I/O是否突出,再按SQL_ID分组找主要贡献者,接着比较PLAN_HASH_VALUE,最后落到对象、文件或阻塞会话。时间窗口不变,问题一层层收窄,证据链不会中途换账本。
从数据结构上看,这相当于把DB Time放进一个可以切片的数据立方体:Top SQL、Top Consumers和Top Resources不再是几张互不相干的排行榜,“最慢SQL”“最忙会话”“最热对象”成了同一活动现场在不同维度上的投影。2011年Oracle Enterprise Manager 12c的ASH Analytics材料进一步把这种思路整理为多维分析方法,支持按服务、模块等维度进行切片、聚合和下钻,并指出早期Top Activity受到固定时间滑块和分析维度的限制。
因此,这一阶段真正的改变是不同排行榜开始共享同一时间坐标和同一组活动样本。数据模型解决了“能否从不同维度观察同一现场”,Top Activity接下来解决的则是“DBA怎样在界面上完成这套下钻”。
同期,Quest Software的Spotlight等第三方工具让数据库性能问题变得更加可视;Oracle Enterprise Manager(OEM)10g的Top Activity则把AAS堆叠图与ASH下钻结合到了一起。如图5所示,DBA先在时间轴上框住尖峰,再看所选时间窗口由哪些CPU活动和等待类别构成,下面的Top SQL和Top Sessions明细窗口随之刷新。界面不再要求用户先猜应该查询哪个视图。
这也是瞬时故障终于有机会被抓住的原因。以小时为统计窗口的汇总报告容易把两分钟的阻塞摊薄,AAS时间轴却能保留尖峰形状;选中尖峰之后,样本仍带着当时的SQL和会话。

图5:Top Activity把AAS时间轴、CPU能力参照与Top SQL、Top Sessions下钻放进同一界面。
这套方法很快有了实际回响。Oracle刊载的2007年客户案例记录:一个系统长期出现60—120秒的实例停顿;升级到10g后,排查者从ASH发现大量会话等待latch: enqueue hash chains,并把起点追到某会话检测死锁后的进程状态转储:转储期间持有相关latch,拖住了其他会话。小时总账里模糊的一两分钟,被拆成了可追查的先后关系。
zCloud又把这条路径延伸到历史对比:先从持续活动趋势中识别异常时段,再在同一窗口内查看Top SQL、Top Event和Top Session,并与正常时段比较。zCloud还会分析过去60天相同时段的活动会话数据,以90分位数形成历史性能基线,再按预设的上浮比例或固定增量计算波峰线,用来识别明显偏离日常水平的异常时段。这正是“先选时间,再找参与者”这一思想的现代回答:让故障与日常负载有可比较的背景,让下钻始终围绕同一个问题展开。

图6:zCloud对活动采样与时间窗口下钻思想的承接。
前文提到,短于采样间隔的问题可能被漏掉;低频却极痛的单次长尾,也可能在总体排序中不起眼。ASH适合找负载贡献与并发模式,精确追一笔交易仍要结合SQL Trace、应用链路、日志和业务请求ID。
还要注意保留期。V$ACTIVE_SESSION_HISTORY使用内存循环区,繁忙时覆盖更快;写入DBA_HIST_ACTIVE_SESS_HISTORY的只是部分样本,拉长观察窗口后细节会减少。看到历史曲线变平,先确认数据分辨率,别急着判断系统当时真的平静。
最后是经常被忽略的授权问题。Oracle 19c授权文档将AWR、ADDM和ASH列入Diagnostics Pack;直接访问V$ACTIVE_SESSION_HISTORY、X$ASH、DBA_HIST_ACTIVE_SESS_HISTORY以及相关AWR、ASH报告,同样需要满足相应授权。CONTROL_MANAGEMENT_PACK_ACCESS用于控制这些管理包功能是否启用,但功能可以访问,并不等于已经取得使用许可。在实际使用中,应以所用数据库版本、部署形态及合同为准;监控平台自行采集系统视图,也要明确哪些采集项会触及付费能力。
-
先锁定故障窗口。从业务告警或投诉时间出发,把范围缩到分钟甚至秒;不要一上来查“过去24小时Top SQL”。
-
先看AAS,再判断CPU。判断数据库活动量是否异常,并把CPU AAS与可用CPU能力比较,避免把等待堆积误判成算力不足。
-
沿证据链逐层下钻。从等待类别到具体事件,再到SQL、计划、会话、对象或阻塞者,每次只切换一个分析维度,并始终保留同一时间窗口。
-
用样本估算贡献。在采样间隔一致时,可以比较某条SQL或某类等待占全部活动样本的比例;如果比较不同采样粒度的数据,则应先按实际采样间隔加权,同时核对正常基线,避免被偶发的一两行记录牵着走。
-
回到精确证据验证。凯特曾给过一个很精确的教训:在一次诊断中,开启SQL_TRACE改变了解析环境,使该次执行未能复用原有子游标;随后发生的硬解析又因绑定变量窥探选择了索引路径,问题反而“消失”。这不是SQL Trace的普遍结果,而是诊断动作可能影响执行环境的一个案例。变快的原因不是跟踪开关本身,而是执行计划发生了变化。因此,发现异常后仍要使用执行计划、SQL Trace、系统I/O和应用链路验证判断;完成优化后,再核对资源消耗、AAS与业务响应是否一起改善。
ASH提供的是对故障现场的统计重建,而不是完整的录像回放;它负责帮助DBA缩小排查范围,指出故障现场最可能的主角及其关系,精确证据负责确认最终结论。
从计数器到等待时间,再到ASH与AAS,数据库监控逐渐学会把损失和参与者连起来。它不再只回答“系统慢过”,而是帮助追问“何时、谁、怎样一起慢了”。图表的数量并不决定诊断质量;能否留下可关联的证据,能否据此验证一次优化,才决定监控是否真正帮到了用户。故障现场可以消散,关于它的判断不该只剩记忆。

-
Kyle Hailey, History of Database Monitoring, 2016. https://www.slideshare.net/khailey/history-of-database-monitoring
-
Ask TOM: The Performance Tuning Process, 2004年9月4日关于ASH的答问,https://asktom.oracle.com/ords/f?p=100:11:::::P11_QUESTION_ID:7890739100948
-
Oracle: Database Performance Tuning Guide, 10g Release 1, 第5章 Automatic Performance Statistics, https://docs.oracle.com/cd/B13789_01/server.101/b10752/autostat.htm
-
Oracle: Enterprise Manager 12c ASH in 3D, 2011, https://www.oracle.com/ocom/groups/public/@otn/documents/webcontent/1667064.pdf
-
Oracle: Real-Time SQL Monitoring, 2009, https://www.oracle.com/technetwork/database/manageability/owp-sql-monitoring-128746.pdf
-
Oracle: 2 Day + Performance Tuning Guide, 10g Release 2, 第4章 Monitoring Real-Time Database Performance, https://docs.oracle.com/cd/B19306_01/server.102/b28051/tdppt_realtime.htm
-
Oracle: A look at Real Application Testing from a customer’s perspective, 2007, https://www.oracle.com/technetwork/oem/app-quality-mgmt/rat-cust-perspectives-white-paper-o-132919.pdf
-
Oracle: Database Licensing Information User Manual, 19c, https://docs.oracle.com/en/database/oracle/oracle-database/19/dblic/Licensing-Information.html
-
云和恩墨:《zCloud技术白皮书》
-
Tom Kyte: Performance Tuning, 2003年10月6日及2004年2月21日答问(历史证据与诊断能力),https://asktom.oracle.com/ords/f?p=100:11:0::::P11_QUESTION_ID:12836314571537
-
Tom Kyte: Inserts with APPEND Hint, 2012年2月3日答问(ASH与“模糊的TKPROF”),https://asktom.oracle.com/ords/f?p=100:11:0::::P11_QUESTION_ID:1211797200346279484
-
Tom Kyte: Tuning with sql_trace=true..., 2007年9月19日(跟踪、子游标与执行计划验证),https://asktom.oracle.com/Misc/tuning-with-sqltracetrue.html
