请通过浏览器功能收藏网页

Oracle运行缓慢 内存分析参数说明汇总(二) 数据库问题

发布时间:2018-08-07 11:08:32  作者:本站编辑  来源:本站原创  浏览次数:
www.javainfo.com.cn 上干货 欢迎收藏

 8. Db file sequential read


这个等待事件在实际生产库也很常见,当Oracle 需要每次I/O只读取单个数据块这样的操作时,会产生这个等待事件。最常见的情


况有索引的访问(除IFFS外的方式),回滚操作,以ROWID的方式访问表中的数据,重建控制文件,对文件头做DUMP等。

 这里的sequential也并非指的是Oracle 按顺序的方式来访问数据,和db file scattered read一样,它指的是读取的数据块在内


存中是以连续的方式存放的。

 这个等待事件有三个参数:

File#: 要读取的数据块锁在数据文件的文件号。

Block#: 要读取的起始数据块号。

Blocks: 要读取的数据块数目(这里应该等于1)。

 9. Db file single write


这个等待事件通常只发生在一种情况下,就是Oracle 更新数据文件头信息时(比如发生Checkpoint)。

 当这个等待事件很明显时,需要考虑是不是数据库中的数据文件数量太大,导致Oracle 需要花较长的时间来做所有文件头的更新


操作(checkpoint)。

 这个等待事件有三个参数:

File#: 需要更新的数据块所在的数据文件的文件号。

Block#: 需要更新的数据块号。

Blocks: 需要更新的数据块数目(通常来说应该等于1)。

 10. Direct path read


这个等待事件发生在会话将数据块直接读取到PGA当中而不是SGA中的情况,这些被读取的数据通常是这个会话私有的数据,所以不


需要放到SGA作为共享数据,因为这样做没有意义。这些数据通常是来自于临时段上的数据,比如一个会话中SQL的排序数据,并行


执行过程中间产生的数据,以及Hash Join,merge join产生的排序数据,因为这些数据只对当前的会话的SQL操作有意义,所以不


需要放到SGA当中。

 当发生direct path read等待事件时,意味着磁盘上有大量的临时数据产生,比如排序,并行执行等操作。或者意味着PGA中空闲


空间不足。

 这个等待事件有三个参数:

Descriptor address:  一个指针,指向当前会话正在等待的一个direct read I/O。

First dba: descriptor address 中最旧的一个I/O数据块地址。

Block cnt: descriptor address上下文中涉及的有效的buffer 数量。

 11. Direct path write

这个等待事件和direct path read 正好相反,是会话将一些数据从PGA中直接写入到磁盘文件上,而不经过SGA。

 这种情况通常发生在:

 使用临时表空间排序(内存不足)

 数据的直接加载(使用append方式加载数据)

 并行DML操作。

 这个等待事件有三个参数:

Descriptor address: 一个指针,指向当前会话正在等待的一个direct I/O.

 First dba: descriptor address 中最旧的一个I/O数据块地址。

Block cnt: descriptor address 上下文中涉及的有效地 buffer 数量。

 12. Enqueue

 Enqueue 这个词其实是lock 的另一种描述语。

 当我们在AWR 报告中发现长时间的enqueue 等待事件时,说明数据库中出现了阻塞和等待,可以关联AWR报告中的enqueue 


activity部分来确定是哪一种锁定出现了长时间等待。

 这个等待事件有2个参数:

Name: enqueue 的名称和类型。

Mode: enqueue的模式。

 可以使用如下SQL 查看当前会话等待的enqueue名称和类型:

/* Formatted on 6/27/2011 1:31:48 PM (QP5 v5.114.809.3010) */

 SELECT  CHR (TO_CHAR (BITAND (p1, -16777216)) / 16777215)

          || CHR (TO_CHAR (BITAND (p1, 16711680)) / 65535)

            "Lock",

          TO_CHAR (BITAND (p1, 65535)) "Mode"

  FROM  v$session_wait

  WHERE  event = 'enqueue';

 13. Free buffer waits

当一个会话将数据块从磁盘读到内存中时,它需要到内存中找到空闲的内存空间来存放这些数据块,当内存中没有空闲的空间时,


就会产生这个等待;除此之外,还有一种情况就是会话在做一致性读时,需要构造数据块在某个时刻的前映像(image),此时需要


申请内存来存放这些新构造的数据块,如果内存中无法找到这样的内存块,也会发生这个等待事件。

 当数据库中出现比较严重的free buffer waits等待事件时,可能的原因是:

 (1)data buffer 太小,导致空闲空间不够

 (2)内存中的脏数据太多,DBWR无法及时将这些脏数据写到磁盘中以释放空间

 这个等待事件包含2个参数:

File#: 需要读取的数据块所在的数据文件的文件号。

