AWR 报告解析

DB TIME= DB CPU + Non-Ldle Wait + Wait on CPU queue
shared pool 一直在收缩,则在shrink过程中一些row cache 对象被lock住,可能导致前台row cache lock等解析等待。

awr-LOAD Profile:

shared pool 一直在grow,那说明shared pool 原有大小不足以满足需求,可能是大量硬解析。结合以下硬解析和SGA breakdown 来一起诊断问题

logical read 单位 次数块数 如:3410368/1024/1024 G=2.6G 逻辑读耗CPU,主频和CPU核数都很重要,逻辑读高则DB CPU 往往很高,也往往可以看到latch :cache buffer chains等待。大量的OLTP系统可以高达几十甚至上百GB

block changes 单位 次数*块数 描绘数据变化频率

physical read 单位次数块数 55578K = 43MB/S ,物理读消耗IO读,体现在IOPS和吞度量等不同维度上;但减少物理读可能意味着消耗更多的CPU。好的存储每秒物理读能到几GB

physical writes 单位 次数*块数,主要是DBWR写datafile,也有direct path write.dbwr长期写入慢会导致定期log file switch(checkpoint no complete),检查点无法完成前台的等待

user calls 单位次数,用户调用次数

parses,解析次数,包括软解析+硬解析,软解析优化的不好,则几乎等于每秒sql执行次数。即执行解析比1:1,而我们希望解析一次到处运行

######万恶之源
hard parses:万恶之源。Cursor pin s on X,library cache:mutex X,latch:row cache objects /shared pool……. 硬解析最好少于每秒20次
硬解析数与 hard parse elapsed time对应。看一眼time model statistics ,可知该系统是否是解析敏感的。

W/A MB processed:单位MB workarea workarea 中处理数据数量结合In-memory Sort%,sorts(disk) PGA aggr 一起看

logons 登录次数,logon storm 登录风暴,结合audit审计数据一起看。
短连接的附带效应是游标缓存无用。

######PGA Memory Advisory
pga_aggregate_target 过小会导致PGA overalloc 过载,但对于变态的hash/sort需求,再打的PGA也打不到cache hit 100%

instance efficiency percentages (target 100%)

buffer nowait%:session 申请一个buffer(兼容模式)不等待的次数比例。
buffer hit%:经典的经典,高速缓存命中率,反映物理读和缓存命中的纠结。但这个指标即使99%,也不能说明物理读等待少了。

redo nowait%:session 在生成redo entry 时不用等待的比例,redo相关的资源争用

#####Shared Pool Statistics
反映sql重用率及共享池中cursor 对内存的使用

shared pool statistics
提供一个大致的sql重用及shared pool 内存使用的评估。应用是否共享sql?有多少内存是给只运行一次的sql占掉的。对比共享sql

如果%sql with executions > 1 的比例小于90%,则需要抓硬编码的非绑定变量sql语句

####TOP 5 Time Foreground Events
基于wait interface 的调优是目前的主流。每个指标都很重要。

DB CPU 逻辑读?解析?Latch spin?PL?SQL,函数运算?
DB CPU/CPU time 是Top1 是好事情吗?未必,注意 DB CPU不包括 wait on cpu queue!
结合host CPU ,instance CPU,SQL orderd by CPU time 一起看

