037.笔记:使用STATSPACK和AWR报表调整等待和闩锁

如果您只能选择两个Oracle实用程序来监控和发现您的系统中的性能问题,那么这两个实用程序应当是Enterprise Manager和新的AWR(Automatic Workload Repository),
自动工作量仓库,简称AWR)报表和/或STATSPACK。STATSPACK是免费工具,AWR需要许可。

1.10gR2(10.2)STATSPACK的新特性

2.10gR1(10.1)STATSPACK的新特性

3.安装STATSPACK
在安装STATSPACK之前,应当创建一个表空间,用来容纳STATSPACK的数据。
安装脚本名为spcreate.sql,可以在Oracle软件的根目录下的/rdbms/admin子目录中找到。spcreate.sql脚本创建了一个名为PERFSTAT的用户,并按计划创建了大量的对象。
spcreate.sql脚本需要用有SYSDBA特权的账户执行。
【技巧】为初次创建PERFSTAT计划的对象分配的空间至少要120MB。Oracle10g需要的空间比Oracle9i多20M。
【注意】经过测试,在10.2.0.1上安装STATSPACK后,通过DBA_SEGMENTS查看到PERFSTAT用户使用了143M的空间。
检查STATSPACK安装结果的脚本:spcpkg.sql
删除STATSPACK的脚本:spdrop.sql

3.1PERFSTAT账户的安全管理
PERFSTAT用户被授予了许多系统权限。任何可以访问您的PERFSTAT账户的用户都可以查看所有的字典视图。如果不对PERFSTAT账户提供任何保护的话,就等于向入侵都提供
了一个安全漏洞,使用他们随意查看您的数据字典,并选择下一步入侵的目标。
可以根据需要来锁定和解锁PERFSTAT账户。
锁定:alter user perfstat account lock;
解锁:alter user perfstat account unlock;

3.2安装之后
安装过程结束之后,PERFSTAT账户将拥有67张表、68个索引、一个同名对象、一个队列和一个数据包。而在Oracle 9i中只有36张表、37个索引、一个队列和一个数据包。
您将使用这个名为STATSPACK的数据包来管理统计信息搜集进程和表中的数据。集合表的名称均以STATS$开头,所定义的列均是基于V$视图的定义。
例如,STATS$WAITSTAT的列均可以在V$WAITSTAT视图中找到,并在顶部增加了3个识别列:
SNAP_ID:集合的数字标识符,每一个集合称为一个“快照”,并分配一个整数值。
DBID:数据库的数字标识符。
INSTANCE_NUMBER:实例的数字标识符,用于实时应用群集的安装。
【技巧】不要在同一个数据库中同时使用STATSPACK和UTLBSTAT/UTLESTAT。早期版本的Oracle提供的UTLBSTAT/UTLESTAT脚本也会创建一张名为STATS$WAITSTAT的表,如果您同时
运行两者时就会遇到错误,除非以PERFSTAT用户身份来运行UTLESTAT。

3.3搜集统计数据
每一个统计信息的集合称为一个快照。统计数据的快照与在复制过程中的快照或物化视图没有关系。当然,它们是在一个时间点上通过V$视图提供的可以使用的统计信息集合,
并被分配了一个SNAP_ID值来标识快照。可以生成报表来反映两张快照之间统计数据的变化。这是比早期版本的Oracle提供的UTLBSTAT/UTLESTAT要显著优越的地方。使用STATSPACK,
可以搜集您所需要的任何数量的快照,然后再生成报表来反映它们任意组合的情况。和UTLBSTAT/UTLESTAT报表一样,在评估快照时,STATSPACK报表只有在数据库没有关闭、重启
的情况下才会有效。
【技巧】要确保在搜集数据前,将数据库初始化参数TIMED_STATISTICS设置为TRUE。

--生成统计信息的快照
execute statspack.snap;

应该在以下两种情况之一时使用快照:
1)评估系统在特定的测试期间的性能。对于这些测试可以手工执行SNAP过程,就像前面展示的示例那样。
2)评估在一段长时间内性能的变化。为了确定系统性能的基线,您可能会按照计划好的操作来生成统计信息的快照。对于这些快照,您应当通过Oracle内部的DBMS_JOB调度
程序(scheduluer)或者一个操作系统的调度程序来安排SNAP过程的执行。

为了支持不同等级的集合,STATSPACK提供了等级参数(_i_snap_level)。默认情况下,等级值被设置为5.在改变等级值之前,应当生成尽可能多的快照,并评估生成的报表。
默认的等级值适用于绝大多数报表。

【可选的等级值】
0-4:通用的性能统计数据,可用于内存区域、闩锁、池、事件,以及段的统计,例如回滚和撤消段。
5:包含一来自低等级的统计信息,外加绝大多数使用大量资源的SQL语句。
6:从Oracle9.0.1开始引入:等级6包括了等级5的结果,再加上SQL计划
7-9:从Oracle10g引入,等级7包括等级6的结果以及其他段等级的统计数据,包括逻辑读操作、物理读/写操作,全局缓存cr/当前服务和缓存忙碌,ITL的行锁定等待。
10及以上:和等级6的统计信息一样,增加了父/子闩锁数据。

--修改等级
BEGIN
STATSPACK.MODIFY_STATSPACK_PARAMETER(i_snap_level => 5);
END;
--经测试,执行STATSPACK.MODIFY_STATSPACK_PARAMETER(i_snap_level => 3);--或snap_level not in(0,5,6,7,10)的值时,会报错误ORA-02291

集合的等级越高,快照花费的时间就越长。在绝大多数使用大量资源的SQL语句进行查询时,默认值(5)可以提供很高的灵活性。快照中针对大量使用资源的SQL部分
使用的参数存储在名为STATS$STATSPACK_PARAMETER的表中。可以通过查询STATS$STATSPACK_PARAMETER来查看在SQL语句搜集数据期间不同的阈值的设置情况。它的列包括
SNAP_LEVEL(快照等级)、EXECUTIONS_TH(执行数量的阈值)、DISK_READS_TH(磁盘读操作数量的阈值)和BUFFER_GETS_TH(缓冲区读操作数量和阈值)。

对于使用了默认阈值的等级5的快照,SQL语句在满足下列任何一个标准时就会被存储起来:
1)SQL语句至少执行了100次。
2)SQL语句执行的磁盘读操作的数量超过1000次。
3)SQL语句执行的解析调用的数量超过1000次。
4)SQL语句执行的缓冲区读操作的数量超过10000次。
5)SQL语句使用的共享内存超过1MB。
6)SQL语句的版本计数超过20.

在评估快照的数据和性能报表时,请记住,SQL的阈值参数值是逐渐累加的。一个效率很高的查询,如果执行足够长的时间,将有超过10000次的缓冲区读操作。将缓冲区读
操作和磁盘读操作的数量与执行的次数相比较,可以用于判定每次查询执行时的活动。
为了修改阈值的默认设置,可以使用STATSPACK数据包的MODIFY_STATSPACK_PARAMETER过程。可以通过i_snap_level参数指定快照的等级,并修改该参数。

【可修改的参数】
参数名称 值的范围 默认值 描 述
i_snap_level 0,5,6,7,10 5 快照等级
i_ucomment 任何文本 空白 快照的注释
i_execution_th 整数>=0 100 执行的累积次数的阈值
i_disk_reads_th 整数>=0 1000 磁盘读操作(物理读操作)的累积次数的阈值
i_parse_calls_th 整数>=0 1000 解析调用的累积次数的阈值
i_buffer_gets_th 整数>=0 10000 缓冲区逻辑读操作的累积次数的阈值
i_sharable_mem_th 整数>=0 1028576 已分配的可共享内存数量的阈值
i_version_count_th 整数>=0 20 SQL语句版本数量的阈值
i_seg_buff_busy_th 整数>=0 100 SEGMENT上缓冲遇忙等待数量的阈值
i_seg_rowlock_w_th 整数>=0 100 SEGMENT上行锁定等待数量的阈值
i_seg_itl_waits_th 整数>=0 100 SEGMENT上ITL等待数量的阈值
i_seg_cr_bks_sd_th 整数>=0 1000 为SEGMENT服务的一致性读操作(CR)数据
i_seg_cu_bks_sd_th 整数>=0 1000 为SEGMENT服务的当前(CU)块数量的阈值
i_seg_phy_reads_th 整数>=0 1000 一个SEGMENT上物理读操作数量的阈值
i_seg_log_reads_th 整数>=0 10000 一个SEGMENT上逻辑读操作数量的阈值
i_session_id 从V$SESSION中 0 Oracle会话的会话ID,如果想搜集会话级的。。(书中的描述不完整)
i_modify_parameter TRUE或FALSE FALSE 如果希望保存当前的设置,以用于将来的快。。(书中的描述不完整)

【示例】
BEGIN
STATSPACK.MODIFY_STATSPACK_PARAMETER(i_snap_level => 5,i_buffer_gets_th => 100000,i_modify_parameter => 'true');
END;

