A**系列是o小白在学习oracle的时候最为苦恼的,由于oracle中带A开头的东西还不少,什么ASH啦,AWR啦,ADDM啦(三者间恩怨情仇,纠缠不清)之外,还有ASM,FGA,STA,SAA一些系列名词书呆子,反正当年是没搞清楚过……如今打算拿ASH和AWR和ADDM开刀,寻找突破口。

最近o小白也很尴尬,这行文的题目不太好找,由于oracle错综复杂,常常一个知识点会牵涉出来许多,而且公司512的电脑很多东西都没法实验,晚上回家的时间又不够,加上o小白本身实力也比较有限,所以也比较苦恼,后来无意间看到statspack,有点兴趣了,小学习了以后发现在oracle10g推出的ASH和AWR一定程度上对Statspack做了改进,那还是觉得花点时间来研究的。

数据库的性能问题总是一个非常棘手的问题,在对性能做分析的时候必然是要通过一些历史数据和统计信息进行分析的,那在oracle10g之前,基本上是使用oracle的内置的一个工具——statspack,通过自己制定一些脚本配合crontab应该可以完成一些自动的统计信息的收集,并且在分析之后生成报表。但是在10g退出之后,AWR(Automatic Workload Repository)算是一个新的体系结构被推出了。

如果说statspack更多的是一个工具的话,那AWR应该算是一个体系结构了。AWR主要包含以下两个部分的信息,一个是在内存中通过动态性能视图和数据字典里的数据而得到的数据,那说到动态性能视图,就不得不提到的是v$session.oracle的操作都是通过会话的方式来进行的,而v$session则记录了每个连接会话的信息,通过这张视图你可以知道会话的连接情况也可以通过和其他视图的配合,来找到性能的瓶颈。那无疑,这必然是寻找性能问题的关键,不过可惜,在oracle10g之前,在session断开后,曾经的会话信息将不在被保留,如果发现了性能问题,那只能要求会话再次连接,反复试验后才能确定性能的问题,更聪明一点的无非也就是自己写脚本进行统计(statspack),但是这种方式将对数据库的性能造成很大的影响。

10g之后,推出了一个新的动态性能视图V$ACTIVE_SESSION_HISTORY用来记录活动会话记录的历史信息(这里需要解释一下,V$session中有一个字段叫做STATUS,用来表明会话的状态,那ACTIVE就是表示活动会话,也就是正在执行SQL语句的会话,这也是对我们来说有分析价值的会话。),ASH也就是这个动态性能视图的缩写。ASH会每隔一秒,将active session的信息记录到SGA中,这块用来记录的信息的区域就叫做ASH缓存。active session的信息是AWR统计信息中非常重要的一块。通过这样对内存区域的操作而非对表直接进行查询那效率自然是要高得多了。

而AWR就是每隔一段时间生成一次快照,所谓快照就是当前时间点数据库的统计信息,默认轻快下,AWR每隔一个小时收集一次快照,当然也可以通过dbms_workload_repository包来收集快照,AWR报表便是通过一个启示快照和一个结束快照来收集信息的。

那简单描述了一下以后,大家应该就明白了,相比statspack,AWR主要是在自动化、效率和实时性的方面要好得多了,没办法,oracle不是开源的,只要他自己推出了这个特性以后才能从根本上解决这些效率和性能的问题,那下面就简单通过实验来看看有关于ASH和AWR的部分。

首先我们来看看v$active_session_history.

有实验环境的同学们可以自己动个手desc一下,还是有蛮多字段的,比较关键的字段如下:

sample_time 采样时间

session_state:session的状态,比较常见的值有ON CPU(等待CPU)和WAITING(等待其他资源)

session_id:没啥说的,session的id

sql_id: 正在执行sql语句的id,那可以和v$sql等其他视图配合定位SQL语句

event:等待时间的名称,那可以定位具体的事件,例如db file scattered read这样的事件

time_waited:事件的等待长度。

那这里再给大家一例,摘自韩思捷老师的书,说是擦着最近一分钟里最消耗CPU的SQL语句:

select sql_id,count(*),round(count(*)/sum(count(*)) over (),2) pctload
from v$active_session_history
where sample_time > sysdate - 1 / (24 * 60)
and session_type <> 'BACKGROUND'
and session_state = 'ON CPU'
group by sql_id
order by count(*) desc;

由于o小白这个是实验环境,所以把一分钟这个限制条件去掉了,得到的结果如下

SQL_ID COUNT(*) PCTLOAD
------------- ---------- ----------
ga35zj5z4czaq 1 .03
04xx2sumpkrbr 1 .03

希望大家可以举一反三,自己写些query来查询自己所需要的内容。至于AWR呢,那也给大家看个例子。$ORACLE_HOME/rdbms/admin下面有很多和awr相关的脚本,这里o小白执行awrrpt脚本(有关于脚本的解释和演示留待后续的版本,这里就简单做个实验)

sql>@$ORACLE_HOME/rdbms/admin/awrrpt.sql

然后会提示Enter value for report_type: 

这里输入html(还有txt格式的),然后会要求输入多少天的快照信息,o小白输入1

Enter value for num_days: 1

然后oracle自动给出1天内的快照信息,并要求输入启示和结束的快照号:

Snap
Instance DB Name Snap Id Snap Started Level
------------ ------------ --------- ------------------ -----
ora10g ORCL 20 07 Aug 2011 10:41 1
ora10g ORCL 21 07 Aug 2011 10:50 1

那这里开始就20结束就21,然后就输入报表名,这里用默认名就直接回车了(默认名就是awrrpt_天数_起始快照号_结束快照号),然后就会自动生成了。在登录oracle的目录下可以看到这份html格式的报表。报表太长了,包含了太多的信息,这里就不贴出了,希望有兴趣的同学自己动手试下。AWR远远没有结束,目前o小白只是初窥门径,和大家分享自己做的一些简单实验,有关于AWR的其他信息留待AWR你好(2)吧~