導致等待事件的常見原因及解決方案

2021-06-05 22:33:28 字數 4911 閱讀 5807

如果你只能選擇兩個oracle實用程式來發現和監控oracle9i資料庫系統中的效能問題,你就應當選擇oralce enterprise manager(oracle企業管理器,現在可用的版本為4.0)和statspack。從oracle8i 8.1.6版開始,statspack應用程式代替了oracle資料庫早期版本用於效能監測的utlbstat/utlestat指令碼檔案;statspack對這些指令碼進行了一些重要的改進。本專欄集中討論關於等待事件的高階問題的解決方案--這些事件是系統在處理某個資源使其可用以及完成某個動作的過程中必須等待的事件。

前5個頂級等待事件

當你試圖消除系統的瓶頸時,應該首先檢視statspack報告中的"前5個頂級等待事件"部分。報告的這一部分給出了前5個頂級等待事件、等待事件的完整列表和後台等待事件。如果系統的temed_statistics初始化引數被設為"真",這些事件是按其等待時間進行排序的。這種排序是較好的排序方式,因為並不是所有的事件都顯示等待。如果timed_statistics被設為"假",這些事件就按等待數目進行排序。

清單1給出了很多與讀取單個塊(db檔案的順序讀取)相關的等待以及latch等待(latch釋放)。在這個清單中可以看到一些等候寫入資料檔案和日誌檔案的高階等待事件。為了確定哪些是主要的問題,必須通過研究statspack其他部分的具體報告來縮小等待事件列表的範圍。

解決等待事件

下面是導致等待事件的10個最常見原因,以及對事件的解釋和可能的解決方案:

1. db檔案分散讀取。這種情況通常顯示與全表掃瞄相關的等待。當全表掃瞄被限制在記憶體時,它們很少會進入連續的緩衝區內,而是分散於整個緩衝儲存器中。如果這個數目很大,就表明該錶找不到索引,或者只能找到有限的索引。儘管在特定條件下執行全表掃瞄可能比索引掃瞄更有效,但如果出現這種等待時,最好檢查一下這些全表掃瞄是否必要。因為全表掃瞄被置於lru(least recently used,最近最少適用)列表的冷端(cold end),所以應盡量儲存較小的表,以避免一次又一次地重複讀取它們。

2. db檔案順序讀取。這一事件通常顯示單個塊的讀取(如索引讀取)。這種等待的數目很多時,可能顯示表的連線順序不佳,或者不加選擇地進行索引。對於高階事務處理(high-transaction)、調整良好(welltuned)的系統,這一數值很大是很正常的,但在某些情況下,它可能暗示著系統中存在問題。你應當將這一等待統計量與statspack報告中的已知問題(如效率較低的sql)聯絡起來。檢查索引掃瞄,以保證每個掃瞄都是必要的,並檢查多表連線的連線順序。db_cache_size也是這些等待出現頻率的決定因素。有問題的雜湊區域(hash-area)連線應當出現在pga記憶體中,但它們也會消耗大量記憶體,從而在順序讀取時導致大量等待。它們也可能以直接路徑讀/寫等待的形式出現。

3. 釋放緩衝區。這種等待表明系統正在等待記憶體中的緩衝,因為記憶體中已經沒有可用的緩衝空間了。如果所有sql都得到了調優,這種等待可能表示你需要增大db_buffer_cache。釋放緩衝區等待也可能表示不加選擇的sql導致資料溢位了帶有索引塊的緩衝儲存器,沒有為等待系統處理的特定語句留有緩衝區。這種情況通常表示正在執行相當多數量的dml(插入/更新/刪除),並且資料庫書寫器(dbwr)寫的速度不夠快,緩衝儲存器可能充滿了相同緩衝器的多個版本,從而導致效率非常低。為了解決這個問題,可能需要考慮增加檢查點、利用更多的dbwr程序,或者增加物理磁碟的數量。