如果计划在一个预定计划中使用SNAP过程,那么应当在数据库启动后就固定STATSPACK数据包。
begin
dbms_shared_pool.keep('perfstat.statspack','P');--dbms_shared_pool是sys用户的包
end;

3.4运行统计数据报表
如果生成了多个快照,可以创建两个快照期间的统计数据的报表。在两次快照执行的期间,数据库绝对不能关闭。
--生成报表
SQL>@$ORACLE_HOME/rdbms/admin/spreport.sql
--默认的报表文件名
sp_beginning_ending.lst

4.自动工作量仓库(AWR)和AWR报表
AWR数据与STATSPACK数据分开保存,因此同时运行这两个数据显得有点多余。
Oracle数据库使用AWR来检测和分析问题以及自我调整。AWR收集许多不同的统计数据,包括等待事件、时间模型统计数据、活动会话历史统计数据、各种系统级和会话级
统计数据、对象使用情况统计数据以及与使用大量资源的SQL语句相关的信息。要正确收集数据库统计数据,应该将初始化参数STATISTICS_LEVEL设置为TYPICAL(默认)或ALL。
AWR由许多表组成,这些表归SYS计划所有,通常保存在SYSAUX表空间里(当前还没有办法将这些对象移动到其他表空间)。所有AWR表名称都以标识符“WR”开始。
AWR表有3种不同的类型名称:
1)元数据(WRM$)
2)历史数据(WRH$)
3)与顾问函数(advisor function)相关的AWR表(AWI$)
Oracle Database 10g还提供一些DBA视图,它们允许您查询AWR仓库。这些表以DBA_HIST开始,后面紧跟描述该表的名称,例如DBA_HIST_FILESTATS、DBA_HIST_DATAFILE
或DBA_HIST_SNAPSHOT。

4.1手动管理AWR
AWR是自动的,但也可以使用影响AWR的手动操作
--修改时间间隔和保存标准
exec dbms_workload_repository.modify_snapshot_settings(retention => 20160,interval => 15);--每15分钟发生一次,快照保存14天。

--查看时间间隔和保存标准
select * from dba_hist_wr_control;

--创建快照
exec dbms_workload_repository.create_snapshot;

--查看已生成的快照
select * from dba_hist_snapshot order by snap_id;

--删除快照
exec dbms_workload_repository.drop_snapshot_range(low_snap_id => 11,high_snap_id => 13);

4.2 AWR自动快照
Oracle Database 10g使用计划任务GATHER_STATS_JOB来收集AWR统计数据。
要查看这项任务,可以使用DBA_SCHEDULER_JOBS视图
select a.JOB_NAME,a.ENABLED,c.WINDOW_NAME,c.REPEAT_INTERVAL
from dba_scheduler_jobs a
inner join dba_scheduler_wingroup_members b on(a.SCHEDULE_NAME=b.WINDOW_GROUP_NAME)
inner join dba_scheduler_windows c on(b.WINDOW_NAME=c.WINDOW_NAME)
where a.JOB_NAME='GATHER_STATS_JOB';

exec dbms_scheduler.disable('GATHER_STATS_JOB');
exec dbms_scheduler.enable('GATHER_STATS_JOB');
【注意】AWR统计数据是用GATHER_STATS_JOB收集。而AWR的快照并不是用GATHER_STATS_JOB生成的。
在默认情况下,快照由MMON进程收集,并且每隔一小时被存储至AWR

4.3 AWR快照报表
AWR报表与STATSPACK报表非常类似。有两个报表:awrrpt.sql(主AWR报表)和awrrpti.sql,它们都在目录$ORACLE_HOME/rdbms/admin中。这些报表的输出结果基本上一样,
除了awrrpti.sql脚本允许您定义一个要报告的特定实例之外。另外,您可以选择生成文本格式或HTML格式的报表。

和使用STATSPACK时一样,在AWR内创建基线是一个好主意。基线定义为一定范围内的快照,它可以用来与其他快照对进行比较,从而有助于确定数据库的性能问题
--创建基线
begin
dbms_workload_repository.create_baseline(start_snap_id => 173,end_snap_id => 176,baseline_name => 'EOM Bashline');
end;

--查询基线
select *
from dba_hist_baseline;

--删除基线
begin
dbms_workload_repository.drop_baseline(baseline_name => 'EOM Bashline',cascade => FALSE);
end;

【注】create_baseline生成的是“Preserved Snapshot Sets”,“Preserved Snapshot Sets”中的compare periods
可能实现AWR报表与基线表的比较。

4.4 在Oracle企业管理器网格控制中运行AWR报表
只要有快照,您就可以运行从任意快照开始和以任意快照结束的报表。

5.解释STATSPACK(以及AWR)的输出结果
STATSPACK输出的绝大多数信息需要结合额外的调查,以解决问题,并实现系统的优化。
5.1 报表头信息
报表的第一部分包含了数据库本身的信息,包括数据库的名称、ID、版本号以及主机等信息。随后是快照开始和结束的时间,以及有多少活动会话的信息。
缓存尺寸部分显示了缓冲区缓存的值(初始化文件中的DB_CACHE_SIZE)、共享池的尺寸(SHARED_POOL_SIZE)、标准数据块的尺寸(DB_BLOCK_SIZE)以及
日志缓冲区(LOG_BUFFER)。
注:AWR的报表头信息包含"WORKLOAD REPOSITORY report for"、“Report Summary”两部分。
【附】AWR报表中的db time。--来自ITPUB
DB Time不包括Oracle后台进程消耗的时间。如果DB Time远远小于Elapsed时间,说明数据库比较空闲。
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)。
说明系统压力非常小。
列出下面这两个来做解释:
Report A:
Snap Id Snap Time Sessions Curs/Sess
--------- ------------------- -------- ---------
Begin Snap: 4610 24-Jul-08 22:00:54 68 19.1
End Snap: 4612 24-Jul-08 23:00:25 17 1.7
Elapsed: 59.51 (mins)
DB Time: 466.37 (mins)

Report B:
Snap Id Snap Time Sessions Curs/Sess
--------- ------------------- -------- ---------
Begin Snap: 3098 13-Nov-07 21:00:37 39 13.6
End Snap: 3102 13-Nov-07 22:00:15 40 16.4
Elapsed: 59.63 (mins)
DB Time: 19.49 (mins)
服务器是AIX的系统,4个双核cpu,共8个核:
/sbin> bindprocessor -q
The available processors are: 0 1 2 3 4 5 6 7
先说Report A,在snapshot间隔中,总共约60分钟,cpu就共有60*8=480分钟,DB time为466.37分钟,则:
cpu花费了466.37分钟在处理Oralce非空闲等待和运算上(比方逻辑读)
也就是说cpu有 466.37/480*100% 花费在处理Oracle的操作上,这还不包括后台进程
看Report B,总共约60分钟,cpu有 19.49/480*100% 花费在处理Oracle的操作上
很显然,2中服务器的平均负载很低。
从awr report的Elapsed time和DB Time就能大概了解db的负载。

可是对于批量系统,数据库的工作负载总是集中在一段时间内。如果快照周期不在这一段时间内,或者快照周期跨度太长而包含了大量的数据库空闲时间,
所得出的分析结果是没有意义的。这也说明选择分析时间段很关键,要选择能够代表性能问题的时间段。

Cache Sizes
Begin End
Buffer Cache: 3,344M 3,344M Std Block Size: 8K
Shared Pool Size: 704M 704M Log Buffer: 14,352K
显示SGA中每个区域的大小(在AMM改变它们之后),可用来与初始参数值比较。
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。

5.2 负载简档
负载简档中查询以下信息:
1)重做数据块的增加、块更改变得频繁,以及每次读操作%BLocks的增加,这些意味着DML(插入/更新/删除)活动的增加。
2)当SQL语句不是在共享池中运行时,就会出现硬分析。硬分析率超过100次/秒就意味着绑定变量的使用效率不高,应当使用CURSOR_SHARING初始化参数;
或者说明共享池的大小存在问题。
3)当SQL语句是在共享池中运行时,就会出现软分析。
4)全部分析率超过300次/秒就意味着应用程序的效率不高,语句被反复地分析,而不是对每个会话应只分析语句一次,以保证高效率。

【技巧】通过检查和理解您的系统中正常的负载简档可以更好地了解您的系统。在类似的工作量下或一天中普通的时间段中,负载简档若出现显著的变化,就
说明您需要做进一步的调查了。

【附:ITPUB上的相关文档】
Load Profile Per Second Per Transaction
Redo size: 918,805.72 775,912.72
Logical reads: 3,521.77 2,974.06
Block changes: 1,817.95 1,535.22
Physical reads: 68.26 57.64
Physical writes: 362.59 306.20
User calls: 326.69 275.88
Parses: 38.66 32.65
Hard parses: 0.03 0.03
Sorts: 0.61 0.51
Logons: 0.01 0.01
Executes: 354.34 299.23
Transactions: 1.18
% Blocks changed per Read: 51.62 Recursive Call %: 51.72
Rollback per transaction %: 85.49 Rows per Sort: ########

