几乎全球的所有行业都在应用Oracle技术。作为一款关系数据库管理系统,Oracle在数据库领域一直处于领先地位。然而,一些不太熟悉Oracle的数据相关人士或IT人士,却对它的等待事件有所疑惑。续《等灯等灯?Oracle常见の等待事件说明(上)》,今天继续为你解惑。
1、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数量。
2、Enqueue
Enqueue这个词其实是lock的另一种描述语。当我们在AWR 报告中发现长时间的enqueue等待事件时,说明数据库中出现了阻塞和等待。可以通过关联AWR报告中的enqueue activity部分来确定是哪一种锁定导致长时间等待的出现。
这个等待事件有两个参数:
①Name:enqueue的名称和类型。
②Mode:enqueue的模式。
3、Free buffer waits
当一个会话将数据块从磁盘读到内存中时,它需要到内存中找到空闲的内存空间来存放这些数据块,当内存中没有空闲的空间时,就会产生这个等待。除此之外,还有一种情况就是会话在做一致性读时,需要构造数据块在某个时刻的前映像(image),此时需要申请内存来存放这些新构造的数据块,如果内存中无法找到这样的内存块,也会发生这个等待事件。
当数据库中出现比较严重的free buffer waits等待事件时,可能的原因是:
①data buffer太小,导致空闲空间不够。
②内存中的脏数据太多,DBWR无法及时将这些脏数据写到磁盘中以释放空间。
这个等待事件包含两个参数:
①File#:需要读取的数据块所在的数据文件的文件号。
②Block#:需要读取的数据块块号。
查询阻塞的语句:
SELECT /*+ ORDERED USE_HASH(H,R) */
h.sid hold_sid, holds.username h_user, holds.lockwait h_lockwait, holds.status h_status, holds.module h_module, holds.row_wait_obj# h_obj, holds.row_wait_row# h_row,
r.sid wait_sid, waits.username w_user, waits.lockwait w_lockwait, waits.status w_status, waits.module w_module, waits.row_wait_obj# w_obj, waits.row_wait_row# w_row,
h.type h_type, h.id1 h_id1, h.id2 h_id2, h.lmode h_lmode, h.request h_request, h.ctime h_ctime, h.block h_block,
r.type r_type, r.id1 r_id1, r.id2 r_id2, r.lmode r_lmode, r.request r_request, r.ctime r_ctime, r.block r_block,
'alter system kill session ''' || holds.sid || ',' || holds.serial# ||
'''; -- kill -9 ' || nvl(holdp.spid, 'null') killhold,
holdsql.sql_text hsql,
waitsql.sql_text wsql
FROM v$lock h,
v$lock r,
v$session holds,
v$session waits,
v$process holdp,
v$sqlarea holdsql,
v$sqlarea waitsql
WHERE h.BLOCK = 1 AND
r.BLOCK = 0 AND
h.TYPE <> 'MR' AND
r.TYPE <> 'MR' AND
h.id1 = r.id1 AND
h.id2 = r.id2 AND
h.sid = holds.sid AND
r.sid = waits.sid AND
holds.paddr = holdp.addr(+) AND
holds.sql_address = holdsql.address(+) AND
holds.sql_hash_value = holdsql.hash_value(+) AND
waits.sql_address = waitsql.address(+) AND
waits.sql_hash_value = waitsql.hash_value(+);
4、Latch free
在10g之前的版本里,latch free等待事件代表了所有的latch等待;在10g以后,一些常用的latch事件已经被独立了出来:
这个等待事件有两个参数:
①Address:会话等待的latch 地址。
②Number:latch号,通过这个号,可以从v$latchname视图中找到这个latch的相关信息。
5、Library cache lock
这个等待事件发生在不同用户在共享中由于并发操作同一个数据库对象导致的资源争用的时候,比如当一个用户正在对一个表做DDL 操作时,其他的用户如果要访问这张表,就会发生library cache lock等待事件,它要一直等到DDL操作完成后,才能继续操作。
这个事件包含四个参数:
①Handle address:被加载的对象的地址。
②Lock address:锁的地址。
③Mode:被加载对象的数据片段。
④Namespace:被加载对象在v$db_object_cache视图中namespace名称。
6、Library cache pin
这个等待事件和library cache lock一样,是发生在共享池中并发操作引起的事件。通常来讲,如果Oracle要对一些PL/SQL或者视图这样的对象做重新编译,需要将这些对象pin到共享池中。如果此时这个对象被其他的用户特有,就会产生一个library cache pin的等待。
这个等待事件也包含四个参数:
①Handle address:被加载的对象的地址。
②Lock address:锁的地址。
③Mode:被加载对象的数据片段。
④Namespace:被加载对象在v$db_object_cache视图中namespace名称。
7、Log buffer space
当log buffer中没有可用空间来存放新产生的redo log数据时,就会发生log buffer space等待事件。 同时,更多大数据与商业智能领域干货、兼职机会及行业资源分享等,可添加微信号bigbigsage了解。如果数据库中新产生的redo log的数量大于LGWR 写入到磁盘中的redo log数量,必须等待LGWR完成写入磁盘的操作,LGWR必须确保redo log写到磁盘成功之后,才能在redo buffer当中重用这部分信息。
如果数据库中出现大量的log buffer space等待事件,可以考虑如下方法:
①增加redo buffer的大小。
②提升磁盘的I/O性能。
8、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次数。
9、Log file sequential read
这个等待事件通常发生在对redo log信息进行读取时,比如在线redo的归档操作。ARCH进程需要读取redo log的信息,由于redo log的信息是顺序写入的,所以在读取时也是按照顺序的方式来读取的。
这个等待事件包含三个参数:
①Log#:发生等待时读取的redo log的sequence号。
②Block#:读取的数据块号。
③Blocks:读取的数据块个数。
10、Log file single write
这个等待事件发生在更新redo log文件的文件头时,当为日志组增加新的日志成员或者redo log的sequence号改变时,LGWR都会更新redo log文件头信息。
这个等待事件包含三个参数:
①Log#:写入的redo log组的编号。
②Block#:写入的数据块号。
③Blocks:写入的数据块个数。
作者: datapeng