Block#: 需要读取的数据块块号。

 14. Latch free


在10g之前的版本里,latch free 等待事件代表了所有的latch等待,在10g以后,一些常用的latch事件已经被独立了出来:

11gr2:

 SQL> select name from v$event_name where name like 'latch%' order by 1;

 NAME

 -----------

 latch activity

 latch free

 latch: Change Notification Hash table latch

 latch: In memory undo latch

 latch: MQL Tracking Latch

 latch: PX hash array latch

 latch: Undo Hint Latch

 latch: WCR: processes HT

 latch: WCR: sync

 latch: cache buffer handles

 latch: cache buffers chains

 latch: cache buffers lru chain

 latch: call allocation

 latch: change notification client cache latch

 latch: checkpoint queue latch

 latch: enqueue hash chains

 latch: gc element

 latch: gcs resource hash

 latch: ges resource hash list

 latch: lob segment dispenser latch

 latch: lob segment hash table latch

 latch: lob segment query latch

 latch: messages

 latch: object queue header operation

 latch: parallel query alloc buffer

 latch: redo allocation

 latch: redo copy

 latch: redo writing

 latch: row cache objects

 latch: session allocation

 latch: shared pool

 latch: undo global data

 latch: virtual circuit queues

已选择33行。

10gr2 rac:

 sys@ORCL> select name from v$event_name where name like 'latch%' order by 1;

 NAME

 -------------

 latch activity

 latch free

 latch: Change Notification Hash table latch

 latch: In memory undo latch

 latch: KCL gc element parent latch

 latch: MQL Tracking Latch

 latch: Undo Hint Latch

 latch: cache buffer handles

 latch: cache buffers chains

 latch: cache buffers lru chain

 latch: checkpoint queue latch

 latch: enqueue hash chains

 latch: gcs resource hash

 latch: ges resource hash list

 latch: library cache

 latch: library cache lock

 latch: library cache pin

 latch: messages

 latch: object queue header heap

 latch: object queue header operation

 latch: parallel query alloc buffer

 latch: redo allocation

 latch: redo copy

 latch: redo writing

 latch: row cache objects

 latch: session allocation

 latch: shared pool

 latch: undo global data

 latch: virtual circuit queues

 29 rows selected.

  所以latch free 等待事件在10g以后的版本中并不常见,而是以具体的Latch 等待事件出现。

 这个等待事件有三个参数:

Address: 会话等待的latch 地址。

Number: latch号,通过这个号,可以从v$latchname 视图中找到这个latch 的相关的信息。

SQL> select * from v$latchname where latch#=number;

 Tries: 会话尝试获取Latch 的次数。

 15. Library cache lock


这个等待事件发生在不同用户在共享中由于并发操作同一个数据库对象导致的资源争用的时候,比如当一个用户正在对一个表做DDL 


操作时,其他的用户如果要访问这张表,就会发生library cache lock等待事件,它要一直等到DDL操作完成后,才能继续操作。

 这个事件包含四个参数:

Handle address: 被加载的对象的地址。

Lock address: 锁的地址。

Mode: 被加载对象的数据片段。

Namespace: 被加载对象在v$db_object_cache 视图中namespace名称。

10gr2 rac:

 sys@ORCL> select name from v$event_name where name like 'library%' order by 1;

 NAME

 -------------

 library cache load lock

 library cache lock

 library cache pin

 library cache revalidation

 library cache shutdown

   16. Library cache pin


这个等待事件和library cache lock 一样是发生在共享池中并发操作引起的事件。通常来讲,如果Oracle 要对一些PL/SQL 或者视


图这样的对象做重新编译,需要将这些对象pin到共享池中。如果此时这个对象被其他的用户特有,就会产生一个library cache 


pin的等待。

 这个等待事件也包含四个参数:

Handle address: 被加载的对象的地址。

Lock address: 锁的地址。

Mode: 被加载对象的数据片段。

Namespace: 被加载对象在v$db_object_cache 视图中namespace名称。

 17. Log file parallel write


后台进程LGWR 负责将log buffer当中的数据写到REDO 文件中,以重用log buffer的数据。如果每个REDO LOG组里面有2个以上的成


员,那么LGWR进程会并行地将REDO 信息写入这些文件中。

 如果数据库中出现这个等待事件的瓶颈,主要的原因可能是磁盘I/O性能不够或者REDO 文件的分布导致了I/O争用,比如同一个组


的REDO 成员文件放在相同的磁盘上。

 这个等待事件有三个参数:

Files: 操作需要写入的文件个数。

Blocks: 操作需要写入的数据块个数。

Requests:操作需要执行的I/O次数。

 18. Log buffer space


当log buffer 中没有可用空间来存放新产生的redo log数据时,就会发生log buffer space等待事件。如果数据库中新产生的redo 