显示数据库负载概况,将之与基线数据比较才具有更多的意义,如果每秒或每事务的负载变化不大,说明应用运行比较稳定。
单个的报告数据只说明应用的负载情况,绝大多数据并没有一个所谓“正确”的值,然而Logons大于每秒1~2个、Hard parses大于每秒100、
全部parses超过每秒300表明可能有争用问题。

Redo size:每秒产生的日志大小(单位字节),可标志数据变更频率, 数据库任务的繁重与否。
Logical reads:每秒/每事务逻辑读的块数.平决每秒产生的逻辑读的block数。Logical Reads= Consistent Gets + DB Block Gets
Block changes:每秒/每事务修改的块数
Physical reads:每秒/每事务物理读的块数
Physical writes:每秒/每事务物理写的块数
User calls:每秒/每事务用户call次数
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则是指都不命中的情况。
Hard parses:其中硬解析的次数,硬解析太多,说明SQL重用率不高。每秒产生的硬解析次数, 每秒超过100次,就可能说明你绑定使用的不好,也可能是共享池设置不合理。
这时候可以启用参数cursor_sharing=similar|force,该参数默认值为exact。但该参数设置为similar时,存在bug,可能导致执行计划的不优。
Sorts:每秒/每事务的排序次数
Logons:每秒/每事务登录的次数
Executes:每秒/每事务SQL执行次数
Transactions:每秒事务数.每秒产生的事务数,反映数据库任务繁重与否。
Blocks changed per Read:表示逻辑读用于修改数据块的比例.在每一次逻辑读中更改的块的百分比。
Recursive Call:递归调用占所有操作的比率.递归调用的百分比,如果有很多PL/SQL,那么这个值就会比较高。
Rollback per transaction:每事务的回滚率.看回滚率是不是很高,因为回滚很耗资源 ,如果回滚率过高,可能说明你的数据库经历了太多的无效操作 ,过多的回滚可能还会
带来Undo Block的竞争.该参数计算公式如下:
Round(User rollbacks / (user commits + user rollbacks) ,4)* 100% 。
Rows per Sort:每次排序的行数
注:
Oracle的硬解析和软解析
  提到软解析(soft prase)和硬解析(hard prase),就不能不说一下Oracle对sql的处理过程。当你发出一条sql语句交付Oracle,在执行和获取结果前,Oracle对此sql将进行
几个步骤的处理过程:
  1、语法检查(syntax check)
   检查此sql的拼写是否语法。
  2、语义检查(semantic check)
   诸如检查sql语句中的访问对象是否存在及该用户是否具备相应的权限。
  3、对sql语句进行解析(prase)
   利用内部算法对sql进行解析,生成解析树(parse tree)及执行计划(execution plan)。
  4、执行sql,返回结果(execute and return)
  其中,软、硬解析就发生在第三个过程里。
  Oracle利用内部的hash算法来取得该sql的hash值,然后在library cache里查找是否存在该hash值;
  假设存在,则将此sql与cache中的进行比较;
  假设“相同”,就将利用已有的解析树与执行计划,而省略了优化器的相关工作。这也就是软解析的过程。
  诚然,如果上面的2个假设中任有一个不成立,那么优化器都将进行创建解析树、生成执行计划的动作。这个过程就叫硬解析。
  创建解析树、生成执行计划对于sql的执行来说是开销昂贵的动作,所以,应当极力避免硬解析,尽量使用软解析。

5.3实例的效率
Instance Efficiency(实例的效率)这一部分信息展示了许多通用的命中率的信息。DBA们经常检测这些参数,以便可以通过和历史数据的比较来预警系统行为的显著变化。
命中率(当做定期托管时)是一个用来预警最近引入系统的普通潜在问题和特定潜在问题(例如糟糕的SQL)的极佳方法,这样就可以在这些问题恶化之前加以解决。
等待是另一个发现问题的好方法,但通常是用在已经出现严重的问题以后。有些DBA忽视了命中率的重要性(主动调整),而完全关注等待(被动调整),因为等待是解决
目前有燃眉之急的最佳方法。
实例效率部分注意以下内容:
1)Buffer NoWait%低于99%:这是一个对特定缓冲区的请求和命中率,在内存中的该缓冲区应当立即可用。如果命中率下降,在Buffer Wait部分中将发现当前存在(热)
数据块的争用现象。
2)Buffer Hit%低于95%:这是一个对特定缓冲区的请求的命中率,并且缓冲区位于内存中,而无需物理磁盘的I/0操作。尽管原来是作为测量内存效率的少数几种方法之一,
但它仍然是一个用于展示您所需要的物理磁盘I/0频率的好方法,这将有益于进一步调查性能问题的原因。但是,如果您在访问时经常使用非选择性索引,它将使您的命中
率很高,这将导致有些DBA做出认为系统性能很好的错误判断。当您有效地调整了您的SQL语句,并在全系统范围内使用了高效的索引,这个问题不会经常遇到,并且命中
率将是一个更佳性能的指示器。高命中率不是优良性能的标准,但低命中率则通常是性能需要改进或至少需要关注的信号。命中率稳定在95%,但有一天上升到99%,这时
就应该查找糟糕的SQL或导致大量逻辑读操作的索引(检查负载简档和首要缓存gets SQL)。命中率稳定在95%,但突然下降到45%,这时就应该查找导致大量物理读操作的
糟糕的SQL(检查首要物理读操作SQL),这些物理读操作没有使用索引或索引被删除了。
3)Library Hit低于95%:较低的库命中率通常意味着SQL语句被过早推出了缓冲池(可能是因为缓冲池太小了)。较低的命中率还意味着没有使用绑定变量或者一些其他的问题造
成SQL没有被重用(在这种情况下,较小的共享池是唯一的权宜之计,或许可以修复所引发的库闩锁问题)。尽管声称始终降低共享池来解决库缓存和共享池闩锁问题,但我
见过的大多数多千兆字节系统都有以十亿字节为单位的共享池,也没有产生任何问题,因为它们解决了SQL问题。您必须解决这个问题(使用绑定变量或者CURSOR_SHARING)
并确定共享池的合适尺寸。
4)In-memory Sort%低于95%(在OLTP中):在一个OLTP系统中,您一定不想做磁盘排序。设置初始化参数PGA_AGGREGATE_TARGET(或者SORT_AREA_SIZE)可有效地解决该问题。
5)Soft Parse%低于95%:正如在负载简档一节中所说的,软分析率低于80%意味着SQL没有重用,并需要作进一步调查。
6)Latch Hit低于99%通常是个大问题:找到特定的闩锁可帮助您解决该问题

【技巧】命中率是有关系统是否健康的重要晴雨表。每一天中命中率的大幅度增加或下降意味着有一个重要的变化需要调整。调查等待就像调查一个已经发生的事故,而调查命中
率的变化就像调查交叉路口的交通流量的变化。如果有些方面调整得不好,未来就会导致交通事故。通常情况下,OLTP的缓冲区和库缓存的命中率应当超过95%,但对于有许多全表
扫描的数据仓库而言可能会低一些。

共享池的统计信息:
Memory Usage %:正使用的共享池的百分比
%SQL with executions>1:共享池中的语句有n%执行的次数多于一次
%Memory for SQL w/exec>1:?

【附】来自ITPUB:Instance Efficiency Percentages (Target 100%)
Buffer Nowait %: 100.00 Redo NoWait %: 100.00
Buffer Hit %: 98.72 In-memory Sort %: 99.86
Library Hit %: 99.97 Soft Parse %: 99.92
Execute to Parse %: 89.09 Latch Hit %: 99.99
Parse CPU to Parse Elapsd %: 7.99 % Non-Parse CPU: 99.95

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

Shared Pool Statistics Begin End
Memory Usage %: 47.19 47.50
% SQL with executions>1: 88.48 79.81
% Memory for SQL w/exec>1: 79.99 73.52