db file sequential read 单块读等待。常见的物理IO等待时间,这里的sequential指的是将数据块读到相连的内存空间中。(contiguous memory space),而不是指所读取的数据块儿是连续的。该wait event可能在以下情景中发生:
1.最为常见的是执行计划中包含了INDEX FULL SCAN/UNIQUE SCAN,此时出现”db file sequential read”等待是预料之中的,一般不需要我们去特别关注
2.当执行计划包含了INDEX RANGE SCAN-(“TABLE ACCESS BY INDEX ROWID”/”DELETE”/”UPDATE”), 服务进程将按照”访问索引->找到rowid->访问rowid指定的表数据块并执行必要的操作”顺序访问index和table,每次物理 读取都会进入”db file sequential read”等待,且每次读取的都是一个数据块;这种情况下clustering_factor将发挥其作用,需要我们特别去关注,本例中提及的解决方法对 这种情景也有效
3.Extent boundary,假设一个Extent区间中有33个数据块,而一次”db file scattered read”多块读所读取的块数为8,那么在读取这个区间时经过4次多块读取后,还剩下一个数据块,但是请记住多块读scattered read是不能跨越一个区间的(span an extent),此时就会单块读取并出现”db file sequential read”。这是一种正常现象,一般不需要额外关注
4.假设某个区间内有8个数据块,它们可以是块a,b,c,d,e,f,g,h,恰好当前系统中除了d块外的其他数据块都已经被缓存在buffer cache中了,而这时候恰好要访问这个区间中的数据,那么此时就会单块读取d这个数据块,并出现”db file sequential read”等待。注意这种情况不仅于表,也可能发生在索引上。这是一种正常现象,一般不需要额外关注
5.chained/migrated rows即链式或迁移行,这里我们不介绍链式行的形成原因,chained/migrated rows会造成服务进程在fetch一行记录时需要额外地单块读取,从而出现”db file sequential read”。这种现象需要我们特别去关注,因为大量的链式/迁移行将导致如FULL SCAN等操作极度恶化(以往的经验是一张本来全表扫描只需要30分钟的表,在出现大量链式行后,全表扫描需要数个小时),同时也会对其他操作造成不那么 明显的性能影响。可以通过监控v$sysstat视图中的”table fetch continued row”操作统计来了解系统中链式/迁移行访问的情况,还可以通过DBA_TBALES视图中的CHAIN_CNT来了解表上的链式/迁移行情况,当然这 要求定期收集表上的统计信息;如果没有定期收集的习惯,那么可以配合@?/rdbms/admin/utlchain脚本和analyze table list chained rows 命令来获取必要的链式行信息
6.创建Index entry,显然当对表上执行INSERT操作插入数据时,虽然在执行计划中你看不到过多的细节,但实际上我们需要利用索引来快速验证表上的某些约束是否 合理,还需要在索引的叶子块中插入相关的记录,此时也可能出现”db file sequential read”等待事件,当然这还和具体的插入的方式有关系。这是一种正常现象,一般不需要额外关注
7.针对表上的UPDATE/DELETE,不同于之前提到的”INDEX RANGE SCAN-UPDATE/DELETE”,如果我们使用rowid去更新或删除数据时,服务进程会先访问rowid指向的表块(注意是先访问table block)上的行数据,之后会根据该行上的具体数据去访问索引叶子块(注意Oracle并不知道这些leaf block在哪里,所以这里同样要如range-scan/unique-scan那样去访问index branch block),这些访问都将会是单块读取,并会出现’db file sequential read’,完成必要的读取后才会执行更新或删除的实际EXEC操作,如下例:
下trace中,obj#=1307547为sample表,而obj#=1307549为sample表上的唯一一个索引
PARSING IN CURSOR #10 len=58 dep=0 uid=64 oct=6 lid=64 tim=1275805024007795 hv=505118268 ad=’d387e470’
update sample set t2=t2+1 where rowid=’AAE/OzAAEAAANUEAAQ’
END OF STMT
PARSE #10:c=1999,e=3016,p=1,cr=1,cu=0,mis=1,r=0,dep=0,og=1,tim=1275805024007787
WAIT #10: nam=’db file sequential read’ ela= 314 file#=4 block#=54532 blocks=1 obj#=1307547 tim=1275805024008308
WAIT #10: nam=’db file sequential read’ ela= 206 file#=6 block#=20 blocks=1 obj#=1307549 tim=1275805024009235
WAIT #10: nam=’db file sequential read’ ela= 206 file#=6 block#=742 blocks=1 obj#=1307549 tim=1275805024009496
WAIT #10: nam=’db file sequential read’ ela= 207 file#=6 block#=24 blocks=1 obj#=1307549 tim=1275805024009750
EXEC #10:c=2000,e=2297,p=6,cr=2,cu=8,mis=0,r=1,dep=0,og=1,tim=1275805024010210 –实际的UPDATE发生在这里
当大量执行这类UPDATE/DELETE操作时将需要频繁地交叉访问表和索引,如果恰好表上的某个索引有较高的 clustering_factor的话,那么就会形成本例中的这种性能问题了。实际上当表上有较多索引时,使用rowid来批量 update/delete数据这种方式是不被推荐的,仅当表上没有索引时才可能十分高效。如果你坚持要这样做,那么可以参照上面提到的建议。
8.BUG!BUG!已知在9i RAC及10g中使用ASM的情况下,存在引发在适用情况下不使用”scattered read”多块读而去使用”sequential read”的BUG。如果你的问题和上述情景都不匹配,但又有大量的”db file sequential read”等待事件,那么你有可能遇到bug了。在这里列出部分已知bug:
Bug# Version Affected
Bug 7243560 – High “db file sequential read” IO times when using ASM 10.2.0.4/11.1.0.7
Bug 7243560: RAPID INCREASE IN DB FILE SEQUENTIAL READ AFTER MOVING TO ASM 10.2.0.3
Bug 9711810: EXCESSIVE DB FILE SEQUENTIAL READS WITH NON COMPLIANT BUFFER CACHE ON RAC 9.2.0.8
Bug 9276739: INSERT STATEMENT HAS SLOW PERFORMANCE WITH DB FILE SEQUENTIAL READ 10.2.0.4
Bug 8625100: EXCESSIVE DB FILE SEQUENTIAL READ ON UNDO 10.2.0.4
Bug 8669544: HIGH DB FILE SEQUENTIAL READ AND GC CR DISK READ WAIT EVENTS DURING FULL SCAN 10.2.0.4
Bug 7427133: AN INSERT CAUSES LOTS OF ‘DB FILE SEQUENTIAL READ’ WAITS FOR THE INDEX BLOCKS 9.2.0.8
Bug 8493139: INCREASE IN DB FILE SEQUENTIAL READ WAITEVENT AFTER MIGRATING TO 10 RAC/ASM 10.2.0.4
Bug 5882268: PERFORMANCE ISSUE WITH ‘DB FILE SEQUENTIAL READ’ 10.2.0.2
Bug 7415702: LOTS OF ‘DB FILE SEQUENTIAL READ’ ON UNDO 10.2.0.3
Bug 5607724: 10202 DB FILE SEQUENTIAL READ THRICE AFTER UPGRADE FROM 9I 10.2.0.2

