1、什么是AWR?
@H_
301_4@AWR (Automatic Workload Repository) 是
自动负载信息库的英文缩写,AWR报告是Oracle 10g以后版本提供的一种
性能收集和分析工具,能提供一个时间段内整个系统资源使用情况的报告,通过报告可以了解一个系统的整个运行情况,
生成的报告
包括多个部分。
@H_
301_4@AWR每小时对v$active_session_history视图(内存中的ASH采集信息,理论为1小时)进行采样一次,并将信息保存到磁盘中,并且保留7天,7天后旧的记录才会被覆盖。这些采样信息被保存在wrh$_active_session_history视图(写入AWR库中的ASH信息,理论为1小时以上)中。而这个采样频率(1小时)和保留时间(7天)是可以根据实际情况进行调整的,这就给DBA们提供了更加有效的系统监测工具。
@H_
301_4@
2、什么情况下会用到AWR?
@H_
301_4@DBA对
数据库运行状态及状况的监控了解、测试过程中发现
数据库出现瓶颈但无法定位到具体原因时,可以借用AWR报告进行分析定位。
@H_
301_4@
数据库出现
性能问题,一般都在三个地方:IO、内存、
cpu,这三个地方又是息息相关的。假设这个三个地方都没有物理上的故障,当IO
负载增大时,肯定需要更多的内存来存放,同时也需要
cpu花费更多的时间来过滤这些数据。相反,
cpu时间花费多的话,有可能是解析
sql语句,也可能是过滤太多的数据,倒不一定是和IO或内存有关系。
@H_
301_4@
cpu:解析
sql语句,尝试多个执行计划,最后
生成一个
数据库认为是比较好的执行计划,但不一定是最优的。因为关联表太多的时候,
数据库并不会穷举所有的执行计划,这会消耗太多的时间,oracle怎么知道这条数据是你要的,另一个就不是你要的呢,这是需要
cpu来过滤的。
@H_
301_4@内存:
sql语句和执行计划都需要在内存保留一段时间,还有取到的数据,根据LRU算法也会尽量在内存中保留,在执行
sql语句过程中,各种表之间的连接,排序等操作也要占用内存。
@H_
301_4@IO:如果需要的数据不在内存中,则需要到磁盘中去取,就会涉及到物理IO了,还有表之间的连接数据太多,以及排序等操作内存放不下的时候,需要用到临时表空间,也会消耗物理io了。
@H_
301_4@这里说明下,ORACLE分配的内存中PGA一般只占20%,对于专用服务器模式,每次执行
sql语句、表数据的运算等操作,都在PGA中进行的,也就是说只能用ORACL分配内存的20%左右,如果多个
用户都执行多表关联,而且表数据又多,再
加上关联不当的话,内存就成为瓶颈了,所以优化
sql很重要的一点就是,减少逻辑读和物理读。
@H_
301_4@
3、如何生成awr报告?
@H_
301_4@第一步,
登录ORACLE
数据库服务器,记住当前目录或者切换至AWR想要保存的目录;
@H_
301_4@第二步,
sqlplus
用户名/密码@服务连接名,连接oracle
数据库实例,如下图所示;

@H_
301_4@第三步,执行@?/rdbms/admin/awrrpt;,会出现
提示,
@H_
301_4@可以
生成以下几种类型AWR报告,大部分情况下都是
生成本实例的AWR报告
@H_
301_4@
@?/rdbms/admin/awrrpt; 本实例AWR包括
@H_
301_4@
@?/rdbms/admin/awrrpti; RAC中选择实例号
@H_
301_4@
@?/rdbms/admin/awrddrpt; AWR 比对报告
@H_
301_4@
@?/RDBMS/admin/awrgrpt; RAC全局AWR报告
@H_
301_4@输入
生成AWR报告的格式是html的,如下图所示:
@H_
301_4@

@H_
301_4@输入天数: 根据实际情况输入(如1,代表当天,如果2,代表今天和昨天,以此往前推)如下图所示:
@H_
301_4@

@H_
301_4@输入开始值与结束值:(输入天数后会列出,snap值)
@H_
301_4@输入AWR报告的
名称:
名称自定义 回车后就开始
自动生产AWR报告,如下图所示:
@H_
301_4@