Memory Usage %:对于一个已经运行一段时间的数据库来说,共享池内存使用率,应该稳定在75%-90%间,如果太小,说明Shared Pool有浪费,而如果高于90,说明共享池中有
争用,内存不足。这个数字应该长时间稳定在75%~90%。如果这个百分比太低,表明共享池设置过大,带来额外的管理上的负担,从而在某些条件下会导致性能的下降。如果
这个百分率太高,会使共享池外部的组件老化,如果SQL语句被再次执行,这将使得SQL语句被硬解析。在一个大小合适的系统中,共享池的使用率将处于75%到略低于90%的范
围内.
SQL with executions>1:执行次数大于1的sql比率,如果此值太小,说明需要在应用中更多使用绑定变量,避免过多SQL解析。在一个趋向于循环运行的系统中,必须认真考虑
这个数字。在这个循环系统中,在一天中相对于另一部分时间的部分时间里执行了一组不同的SQL语句。在共享池中,在观察期间将有一组未被执行过的SQL语句,这仅仅是因
为要执行它们的语句在观察期间没有运行。只有系统连续运行相同的SQL语句组,这个数字才会接近100%。
Memory for SQL w/exec>1:执行次数大于1的SQL消耗内存的占比。这是与不频繁使用的SQL语句相比,频繁使用的SQL语句消耗内存多少的一个度量。这个数字将在总体上与
% SQL with executions>1非常接近,除非有某些查询任务消耗的内存没有规律。在稳定状态下,总体上会看见随着时间的推移大约有75%~85%的共享池被使用。如果Statspack
报表的时间窗口足够大到覆盖所有的周期,执行次数大于一次的SQL语句的百分率应该接近于100%。这是一个受观察之间持续时间影响的统计数字。可以期望它随观察之间的时间
长度增大而增大。

小结:通过ORACLE的实例有效性统计数据,我们可以获得大概的一个整体印象,然而我们并不能由此来确定数据运行的性能。当前性能问题的确定,我们主要还是依靠下面的
等待事件来确认。我们可以这样理解两部分的内容,hit统计帮助我们发现和预测一些系统将要产生的性能问题,由此我们可以做到未雨绸缪。而wait事件,就是表明当前数据库
已经出现了性能问题需要解决,所以是亡羊补牢的性质。

5.4 首要等待事件
当您需要快速解决系统中出现的瓶颈时,STATSPACKK的这一部分信息可能是整个报表中最能揭示问题的部分。报表的这一部分显示了五个最重要的等待事件、等待事件的全部
列表以及后台的等待事件。如果TIMED_STATISTICS是true,那么事件将按照等待的时间排序;如果是false,那么事件将按照等待的数量排序(在Microsoft Windows平台的测试
中,它仍然是按照等待时间排序)。

下面是一些最常见的问题;同时给出了解释和可能的解决方案。这些部分非常重要,并且相当有价值!
【DB File Scattered Read】
DB File Scattered Read等待事件意味着等待与全表扫描或快速全索引扫描有关。因为全表扫描是被放入内存中进行的,通常情况下它不可能被放入连续的缓冲区中,所以就
散布在缓冲区的缓存中。该指数的数量过大说明缺少索引或者限制使用索引。这种情况也可能是正常的,因为执行全表扫描可能比索引扫描效率更高。当您看到这些等待时,需要
通过检查来确定全表扫描是否是必需的。尝试将较小的表放入缓存中,避免反复读取它们。将数据定位在磁盘系统上,这些系统有更多磁盘缓存或由OS文件系统缓存缓冲。
DB_FILE_MULTIBLOCK_READ_COUNT能够让全扫描更快(但它也会影响Oracle完成更多扫描)。您也可以将表和索引分区,以便只扫描其中一部分。缓慢的文件I/O(缓慢的磁盘)
也会导致这些等待。关联每个等待是P1,P2,P3=file,block,blocks的值。

【DB File Sequential Read】
DB File Sequential Read等待事件通常是指单一的数据块读操作(例如,索引的读取)。该值过大说明表的连接顺序很糟糕,或者使用了非先择性索引。当然,在一个高事务量
、做过较好调整的系统中,该数字应该是较大的(通常情况下)。应当将这种等待与STATSPACK报表中其他已知的问题联系起来,例如效率不高的SQL。通过检查确保索引扫描是必须
的,并确保多表连接的连接顺序。DB_CACHE_SIZE也是一个决定性因素,它将决定这些等待出现的频率;散列区域的连接引起的问题应当体现在PGA内存中,但它们会贪婪地侵占内存,
直至使用顺序读操作有大量的等待出现,或者它们也能揭示直接路径读/写操作出现的等待。如果数据分布在许多不同块里,范围扫描就要读取许多块(块内的密度会导致范围扫描
问题,反转键索引会产生范围扫描问题)。以排序的方式加载数据有助于范围扫描,还可以减少块读取的数量。分区也很有帮助,因为它可以排除一些块。注意非选择性索引,它们
会导致许多块读取。将数据定位在磁盘系统上,这些系统有更多磁盘缓存和/或由OS文件系统缓存缓冲。关联每个等待的是P1,P2,P3=file,block,blocks的值。

【Buffer busy Waits IDs及其含义】
当一个缓冲区以一种非共享方式被使用,或者正被读入缓存时,就会出现该种等待。Buffer busy wait不应该高于1%。检查缓冲区等待的统计信息部分(或者是V$WAITSTAT)
来确认等待的位置。与Segment Header、Undo Header、Undo Block、Data Block和Index Block相关的Buffer busy wait可以采用本节的解决方案。关联等待的是P1,P2,P3=file,
block,id的值(参见下面的列表)。有人争论说添加更多的ITL空间(initrans)(有关ITL的更多信息,参阅“在块级别调整和查看”)有助于缓解buffer busy wait,但下表显示的信息
说明:initrans在适当条件下会有帮助(依据相关的TX入列等待)。
原因代码(ID) 原因
<=8.0.6 >=8.1.6
0 0 正在读取块
1003 100 我们想对块执行NEW操作,但另一个会话(很有可能是重做)当前正在读取块
1007 200 我们想对块执行NEW操作,但其他人正在使用当前副本,因此我们必须等待他们完成
1010 230 试图在CR/CRX模式下获得缓冲区,但缓冲区上开始的修改还没有完成
1012 - 修改出现在SCUR或XCUR缓冲区上,但还没有完成
1012(dup.) 231 CR/CRX扫描找到CURRENT块,但缓冲区上开始的修改还没有完成
1013 130 另一个会话正在读取这个块,但又没有找到其他合适的块,因此我们等待读操作完成。这在假定缓冲区缓存死锁之后也可能发生。内核不能让
缓冲区处于某段时间内,并假设死锁。因此它读取块的CR版本。
1014 110 我们想让CURRENT块作为共享或专用块,但另一个会话正将它读入缓存,因此我们必须等待read()完成。
1014(复制) 120 我们想获得当前模式中的块,但其他人当前正在将它读入缓存。我们必须等待他们完成读操作。这在缓冲区查找过程中发生。
1016 210 会话需要SCUR或XCUR模式下的块。如果这是缓冲区交换或者会话处于离散的TX模式下,第一次会话等待;第二次,它作为死锁增加块,因此不会
表现为等待很长时间。在这种情况下,统计数据“交换死锁”会增加,我们产生“缓冲区死锁”等待事件的CPU
1016(复制) 220 在缓存查找缓存CURRENT副本的过程中,我们已经找到缓冲区,但有人将在保存为不兼容模式,因此我们必须等待


【Buffer Busy/Segment Header】
如果等待针对一个段的头信息,就增加空闲列表或空闲列表组的数量(也甚至可以帮助单个实例),或者扩大PCTUSED与PCTFREE之间的间隔。请使用自动段空间管理(Automatic
Segment Space Management,ASSM)。如果您使用了ASSM,Oracle将通过使用位图空闲列表来实现这一点。所以也就不需要再设置PCTUSED。

【Buffer Busy/Undo Header】
如果等待是针对一个撤消请求的头信息,则可以通过增加回滚段来解决它或者增加撤消区域。

【Buffer Busy/Undo Block】
如果它是针对一个撤消的数据块,应该更频繁(但不是过于频繁,否则您就会遇到“日志文件同步”等待)提交或使用更大回滚段或撤消区。您需要减少驱动一致性读操作的表上
的数据密集度,或者是增加DB_CACHE_SIZE。

【Buffer busy/Data Block】
如果等待是在一个数据块上,可以将数据移至另外一个数据块上,以避开这个热数据块,或者使用更小的数据块(以减少每个数据块的行数,让它变得不太热)。检查扫描非选择
性数据并修复导致这一问题的查询,或者给表分区以排除不必要的数据扫描。您也可以增加热块的initrans(其中用户同时访问相同的块)。不要把initrans设置得太高,因为每个
ITL空间它都占用24个字节,您只要提供同时访问相同DML块的用户数量所需的空间够了(通常是5就足够了)。当一个DML(插入/更新/删除)操作出现时,锁字节在块里设置,访问
记录的所有用户在改变时都必须检查ITL关于构建前面块图像的信息。Oracle数据库将信息写入数据块,包括所有对数据块的状态有兴趣的用户信息(感兴趣的事务列表,Interested
Transaction List,ITL)。
为减少这一区域的等待,您可以增加initrans的值,它将在数据块中创建空间来容纳多个ITL空间(用于多个DML用户访问)。在默认情况下是每个索引或数据块两个ITL空间。
您也可以在块存在的表上增加pctfree值。当指定的initrans预制的空间不够时,Oracle会使用pctfree中的空间来增加ITL空间,直到9i中maxtrans指定的数量为止(在10g中没有
设置maxtrans,默认值是255)。检查相关的TX4入列等待。