log的数量大于LGWR 写入到磁盘中的redo log 数量,必须等待LGWR 完成写入磁盘的操作,LGWR必须确保redo log写到磁盘成功之


后,才能在redo buffer当中重用这部分信息。

 如果数据库中出现大量的log buffer space等待事件,可以考虑如下方法:

 (1)增加redo buffer的大小。

 (2)提升磁盘的I/O性能

19. Log file sequential read


这个等待事件通常发生在对redo log信息进行读取时,比如在线redo 的归档操作,ARCH进程需要读取redo log的信息,由于redo 


log的信息是顺序写入的,所以在读取时也是按照顺序的方式来读取的。

 这个等待事件包含三个参数:

Log#: 发生等待时读取的redo log的sequence号。

Block#: 读取的数据块号。

Blocks: 读取的数据块个数。

 20. Log file single write


这个等待事件发生在更新redo log文件的文件头时,当为日志组增加新的日志成员时或者redo log的sequence号改变时,LGWR 都会


更新redo log文件头信息。

 这个等待事件包含三个参数:

Log#: 写入的redo log组的编号。

Block#:写入的数据块号。

Blocks:写入的数据块个数。

 21. Log file switch(archiving needed)


在归档模式下,这个等待事件发生在在线日志切换(log file switch)时,需要切换的在线日志还没有被归档进程(ARCH)归档完


毕的时候。 当在线日志文件切换到下一个日志时,需要确保下一个日志文件已经被归档进程归档完毕,否则不允许覆盖那个在线日


志信息(否则会导致归档日志信息不完整)。

 出现这样的等待事件通常是由于某种原因导致ARCH 进程死掉,比如ARCH进程尝试向目的地写入一个归档文件,但是没有成功(介


质失效或者其他原因),这时ARCH进程就会死掉。 如果发生这种情况,在数据库的alert log文件中可以找到相关的错误信息。

 这个等待事件没有参数。

 22. Log file switch(checkpoint incomplete)


当一个在线日志切换到下一个在线日志时,必须保证要切换到的在线日志上的记录的信息(比如一些脏数据块产生的redo log)被


写到磁盘上(checkpoint),这样做的原因是,如果一个在线日志文件的信息被覆盖,而依赖这些redo 信息做恢复的数据块尚未被


写到磁盘上(checkpoint),此时系统down掉的话,Oracle将没有办法进行实例恢复。

 在v$log 视图里记录了在线日志的状态。通常来说,在线日志有三种状态。

Active: 这个日志上面保护的信息还没有完成checkpoint。

Inactive: 这个日志上面保护的信息已完成checkpoint。

Current: 当前的日志。

Oracle 在做实例恢复时,会使用状态为current和Active的日志进行实例恢复。

 如果系统中出现大量的log file switch(checkpoint incomplete)等待事件,原因可能是日志文件太小或者日志组太少,所以解


决的方法是,增加日志文件的大小或者增加日志组的数量。

 这个等待事件没有参数。

23. Log file sync


这是一个用户会话行为导致的等待事件,当一个会话发出一个commit命令时,LGWR进程会将这个事务产生的redo log从log buffer


里面写到磁盘上,以确保用户提交的信息被安全地记录到数据库中。

 会话发出的commit指令后,需要等待LGWR将这个事务产生的redo 成功写入到磁盘之后,才可以继续进行后续的操作,这个等待事


件就叫作log file sync。

 当系统中出现大量的log file sync等待事件时,应该检查数据库中是否有用户在做频繁的提交操作。

 这种等待事件通常发生在OLTP系统上。OLTP 系统中存在很多小的事务,如果这些事务频繁被提交,可能引起大量的log file sync


的等待事件。

 这个等待事件包含一个参数:

Buffer#: redo buffer 中需要被写入到磁盘中的buffer。

 24. SQL*Net break/reset to client


当出现这个等待事件时,说明服务器端在给客户端发送一个断开连接或者重置连接的请求,正在等待客户的响应,通常的原因是服


务器到客户端的网络不稳定导致的。

 这个等待事件包含两个参数:

Driver id: 服务器和客户端连接使用的协议信息。

Break?:零表示服务端向客户端发送一个重置(reset)信息,非零表示服务器端向客户端发送一个断开(break)消息。

 25. SQL*Net break/reset to dblink


这个等待事件和SQL*Net break/reset to client 相同。不过它表示的是数据库通过dblink访问另一台数据库时,他们之间建立起


一个会话,这个等待事件发生在这个会话之间的通信过程中,同样如果出现这个等待事件,需要检查两台数据库之间的通信问题。

 这个等待事件有两个参数:

Driver id: 服务器和客户端连接使用的协议信息。

Break?:零表示服务端向客户端发送一个重置(reset)信息,非零表示服务器端向客户端发送一个断开(break)消息。