@H_
301_4@这里说明一下快照节点可以手工创建,根据实际情况执行如下命令:
@H_
301_4@exec dbms_workload_repository.create_snapshot;就可以手工创建一个快照。
@H_
301_4@

@H_
301_4@结束后就可以去指定目录下照AWR报告
文件,
文件为 test_awr.lst,如下图所示:
@H_
301_4@

@H_
301_4@
修改扩展名为HTML,下载到Windows平台即可查看,即可用IE打开AWR报告,如下图所示:
@H_
301_4@

@H_
301_4@
4、分析AWR报告
@H_
301_4@AWR报告
内容很丰富这里选其中一小部分来讲解,分析AWR报告前先了解一下Oracle的硬解析和软解析,首先说一下Oracle对
sql的处理过程。当你发出一条
sql语句交付Oracle,在执行和
获取结果前Oracle对此
sql将进行几个步骤的处理过程:
@H_
301_4@1、语法检查(
Syntax check)
@H_
301_4@检查此
sql的拼写是否语法。
@H_
301_4@2、语义检查(semantic check)
@H_
301_4@诸如检查
sql语句中的访问对象是否存在及该
用户是否具备相应的权限。
@H_
301_4@3、对
sql语句进行解析(prase)
@H_
301_4@利用内部算法对
sql进行解析,
生成解析树(parse tree)及执行计划(execution plan)。
@H_
301_4@4、执行
sql,返回结果(execute and return)
@H_
301_4@其中,软、硬解析就发生在第三个过程里。
@H_
301_4@Oracle利用内部的hash算法来取得该
sql的hash值,然后在library cache里查找是否存在该hash值;
@H_
301_4@假设存在,则将此
sql与cache中的进行比较;
@H_
301_4@假设“相同”,就将利用已有的解析树与执行计划,而省略了优化器的相关工作。这也就是软解析的过程。
@H_
301_4@当然,如果上面的2个假设中任有一个不成立,那么优化器都将进行创建解析树、
生成执行计划的动作。这个过程就叫硬解析。
@H_
301_4@创建解析树、
生成执行计划对于
sql的执行来说是开销昂贵的动作,所以,应当极力避免硬解析,尽量使用软解析。
@H_
301_4@打开AWR报告头如下图所示:
@H_
301_4@

@H_
301_4@Elapsed快照监控时间:如果为了诊断特定时段
性能问题则Elapsed不宜过长15分钟~2、3个小时。如果是看全天
负载那么可以长一些,最常见是60分钟后者120分钟。
@H_
301_4@DB Time:不
包括Oracle
后台进程消耗的时间,如果DB Time远远小于Elapsed时间,说明
数据库比较空闲。
@H_
301_4@DB Time=
cpu time + wait time(不包含空闲等待) (非
后台进程),DB Time就是记录的服务器花在
数据库运算(非
后台进程)和等待(非空闲等待)上的时间,DB time =
cpu time + all of nonidle wait event time在79分钟里(其间收集了3次快照数据),
数据库耗时11分钟,RDA数据中
显示系统有8个逻辑
cpu(4个物理
cpu),平均每个
cpu耗时1.4分钟,
cpu利用率只有大约2%(1.4/79),说明系统压力非常小。
@H_
301_4@但是对于批量系统,
数据库的工作
负载总是集中在一段时间内,如果快照周期不在这一段时间内,或者快照周期跨度太长而包含了大量的
数据库空闲时间,所得出的分析结果是没有意义的,这也说明选择分析时间段很关键,要选择能够代表
性能问题的时间段。
@H_
301_4@

@H_
301_4@
显示SGA中每个区域的大小,可用来与初始参数值比较。
@H_
301_4@shared pool主要
包括library cache和dictionary cache。library cache用来存储最近解析(或编译)后
sql、PL/
sql和Java classes等。library cache用来存储最近引用的数据字典。发生在library cache或dictionary cache的cache miss代价要比发生在buffer cache的代价高得多,因此shared pool的设置要确保最近使用的数据都能被cache。
@H_
301_4@