--关于initrans
create table DEPT2
(
deptno NUMBER(2),
deptname VARCHAR2(44)
)
tablespace USERS
pctfree 10
initrans 1
maxtrans 255
storage
(
initial 64K
minextents 1
maxextents unlimited
);

【Buffer Busy/Index Block】
使用反转键索引和/或更小的块(来减少每个块的行数)。注意反转键索引会放慢范围扫描,其中您想让数据继续位于相同的块。检查扫描非选择性索引(糟糕的代码/糟糕的
索引)。您可能需要重建索引或给索引分区以减少对它的访问。增加热块的initrans(不要太高,每个空间24个字节),其中多个用户访问相同的DML块(有关ITL的更多信息,
请参阅“在块级别调整和查看”这一部分)。检查相关的TX4入列等待。

【Latch Free】
闩锁是底层的队列机制(更加准确的名称应当是互斥机制),用于保护系统全局区(SGA)的共享内存结构。闩锁就像是内存上的锁,它可以快速的获取和释放。闩锁用于防止
对共享内存结构的并行访问。如果闩锁不可用,就会记录一次空闲闩锁丢失。绝大多数的闩锁问题都与使用绑定变量失败(库缓存闩锁和共享池闩锁)、生成重做问题(重做分配
闩锁)、缓存的争用问题(缓存lru链)以及缓存的热数据块(缓存链)有关。闩锁与bug也有关;如果您怀疑这个原因,就检查MetaLink的bug报告。当闩锁丢失率高于0.5%时,
您应当调查一下这个问题。

【Enqueue】
入列(enqueue)是保护共享资源的一种锁机制。这种锁保护共享资源,例如一条记录中的数据,以防止两个人同时更新相同的数据。它包含了一个队列排队的机制,即先进先出
(FIFO)。需要注意的是,Oracle的闩锁机制不是FIFO。
入列等待通常是指ST入列、HW入列以及TX4入列。
ST入列用于字典托管表空间的空间管理和分配。使用本地托管的表空间(Locally Managed Tablespaces,简称LMT),或者设法预留空间,或者至少保证有问题的管理字典表空间
有足够大的扩展空间。
HW入列用于一个高容量的段;手工分配扩展空间可以回避这种等待。
TX4是最常见的入列等待。TX4入列等待通常是3种问题中的某一种造成的结果。
第1种问题是唯一索引中的复制;您需要执行提交/回滚操作来释放队列。
第2种问题是对同一个位图索引段的多个更新操作。因为一个单一的位图索引段可能包含多个ROWIDS,当多个用户试图更新同一个段时,您需要提供一个提交或回滚操作以释放入列。
第3种问题也是最有可能的一种问题就是多个用户同时更新同一个数据块。当不同多个用户要在相同数据块的不同行上执行DML时,如果没有空闲的ITL空间,就会出现数据块级的
锁。您可以很简单地避免这种情况的出现,方法是通过增加initrans来创建更多的ITL空间,以及/或者通过增加表上的pctfree值来实现(这样Oracle就能够创建所需的ITL空间)。
您也可以使用更小的块尺寸,让块中的数据行更少,因此允许数据上更大的并发性。
也有其他两个不太普遍的TX4等待:等待准备好的语句和在索引(其中另外一个事务正在分裂索引块)中插入一行。
当用户要改变块中的相同记录时,结果就是TX6锁。最后,您不再获得TM锁(当您不将外键编入索引时,它们是表锁)时,确保仍然将它们编入索引以免产生性能问题。与等待
相关的是P1,P2,P3=lock type and mode,lockid1,lockid2的值(还有p2raw和p3raw,它们在十六进制中显示为p2/p3)。
在10g中,入列部分实际上清楚说明了队列的类型。例如,如果是TX Enqueue,现在它就会显示TX Transaction。如果这样还不够,它会进一步说明,甚至告诉您TX的类型。
例如,对于TX4而言,它会显示这是TX Transaction(数据行锁争用),然后给出Requests、Gets、Waits和其他一些有用信息。通过AWR报表的"Enqueue Activity"可以说明这一点。

【Log File Switch】
所有的提交操作均要等待日志文件切换(归档所需要的)或日志文件切换(不完整的chkpt)。确保归档的磁盘未满,并且速度足够快。由于I/O的原因,DBWR可能速度很慢。您
可能需要增加更多或更大的重做日志,并且如果DBWR存在问题,您可能需要增加数据库的写入器。

【Log Buffer Space】
发生改变时,改变的块被复制到日志缓冲区。如果日志缓冲区没有足够快地写入重做日志,就会导致log buffer space问题(备份)。当您一次提交大量数据时也会产生这个问题
(让它对于这些类型的事务而言太大)。
这种等待出现在您写日志缓冲区的速度已于LGWR写重做日志的速度,或者是日志切换太慢了,但通常不是因为日志缓冲区太小(尽管有时这也是原因之一)。为了解决这个问题,
可以增加日志文件的尺寸,或者使用更快的磁盘来写数据,但最终手段可以增加日志缓冲区的尺寸(大型系统中,经常有好几万兆字节的日志缓冲区)。您甚至可以考虑使用高速的
固态磁盘。

【Log File Sync】
用户改变记录时,记录被复制到日志缓冲区。当发生提交或回滚时,LGWR(日志写入器)将日志缓冲区冲洗(复制)到重做日志。提交将改变后的数据从日志缓冲区写入重做日志
的操作,以及确认写操作成功完成,这个过程为日志文件同步(log file sync)。为了减少日志文件的同步等待,就尝试一次提交更多的记录(如果可能的话一次提交50条记录,而不
是一次一条)。将重做日志放到更快的磁盘上,或者将重做日志放在不同的物理磁盘上,以减少LGWR归档时的影响。不要使用RAID5,因为应用程序的写操作很多时,它的速度太慢;
可以考虑使用直接I/O的文件系统或裸设备,它们在写信息时的速度很快。与等待相关的是P1,P2,P3=buffer#,unused,unused的值。

【Global Cache CR Request】
当使用多个实例(RAC/网络)时,当一个实例等待另一个实例的缓存的数据块时(通过互连发送),就会发生global cache CR request。这种等待说明,当前实例在局部缓存
中没有找到代码块的一致性读操作(CR)版本。如果数据块不在远程缓存中,那么这种等待之后就是db file sequentail read等待。调整SQL,它会产生大量从节点到节点的读操作。
尽量将使用相同代码块的用户放在相同的实例上,以便数据不会在实例间移动。有些非Oracle应用服务器会在节点间移动相同的进程,以便查找最快的节点(未意识到它们在节点
间移动相同的代码块)。将这些长进程固定到相同的节点。如果与较小缓存相关的缓慢I/O有问题,就要潜在增加本地缓存的大小。监控V$CR_BLOCK_SERVER,查看是否有像读取
UNDO段这样的问题。与等待相关的是P1,P2,P3=file,block,lenum的值(查看V$LOCK_ELEMENT,查找lock_element_addr将相同值作为lenum的行)。

【Log File Parallel Write】
将重做日志放在较快的磁盘上,不要使用RAID 5。将重做日志与可能让它们变慢的其他数据分离开,确保在热备份模式中没有保留表空间。与等待相关的是P1,P2,P3=files,
written to,blocks,requests的值。

【DB File Parallel Write】
固定和/或加速操作系统I/O和或文件系统I/O数据库写入数据库文件。与等待相关的是P1,P2,P3=files,blocks,requests/timeouts的值。

【Direct Path Read】
Oracle通常使用direct path reads直接将数据块读入PGA。它可用于排序、并行查询和提前读操作。这里的时间并不总是反映实际等待时间。这通常是文件I/O的问题(使用OS
工具查看一下是否有磁盘是I/O bound)。检查磁盘上而不是内存中的排序。使用异步I/O可以减少汪消耗时间,尽管它不会减少等待时间。与等待相关的是P1,P2,P3=file,start block,
number of blocks的值。

【Direct Path Write】
直接路径写操作通常用于直接加载操作、并行DML和写入未缓存的LOB(大对象)。这里的时间并不总是反映实际等待时间。这通常是文件I/O的问题(使用OS工具查看一下是否有
磁盘是I/O bound)。检查磁盘上的排序。使用异步I/O可在减少消耗时间,尽管它不会减少等待时间。与等待相关的是P1,P2,P3=file,start block,number of blocks的值。

【Async Disk I/O】
Oracle等待异步写操作完成,或等待写入的异步从属。问题可能是与DBWR(数据库写入器)、LGWR(日志写入器)、ARCH(归档器)和/或CKPT(检查点进程)有关的I/O问题,
但通常是某个文件I/O问题。