Log file sync 蝴蝶效应
log file sync ->enq:TX,gc buffer busy,buffer busy wait
等待事件的混沌理论,性能不是线性的,而是多维度的。
Enq:TX row lock 出现在哪里?哪些语句收到GC buffer busy 影响?最主要是update 和 insert 受影响,前台业务处理速度放慢。

direct path read
从11G开始oracle通过内部算法来决定串行扫描大表是通过直接路径读direct path read,还是先读入到buffer cache中,此算法依据表的大小评估。降低direct path read,则将引起CPU上升(物理读替换为逻辑读,当存储IO不行,CPU使用低可以操作)

性能优化的多维度理论:
增加了CPU ——>更大的并发量,更过的并发争用
调整了IO存储 -> 更少的IO,更多的CPU计算,更高的CPU使用率。
redo写得慢 -> 影响commit,造成enq:tx 和 gc buffer busy 等待 注:log file sync —>格外注意
datafile写得慢 -> 检查点完不成,日志无法切换,前天的dml hang
sequence no cache -> insert index 很容易造成 enq:index conntention 和 row cache lock 和 enq:SQL

#####Host CPU (CPUs:64 Cores:32 Sockets:2)

这里的CPU数是指逻辑CPU数(Number of logical CPUs available (includes hardware threads if hardware threading is turned on))当硬件多线程技术打开时:例如:POWER SMT(Simultaneous Multi-Thread)
Intel Ht(Hyper Thread) 此时一个CPU core 被视作2个或更多个逻辑CPU
“Load Average” begin/end 值代表了每个CPU的大致运行队列大小。上图中快照开始到结束,平均CPU负载增加了。
%User + %System => 总的CPU使用率 或者 100% - %Idle =>总的CPU使用率。这里是29.0%
Elapsed Time * NUM_CPUS*CPU utilization = 299.70 (mins) * 64 * 29% = 5562.4mins = busy Time
与 《Operating System Statistics》中的LOAD相对应
%Total CPU 该实例所使用的的CPU占总CPU的比例 - > of taotal CPU for instance
%Busy CPU,该实例所使用的的CPU占总的被使用的CPU的比例 -> % of busy CPU for instance
例如共计4个逻辑CPU,其中3个被完全使用,3个中的1个完全被该实例使用。则%Total CPU=1/4=25%,而%Busy CPU=1/3=33%
当CPU高时一般看%Busy CPU可以确定CPU到底是否是本实例消耗的,还是主机上的其他程序