@H_
301_4@
显示数据库负载概况,将之与基线数据比较才具有更多的意义,如果每秒或每事务的
负载变化不大,说明应用运行比较稳定。单个的报告数据只说明应用的
负载情况,绝大多数据并没有一个所谓“正确”的值,然而
logons大于每秒1~2个、Hard parses大于每秒100、全部parses超过每秒300表明可能有争用问题。
@H_
301_4@Redo size:每秒产生的日志大小(单位字节),可标志数据变更频率,
数据库任务的繁重与否。
@H_
301_4@Logical reads:每秒/每事务逻辑读的块数.平决每秒产生的逻辑读的block数。Logical Reads= Consistent Gets + DB Block Gets;
@H_
301_4@Block changes:每秒/每事务
修改的块数;
@H_
301_4@Physical reads:每秒/每事务物理读的块数;
@H_
301_4@Physical writes:每秒/每事务物理写的块数;
@H_
301_4@User calls:每秒/每事务
用户call
次数;
@H_
301_4@Parses:
sql解析的
次数.每秒解析
次数,
包括fast parse,soft parse和hard parse三种
数量的综合。 软解析每秒超过300次意味着你的"应用程序"效率不高,调整session_cursor_cache。在这里,fast parse指的是直接在PGA中命中的情况(设置了session_cached_cursors=n);soft parse是指在shared pool中命中的情形;hard parse则是指都不命中的情况。
@H_
301_4@Hard parses:其中硬解析的
次数,硬解析太多,说明
sql重用率不高。每秒产生的硬解析
次数,每秒超过100次,就可能说明你绑定使用的不好,也可能是共享池设置不合理。这时候可以启用参数cursor_sharing=similar|force,该参数默认值为exact。但该参数设置为similar时,存在bug,可能导致执行计划的不优。
@H_
301_4@Sorts:每秒/每事务的排序
次数;
@H_
301_4@
logons:每秒/每事务
登录的
次数;
@H_
301_4@Executes:每秒/每事务
sql执行
次数;
@H_
301_4@Transactions:每秒事务数.每秒产生的事务数,反映
数据库任务繁重与否。
@H_
301_4@Blocks changed per Read:表示逻辑读用于
修改数据块的比例.在每一次逻辑读中更改的块的百分比。
@H_
301_4@Recursive Call:递归
调用占所有操作的比率.递归
调用的百分比,如果有很多PL/
sql,那么这个值就会比较高。
@H_
301_4@Rollback per transaction:每事务的回滚率.看回滚率是不是很高,因为回滚很耗资源,如果回滚率过高,可能说明你的
数据库经历了太多的无效操作,过多的回滚可能还会带来Undo Block的竞争 该参数计算公式如下:
@H_
301_4@Round(User rollbacks / (user commits + user rollbacks),4)* 100% 。
@H_
301_4@Rows per Sort:每次排序的行数
@H_
301_4@