【Idle Events】
在下面的输出结果之后还有许多通常可以忽略掉的闲置等待事件。闲置事件通常列在每一部分的底部,包括了一些像SQL*Net与客户端的交互信息,以及其他的与后台有关的
计时信息等。闲置事件保存在stats$idle_event表中。下面列出了一些最常见的闲置事件(闲置事件的类型):
1)调度程序计时器(共享服务器闲置事件)
2)远程消息的锁管理器等待(RAC闲置事件)
3)获取管道(用户进程闲置事件)
4)pmon定时器(后台进程闲置事件)
5)PX闲置等待(并行查询闲置事件)
6)PX Deq:需要缓存(并行查询闲置事件)
7)PX Deq:执行Msg(并行查询闲置事件)
8)Rdbms ipc 消息(后台进程闲置事件)
9)Smon计时器(后台进程闲置事件)
10)从客户端返回的SQL*Net消息(用户进程闲置事件)
11)Virtual circuit状态(共享服务器闲置事件)

【常见的等待问题和潜在的解决方法】
等待问题 潜在的解决方法
Sequential Read 说明有很多索引读操作。请调整代码(尤其是连接)
Scattered Read 说明有很多全表扫描。请调整代码;缓存较小的表
Free Buffer 增加DB_CACHE_SIZE;缩短检查点;请调整代码
Buffer Busy/Segment Header 段头信息--增加空闲列表或空闲列表组
Buffer Busy/Data Block 数据块--分离“热”数据;使用反转键索引;使用较小的数据块。或者增加initrans和/或maxtrans
Buffer Busy/Undo Header 撤消头信息增加回滚段或区域
Buffer Busy/Undo Block 撤消块提交更多数据;更大的回滚段或区域
Latch Free 调查细节
Enqueue - ST 使用LMT或者预留较大的盘区
Enqueue - HW 预留高于最高水平线的盘区
Enqueue - TX4 增加initrans或使用表或索引上较小的数据块尺寸
Enqueue - TX6 修复让数据块不能共享的代码(使用v$lock查找)
Enqueue - TM 为外键建立索引;为重做日志使用更快的磁盘
Log Buffer Space 增加日志缓冲区;为重做日志使用更快的磁盘
Log File Switch 归档目标已满或速度太慢;增加或使用更大的重做日志
Log File Sync 一次提交更多的记录;为撤消日志使用更快的磁盘;使用裸设备
Write Complete Waits 增加数据库写入器;更多的检查点;缓存太小
Idle Event 忽略

【等待事件柱状图】
在Oracle 10g中也有等待事件柱状图(Wait Event Histogram),它显示属于各种区间(0-1ms、1-4ms、4-8ms、8-16ms、和32+ms)的等待的数量。表空间也为文件I/O提供
了这种类型的柱状图,显示是在大多数具有一些长等待的短等待上等待,还是在许多中等长度的等待上等待。

【注意】
5个最重要的等待事件从全局角度揭示了您的系统中最大的问题。它们几乎不会向您指出一个具体的问题。STATSPACK的其他部分或AWR报表将告诉您为什么会遇到这5个等待。

5.5 Oracle Bugs
也有与等待事件相关的Oracle bugs(未入档特性?)。解决这种行为的第一个诊断步骤是应用平台内可用的最新补丁集。应用这些补丁集可以避免大多数与故障相关的缓冲
区缓存问题。下表总结了与缓冲区缓存问题有关的最常见故障、可能的工作区和修复问题的补丁集。
故障 描述 工作区 修复
BUG:2079526 释放缓冲区等待/写操作密集的系统上可能的LRU闩锁争用 不可用 8174,9013,9201,10g
Bug:1967363 在8i/9i中增加索引块gets/“缓冲区缓存链”争用 不可用 8173,9013,9201,10g
Bug:2268098 如果您将缓冲池压缩某个数量,后来又要将共享池增加这个数量 不可用 9014,9201,10g
,这种尝试会以“内存不足”错误而失败

5.6 Oracle影子进程的生命周期
下面是一个很好的Oracle影子进程的生命周期的状态列表。它是从Oracle Doc ID61998.1获得,并提供了Oracle内部在不到1秒钟的时间内所发生的事情:

状态 说明
IDLE 等待从客户端返回的SQL*NET消息(等待用户)。接收SQL*Net关于解析/执行一个语句的请求。
ON CPU 解码SQL*Net的数据包
WAITING 等待闩锁的释放以获得库缓存的闩锁。获得库缓存的闩锁。
ON CPU 扫描共享池以获得SQL语句,找到匹配项,释放闩锁。设置与共享游标的链接,等等,并开始执行。
WAITING 等待数据库文件的顺序读取;我们需要一个不在缓存中的数据块(等待I/O)
ON CPU 从磁盘读取数据块完成。继续执行。使用第一行数据建立SQL*Net数据包,并发送给客户端
WAITING 等待从客户端返回的SQL*Net消息,以确认数据包已经被接受
IDLE 等待从客户端返回的下一条SQL*Net消息

【注】:影子进程(相对用户进程而言)是指服务器进程

5.7 RAC等待事件和互连统计数据
如果您运行RAC,下面的报表就会列出RAC事件(多个实例)。如上所述,需要为每个实例运行STATSPACK或AWR报表。对于STATSPACK而言,您需要运行要监控的每个节点
上的STATSPACK.SNAP程序和spreport.sql脚本,以便与其他实例比较。最好的比较报表是来自访问相同数据库的另一个节点的报表。单个实例调整应该在调整通过集群互连
通信的进程之前完成,记住这一点非常重要。换句话说,在将单个实例模式中的系统移动到RAC之前调整它。
下面简要列举了您可能遇到的一些首要等待事件。要注意的首要全局缓存(gc)等待事件包括:
1)gc current block busy :当实例请求CURR数据块(要完成某个DML)和要传输的代码块正在使用时会出现这种情况。
2)gc buffer busy :当会话必须等待资源上正在进行的操作完成时出现的等待事件,因为数据块正在使用。
3)gc buffer busy :当进程必须等待块变得可用时发生的等待事件,因为另一个进程正在获取这个块的资源。
4)gc cr request :当实例请求CR数据块以及要传输的数据块没有到达请求实例时发生。这是最常见的情况,通常是因为SQL没有调整好,而许多索引块在实例间来回移动。

访问另一个节点上的远程缓存几乎总是比访问磁盘更快(假设有足够的互连,并且没有互连饱和。

5.8 首要的SQL语句
在AWR报表中有许多首要SQL部分,它们包括:
1)按Elapsed Time排序的SQL
2)按CPU Time排序的SQL
3)按Gets排序的SQL
4)按Reads排序的SQL
5)按Executions排序的SQL
6)按Parse Calls排序的SQL
7)按Sharable Memory排序的SQL
8)按Version Count排序的SQL
9)按Cluster Wait Time排序的SQL
10)SQL Text的完整列表
【技巧】调整首要的25个缓冲区get操作和首要的25个磁盘get操作的查询,将可对系统的性能产生5%到5000%的增益。STATSPACK报表的SQL部分将告诉您可能首先需要调整的查询
是哪些。SQL中前10条语句不应当多于缓冲区读操作和磁盘读操作语句的10%。

5.9 实例活动统计数据
在SQL语句列表之后,您将看到从V$SYSSTAT视图获得的统计信息变化的列表,标题为Instance Activity Stats。V$SYSSTAT视图的统计信息将有助于识别在前面的章节中没有反应出
来的性能问题。
【在实例统计数据部分中请注意以下内容】
1)比较在磁盘上执行的排序数量和在内存中执行的排序数量;增加PAG_AGGREGATE_TARGET(或者以前版本中的SORT_AREA_SIZE)的值来减少磁盘上的排序。
2)如果磁盘的读操作数量很高,则表明您可能执行了全表扫描。如果目前存在对大量的对较大表的全表扫描,就应当评估最常用的查询,并通过使用索引来减少这种低效率
的事情发生
3)大量的一致性读操作意味着使用了过多的索引或使用了非选择性索引。
4)如果观察到的脏读缓冲区数量高于所请求的空闲缓冲区数量(超过5%),那么说明DB_CACHE_SIZE可能太小,或者您没有建立足够多的检查点。
5)如果叶结点的分裂数量很高,可以考虑重建已增长或已碎片化的索引。
【技巧】如果大量的排序操作是在磁盘上进行的(超过参加排序的记录总数的1%-5%),您可能需要增加和排序有关的初始化参数。

【需要考虑的关键问题】
1)Consistent gets:没有使用SELECT FOR UPDATE子句的查询在缓存中访问的数据块数量。这个统计信息的值加上db block gets统计信息的值就是逻辑读操作(内存
中缓存的所有读操作)。它们通常是数据块的当前(CURRENT)版本,也可以是一致性读操作(consistent read,CR)版本。
2)DB block gets:INSERT、UPDATE、DELETE或者SELECT FOR UPDATE语句在缓存中访问的数据块数量。它们是数据块的当前版本。发生改变时,它们反映在“db block changes”值中。
3)Physical reads:没有从缓存读取的数据块数量。可以从磁盘、OS缓存或磁盘缓存读取、以满足SELECT、SELECT FOR UPDATE、INSERT、UPDATE或DELETE语句。