resmgr:CPU quantum 等待时间是当resource manager控制CPU调度的时候,需要控制对应的进程暂时不使用CPU而进程到内部运行队列中,以保证该进程对应的consumer group 没有消耗指定resource manager 指令更多的CPU

Memory statistics

11G 以后才有的一个section,可以了解SGA,PGA主机物理内存的大致使用情况。
PGA在快照时间从23677M增长到了26301M,pga_aggregate_target=16G ,存在overalloc
%Host Mem used for SGA + PGA 可以大致反映本实例占用主机物理内存的情况。
根据pga memory advisory 查看pga大小建议,看配置是否合理

Time Model Statistics

Time Model Statistics

connection management call elapsed time 建立数据库session 连接和断开
failed parse elapsed time 解析失败,例如 ORA-4031
hard parse(sharing criteria) elapsed time 由于无法共享游标造成的硬解析
hard parse(bind mismatch) elapsed time 由于bind type or bind size 不一致造成的硬解析

AWR RAC

常见的global cache 等待事件
gc cr disk read事件
当node 1需要读取的block在node 2的buffer cache里,且block中包含尚未提交的事务,那么node 2的LMS进程需要使用undo record将该block回滚至node 1发起那一时刻的内容后再传给node 1,假如这时undo record所在的undo block不在node 2的buffer cache里,node 1上就会出现gc cr disk read事件,表示node 1正等待node 2的LMS授予其直接从磁盘读取undo block的权限。

gc current block 2-way
node 1、node 2的buffer cache里都没有block A,这时node 1读取了某个block A里的某一行,随后node 2也读取了block A或者对block A里的某一行作了DML操作,这两种情况下node 2上都会出现”gc current block 2-way”等待,current在这里表示node 2读取或修改的block版本是最新的,该block里不存在未提交的事务。值得注意的是在”gc current block 2-way”事件发生之后,GRD里会为该block上KJUSERPR(读操作)或者KJUSEREX锁(写操作)

gc cr block 2-way
细分一下有两种情况
(1)、node 1修改了记录但没有提交:
node 1、node 2的buffer cache里都没有block A,这时node 1修改了block A里的某一行,但没有提交;随后node 2执行了Select block A操作,按照一致性读的定义,node 2此时应该收到block A在select发起那一时刻所对应的快照block A’,block A’将由node 1上的LMS进程以应用undo record到block A的方式构造出来后传给node 2,此时在node 2上就发生了一次”gc cr block 2-way”等待事件,node 2接收到的block A’在buffer cache中标记为cr类型,cr类的block仅满足当次查询的需要,无法被之后的查询所重用,也就是说假如node 2仅接着又发起一次对于block A的select操作,node 1上的LMS进程还是会重新构造出一个block A’’后传递给node 2,尽管block A’’与block A’的内容是完全一样的。这一特性决定了cr block在构造及传输的过程中在GRD里不需要任何的锁来保护。
(2)、node 1修改了记录且已经提交:
node 1、node 2的buffer cache里都没有block A,这时node 1修改了block A里的某一行,并且已经提交。因为_fairness_threshold参数的作用,当node 2执行了Select block A操作,仍然有可能触发node 1上的LMS进程构造cr block然后传输给node 2的动作,node 2就会遇到gc cr block 2-way等待。
值得一提的是不管是gc cr block 2-way还是gc current block 2-way,它们的出现并不意味着RAC的性能出现了问题,可以认为这是消息类的等待事件,仅仅表示两节点间存在block的传输,但如果在AWR里发现这两种等待事件平均耗时较长(>10ms),就可以认为网络上存在瓶颈,需要联系网络管理员介入处理