@H_
301_4@上图包含了Oracle关键指标的内存命中率及其它
数据库实例操作的效率,其中Buffer Hit Ratio 也称Cache Hit Ratio,Library Hit ratio也称Library Cache Hit ratio。同Load Profile一节相同,这一节也没有所谓“正确”的值,而只能根据应用的特点判断是否合适。在一个使用直接读执行大型并行
查询的DSS环境,20%的Buffer Hit Ratio是可以接受的,而这个值对于一个OLTP系统是完全不能接受的。根据Oracle的经验,对于OLTPT系统,Buffer Hit Ratio理想应该在90%以上。
@H_
301_4@Buffer Nowait表示在内存获得数据的未等待比例,在缓冲区中
获取Buffer的未等待比率,Buffer Nowait的这个值一般需要大于99%。否则可能存在争用,可以在后面的等待事件中进一步确认。
@H_
301_4@Buffer Hit表示进程从内存中找到数据块的比率,监视这个值是否发生重大变化比这个值本身更重要。对于一般的OLTP系统,如果此值低于80%,应该给
数据库分配更多的内存。数据块在数据缓冲区中的命中率,通常应在95%以上。否则,小于95%,需要调整重要的参数,小于90%可能是要加db_cache_size。一个高的命中率,不一定代表这个系统的
性能是最优的,比如大量的非选择性的索引被频繁访问,就会造成命中率很高的假相(大量的db file sequential read),但是一个比较低的命中率,一般就会对这个系统的
性能产生影响,需要调整。命中率的突变,往往是一个不好的信息。如果命中率突然增大,可以检查TOP buffer get
sql,查看导致大量逻辑读的语句和索引,如果命中率突然减小,可以检查TOP physical reads
sql,检查产生大量物理读的语句,主要是那些没有使用索引或者索引被
删除的。
@H_
301_4@Redo NoWait表示在LOG缓冲区获得BUFFER的未等待比例。如果太低(可参考90%阈值),考虑
增加LOG BUFFER。当redo buffer达到1M时,就需要写到redo log
文件,所以一般当redo buffer设置超过1M,不太可能存在等待buffer空间分配的情况。当前,一般设置为2M的redo buffer,对于内存总量来说,应该不是一个太大的值。
@H_
301_4@Library Hit:表示Oracle从Library Cache中检索到一个解析过的
sql或PL/
sql语句的比率,当应用程序
调用sql或存储过程时,Oracle检查Library Cache确定是否存在解析过的版本,如果存在,Oracle立即执行语句;如果不存在,Oracle解析此语句,并在Library Cache中为它分配共享
sql区。低的library hit ratio会导致过多的解析,
增加cpu消耗,降低
性能。如果library hit ratio低于90%,可能需要调大shared pool区。STATEMENT在共享区的命中率,通常应该保持在95%以上,否则需要要考虑:加大共享池;使用绑定变量;
修改cursor_sharing等参数。
@H_
301_4@Latch Hit:Latch是一种保护内存结构的锁,可以认为是SERVER进程
获取访问内存数据结构的许可。要确保Latch Hit>99%,否则意味着Shared Pool latch争用,可能由于未共享的
sql,或者Library Cache太小,可使用绑定变更或调大Shared Pool
解决。要确保>99%,否则存在严重的
性能问题。当该值出现问题的时候,我们可以借助后面的等待时间和latch分析来查找
解决问题。
@H_
301_4@Parse
cpu to Parse Elapsd:解析实际运行时间/(解析实际运行时间+解析中等待资源时间),越高越好。计算公式为:Parse
cpu to Parse Elapsd %= 100*(parse time
cpu / parse time elapsed)。即:解析实际运行时间/(解析实际运行时间+解析中等待资源时间)。如果该比率为100%,意味着
cpu等待时间为0,没有任何等待。
@H_
301_4@Non-Parse
cpu :
sql实际运行时间/(
sql实际运行时间+
sql解析时间),太低表示解析
消耗时间过多。计算公式为:% Non-Parse
cpu =round(100*1-PARSE_
cpu/TOT_
cpu),2)。如果这个值比较小,表示解析消耗的
cpu时间过多。与PARSE_
cpu相比,如果TOT_
cpu很高,这个比值将接近100%,这是很好的,说明计算机执行的大部分工作是执行
查询的工作,而不是分析
查询的工作。
@H_
301_4@Execute to Parse:是语句执行与分析的比例,如果要
sql重用率高,则这个比例会很高。该值越高表示一次解析后被重复执行的
次数越多。计算公式为:Execute to Parse =100 * (1 - Parses/Executions)。本例中,差不多每execution 5次需要一次parse。所以如果系统Parses > Executions,就可能出现该比率小于0的情况。该值<0通常说明shared pool设置或者语句效率存在问题,造成反复解析,reparse可能较严重,或者是可能同snapshot有关,通常说明
数据库性能存在问题。
@H_
301_4@In-memory Sort:在内存中排序的比率,如果过低说明有大量的排序在临时表空间中进行。考虑调大PGA(10g)。如果低于95%,可以通过适当调大初始化参数PGA_AGGREGATE_TARGET或者SORT_AREA_SIZE来
解决,注意这两个参数设置作用的范围时不同的,SORT_AREA_SIZE是针对每个session设置的,PGA_AGGREGATE_TARGET则时针对所有的sesion的。
@H_
301_4@Soft Parse:软解析的百分比(softs/softs+hards),近似当作
sql在共享区的命中率,太低则需要调整应用使用绑定变量。
sql在共享区的命中率,小于<95%,需要考虑绑定,如果低于80%,那么就可以认为
sql基本没有被重用。
@H_
301_4@