26. SQL*Net message from client


这个等待事件基本上是最常见的一个等待事件。当一个会话建立成功后,客户端会向服务器端发送请求,服务器端处理完客户端请


求后,将结果返回给客户端,并继续等待客户端的请求,这时候会产生SQL*Net message from client 等待事件。

 很显然,这是一个空闲等待,如果客户端不再向服务器端发送请求,服务器端将一直处于这个等待事件状态。

 这个等待事件包含两个参数:

Driver id: 服务器端和客户端连接使用的协议信息。

#bytes: 服务器端接收到的来自客户端消息的字节数。

 27. SQL*Net message from dblink


这个等待事件和SQL*Net message from client相同,不过它表示的是数据库通过dblink 访问另一个数据库时,他们之间会建立一


个会话,这个等待事件发生在这个会话之间的通信过程中。

 这个等待事件也是一个空闲等待事件。

 这个事件包含两个参数:

Driver id: 服务器端和客户端连接使用的协议信息。

#bytes: 服务器端通过dblink 收到的来自另一个服务器端消息的字节数。

28. SQL*Net message to client


这个等待事件发生在服务器端向客户端发送消息的时候。当服务器端向客户端发送消息产生等待时,可能的原因是用户端太繁忙,


无法及时接收服务器端送来的消息,也可能是网络问题导致消息无法从服务器端发送到客户端。

 这个等待事件有两个参数:

Driver id: 服务器端和客户端连接使用的协议信息。

#bytes: 服务器端向客户端发送消息的字节数。

 29. SQL*Net message to dblink


这个等待事件和SQL*Net message to client 相同,不过是发生在数据库服务器和服务器之间的等待事件,产生这个等待的原因可


能是远程服务器繁忙,而无法及时接收发送过来的消息,也可能是服务器之间网络问题导致消息无法发送过来。

 这个等待时间包含两个参数:

Driver id: 服务器端和客户端连接使用的协议信息。

#bytes: 服务器端通过dblink发送给另一个服务器消息的字节数。

 30. SQL*Net more data from client


服务器端等待用户发出更多的数据以便完成操作,比如一个大的SQL文本,导致一个SQL*Net 数据包无法完成传输,这样服务器端会


等待客户端把整个SQL 文本发过来在做处理,这时候就会产生一个SQL*Net more data from client 等待事件。

 这个等待时间包含两个参数:

Driver id: 服务器端和客户端连接使用的协议信息。

#bytes: 服务器端从客户端接收到消息的字节数。

 31. SQL*Net more data from dblink


在一个分布式事务中,SQL 分布在不同的数据库中执行,远程数据库执行完毕后将结果通过dblink返给发出SQL的数据库,在等待数


据从其他数据库中通过dblink传回的过程中,如果数据在远程数据库上处理时间很久,或者有大量的结果集需要返回,或者网络性


能问题都会产生SQL*Net more data from dblink 等待事件,它的意思是本地数据库需要等到所有的数据从远程处理完毕通过


dblink传回后,才可以在本机继续执行操作。

 这个等待时间包含两个参数:

Driver id: 服务器端和客户端连接使用的协议信息。

#bytes: 服务器端通过dblink发送给另一个服务器消息的字节数。

 32. SQL*Net more data to client


当服务器端有太多的数据需要发给客户端时,可能会产生SQL*Net more data to client等待事件,也可能由于网络问题导致服务器


无法及时地将信息或者处理结果发送给客户端,同样会产生这个等待。

 这个等待时间包含两个参数:

Driver id: 服务器端和客户端连接使用的协议信息。

#bytes: 服务器端向客户端发送消息的字节数。

 33. SQL*Net more data to dblink


这个等待事件和SQL*Net more data to client 等待时间基本相同,只不过等待发生在分布式事务中,即本地数据库需要将更多的


数据通过dblink发送给远程数据库。由于发送的数据太多或者网络性能问题,就会出现SQL*Net more data to dblink等待事件。

 这个等待时间包含两个参数:

Driver id: 服务器端和客户端连接使用的协议信息。

#bytes: 服务器端通过dblink发送给另一个服务器消息的字节数。


oracle 常见等待事件及处理方法

我们可以通过视图v$session_wait来查看系统当前的等待事件,以及与等待事件相对应的资源的相关信息,从而可确定出产生瓶颈


的类型及其对象。v$session_wait的p1、p2、p3告诉我们等待事件的具体含义,根据事件不同其内容也不相同,下面就一些常见的


等待事件如何处理以及如何定位热点对象和阻塞会话作一些介绍。 


<1> db file scattered read DB 文件分散读取 

(太多索引读,全表扫描-----调整代码,将小表放入内存) 

