本文小编为大家详细介绍“ORACLE的buffer busy wait等待事件怎么解决”,内容详细,步骤清晰,细节处理妥当,希望这篇“ORACLE的buffer busy wait等待事件怎么解决”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。
1. ORACLE 访问Data buffer block的过程:
1)依据数据块的地址计算出数据块所在的bucket
2)获得保护这个bucket的cbc latch
3)在这个链表上找寻我们需要的数据块,找到后,pin这个buffer(读取s,修改x)
4)释放cbc latch
5)读取/修改数据块的内容
6)获取cbc latch
7)unpin这个buffer
8)释放cbc latch
2.buffer busy wait 等待事件形成原因:
(1). 读读
当一个session 读取一个block时,该block在cache中不存在,需要从disk读取至cache,此时其他session 想要读取该block时,就会发生buffer busy wait 等待事件。
(2). 写写
当一个session 修改block时,首先会对该block 进行buffer pin(修改x),因此其他session在对该block进行修改时都要等待上一个session unpin buffer。
(3). 读写
1)当读取的进程发现内存块正在被修改的时候(如果有x模式的buffer pin,就说明正在被修改),它只能等待,它不能clone块,因为这个时候内存块正在变化过程中ing,这个时候clone是不安全的。很多人说,oracle里读写是互相不阻塞的,oracle可以clone内存块,把读写的竞争分开。其实要看情况,在读的时候发现内存块正在被写,是不能够clone的,因为是不安全的。这个时候读的进程只能等待buffer busy waits。
2)当写的进程发现内存块正在被读,这个时候,读是不阻塞写的,因为ORACLE可以很容易的clone出一个xcur的数据块,然后在clone的块上进行写,这个时候clone是安全的,因为读内存块的进程不会去修改数据块,保证了clone的安全性。
3.buffer busy wait 常见发生原因
(1). 性能差的QUERY访问相同的block 并发执行时,产生大量的物理读。
(2). freelist 设置过小,导致并发insert table时,频繁扫描freelist,产生争用。
(3). 大量session 并发修改相同的index block
4.常用解决方法
(1). tuning sql 减少物理读
(2). 删除一些hot row 并重新insert 至其他block中
(3). 如果table 较小,可以考虑将其数据 cache至keep data buffer中
(4). 减少low cardinality index的使用。 避免index block 争用。
(5). 增加extents size。 避免oracle频繁分配空间而造成的extent map 争用。
5. 产生等待的block 类型及解决方法
Block Type | Possible Actions |
data blocks | Eliminate HOT blocks from the application. Check for repeatedly scanned / unselective indexes. Change PCTFREE and/or PCTUSED. Check for 'right- hand-indexes' (indexes that get inserted into at the same point by many processes). Increase INITRANS. Reduce the number of rows per block. |
segment header | Increase of number of FREELISTs. Use FREELIST GROUPs (even in single instance this can make a difference). |
freelist blocks | Add more FREELISTS. In case of Parallel Server make sure that each instance has its own FREELIST GROUP(s). |
undo header | Add more rollback segments. |
6.相关命令
SELECT p1 "File", p2 "Block", p3 "Reason"
FROM v$session_wait
WHERE event='enq: TX - row lock contention';
select objd, file#,block#,class#,ts#,cachehint,status,dirty from v$bh where file#=546 and block#=1289912;
select * from dba_objects where object_id = 124269
select current_obj#,obj.object_name,count(*) from dba_hist_active_sess_history , dba_objects obj
where event='buffer busy waits'
and sample_time>=to_date('2017-07-09 00:00:00','yyyy-mm-dd hh34:mi:ss')
and sample_time<=to_date('2017-07-10 00:00:00','yyyy-mm-dd hh34:mi:ss')
and obj.data_object_id = current_obj#
group by current_obj#,obj.object_name
读到这里,这篇“ORACLE的buffer busy wait等待事件怎么解决”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注亿速云行业资讯频道。