4. 緩衝區忙。這是為了等待乙個以非共享方式使用的緩衝區,或者正在被讀入緩衝儲存器的緩衝區。緩衝區忙等待不應大於百分之一。檢查緩衝等待統計部分(或v$waitstat),看一下等待是否位於字段頭部。如果事實如此,應增加自由列表(freelist)的組數,或者增加pctused到pctfree之間的距離。如果這一等待處於回退段(undo)頭部塊,可以通過增加回滾段(rollback segment)來解決緩衝區的問題;如果等待處於回退段(undo)非頭部塊上,就需要降低驅動一致讀取的表中的資料密度,或者增大db_cache_size;如果等待處於資料塊,可以將資料移到另一資料塊以避開這個"熱"資料塊、增加表中的自由列表或使用本地化管理的表空間(locally managed tablespaces);如果等待處於索引塊,應該重建索引、分割索引或使用反向鍵索引。為了防止與資料塊相關的緩衝忙等待,也可以使用較小的塊:在這種情況下,單個塊中的記錄就較少,所以這個塊就不是那麼"繁忙"。在執行dml(插入/更新/刪除)時,oracle資料庫書寫器就向塊中寫入資訊,包括所有對塊狀態"感興趣"的使用者(感興趣的事務表,itl)。為了減少這一區域的等待,可以增加initrans,這樣會在塊中建立空間,從而使你能夠使用多個itl槽。你也可以增加該塊所在表中的pctfree(當根據指定的initrans建立的槽數量不足時,這樣可以使itl資訊數量達到maxtrans指定的數量)。

下一步5. latch釋放。latch是一種低階排隊機制(它們被準確地稱為相互排斥機制),用於保護系統全域性區域(sga)中共享記憶體結構。latch就像是一種快速地被獲取和釋放的記憶體鎖。latch用於防止共享記憶體結構被多個使用者同時訪問。如果latch不可用,就會記錄latch釋放失敗。大多數latch問題都與以下操作相關:不能使用邦定變數(庫快取latch)、重複生成問題(重複分配latch)、緩衝儲存器競爭問題(緩衝器儲存lru鏈),以及緩衝儲存器中的"熱"塊(緩衝儲存器鏈)。也有一些latch等待與bug(程式錯誤)有關,如果懷疑是這種情況,可以檢查metalink上的bug報告(oracle.com/support)。當latch不命中率大於0.5%時,就應當研究這一問題。在我的下乙個oracle雜誌專欄中,將詳細介紹latch等待,這一主題本身就需要一整篇文章來介紹。

6. enqueue。enqueue是一種保護共享資源的鎖定機制。該鎖定機制保護共享資源,如記錄中的資料,以避免兩個人在同一時間更新同一資料。enqueue包括乙個排隊機制,即fifo(先進先出)排隊機制。注意:oracle的latch機制不是fifo。enqueue等待通常指的是st enqueue、hw enqueue、tx4 enqueue和tm enqueue。st enqueue用於空間管理和字典管理的表空間的分配。利用lmt,或者試圖對區域進行預分配,或者至少使下乙個區域大於有問題的字典管理的表空間。hw enqueue與段的高水位標記一起使用;手動分配區域可以避免這一等待。tx4是最常見的enqueue等待。tx4 enqueue等待通常是以下三個問題之一產生的結果。第乙個問題是唯一索引中的重複索引,你需要執行提交(commit)/回滾(rollback)操作來釋放enqueue。第二個問題是對同一位圖索引段的多次更新。因為單個點陣圖段可能包含多個行位址(rowid),所以當多個使用者試圖更新同一段時,你需要執行提交或回滾操作,以釋放enqueue。第三個問題,也是最可能發生的問題是多個使用者同時更新同乙個塊。如果沒有自由的itl槽,就會發生塊級鎖定。通過增大initrans和/或maxtrans以允許使用多個itl槽,或者增大表上的pctfree值,就可以很輕鬆地避免這種情況。最後,tm enqueue在dml期間產生,以避免對受影響的物件使用ddl。如果有外來關鍵字,一定要對它們進行索引,以避免這種常見的鎖定問題。

7. 日誌緩衝空間。當你將日誌緩衝(log buffer)寫入重做日誌(redo log)的速度比lgwr的寫入速度快,或者是當日誌轉換(log switch)太慢時,就會發生這種等待。為解決這個問題,可以增大日誌檔案的大小,或者增加日誌緩衝器的大小,或者使用寫入速度更快的磁碟。你甚至可以考慮使用固態磁碟,因為它們的速度很高。