@H_
301_4@Memory Usage %:对于一个已经运行一段时间的
数据库来说,共享池内存使用率应该稳定在75%-90%间,如果太小,说明Shared Pool有浪费,而如果高于90,说明共享池中有争用,内存不足。这个数字应该长时间稳定在75%~90%。如果这个百分比太低,表明共享池设置过大,带来额外的管理上的负担,从而在某些条件下会导致
性能的下降。如果这个百分率太高,会使共享池外部的组件老化,如果
sql语句被再次执行,这将使得
sql语句被硬解析。在一个大小合适的系统中,共享池的使用率将处于75%到略低于90%的范围内.
@H_
301_4@
sql with executions>1:执行
次数大于1的
sql比率,如果此值太小,说明需要在应用中更多使用绑定变量,避免过多
sql解析。在一个趋向于循环运行的系统中,必须认真考虑这个数字。在这个循环系统中,在一天中相对于另一部分时间的部分时间里执行了一组不同的
sql语句。在共享池中,在观察期间将有一组未被执行过的
sql语句,这仅仅是因为要执行它们的语句在观察期间没有运行。只有系统连续运行相同的
sql语句组,这个数字才会接近100%。
@H_
301_4@Memory for
sql w/exec>1:执行
次数大于1的
sql消耗内存的占比。这是与不频繁使用的
sql语句相比,频繁使用的
sql语句消耗内存多少的一个度量。这个数字将在总体上与%
sql with executions>1非常接近,除非有某些
查询任务消耗的内存没有规律。在稳定状态下,总体上会看见随着时间的推移大约有75%~85%的共享池被使用。如果Statspack报表的时间窗口足够大到覆盖所有的周期,执行
次数大于一次的
sql语句的百分率应该接近于100%。这是一个受观察之间持续时间影响的
统计数字。可以期望它随观察之间的
时间长度增大而增大。
@H_
301_4@通过ORACLE的实例有效性
统计数据,我们可以获得大概的印象,然而并不能由此确定数据运行的
性能。当前
性能问题的确定,主要还是依靠下面的等待事件来确认。我们可以这样理解两部分的
内容,hit
统计帮助发现和预测一些系统将要产生的
性能问题,由此可以做到未雨绸缪。而wait事件,就是表明当前
数据库已经出现了
性能问题需要
解决,是亡羊补牢的性质。
@H_
301_4@

@H_
301_4@TOP5 time Event是AWR报告概要的最后一节,
显示了系统中最严重的5个等待,按所占等待时间的比例倒序列示。一个
性能良好的系统,
cpu Time应该在TOP 5的前面,否则说明你的系统大部分时间都用在等待上。当我们调优时,总希望观察到最显著的
效果,因此应当从这里入手确定下一步做什么。例如‘buffer busy wait’是较严重的等待事件,应当继续研究报告中Buffer Wait和File/Tablespace IO区的
内容,识别哪些
文件导致了问题。如果最严重的等待事件是I/O事件,应当研究按物理读排序的
sql语句区以识别哪些语句在执行大量I/O,并研究Tablespace和I/O区观察较慢响应时间的
文件。如果有较高的LATCH等待,就需要察看详细的LATCH
统计识别哪些LATCH产生的问题。
@H_
301_4@在这里,log file parallel write是相对比较多的等待,占用了7%的
cpu时间。通常借助AWR报告寻找耗时比较长或资源使用比较高的
sql语句,按各种资源分别列出对资源消耗最严重的
sql语句,并
显示它们所占
统计期内全部资源的比例,这给出我们调优指南。例如在一个系统中,
cpu资源是系统
性能瓶颈所在,那么优化buffer gets最多的
sql语句将获得最大
效果。在一个I/O等待是最严重事件的系统中,调优的目标应该是physical IO最多的
sql语句。
@H_
301_4@

@H_
301_4@
这里列出了耗时比较长的sql,从高到低排序TOP100,在AWR报告中点击sql ID连接即可跳转到详细的sql语句的地方。
@H_
301_4@

@H_
301_4@这里其实和云智慧透视宝的一个
功能很像,就是在应用请求信息中,透视宝可以抓取到
MysqL数据库的每个
sql语句的耗时,而且是实时的。这点比AWR报告要方便很多,不用设置快照节点实时查看。
@H_
301_4@

@H_
301_4@这个地方是根据
cpu time 排序的TOP 100的
sql语句,同样点击
sql ID中的连接可以展开详细的
sql语句。
@H_
301_4@AWR报告的
内容很丰富,本文的
内容希望能起到一个抛砖引玉的作用,大家可以动手实际操作一下,对AWR进一步的研究学习。