您好,登錄后才能下訂單哦!
本文小編為大家詳細介紹“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等待事件怎么解決”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。