8. 日誌檔案轉換。所有的提交請求都需要等待"日誌檔案轉換(必要的歸檔)"或"日誌檔案轉換(chkpt.不完全)"。確保歸檔磁碟未滿,並且速度不太慢。dbwr可能會因為輸入/輸出(i/o)操作而變得很慢。你可能需要增加更多或更大的重做日誌,而且如果dbwr是問題癥結所在的話,可能需要增加資料庫書寫器。

9. 日誌檔案同步。當乙個使用者提交或回滾資料時,lgwr將會話期的重做由日誌緩衝器寫入到重做日誌中。日誌檔案同步過程必須等待這一過程成功完成。為了減少這種等待事件,可以嘗試提交更多的記錄(如一次提交50個記錄,而不是乙個)。將重做日誌置於較快的磁碟上,或者交替使用不同物理磁碟上的重做日誌,以降低歸檔對lgwr的影響。不要使用raid 5,因為它對於那些書寫很多的應用程式速度很慢,可以考慮使用檔案系統直接輸入/輸出,或者使用原始裝置(raw device),它們在書寫資訊時的速度非常快。

10. 空閒事件。在輸出之後列出了幾個空閒等待事件,你可以忽略它們。空閒事件一般被列在每節的底部,並且包括諸如送給/來自客戶機構的sql*net訊息以及其他與後台相關的時間選擇。空閒事件被列於stats$idle_event表中。

保持調優

在下一期的oracle雜誌中,將研究latch-另一種可能遇到的常見等待,研究這種常見的latch,你將會了解如何對它們進行調優以獲得最佳的效能。

rich niemiec是tusc (www.tusc.com) 的ceo,同時也是國際oracle使用者團體(international oracle users group,www.ioug.org)的主席。感謝steve adams在編輯方面所給予的幫助。

等待事件快速參考指南

等待問題 可能的解決方法

db檔案分散讀取 表明有許多全表掃瞄:調優**;儲存較小的表。

db檔案順序讀取 表明有許多索引讀取:調優**(特別是連線)。

釋放緩衝區 增大db_cache_size;縮短檢查點;調優**。

緩衝區忙 段頭部:增加自由列表或自由列表組。

緩衝區忙 資料塊:分離"熱"資料;利用反向鍵索引和/或較小的塊。

緩衝區忙 資料塊:增大initrans和/或maxtrans。

緩衝區忙 回退段頭部塊:增加回滾段或區域。

緩衝區忙 回退段非頭部塊:增大提交頻率;使用更大的回滾段或區域。

釋放latch 詳細研究latch。

enqueue—st 利用lmt或預分配較大的區域。

enqueue—hw 對高於最高水位標記的區域進行預分配。

enqueue—tx4 增大與表或索引相關的initrans和/或maxtrans。

enqueue—tm 對外來關鍵字進行索引,檢查鎖定表的應用程式。

日誌緩衝空間 增大日誌緩衝;利用較快的磁碟進行重做日誌。

日誌檔案轉換 歸檔磁碟變慢或已滿;增加更多或更大的重做日誌。

日誌檔案同步 一次提交更多的記錄;利用更快的重做日誌磁碟或原始裝置。

空閒事件 忽略

等待事件之日誌等待事件解決的方法

我堅持每天看3套rac的awr,總結了一下。查詢日誌等待事件的sql 9i select from v event name where name like log 大概14個左右 10g select name,wait class from v event name where name lik...

什麼是oom,常見造成oom的原因,及解決方法

一 什麼是oom oom就是我們常說的記憶體溢位,它是指需要的記憶體空間大於系統分配的記憶體空間,oom後果就是專案程式crash 二 常見造成oom的原因 1.記憶體洩露造成 2.載入的檔案或者過大造成 三 解決方案 記憶體洩露是造成記憶體溢位的乙個原因,所以避免記憶體洩露的那些方法都適用於記憶體...

Oracle 常見的幾種等待事件

等待事件分為主動觸發事件與被動觸發事件。主動觸發事件 發生一次就進性一次記錄,例如io等 被動觸發事件 例如latch的獲取,只有當遇到阻塞時,獲取不到時,才會記錄該等待事件,如果沒有阻塞,即使獲取的時間再長,也不會記錄該事件。讀不阻塞寫,寫阻塞讀。等待的元凶只能是dml語句 因為當乙個使用者a讀取...