本文示例数据库是11g,相对于之前版本稍有不同,但大部分一样。
AWR报告内容和Statspack内容相差不多,因此理解了Statspack报告内容分析也就理解了AWR报告。
一、第一部分:数据库概要信息
报表开头部分是数据库概要信息,包含数据库的一些基本信息(数据库名称、版本号、主机等信息)和采样信息、数据库的Cache信息等。
(1)、首先是数据库基本信息:
Database DB Id Instance Inst Num Startup Time Release RAC
~~~~~~~~ ------- ---------- -------- ------------- ------- ----
2130218216 tsid 1 10-12月-13 09:33 11.2.0.1.0 NO
Host Name Platform CPUs Cores Sockets Memory (G)
~~~~ ----- ----------------- ------ ----- ------ -----------
ZZLK-3 Microsoft Windows IA ( 2 2 1 3.0
(2)、接下来是数据库采样时段信息
这一部分记录了数据库采样的时间,以及采样的点数,这部分信息对于report来说十分重要。任何统计数据都需要通过时间维度来衡量,离开了时间,任何数据都失去了意义。
Snapshot Snap Id Snap Time Sessions Curs/Sess Comment
~~~~~~~~ ---------- ------------------ -------- ---------
Begin Snap: 31 10-12月-13 09:34:16 31 1.1
End Snap: 41 10-12月-13 09:36:18 27 1.7
Elapsed: 2.03 (mins) Av Act Sess: 0.1
DB time: 0.28 (mins) DB CPU: 0.12 (mins)
(3)、Cache信息
这一部分列举了数据库的内存分配信息。由于从Oracle 9i开始,主要SGA参数可以进行动态调整,所以此处的Cache信息来自采样结束时刻:
Cache Sizes Begin End
~~~~~~~~~~~ ---------- ----------
Buffer Cache: 176M Std Block Size: 8K
Shared Pool: 112M Log Buffer: 5,480K
在数据库概要信息之后,报表中输出的是数据库的负载概要信息,这些信息分别通过每秒和每事务形式展现。通过这部分信息,报告将数据库的整体运行状况快速展现出来。
Load Profile Per Second Per Transaction Per Exec Per Call
~~~~~~~~~~~~ ------------------ ----------------- ----------- ----------
DB time(s): 0.1 1.7 0.01 0.29
DB CPU(s): 0.1 0.7 0.00 0.12
Redo size: 47,288.5 576,920.0
Logical reads: 154.9 1,889.3
Block changes: 86.4 1,054.5
Physical reads: 7.9 96.6
Physical writes: 0.0 0.0
User calls: 0.5 5.8
Hard parses: 1.2 14.0
W/A MB processed: 1.3 15.4
Logons: 0.0 0.5
Executes: 20.9 254.7
Rollbacks: 0.0 0.0
Transactions: 0.1
这部分信息来自v$sysstat视图收集的统计信息,Statspack将这部分信息定时收集记录在stats$sysstat字典表中,然后通过前后对比,得出在报告时段数据库的负载变化。例如,这里的redo size就代表在起始采样点和结束采样点之间,数据库生成的redo大小。
参数说明:
-----------------------------------------------------------------
Redo size:每秒产生的重做日志大小(单位字节),可标志数据变更频率,数据库任务的繁重与否。
Logical reads:平均每秒产生的逻辑读,单位是block。
Block changes:每秒block变化数量,数据库事务带来改变的块数量。
Physical reads:平均每秒数据库从磁盘读取的block数。
Physical writes:平均每秒数据库写磁盘的block数。
User calls:每秒用户call次数。
Parses和Hard parses:每秒大约8.4个解析,其中有14%为硬解析。对于优化好的系统,运行了好几天后,这一列应该达到0,所有的sql在一段时间后都应该在共享池中。
Sorts:每秒产生的排序次数。(11g对10g有所改变,没有该项)
Executes:每秒执行次数。
Transactions:每秒产生的事务数,反应数据库任务繁重与否。
对于之前的版本,还会有下面两行,如:
% Blocks changed per Read: 54.27 Recursive Call %: 86.94
Rollback per transaction %: 12.00 Rows per Sort: 32.59
% Blocks changed per Read:说明46%的逻辑读是用于那些只读而不可修改的块,该系统只更新54%的块。
Rollback per transaction %:事务回滚的百分比。计算公式为:Round(User rollbacks / (user commits + user rollbacks) , 4) * 100%。本例中每8.33个事务导致一个回滚。如果回滚率过高,可能说明数据库经历了太多的无效操作。过多的回滚可能还会带来Undo Block的竞争。
-----------------------------------------------------------------
1、Redo size信息
Redo size信息单位为Bytes:
Load Profile Per Second Per Transaction
~~~~~~~~~~~~ ------------------ -----------------
对于这个采样,数据库每秒产生了大约46KB的Redo信息,每个事务平均产生了563KB左右的Redo信息。Redo size的信息也可以从报告后面的Instance Activity Stats信息中获得:
Instance Activity Stats DB/Inst: TEST/tsid Snaps: 31-41
Statistic Total per Second per Trans
--------------------------------- ------------------ -------------- ------------
.......
redo blocks checksummed by FG (ex 7,911 64.8 791.1
redo blocks written 11,279 92.5 1,127.9
redo entries 5,611 46.0 561.1
redo k-bytes read total 0 0.0 0.0
redo ordering marks 416 3.4 41.6
redo size 5,769,200 47,288.5 576,920.0
redo subscn max counts 706 5.8 70.6
redo synch time 17 0.1 1.7
redo synch writes 7 0.1 0.7
redo wastage 3,592 29.4 359.2
redo write time 24 0.2 2.4
redo writes 12 0.1 1.2
......
这里的redo size和负载概要里面的redo size信息时一致的,只不过在概要信息里只显示了平均每秒产生的redo size以及平均每个事务产生的redo size。
Redo Size是数据库操作产生的日志量(Redo Log)的大小,单位为Byte,如果单位时间内数据库产生的Redo非常多,那么就意味着LGWR要非常频繁地将Redo Log Buffer中的数据写出到Redo Log File上来,而这又意味着Redo Log File的I/O写入将会很频繁,也就可能导致I/O竞争和忙碌,同时Log Switch可能增加,也就会导致检查点的发生,从而DBWR要被唤醒,执行脏数据的写出,CKPT进程也要开始它的工作;如果日志过多,在归档模式下,归档日志可能就会非常频繁的产生,这又意味着I/O竞争和空间耗用;如果日志切换更快,那么数据库就可能出现“检查点未完成”的错误提示,日志组可能全部处于Active状态,如果此时数据库崩溃,那么数据库可能会经历更为漫长的恢复过程。。。。
2、逻辑读信息
逻辑读信息也非常重要:
Logical reads: 154.9 1,889.3
逻辑读(Logical Reads)是指以任何模式进行数据库读取的逻辑读请求次数。逻辑读代表了数据库读取数据库的繁忙程度,如果数据库每秒都要进行大量的逻辑读,那么不管是I/O还是buffer的竞争都看你会非常的激烈。有效的降低逻辑读是SQL优化的基本原则之一,对于业务非常繁忙的系统,甚至每一个逻辑读都需要进行精心调解。
根据逻辑读,结合物理读信息,可以进一步获得数据库系统的其他概况:
Logical reads: 154.9 1,889.3
Block changes: 86.4 1,054.5
Physical reads: 7.9 96.6
从以上的数据可以看到,数据库每秒的物理读约8个,也就是说有5%左右的逻辑读导致了物理读取。如果物理读的比例过高,那么系统的性能将会出现性能问题。
3、其他信息
负载概要信息中还包含一系列的重要信息。
(1)、Block changes
Block changes代表采样阶段Block修改信息:
Block changes: 86.4 1,054.5
Block changes数据来自v$sysstat表中的db block changes数据。
(2)、SQL解析信息
Parses: 8.4 102.6
Hard parses: 1.2 14.0
Parses代表数据库在采样阶段的总的分析次数,Hard parses代表硬解析的数量。一个优化良好的数据库应该具有很低的硬解析,硬解析是非常消耗资源的数据库活动。硬解析频繁的数据库通常是因为没有很好的使用绑定变量,或者共享内存设置的不够合理。这两个数据来自report中Instance Activity Stats部分:
Instance Activity Stats DB/Inst: TEST/tsid Snaps: 31-41
Statistic Total per Second per Trans
--------------------------------- ------------------ -------------- ------------
parse count (hard) 140 1.2 14.0
parse count (total) 1,026 8.4 102.6
(3)、%Blocks changed per Read和Rollback per transaction
(11g不再有这两行)
%Blocks changed per Read代表逻辑读导致的Block变更百分比,这个计算数值来自于Block changes和Logical reads两个数值计算:
% Block changes / Logical reads = round(86.4/154.9,4)*100% = 55.78
因此,我这里的%Blocks changed per Read就是55.78。这个数值越高说明数据库的数据块变更越频繁,频繁的数据变更会给数据库带来一系列的压力及性能影响。
Rollback per transaction代表平均事务回滚率,计算公式如下:
round(user rollbacks / (user commits + user rollbacks),4)*100%
user rollbacks和user commits来自Instance Activity Stats部分:
Instance Activity Stats DB/Inst: TEST/tsid Snaps: 31-41
Statistic Total per Second per Trans
--------------------------------- ------------------ -------------- ------------
user commits 10 0.1 1.0
user rollbacks 0 0.0 0.0
因此,我这里的平均事务回滚率就是0。回滚率是非常昂贵的数据库操作,如果回滚率过高,可能说明你的数据库经历了太多的无效操作,过多的回滚可能还会带来Undo Block的竞争。
关于回滚率的计算,还应该了解user rollbacks和transaction rollbacks的区别。在数据库中,user rollbacks的数据量通常会比transaction rollbacks偏大:
Instance Activity Stats DB/Inst: TEST/tsid Snaps: 31-41
Statistic Total per Second per Trans
--------------------------------- ------------------ -------------- ------------
transaction rollbacks 0 0.0 0.0
user calls 58 0.5 5.8
user commits 10 0.1 1.0
user rollbacks 0 0.0 0.0
当然,我这里的测试数据库是新建的,数据没什么意义,都是0。通常user rollbacks的数据量是大于transaction rollbacks的。
这是因为即使不执行事务,仅发出rollback操作,user rollbacks统计信息也会增长,而transaction rollbacks则仅会在事务回滚时增长,下面进行个测试:
SQL> select name,value from v$sysstat where name in ('transaction rollbacks','user rollbacks');
NAME VALUE
---------------------------------------------------------------- ----------
user rollbacks 2
transaction rollbacks 9
SQL> rollback;
回退已完成。
SQL> select name,value from v$sysstat where name in ('transaction rollbacks','user rollbacks');
NAME VALUE
---------------------------------------------------------------- ----------
user rollbacks 3
transaction rollbacks 9
SQL> delete from test where rownum<2;
已删除 1 行。
SQL> rollback;
回退已完成。
SQL> select name,value from v$sysstat where name in ('transaction rollbacks','user rollbacks');
NAME VALUE
---------------------------------------------------------------- ----------
user rollbacks 4
transaction rollbacks 10
基于这个不同,回滚率更为精确的计算方式应该为:
round(transaction rollbacks/(user commits + transaction rollbacks),4)*100%
通常的OLTP数据库,事务提交居多,回滚极少,所以可以忽略这个误差的影响;如果这两者差距很大,就应该通过考察统计数据来确定回滚率是否真的偏高。
这一部分通过Statspack收集的统计信息计算出一些性能指标,通过这些性能指标,可以快速地对数据库的运行状况得出总体的评估。
Instance Efficiency Indicators
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Buffer Nowait %: 99.96 Redo NoWait %: 100.00
Buffer Hit %: 94.89 Optimal W/A Exec %: 100.00
Library Hit %: 81.25 Soft Parse %: 86.35
Execute to Parse %: 59.72 Latch Hit %: 99.96
Parse CPU to Parse Elapsd %: 77.50 % Non-Parse CPU: 93.86
参数说明:
-------------------------------------------------
Buffer Nowait %: 在缓冲区中获取Buffer的未等待比率,Buffer Nowait<99%说明,有可能有热块(查找x$bh的 tch和v$latch_children的cache buffers chains)。
Redo NoWait %:在Redo缓冲区获取Buffer的未等待比率。
Buffer Hit %:数据块在数据缓冲区中的命中率,通常应在99%以上,小于95%需要调整重要参数,小于90%可能要增加db_cache_size,但是大量的非选择的索引也会造成该值很高(大量的db file sequential read)。如果一个经常被访问的列上的索引被删除,可能会造成buffer hit显著下降。如果增加了索引,但是它影响了Oracle正确的选择表连接时的驱动顺序,那么可能会导致buffer hit显著增高。如果命中率变化幅度很大,说明需要改变SQL模式。
In-memory Sort %:在内存中的排序率。
Library Hit %:主要代表SQL在共享区的命中率,通常在95%以上,否则需要考虑加大共享池,绑定变量,修改cursor_sharing等参数。
Soft Parse %:近似看作sql在共享区的命中率,小于95%,需要考虑到绑定,如果低于80%,那么就可能sql基本没有被重用。
Execute to Parse %:一个语句执行和分析了多少次的度量。在一个分析,然后执行语句,且再也不在同一个会话中执行它的系统中,这个比值为0.
Latch Hit %:要确保>99%,否则存在严重的性能问题,比如绑定等会影响该参数。
Parse CPU to Parse Elapsd %:分析CPU与分析时间比率。如果该比率为100%,意味着CPU时间等于经过的时间,没有任何等待。
% Non-Parse CPU:计算公式为:%Non-Parse CPU=round(100*(1-Parse_cpu/tot_cpu),2)。太低表示解析消耗的时间过多。与Parse_cpu相比,如果tot_cpu很高,这个比值将接近100%,这是很好的,说明计算机执行的大部分工作是执行查询的工作,而不是分析查询的工作。
-------------------------------------------------
这里面有几个常见的重要比率。
1、Buffer命中率(Buffer Hit %)
Buffer命中率表示当进行数据访问时,在内存中找到数据的百分比。这个比率越高说明物理I/O就越少,所以通常期望这个比率是100%。如果这个比率过低,通常意味着Buffer Cache可能设置得过低,大量读操作都需要通过物理I/O访问来完成,可能造成数据库的性能低下。
但是需要强调的是,早期很具有参考意义的这个比率现在的意义已经越来越低。因为现在随着硬件能力的扩展,数据库的Buffer Cache已经越来越大,所以看到这个比率较低的情况已经越来越少。根据传统的建议,通常这个比率应该维持在99%左右,如果这个比率低于95%就应当引起注意。
2、内存排序率(In-memory Sort %)
在11g之前, Optimal W/A Exec %: 100.00 这里是In-memort Sort %。
排序是非常昂贵的数据操作,特别是磁盘排序,所以Oracle提出这一性能指标,用于衡量在内存排序的比率。
内存排序率的计算公式为:
In-memory Sort%=100*(sort memory/(sort memory+sort disk))
sorts (memory)可以在后面的Instance Activity Stats部分中找到:
Instance Activity Stats DB/Inst: TEST/tsid Snaps: 31-41
Statistic Total per Second per Trans
--------------------------------- ------------------ -------------- ------------
sorts (memory) 883 7.2 88.3
sorts (rows) 20,359 166.9 2,035.9
注:这里我没有找到sorts (disk)这一指标,不知道是10g、11g中取消了还是100%的缘故。
如果内存排序率过低,那么一定要引起注意,找到引发磁盘排序的SQL,看是否能够通过优化降低其磁盘排序,从而提高系统性能。
3、软解析率(Soft Parse %)
软解析率的计算方法为:
Soft Parse %=1-parse count(hard)/parse count(total)
这两个数据来自report中Instance Activity Stats部分:
Instance Activity Stats DB/Inst: TEST/tsid Snaps: 31-41
Statistic Total per Second per Trans
--------------------------------- ------------------ -------------- ------------
parse count (hard) 140 1.2 14.0
parse count (total) 1,026 8.4 102.6
对于本例这个比率为:
Soft Parse%=100*round((1-140/1026),4)=86.35%
这个比率通常应该在99%以上,对于这个报告,硬解析是高的。
4、执行分析比率(Execute to Parse %)
执行分析比率计算公式如下:
100*(1-Parses/Executions)=Execute to Parse
所以如果系统Parses>Executions时,就可能出现该比率小于0的情况。该参数计算来自Instance Activity Stats部分:
Instance Activity Stats DB/Inst: TEST/tsid Snaps: 31-41
Statistic Total per Second per Trans
--------------------------------- ------------------ -------------- ------------
execute count 2,547 20.9 254.7
......
parse count (failures) 0 0.0 0.0
parse count (hard) 140 1.2 14.0
parse count (total) 1,026 8.4 102.6
通过公式及以上两个数值:
100*round((1-1026/2547),4)=59.72%
该值<0通常说明shared pool设置或效率存在问题,造成反复解析,reparse可能较严重,或者可能同snapshot有关,如果该值为负值或者极低,通常说明数据库性能存在问题。
5、分析CPU与分析时间比率(Parse CPU to Parse Elapsd %)
这个比率来自parse time cpu和parse time elapsed:
100*(parse time cpu/parse time elapsed)=Parse CPU to Parse Elapsd %
Instance Activity Stats DB/Inst: TEST/tsid Snaps: 31-41
Statistic Total per Second per Trans
--------------------------------- ------------------ -------------- ------------
parse time cpu 31 0.3 3.1
parse time elapsed 40 0.3 4.0
对于本例,这个比率计算为:
100*round(31/40,4)=77.50%
Parse Time CPU代表在进行SQL解析的过程中所耗用的CPU时间;而Parse Time Elapsed则代表整个SQL解析所消耗的时间。这个比率的期望值是100%,如果该值达到100%那么说明SQL的解析时间都消耗在CPU上,而不是浪费在其它等待上;如果分析时间远远大于CPU时间,则说明在其他方面可能存在竞争或等待,比如获取字典信息的物理I/O访问等。
但是这个统计信息并不具备太多的意义,在多CPU的系统中,Oracle计算的Parse Time CPU时间可能会超过Parse Time Elapsed时间,这样就会出现此比率大于100%的情形。(注:10g、11g AWR不知道有没有解决这一问题)
Shared Pool Statistics Begin End
------ ------
Memory Usage %: 76.88 83.04
% SQL with executions>1: 48.36 57.69
% Memory for SQL w/exec>1: 47.95 61.18
参数说明:
-------------------------------------------------
Memory Usage %:正在使用的共享池的百分率。这个数字应该长时间稳定在75~90%。如果这个百分率太低,就浪费内存。如果这个百分率太高,会使共享池外部的组件老化。如果SQL语句被再次执行,这将使得SQL语句被硬解析。在一个大小合适的系统中,共享池的使用率将处于75%到略低于90%的范围内。
% SQL with executions>1:这是在共享池中有多少个执行次数大于一次的SQL语句的度量。在一个趋向于循环运行的系统中,必须认真考虑这个数字。在这个循环系统中,在一天中相对于另一部分时间的部分时间里执行了一组不同的SQL语句。在共享池中,在观察期间将有一组未被执行过的SQL语句,这仅仅是因为要执行它们的语句在观察期间没有运行。只有系统连续运行相同的SQL语句组,这个数字才会接近100%。
% Memory for SQL w/exec>1:这是与不频繁使用的SQL语句相比,频繁使用的SQL语句消耗内存多少的一个度量。这个数字将在总体上与% SQL with executions>1非常接近,除非有某些查询任务消耗的内存没有规律。
在稳定状态下,总体上会看见随着时间的推移大约有75%~85%的共享池被使用。如果Statspack报表的时间窗口足够大到覆盖所有的周期,执行次数大于一次的SQL语句的百分率应该接近于100%。这个一个受观察之间持续时间影响的统计数字。可以期望它随观察之间的时间长度增大而增大。
-------------------------------------------------
对于数据库系统来说,响应时间是一个衡量性能的重要指标,Statspack的接下来部分开始对时间进行衡量。
这部分通常也是最值得注意的部分。Top 5 Timed Events部分列出了最消耗时间的Top 5事件:
Top 5 Timed Events Avg %Total
~~~~~~~~~~~~~~~~~~ wait Call
Event Waits Time (s) (ms) Time
----------------------------------------- ------------ ----------- ------ ------
CPU time 5 43.4
control file sequential read 2,634 2 1 20.2
db file sequential read 303 2 6 15.1
control file parallel write 43 1 29 10.8
db file scattered read 113 1 6 5.8
在Oracle 9i之前,这部分称为“Top 5 Wait Events”,只列出等待事件,从Oracle 9i开始,Oracle将CPU time加入进来。其余部分的等待事件来自Statspack报告中的Wait Events部分。在数据库中,实际上是采样v$system_event视图得到的,存储在stats$system_event表中。
这里是比其他任何事件都能使速度减慢的事件。比较影响性能的常见等待事件:
-------------------------------------------------
db file scattered read:该事件通常与全表扫描有关。因为全表扫描是被放入内存中进行的,通常情况下它不可能被放入连续的缓冲区中,所以就散步在缓冲区的缓存中。该指数的数量过大说明缺少索引或者限制了索引的使用(也可以调整optimizer_index_cost_adj)。这种情况也可能是正常的,因为执行全表扫描可能比索引扫描效率更高。当系统存在这些等待时,需要通过检查来确定全表扫描是否必需的来调整。如果经常必须进行全表扫描,而且表比较小,把该表存入keep池。如果是大表经常进行全表扫描,那么应该是OLAP系统,而不是OLTP系统。
db file sequential read:该事件说明在单位个数据块上大量等待。该值过高通常是由于表间连接顺序很糟糕,或者使用了非选择性索引。通过将这种等待与Statspack报表中已知其它问题联系起来(如效率不高的sql),通过检查确保索引扫描是必须的,并确保多表连接的连接顺序来调整,DB_CACHE_SIZE可以决定该事件出现的频率。
buffer busy wait:当缓冲区以一种非共享方式或者如正在被读入到缓冲时,就会出现该等待。该值应该不大于1%,确认是不是由于热点块造成(如果是可以用反转索引,或者用更小块大小)。
latch free:常跟应用没有很好的应用绑定有关。闩锁是底层的队列机制(更加准确的名称应该是互斥机制),用于保护系统全局区(SGA)共享内存结构,闩锁用于防止对内存结构的并行访问。如果闩锁不可用,就会记录一次闩锁丢失。绝大多数的闩锁问题都与使用绑定变量失败(库缓存闩锁)、生成重作问题(重执行分配闩锁)、缓存的争用问题(缓存LRU链)以及缓存的热数据宽块(缓存链)有关。当闩锁丢失率高于0.5%时,需要调整这个问题。
log buffer space:日志缓冲区写的速度快于LGWR写redofile的速度,可以增大日志文件的大小,增加日志缓冲区的大小,或者使用更快的磁盘来写数据。
logfile switch:通常是因为归档速度不够快,需要增大重做日志。
log file sync:当一个用户提交或回滚数据时,LGWR将会话的重做操作从日志缓冲区填充到日志文件中,用户的进程必须等待这个填充工作完成。在每次提交时都出现,如果这个等待事件影响到数据库性能,那么旧需要修改应用程序的提交频率,为减少这个等待时间,须一次提交更多记录,或者将重做日志redo log文件放在不同的物理磁盘上。
Wait time:等待时间包括日志缓冲的写入和发送操作。
-------------------------------------------------
在Oracle 10g的Statspack报告中,还包含了主机系统信息,这些信息包括主机负载、数据库实例CPU使用、内存统计等内容:
Host CPU (CPUs: 2 Cores: 2 Sockets: 1)
~~~~~~~~ Load Average
Begin End User System Idle WIO WCPU
------- ------- ------- ------- ------- ------- --------
6.08 6.81 87.11
Instance CPU
~~~~~~~~~~~~ % Time (seconds)
-------- --------------
Host: Total time (s): 235.9
Host: Busy CPU time (s): 30.4
% of time Host is Busy: 12.9
Instance: Total CPU time (s): 7.2
% of Busy CPU used for Instance: 23.6
Instance: Total Database time (s): 19.9
%DB time waiting for CPU (Resource Mgr): 0.0
Virtual Memory Paging
~~~~~~~~~~~~~~~~~~~~~
KB paged out per sec: 8.4
KB paged in per sec: 15.8
Memory Statistics Begin End
~~~~~~~~~~~~~~~~~ ------------ ------------
Host Mem (MB): 3,030.0 3,030.0
SGA use (MB): 510.8 510.8
PGA use (MB): 73.3 65.5
% Host Mem used for SGA+PGA: 19.3 19.0
-------------------------------------------------------------
这部分信息在后来也被引入到AWR报告中。
七、第七部分:详细信息
剩余部分是详细信息,这些信息都是详细的数据库信息列表。在此前各部分发现的问题可以通过这些具体信息进行进一步定位和诊断。