gc current block busy
node 1正在更新block A的时候node 2也发起了对block A的更新,这时node 2在等待接收node 1上的LMS进程构造出block A在node 2发起更新时刻的block映像,node 2在接收到block A映像之前,就会处于gc current block busy状态

gc cr block busy
当node 1正在更新block A的时候,node 2发起了对block A的查询,这时node 2在等待接收node 1上的LMS进程构造出block A在node 2发起查询时刻的block映像,node 2在接收到block A映像之前,就会处于gc cr block busy状态

gc buffer busy acquire
实例1和实例2的buffer cache都含有某个block,T1时刻实例1修改了这个block,T2时刻实例2上的会话1读取这个block,当这个读取还没有完成,实例2上的会话2也发起了读取相同block的操作,这时会话2就会等在gc buffer busy acquire上。实例2同时发起的读取相同block的会话数越多,我们就越容易观察到gc buffer busy acquire等待。

gc buffer busy release
在session#1尝试请求访问本地实例buffer时,发现之前已经有远程实例的session#2请求访问该buffer,并且没有完成,那么session#1等待gc buffer busy release。

########RAC Global Cache Load Profile(RAC 特有)

rac statistics
0.03%的逻辑读由其他节点上的缓存满足Global cache Receive/server 的原因一般是节点间的缓存争用或本地无此缓存

(received + send)* db_block_size = 901 * 8k = 7.04MB/s 一般建议private network 选用10Gb带宽

如果Interconnect 的网络延迟 > IO子系统的延迟,那么RAC本身就是性能瓶颈
IO相应事件对RAC来说非常重要。log file sync => gc buffer busy,所以千万别用garbage storage 去搭建RAC

########Global Cache Efficiency Percentages (Target local + remote 100%) RAC 特有

Avg global cache cr block receive time (ms) :0.7 该指标反映平均每个global cr块从申请到收到的耗时
Avg global cache current blcok receive time(ms) :1.0 这两个指标需要 < 2ms 该指标反映平均每个global current 块从申请到收到的耗时。如果指标过高,则说明本实例出现大量cluster等待
Avg global cache pin/send/flush time 高,本实例server global cache 也不给力,其他节点的性能大致也和此处一副德行
至关重要的两个指标,结合其他节点的awr报告一起分析这两个指标,一般要求小于2ms
注”若在RAC实例之间两个指标的差异很大,一般说明interconnect问题出现于OS buffer 层或者网卡上”
Avg message sent queue time on Ksxp 对端收到该消息并返回ACK的时间。这个指标很重要,直接反映了网络延迟。一般小于1ms

#####Apex-high Cluster Wait
大量的Cluster Wait,平均每次等待241ms,而一个事务平均等待9.2次,则一个事务平均等Cluster 2秒。换句话来说如果不是RAC的话,每个事务可以提速2S
Cluster Wait并不鼓励,会影响Application类型的enq:TX -row lock contention 等待时间出现的频率和单词等待耗时

Timed Foreground Events

gcs resource directory to be unfrozen 与 drm 有直接关系
gc cr block lost :GLobal Cache问题一定要和OS跟Network层结合起来看,ifconfig、netstat、syslog 信息极意获得,nmon,osw亦有价值
gc buffer busy acquire: RAC负载均衡下并发insert 很容易造成gc buffer busy acquire
本实例第一个申请该current block 时进入gc current request,本实例后续其他进程若又发起对该current block的申请,则均进入’gc buffer busy acquire‘等待
11g后gc buffer busy 分成 ‘gc buffer busy acquire’ 和 ‘gc buffer busy release了’ 一般来说 不能出现超过10ms

#########AWR SQL STATISTICS
注意对于plsql,sql statistic 不仅会体现该plsql的执行情况。还会包括该plsql包含的sql语句的情况