将consistent gets加上db block gets,即可得到逻辑读操作的数量(内存读操作)。使用下面的公式,您就能计算出数据缓存的命中率:
Hit Ratio=(Logical Reads - Physical Reads)/ Logical Reads

4)Dirty buffers inspected:从LRU列表中清除掉的脏读(经过修改的)数据缓冲区的数量。这里的值说明DBWR的数量不够。您可以通过增加更多的DBWR来获得增益。
注:“Dirty buffers inspected”与【OCP笔记:监视与管理内存】里提到的“检查点队列”是一样的吗?有什么区别?
【技巧】如果观察到的脏读缓冲区的数量超过0,可以考虑增加DBWR的数量。
【附】脏数据从LRU列表中老化,A value here indicates that the DBWR is not keeping up。如果这个值大于0,就需要考虑增加DBWRs。
dirty buffers inspected: This is the number of dirty (modified) data buffers that were aged out on the LRU list.
You may benefit by adding more DBWRs.If it is greater than 0, consider increasing the database writes.
5)Enqueue timeouts:请求入列的次数(锁定)以及所请求的特定队列不可用的次数。如果这个统计信息大于0,就需要调查锁定的问题。
6)Free buffer inspected:由于是脏读数据、被固定或者正忙等原因而跳过的缓冲区数量。如果您从统计中减去这些值(观察到的脏读数据量和被固定的缓冲区数量),
就将剩下由于闩锁的争用而无法重用的缓冲区数量。如果数量很大的话,就很好地说明缓冲区缓存太小了。
【附】这个值包含dirty,pinned,busy的buffer区域,如果free buffer inspected - dirty buffers inspected - buffer is pinned count的值还是比较大,
表明不能被重用的内存块比较多,这将导致latch争用,需要增大buffer cache
7)Parse count:一条SQL语句被解析的次数(总次数)。
8)Recursive calls:数据库中递归调用的数量。有些原因将导致这种类型的调用,例如,字典缓存中的数据丢失,动态存储的扩展 以及PL/SQL语句在执行等原因。通常
情况下,如果每个进程中的递归调用数量大于4,您应当检查数据字典缓存的命中率,以及是否有表或索引的范围过大。除非大量使用了PL/SQL,否则在用户调用中,递归
调用所占的比例应当低于10%或更低。
9)Redo size:写入重做日志中、以字节为单位的重做信息的数量。该信息将有助于确定重做日志的大小。
10)Sort(disk):无法在内存中执行的排序的数量,必须在临时表空间中创建一个临时段以供排序使用。该统计信息除以内存中排序的数量不应高于5%。如果高于这个值,您
应当增加init.ora文件中SORT_AREA_SIZE或者PGA_AGGREGATE_TARGET的值。
11)Sorts(memory):在内存中执行排序的数量。
12)Sorts(rows):参加排序的数据行的数量。
【技巧】sorts(disk)的统计数据除以sorts(memory)应当不高于1-5%。如果高于该值,您应当在初始化文件中增加PGA_AGGREGATE_TARGET(或者SORT_AREA_SIZE)的数量(设定
可以使用的物理内存的大小)。请记住SORT_AREA_SIZE分配的内存是面向每个用户的,而PGA_AGGREGATE_TARGET分配的内存是面向所有会话的。
13)table fetch by rowid:通过使用ROWID访问的数据行的数量。ROWID来自一个索引,或者一个where rowid=语句。该数值很高通常意味着就获取数据的操作而言,应用程序
调整得不错。
14)Table fetch continued row:获取的数据行的数量,可以是链化数据行,也可以是迁移的数据行。
【技巧】如果前一个参数说明的是链化数据行,则应当尽可能快的解决掉这个问题。如果有大量的数据行相链接,会引起性能的严重劣化。
【附】这是发生行迁移的行。当行迁移的情况比较严重时,需要对这部分进行优化。
检查行迁移的方法:
1) 运行$ORACLE_HOME/rdbms/admin/utlchain.sql
2) analyze table table_name list chained rows into CHAINED_ROWS
3) select * from CHAINED_ROWS where table_name='table_name';
清除的方法:
方法1:create table table_name_tmp as select * from table_name where rowed in (select head_rowid from chained_rows);
Delete from table_name where rowed in (select head_rowid from chained_rows);
Insert into table_name select * from table_name_tmp;
方法2:create table table_name_tmp select * from table_name ;
truncate table table_name
insert into table_name select * from table_name_tmp
方法3:用exp工具导出表,然后删除这个表,最后用imp工具导入这表
方法4:alter table table_name move tablespace tablespace_name,然后再重新表的索引
上面的4种方法可以用以消除已经存在的行迁移现象,但是行迁移的产生很多情况下时由于PCT_FREE参数设置的太小所导致,所以需要调整PCT_FREE参数的值。
15)table scans(long tables):大于_SMALL_TABLE_THRESHOLD(隐藏的),并且没有使用CACHE子句的表。在Oracle 10g和Oracle 9i中,_SMALL_TABLE_THRESHOLD的默认值是2%。
如果不仔细评估它的影响,修改_SMALL_TABLE_THRESHOLD参数会非常危险。因为它将影响所访问的表,所以突然大幅度增加它的值是不明智的,因为它将引起数据块失效得更快
并降低您的命中率。在Oracle中,【这个参数是数据库块的数量】,等于这个数量就认为表太小了。这个阈值用来确定直接读操作的切换点。比它小的所有对象都不值得执行
直接读操作,因此会从缓冲区缓存中读取。如果每个事务表扫描的数量都大于0,您可能要检查应用程序SQL语句,并试着增加索引的使用。
【注意】表扫描(long tables)参数在Oracle 10g(小于缓冲区缓存的2%),Oracle 9i(小于缓冲区缓存的2%),Oracle 8i(少于20个数据块)和Oracle7(少于5个数据块)
中的含义各不相同。
【技巧】如果执行了全表扫描,结果可能会造成严重的性能问题,并且数据命中率将会歪曲。需要鉴定这些表是否创建或使用了合适的索引。
【附】longtables就是表的大小超过buffer buffer* _SMALL_TABLE_THRESHOLD的表。
如果一个数据库的大表扫描过多,那么db file scattered read等待事件可能同样非常显著。
如果table scans (long tables)的per Trans值大于0,你可能需要增加适当的索引来优化你的SQL语句
16)table scan(short tables)在10g中,short table是比缓冲区缓存的2%更短的表。Oracle更喜欢在short table上进行全表扫描。
【附】short tables是指表的长度低于buffer chache 2%的表。这些表将优先使用全表扫描。一般不使用索引。
_SMALL_TABLE_THRESHOLD值的计算方法如下(9i,8K): (db_cache_size/8192)*2%。
注意:_SMALL_TABLE_THRESHOLD参数修改是相当危险的操作

5.10 表空间和文件I/O的统计数据
如果您的文件没有采用合适的I/O,在高活动量时就会遇到性能瓶颈。
如果“Av Rd(ms)”列高于14ms(假定相当数量的读操作已经完成),您可能需要调查,因为大多数磁盘至少会提供这种性能。如果这一列显示1000ms或更多,您也许遇到了某种
类型的I/O问题。如果它显示为######,那么您就遇到了某种严重的I/O问题(这也可能是格式问题,但完成相当数量的读操作时,大于1000就有问题)。
对于在磁盘上缓存了许多内存的磁盘而言,磁盘(在上面完成大量读操作)I/O时间通常少于1ms。
在init.ora中可以设置的参数DB_FILE_MULTIBLOCK_READ_COUNT将有助于提高读取的时间。DB_FILE_MULTIBLOCK_READ_COUNT参数控制在全表扫描时,一次I/O中读入的数据块的数量。
这将减少扫描一张表所需的I/O数量,从而提高了全表扫描的性能。但是,设置DB_FILE_MULTIBLOCK_READ_COUNT参数的结果是优化器可能会执行更多的全表扫描,所以您也需要将
OPTIMIZER_INDEX_COST_ADJ设置为一个数值,例如10,来消除这个问题并驱动索引的使用。

输出结果中一些列的描述:
tablespace 表空间的名称
Reads 从数据文件检索数据的物理读操作的次数
Av Blks/Rd 从数据文件读取数据块的读操作的平均次数
Writes 对数据文件执行写操作的次数

在表空间I/O统计数据后面是文件I/O统计数据的详细分类。这是一个非常精细的观察数据文件之间I/O分布情况的工具。如果一个数据文件获得了主要的读和写操作,那么您
就可以通过在分离的磁盘上创建多个文件,或者将数据文件强制分布在多个磁盘上来提高性能。同样,不要使用RAID5,否则您的写操作将显得非常缓慢。