这种情况通常显示与全表扫描相关的等待。当全表扫描被限制在内存时,它们很少会进入连续的缓冲区内,而是分散于整个缓冲存


储器中。如果这个数目很大,就表明该表找不到索引,或者只能找到有限的索引。尽管在特定条件下执行全表扫描可能比索引扫描


更有效,但如果出现这种等待时,最好检查一下这些全表扫描是否必要。因为全表扫描被置于LRU(Least Recently Used,最近最少


适用)列表的冷端(cold end),所以应尽量存储较小的表,以避免一次又一次地重复读取它们。 

================================================== 

该类事件的p1text=file#,p1是file_id,p2是block_id,通过dba_extents即可确定出热点对象(表或索引) 

select owner,segment_name,segment_type 

from dba_extents 

where file_id = &file_id 

and &block_id between block_id and block_id + &blocks - 1; 

================================================== 

<2> db file sequential read DB 文件顺序读取

 (表连接顺序不佳-----调整代码,特别是表连接) 

这一事件通常显示单个块的读取(如索引读取)。这种等待的数目很多时,可能显示表的连接顺序不佳,或者不加选择地进行索引。


对于大量事务处理、调整良好的系统,这一数值大多是很正常的,但在某些情况下,它可能暗示着系统中存在问题。你应当将这一


等待统计量与Statspack 报告中的已知问题(如效率较低的SQL)联系起来。检查索引扫描,以保证每个扫描都是必要的,并检查多


表连接的连接顺序。DB_CACHE_SIZE 也是这些等待出现频率的决定因素。有问题的散列区域(Hash-area)连接应当出现在PGA 内存


中,但它们也会消耗大量内存,从而在顺序读取时导致大量等待。它们也可能以直接路径读/写等待的形式出现。 

=================================================== 

该类事件的p1text=file#,p1是file_id,p2是block_id,通过dba_extents即可确定出热点对象(表或索引) 

select owner,segment_name,segment_type 

from dba_extents 

where file_id = &file_id 

and &block_id between block_id and block_id + &blocks - 1; 

================================================== 


<3> free buffer waits 释放缓冲区等待

 (增大DB_CACHE_SIZE,加速检查点,调整代码) 

这种等待表明系统正在等待内存中的缓冲,因为内存中已经没有可用的缓冲空间了。如果所有SQL 都得到了调优,这种等待可能表


示你需要增大DB_BUFFER_CACHE。释放缓冲区等待也可能表示不加选择的SQL 导致数据溢出了带有索引块的缓冲存储器,没有为等待


系统处理的特定语句留有缓冲区。这种情况通常表示正在执行相当多数量的DML(插入/更新/删除),并且数据库书写器(DBWR)写


的速度不够快,缓冲存储器可能充满了相同缓冲器的多个版本,从而导致效率非常低。为了解决这个问题,可能需要考虑增加检查


点、利用更多的DBWR 进程,或者增加物理磁盘的数量。 

<4> buffer busy waits 缓冲区忙等待 (BUFFER热块) 

这是为了等待一个以非共享方式使用的缓冲区,或者正在被读入缓冲存储器的缓冲区。缓冲区忙等待不应大于1%。检查缓冲等待统


计部分(或V$WAITSTAT): 

A、如果等待处于字段头部,应增加自由列表(freelist)的组数,或者增加pctused到pctfree之间的距离。 

B、如果等待处于回退段(undo)头部块,可以通过增加回滚段(rollback segment)来解决缓冲区的问题; 

C、如果等待处于回退段(undo)非头部块上,就需要降低驱动一致读取的表中的数据密度,或者增大DB_CACHE_SIZE; 

D、如果等待处于数据块,可以将数据移到另一数据块以避开这个"热"数据块、增加表中的自由列表或使用LMT表空间; 

E、如果等待处于索引块,应该重建索引、分割索引或使用反向键索引。 

为了防止与数据块相关的缓冲忙等待,也可以使用较小的块:在这种情况下,单个块中的记录就较少,所以这个块就不是那么"繁忙


"。在执行DML(插入/更新/删除)时,Oracle DBWR就向块中写入信息,包括所有对块状态"感兴趣"的用户(感兴趣的事务表,ITL)。为


减少这一区域的等待,可以增加initrans,这样会在块中创建空间,从而使你能够使用多个ITL槽。你也可以增加该块所在表中的


pctfree(当根据指定的initrans 建立的槽数量不足时,这样可以使ITL 信息数量达到maxtrans 指定的数量)。 


<6> enqueue 


enqueue 是一种保护共享资源的锁定机制。该锁定机制保护共享资源,如记录中的数据,以避免两个人在同一时间更新同一数据。


enqueue 包括一个排队机制,即FIFO(先进先出)排队机制。注意:Oracle 的latch 机制不是FIFO。Enqueue 等待通常指的是ST 


