编者按:
本文作者系Scott(中文名陈晓辉),现任大连华信资深分析师 ,ORACLE数据库专家,曾就职于甲骨文中国。个人主页:segmentfault.com/u/db_perf ,经其本人授权发布。
【免责声明】本公众号文章仅代表个人观点,与任何公司无关。

在ORACLE性能问题调查时,有价值的诊断情报有很多:STATSPACK,AWR,ASH,SYSTEMSTATE DUMP等等。每一种都在特定的场景起到重要的作用。其中最多的一个场景就是问题发生后采用了紧急对应,暂时回避了问题,但是问题的原因需要详细的调查。这时候,ASH就是一个非常有效的情报。
为什么呢?
因为在这种情况下,无论是客户还是Support工程师,最想知道的就是到底发生了啥问题。ASH就是为了满足这个需要而产生的,它可以提供两种时间间隔(1秒和10秒)的Active Session的几乎所有相关的信息。
下面先说一下ASH的内部设计吧。

参照上面的图,我们来整理一下ASH情报的来源和处理过程。
1. 后台进程MMNL(MMON Lite 即轻量化的MMON进程),每1秒钟1次(采集间隔由隐藏参数“_ash_sampling_interval”控制)把V$SESSION 和V$SESSION_WAIT的数据里的ACTIVE SESSION(非IDLE待机SESSION)转存到V$ACTIVE_SESSION_HISTORY里。2. V$ACTIVE_SESSION_HISTORY的数据存储在SGA中的一个循环使用的Buffer里,大小用隐藏参数“_ash_size”控制。3. Buffer里的记录按照比例( 由隐藏参数“_ash_disk_filter_ratio”控制)被写到磁盘上,可以通过DBA_HIST_ACTIVE_SESS_HISTORY查询。4. 存到磁盘上的数据遵守AWR的保存Policy。
关于ASH机能一些隐藏参数,可以参照以下:
Parameter Value-------------------------------------------------- ----------Description----------------------------------------------------------------------------------------------------_ash_sampling_interval 1000Time interval between two successive Active Session samples in millisecs_ash_size 1048618To set the size of the in-memory Active Session History buffers_ash_enable TRUETo enable or disable Active Session sampling and flushing_ash_disk_write_enable TRUETo enable or disable Active Session History flushing_ash_disk_filter_ratio 10Ratio of the number of in-memory samples to the number of samples actually written to disk_ash_eflush_trigger 66The percentage above which if the in-memory ASH is full the emergency flusher will be triggered_ash_sample_all FALSETo enable or disable sampling every connected session including ones waiting for idle waits_ash_dummy_test_param 0Oracle internal dummy ASH parameter used ONLY for testing!_ash_min_mmnl_dump 90Minimum Time interval passed to consider MMNL Dump_ash_compression_enable TRUETo enable or disable string compression in ASH_ash_progressive_flush_interval 300ASH Progressive Flush interval in secs
那么如何利用ASH情报分析性能问题呢?
这个问题没有固定答案,因为ASH是一种原始数据,只负责记录SESSION在采样时的状态。所以ASH并不直接反映问题,只提供分析问题的材料。
也就是说,DBA或Support工程师必须先对问题分析,想定一个或多个问题发生的原因和剧本。然后在利用ASH数据找到支持自己设想的证据。
今天举一个简单的例子。
客户报告3个APP Servers和两个节点的RAC环境中,有一个APP Server的处理比另外两个APP Servers的处理慢,但是发往3个APP Servers的处理本身没有任何区别。
因为客户是在APPLICATION 的画面上确认到的这个问题,所以首先调查了APP Server端,但是没有找到原因,于是APP Server的Support工程师怀疑DB端的问题,就向我们DB的Support发出了调查要求。
基于前面问题的描述,最直观的反应就是这个问题和DB没有关系,原因有二:第一是3个APP Servers发出的处理(SQL文)本身没有区别;第二是DB端处理SQL文时只关注SQL的请求内容,不会关注是哪一台APP Server发来的请求。
为了找到证据来证明上面的观点,我首先假设这个问题慢的地方不在DB,而是APP Server本身或网络延迟,而在DB端实际没有任何延迟,3台APP Servers的处理速度是一样的。
然后我用下面的SQL文对延迟时间段内3台APP Servers发出的所有SQL文进行了抽取和比较,结果如下:
SQL> select SQL_ID,SQL_PLAN_HASH_VALUE,SQL_EXEC_ID,count(*)from m_dba_hist_active_sess_historywhere PROGRAM='JDBC Thin Client'and MACHINE='APP Server Name'group by SQL_ID,SQL_PLAN_HASH_VALUE,SQL_EXEC_IDorder by count(*) desc;◆1号機(Slow Node)SQL_ID SQL_PLAN_HASH_VALUE SQL_EXEC_ID COUNT(*)-------------------- ------------------- ----------- ----------aaaaaaaaaaaa 2617621828 16777258 115aaaaaaaaaaaa 2617621828 16777220 69bbbbbbbbbbbb 1192575627 33554439 34cccccccccccc 1878459779 16777216 13dddddddddddd 2703624694 16777216 7dddddddddddd 2703624694 33554432 6eeeeeeeeeeee 876643066 33554438 4eeeeeeeeeeee 876643066 33554439 4eeeeeeeeeeee 876643066 16777238 4eeeeeeeeeeee 876643066 16777237 4eeeeeeeeeeee 876643066 16777240 4◆2号機SQL_ID SQL_PLAN_HASH_VALUE SQL_EXEC_ID COUNT(*)-------------------- ------------------- ----------- ----------aaaaaaaaaaaa 2617621828 16777223 150aaaaaaaaaaaa 2617621828 16777221 150aaaaaaaaaaaa 2617621828 16777224 30aaaaaaaaaaaa 2617621828 16777222 30aaaaaaaaaaaa 2617621828 16777225 27aaaaaaaaaaaa 2617621828 16777219 16aaaaaaaaaaaa 2617621828 16777218 16bbbbbbbbbbbb 3425641204 16777222 32bbbbbbbbbbbb 3425641204 16777221 31bbbbbbbbbbbb 3425641204 16777223 28bbbbbbbbbbbb 3425641204 16777220 16bbbbbbbbbbbb 3425641204 16777219 15dddddddddddd 2703624694 33554437 7dddddddddddd 2703624694 33554436 6eeeeeeeeeeee 876643066 33554450 4eeeeeeeeeeee 876643066 16777219 4eeeeeeeeeeee 876643066 16777220 4eeeeeeeeeeee 876643066 33554440 4eeeeeeeeeeee 876643066 16777221 4eeeeeeeeeeee 876643066 33554452 4eeeeeeeeeeee 876643066 16777222 3eeeeeeeeeeee 876643066 33554441 3eeeeeeeeeeee 876643066 16777241 3eeeeeeeeeeee 876643066 16777224 3eeeeeeeeeeee 876643066 33554453 3◆3号機SQL_ID SQL_PLAN_HASH_VALUE SQL_EXEC_ID COUNT(*)-------------------- ------------------- ----------- ----------aaaaaaaaaaaa 2617621828 16777217 7bbbbbbbbbbbb 3425641204 16777218 8eeeeeeeeeeee 876643066 16777216 6eeeeeeeeeeee 876643066 33554449 4eeeeeeeeeeee 876643066 33554446 4eeeeeeeeeeee 876643066 16777239 4eeeeeeeeeeee 876643066 16777244 4eeeeeeeeeeee 876643066 16777223 4eeeeeeeeeeee 876643066 16777243 4eeeeeeeeeeee 876643066 33554443 4eeeeeeeeeeee 876643066 16777217 4eeeeeeeeeeee 876643066 16777245 3eeeeeeeeeeee 876643066 33554445 3eeeeeeeeeeee 876643066 33554444 3eeeeeeeeeeee 876643066 16777218 3eeeeeeeeeeee 876643066 33554442 3eeeeeeeeeeee 876643066 33554448 3eeeeeeeeeeee 876643066 33554451 3eeeeeeeeeeee 876643066 33554447 3eeeeeeeeeeee 876643066 16777242 3
通过上面的比较,我们会发现相同的SQL文在客户报告处理慢的1号机和不慢的2号机3号机相比,采样时并没有明显的区别。因为一个采样基本可以看作SQL文执行了10秒钟。
这就证明了我们对DB端没有区别,问题点也不在DB端的设想,剩下的就得让APP Server和网络的Support去调查了。
今天只是用一个小例子来简单说明一下ASH的用法,以后我会分享更多的例子,欢迎关注。
后续文章更加精彩,欢迎关注本公众号或访问【阅读原文】。
——End——
专注于技术不限于技术!
用碎片化的时间,一点一滴地提高数据库技术和个人能力。
欢迎关注!
数据库基础系列(从基础了解数据库):
通过寄存服务来“理解”Oracle数据库基本体系结构和动作流程
手把手系列(帮助个人技术成长):