【技巧】如果一个物理磁盘上的物理读操作的数量很高,合理平衡数据将有可能提高性能。

5.11 段统计数据
Oracle在Oracle 9i中提供的新的数据字典视图之一是V$SEGMENT_STATISTICS视图。这个视图很快成为了DBA的最爱。现在,Oracle 10g使用段统计数据继续推广这种方法。
下面是Oracle 10gR2中显示的AWR报表部分:
1)按逻辑读分类的(Segments by Logical Reads)
2)按物理读分类的段(Segments by Physical Reads)
3)按Row Lock Waits分类的段(Segments by Row Lock Waits)
【附】当一个进程予在正被其它进程锁住的数据行上获得排它锁时发生这种等待。这种等待经常是由于在一个有主键索引的表上做大量INSERT操作。
4)按ITL Waits分类的段(Segments by ITL Waits)
5)按Buffer Busy Waits分类的段(Segments by Buffer Busy Waits)
6)按Global Cache Buffer Busy分类的段(Segments by Global Cache Buffer Busy)
7)按接收到的CR块分类的段(Segments by CR Blocks Received)
8)按接收到的当前块分类的段(Segments by Current Blocks Received)
【技巧】段统计数据是性能问题定位到指定表、索引或分区的好方法。Oracle 10gR2在AWR报表和STATSPACK中包含了许多段级别的统计数据。
select *
from dba_hist_seg_stat t
where t.snap_id=195
order by t.logical_reads_total desc;

5.12 顾问程序的统计数据(Advisory Statistics)
1)Instance Recovery Stats :实例恢复统计数据
2)Buffer Pool Advisory :数据缓冲区顾问
3)PGA Aggr Summary :PGA Aggr 概述
4)PGA Aggr Target Stats :PGA Aggr目标统计数据
5)PGA Aggr Target Histogram :PGA Aggr目标统计柱状图
6)PGA Memory Advisory :PGA内存顾问
7)Shared Pool Advisory :共享池顾问
8)SGA Target Advisory :SGA目标顾问
9)Streams Pool Advisory :流池顾问
10)Java Pool Advisory :JAVA池顾问

5.13 撤消统计数据
【附】
Undo从9i开始,回滚段一般都是自动管理的,一般情况下,这里我们不需要太重点关注。
在这里,主要关注pct waits,如果出现比较多的pct waits,那就需要增加回滚段的数量或者增大回滚段的空间。另外,观察一下各个回滚段使用的情况,比较理想的是
各个回滚段上Avg Active比较均衡。
在oracle 9i之前,回滚段时手工管理的,可以通过指定optimal值来设定一个回滚段收缩的值,如果不设定,默认也应当为initial+(minextents-1)*next extents ,
这个指定的结果,就是限制了回滚段不能无限制的增长,当超过optimal的设定值后,在适当的时候,oracle会shrinks到optimal大小。但是9i之后,undo一般都设置为auto模式,
在这种模式下,我们无法指定optimal值,好像也没有默认值,所以无法shrinks,回滚段就会无限制的增长,一直到表空间利用率达到为100%,如果表空间设置为自动扩展的方式,
这种情况下,就更糟糕,undo将无限制的增长。在这里,我们也可以看到,shrinks的值为0,也就是说,从来就没收缩过。

5.14 闩锁统计数据
闩锁是底层的队列机制(更加准确的名称应当是互斥机制),用于保护系统全局区(SGA)的共享内存结构。闩锁就像是内存上的锁,它可以快速的获取和释放,大约占用
32个字节。闩锁被用于防止对共享内存结构的并行访问。如果闩锁不可用,就会记录一次闩锁丢失。绝大多数的闩锁问题都与没有使用绑定变量(库缓存闩锁)、重做生成问题
(重做分配闩锁)、缓存争用问题(缓存lru链),以及缓存热数据块(缓存链)有关。闩锁与BUG也有关:如果您怀疑是这个原因的话,就检查MetaLink。当闩锁丢失率高于
0.5%时,您应当调查一下这个问题。在Oracle 10gR2中,可以在某种程序上共享缓冲区缓存链(Cache Buffers Chains,CBC)闩锁。
存在两种类型的闩锁:愿意等待的闩2锁(例如库缓存闩锁)和不愿意等待的闩锁(例如重做复制闩锁)。愿意等待的闩锁会一直尝试去获得一个闩锁。如果没有可用的闩锁,
它就快速再次请求闩锁。如果它持续这样做的次数达到了初始化参数_SPIN_COUNT指定的值(注意这样会占用CPU),它将进入休眠状态。它将等待一段时间,什么也不执行,然后
在一厘秒(百分之一秒)后苏醒过来。它将这样重复再次。然后它再重复同样的进程,快速请求直至达到_SPIN_COUNT然后休眠两倍的时间(百分之二秒)。它将一直重复下去。
所以它的模式是1,1,2,2,4,4,等等。它将持续重复这样的动作,直到获得了闩锁。每次闩锁休眠时,它就生成一个闩锁休眠等待。一个愿意等待的闩锁的示例就是库缓存闩锁。
有些闩锁不愿意等待。这种类型的闩锁不会等待出现可用的闩锁。它立即报告超时,然后再尝试获得闩锁。一个不愿意等待的闩锁的示例就是重做复制闩锁。它产生V$LATCH视图
的immediate_gets和immediate_misses列的信息,并反映在STATSPACK报表中。这些闩锁的命中率应当接近99%,并且丢失率永远也不就当超过1%。
【报表中的常术语及定义】:
Latch Name 闩锁的名称
Gets 对闩锁的愿意等待请求且获得闩锁的次数
Misses 对闩锁的愿意等待请求但未获得闩锁的次数
Sleeps 对闩锁的愿意等待请求反复失败,直至超过阈值,进程进入休眠的请求次数。休眠的次数可能高于丢失的次数。进程在获得闩锁前可能会休眠许多次
NoWaitMisses 对闩锁发生的立即(不愿意等待)请求但并未获得闩锁的次数
【常见的闩锁问题和可能的解决方案】:
闩锁的问题 可能的解决办法
Library cache 使用绑定变量;调整shared_pool_size参数
Shared pool 使用绑定变量;调整shared_pool_size参数
Redo copy 增加_log_simultaneous_copies参数
Row cache objects 增加共享池
Cache buffers chain 增加_DB_BLOCK_HASH_BUCKETS参数或让它素数化
Cache buffers lru chain 使用多个缓冲区共享池,或修复导致过多读操作的查询

【技巧】闩锁就像部分内存(或者内存缓冲区)上的锁。如果闩锁的命中率低于99%,这将是个严重的问题,因为即使是用于获得内存的闩锁本身也无法得到。

【附】
Latch是一种低级排队机制,用于防止对内存结构的并行访问,保护系统全局区(SGA)共享内存结构。Latch是一种快速地被获取和释放的内存锁。如果latch不可用,
就会记录latch free miss 。
有两种类型的Latch:willing to wait和(immediate)not willing to wait。
对于愿意等待类型(willing-to-wait)的latch,如果一个进程在第一次尝试中没有获得latch,那么它会等待并且再尝试一次,如果经过_spin_count次争夺不能获得latch,
然后该进程转入睡眠状态,百分之一秒之后醒来,按顺序重复以前的步骤。在8i/9i中默认值是_spin_count=2000。睡眠的时间会越来越长。
  对于不愿意等待类型(not-willing-to-wait)的latch,如果该闩不能立即得到的话,那么该进程就不会为获得该闩而等待。它将继续执行另一个操作。
  大多数Latch问题都可以归结为以下几种:
  没有很好的是用绑定变量(library cache latch和shared pool cache)、重作生成问题(redo allocation latch)、缓冲存储竞争问题(cache buffers LRU chain),
以及buffer cache中的存在"热点"块(cache buffers chain)。
另外也有一些latch等待与bug有关,应当关注Metalink相关bug的公布及补丁的发布。
当latch miss ratios大于0.5%时,就需要检查latch的等待问题。
如果SQL语句不能调整,在8.1.6版本以上,可以通过设置CURSOR_SHARING = force 在服务器端强制绑定变量。设置该参数可能会带来一定的副作用,可能会导致执行计划不优,
另外对于Java的程序,有相关的bug,具体应用应该关注Metalink的bug公告。
下面对几个重要类型的latch等待加以说明:
1) latch free:当‘latch free’在报告的高等待事件中出现时,就表示可能出现了性能问题,就需要在这一部分详细分析出现等待的具体的latch的类型,然后再调整。
2) cache buffers chain:cbc latch表明热块。为什么这会表示存在热块?为了理解这个问题,先要理解cbc的作用。ORACLE对buffer cache管理是以hash链表的方式来实现的
(oracle称为buckets,buckets的数量由_db_block_hash_buckets定义)。cbc latch

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/7901922/viewspace-1060020/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/7901922/viewspace-1060020/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值