enqueue、HW enqueue、TX4 enqueue 和TM enqueue。 

A、ST enqueue 用于空间管理和字典管理的表空间的分配。利用LMT,或者试图对区域进行预分配,或者至少使下一个区域大于有问


题的字典管理的表空间。 

B、HW enqueue 与段的高水位标记一起使用;手动分配区域可以避免这一等待。 

C、TX4 enqueue是最常见的enqueue 等待,通常是以下三个问题之一产生的结果: 

第一个问题是唯一索引中的重复索引,需要执行提交(commit)/回滚(rollback)操作来释放enqueue。 

第二个问题是对同一位图索引段的多次更新。因为单个位图段可能包含多个行地址(rowid),所以当多个用户试图更新同一段时,你需


要执行提交或回滚操作,以释放enqueue。 

第三个问题,也是最可能发生的问题是多个用户同时更新同一个块。如果没有自由的ITL槽,就会发生块级锁定。通过增大initrans 


和/或maxtrans以允许使用多个ITL槽,或者增大表上的pctfree 值,就可以很轻松地避免这种情况。 

D、TM enqueue 在DML 期间产生,以避免对受影响的对象使用DDL。如果有外来关键字,一定要对它们进行索引,以避免这种常见的


锁定问题。 

<7> log buffer space 日志缓冲空间

 (写REDO慢-----增大log_buffer,redo log file放到快速磁盘上) 

当日志缓冲(log buffer)写入重做日志(redo log)的速度比LGWR 的写入速度慢,或者是当日志转换(log switch)太慢时,就会发生


这种等待。为解决这个问题,可以增大日志文件的大小,或者增加日志缓冲器的大小,或者使用写入速度更快的磁盘。甚至可以考


虑使用固态磁盘,因为它们的速度很高。 

<8> log file switch 日志文件转换 

(归档慢-----增加或者扩大重做日志) 有两种情况: 

A、log file switch (archiving needed) 

当日志切换的时候由于日志组循环使用了一圈但日志归档还没有完成,通常是io有严重问题,可增大日志文件和增加日志组,调整


log_archive_max_processes 

B、log file switch (checkpoint incomplete) 

当日志切换的时候由于日志组循环使用了一圈但将被使用的日志组中的checkpoint还没有完成造成,通常是io有严重问题,可增大


日志文件和增加日志组 

<9> log file sync 日志文件同步 (提交太频繁----批量提交) 

当用户commit的时候通知lgwr写日志但lwgr正忙,造成的可能原因是commit太频繁或者lgwr一次写日志时间太长(可能是因为一次


log io size 太大),可调整 _log_io_size,结合log_buffer,使得 (_log_io_size*db_block_size)*n = log_buffer,这样可避免


和增大log_buffer引起冲突;放置日志文件于高速磁盘上 

<10> library cache pin 

该事件通常是发生在先有会话在运行PL/SQL,VIEW,TYPES等object时,又有另外的会话执行重新编译这些object,即先给对象加上了一


个共享锁,然后又给它加排它锁,这样在加排它锁的会话上就会出现这个等待。P1,P2可与x$kglpn和x$kglob表相关 

X$KGLOB (Kernel Generic Library Cache Manager Object) 

X$KGLPN (Kernel Generic Library Cache Manager Object Pins) 

-- 查询X$KGLOB,可找到相关的object,其SQL语句如下 

(即把V$SESSION_WAIT中的P1raw与X$KGLOB中的KGLHDADR相关连) 

select kglnaown,kglnaobj from X$KGLOB 

where KGLHDADR =(select p1raw from v$session_wait 

where event='library cache pin') 

-- 查出引起该等待事件的阻塞者的sid 

select sid from x$kglpn , v$session 

where KGLPNHDL in 

(select p1raw from v$session_wait 

where wait_time=0 and event like 'library cache pin%') 

and KGLPNMOD <> 0 

and v$session.saddr=x$kglpn.kglpnuse 

-- 查出阻塞者正执行的SQL语句 

select sid,sql_text 

from v$session, v$sqlarea 

where v$session.sql_address=v$sqlarea.address 

and sid=<阻塞者的sid> 

这样,就可找到"library cache pin"等待的根源,从而解决由此引起的性能问题。 

<11> library cache lock 

该事件通常是由于执行多个DDL操作导致的,即在library cache object上添加一个排它锁后,又从另一个会话给它添加一个排它锁,


这样在第二个会话就会生成等待。可通过到基表x$kgllk中查找其对应的对象。 

-- 查询引起该等待事件的阻塞者的sid、会话用户、锁住的对象 

select b.sid,a.user_name,a.kglnaobj 

from x$kgllk a , v$session b 

where a.kgllkhdl in 

(select p1raw from v$session_wait 

where wait_time=0 and event = 'library cache lock') 

and a.kgllkmod <> 0 

and b.saddr=a.kgllkuse 

当然也可以直接从v$locked_objects中查看,但没有上面语句直观根据sid可以到v$process中查出pid,然后将其kill或者其它处理


。 

<5> latch free (等待LATCH FREE) 

latch是一种低级排队机制(它们被准确地称为相互排斥机制),用于保护系统全局区域(SGA)中共享内存结构。latch 就像是一种快速


地被获取和释放的内存锁。latch 用于防止共享内存结构被多个用户同时访问。如果latch 不可用,就会记录latch 释放失败。大


多数latch 问题都与以下操作相关:不能使用邦定变量(库缓存latch)、重复生成问题(重复分配latch)、缓冲存储器竞争问题


(缓冲器存储LRU 链),以及缓冲存储器中的"热"块(缓冲存储器链)。也有一些latch 等待与bug(程序错误)有关,如果怀疑是


这种情况,可以检查MetaLink 上的bug 报告。 

该事件的热点对象可通过以下语句查找,其中&2值是v$session_wait中的P1RAW,x$bh中的字段Hladdr表示该block buffer在哪个


cache buffer chain latch 上,可以通过v$latch_children定位哪些segment是热点块。 

=================================================== 

select a.hladdr, a.file#, a.dbablk, a.tch, a.obj, b.object_name 

from x$bh a, dba_objects b 

where (a.obj = b.object_id or a.obj = b.data_object_id) 

and a.hladdr = &2 

union 

select hladdr, file#, dbablk, tch, obj, null 

from x$bh 

where obj in 

(select obj from x$bh 

where hladdr = &2 

minus 

select object_id from dba_objects 

minus 

select data_object_id from dba_objects) 

and hladdr = &2 

order by 4; 

==================================================== 

***Latch 问题及可能解决办法 

------------------------------ 

* Library Cache and Shared Pool (未绑定变量---绑定变量,调整shared_pool_size) 

每当执行SQL或PL/SQL存储过程,包,函数和触发器时,这个Latch即被用到.Parse操作中此Latch也会被频繁使用. 

* Redo Copy (增大_LOG_SIMULTANEOUS_COPIES参数) 

重做拷贝Latch用来从PGA向重做日志缓冲区拷贝重做记录. 

* Redo Allocation (最小化REDO生成,避免不必要提交) 

此Latch用来分配重做日志缓冲区中的空间,可以用NOLOGGING来减缓竞争. 

* Row Cache Objects (增大共享池) 

数据字典竞争.过度parsing. 

* Cache Buffers Chains (_DB_BLOCK_HASH_BUCKETS应增大或设为质数) 

"过热"数据块造成了内存缓冲链Latch竞争. 

* Cache Buffers Lru Chain (调整SQL,设置DB_BLOCK_LRU_LATCHES,或使用多个缓冲区池) 

扫描全部内存缓冲区块的LRU(最近最少使用)链时要用到内存缓冲区LRU链Latch.太小内存缓冲区、过大的内存缓冲区吞吐量、过多


的内存中进行的排序操作、DBWR速度跟不上工作负载等会引起此Latch竞争。 

<12> db file parallel write 

与DBWR进程相关的等待,一般代表了I/O能力出现了问题. 通常与配置的多个DBWR进程或者DBWU的I/O slaves个数有关.当然也可能意


味着设备上存在着I/O竞争 

<13> db file single write 

表示在检查点发生时与文件头写操作相关的等待.通常与检查点同步数据文件头时文件号的紊乱有关. 

<14> direct path read 和 direct path write 


表示与直接I/O读相关的等待.当直接读数据到PGA内存时,direct path read 出现.这种类型的读请求典型地作为:排序IO(为排序不


能在内存中完成的时候),并行Slave查询或者预先读请求等. 通常这种等待与I/O能力或者I/O竞争有关. 


<15> free buffer inspected 


表示在将数据读入数据调整缓存区的时候等待进程找到足够大的内在空间通常这类等待表示数据调整缓存区偏小. 

<16> library cache load lock 


表示在将对象装载到库高速缓存时出现了等待.这种事件通常代表着发生了负荷尔蒙很重的语句重载或者装载,可能由于SQL语句没有


共享或者共享池区域编小造成的. 

<17> log file parallel write 


表示等待LGWR向操作系统请求I/O开始直到完成IO.在触发LGWR写的情况下如3秒、1/3、1MB、DBWR写之前可能发生.这种事件发生通


常表示日志文件发生了I/O竞争或者文件所在的驱动器较慢 

<18> log file single write 


表示写日志文件头块时出现了等待.一般都是发生在检查点发生时. 

<19> transaction 


表示发生了一个阻塞回滚操作的等待 

<20> undo segment extension 


表示在等待回滚段的动态扩展.这表示可能事务量过大,同时也意味着可能回滚段的寝大小不是最优,MINEXTENTS设置得偏小.考虑减


少事务,或者使用最小区数更大的回滚段.



Oracle 缓冲区命中率低的分析及解决办法

首先确定下面的查询结果:

1,缓冲区命中率的查询(是否低于90%):

select round((1 - sum(decode(name,'physical reads',value,0)) /

(sum(decode(name,'db block gets',value,0)) + sum(decode(name,'consistent gets',value,0))) ),4) *100 || '%' chitrati

from v$sysstat;

2,使用率的查询(有无free状态的数据快.):

select count(*), status from v$bh group by status ;

3,相关等待事件的查询(是否有相关等待事件)

select event,total_waits from v$system_event where event in ('free buffer waits');

4,当前大小(是否已经很大)

select value/1024/1024 cache_size from v$parameter where name='db_cache_size'

5,top等待事件分析(Db file scatered read的比率是否大)

select event ,total_waits,suml

from

(select event,total_waits,round(total_waits/sumt*100,2)||'%' sumlfrom

(select event,total_waits from v$system_event ),(select sum(total_waits) sumt from v$system_event) order by 


total_waits desc)

where rownum<6

and event not like 'rdbms%'

and event not like 'pmon%'

and event not like 'SQL*Net%'

and event not like 'smon%';

6,db_cache_advice建议值

(9i后的新特性,可以根据他更好的调整cache_size)

select block_size,size_for_estimate,size_factor,estd_physical_reads from v$db_cache_advice;

说明分析:

缓冲区命中率(低于90的命中率就算比较低的).

没有free不一定说明需要增加,还要结合当前cache_size的大小(我们是否还可以再增大,是否有需要增加硬件,增加开销), 

空闲缓冲区等待说明进程找不到空闲缓冲区,并通过写出灰缓冲区,来加速数据库写入器生成空闲缓冲区,当DBWn将块写入磁盘后


,灰数据缓冲区将被释放,以便重新使用.

产生这种原因主要是:

1,DBWn可能跟不上写入灰缓冲区:i/0系统较慢,尽量将文件均匀的分布于所有设备,

2,缓冲区过小或过大。

3,可以增加db_writer_processes数量。

4,可能有很大的一个事物,或者连续的大事物

我们需要长期观察这个事件是否长期存在并数值一直在增大,如果一直在增大,则说明需要增大db_cache大小.或优化sql. 


数据分散读等待

通常表现存在着与全表扫描相关的等待,逻辑读时,在内存中进行的全表扫描一般是零散地,而并非连续的被分散到缓冲区的各个


部分,可能有索引丢失,或被仰制索引的存在。该等待时间在数据库会话等待多块io读取结束的时候产生,并把指定的块数离散的


分布在数据缓冲区。这意味这全表扫描过多,或者io不足或争用,

存在这个事件,多数都是问题的,这说明大量的全部扫描而未采用索引.

db_cache_advice对我们调整db_cache_size大小有一定的帮助,但这只是一个参考,不一定很精确。

通过上面6种情况的综合分析,判断是否需要增加大cache_size. 或者把常用的(小)表放到keep区。

但多数的时候做这些不会解决质的问题,

而真正的问题主要是对sql语句的优化(如:是否存在大量的全表扫描等)

索引是在不需要改变程序的情况下,对数据库性能,sql语句提高的最实用的方法.

我在生产中遇到过类似的问题,200M的cache_size,命中率很低21%,但通过对sql语句的优化(添加索引,避免全表扫描),命中率增加到


96%,程序运行时间由原来的2小时减少到不到10分钟.

这就提到了怎么定位高消耗的sql问题

.全表扫描的问题,在这里不做细致的解说,这里只说明方法,我会在相关的章节专门介绍怎么使用这些工具

1,sql_trace跟踪session.用tkprof 分别输出磁盘读,逻辑读,运行时间长的sql进行优化.这些高消耗的sql一般都伴随着全表扫描.

2,statspack分析.在系统繁忙时期进行时间点的统计分析,产看TOP事件是否有Db file scatered read.并查看TOP sql语句是否存在


问题等.

还要说一句:当然在硬件允许的情况下,尽量增大db_cache_size 减少磁盘读,但并不是越大越好,一定要根据自己的库数据量的


程度来调节,因为大的db_cache_size同样会增大数据库管理的开销,当然可能开销并不会明显的影响数据库的性能,硬件价格也越


来越低,这就需要我们具体问题具体分析了。



会明显的影响数据库的性能,硬件价格也越来越低,这就需要我们具体问题具体分析了。



如有疑问 请留言 欢迎提供建议

评论已有 0