久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

怎么理解Oracle等待事件的分類、發現及優化

178次閱讀
沒有評論

共計 8674 個字符,預計需要花費 22 分鐘才能閱讀完成。

本篇內容介紹了“怎么理解 Oracle 等待事件的分類、發現及優化”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓丸趣 TV 小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

一、等待事件由來

大家可能有些奇怪,為什么說等待事件,先談到了指標體系。其實,正是因為指標體系的發展,才導致等待事件的引入。總結一下,Oracle 的指標體系,大致經歷了下面三個階段:

以命中率為主要參考指標

以各種命中率為主要的優化入口依據,常見的有”library cache hit radio“等。但這種方式弊端很大,一個命中率為 99% 的系統,不一定就比 95% 的系統優化的更好。在老的 Oracle 版本中,往往采用這種方式,如 8i、9i 等。

以等待事件為主要參考指標

以各種等待事件為優化入口依據,常見的有 db file sequential read 等。可以較直觀的了解,在一段時間內,數據庫主要經歷了那些等待。這些 瓶頸,往往就是我們優化的著手點。在 10g、11g 版本中,廣泛使用。

以時間模型為主要參考指標

以各種資源整體消耗為優化入口依據。可以從整體角度了解數據庫在一段時間內的消耗情況。較等待事件的方式,更有概括性。常見的如 DB Time。Oracle 在不斷加強這個方面的工作。

從上面三個階段可見,等待事件的引入,正是為了解決以命中率為指標的諸多弊端。與后面的時間模型相比,等待事件以更加直觀、細粒度的方式觀察 Oracle 的行為,往往作為優化的重要入口。而時間模型,更側重于整體、系統性的了解數據庫運行狀態。兩者的側重點不同。

二、等待事件分類

讓我們首先從等待事件的分類入手,認識等待事件。從大的分類上來看,等待事件可分為空閑的、非空閑的兩大部分。在非空閑的等待事件,又可進一步劃分細的類別。

可以通過下面的方法,觀察系統包含的等待事件數量及大致分類(以下語句在 11g 環境運行)。

其中 WAIT_CLASS 為“Idle”的等待事件就是空閑的,其他的都是非空閑的等待事件。

1. 區分 — 空閑與非空閑等待事件

空閑等待事件,是指 Oracle 正等待某種工作,比如用 sqlplus 登錄之后,但沒有進一步發出任何命令,此時該 session 就處于 SQL*Net message from/to client 等待事件狀態,等待用戶發出命令,任何的在診斷和優化數據庫的時候,一般不用過多注意這部分事件。

非空閑等待事件,專門針對 Oracle 的活動,指數據庫任務或應用運行過程中發生的等待,這些等待事件是調整數據庫的時候應該關注與研究的。

2. 等待事件分類說明

管理類 -Administrative

此類等待事件是由于 DBA 的管理命令引起的,這些命令要求用戶處于等待狀態(比如,重建索引)。

應用程序類 -Application

此類等待事件是由于用戶應用程序的代碼引起的(比如,鎖等待)。

群集類 -Cluster

此類等待事件和真正應用群集 RAC 的資源有關(比如,gc cr block busy 等待事件)。

提交確認類 -Commit

此類等待事件只包含一種等待事件——在執行了一個 commit 命令后,等待一個重做日志寫確認(也就是 log file sync)。

并發類 -Concurrency

此類等待事件是由內部數據庫資源引起的(比如閂鎖)。

配置類 -Configuration

此類等待事件是由數據庫或實例的不當配置造成的(比如,重做日志文件尺寸太小,共享池的大小等)。

空閑類 -Idle

此類等待事件意味著會話不活躍,等待工作(比如,sql * net messages from client)。

網絡類 -Network

和網絡環境相關的一些等待事件(比如 sql* net more data to dblink)。

其它類 -Other

此類等待事件通常比較少見(比如 wait for EMON to spawn)。

調度類 -Scheduler

此類等待事件和資源管理相關(比如 resmgr: become active)。

系統 I / O 類 -System I/O

此類等待事件通過是由后臺進程的 I / O 操作引起的(比如 DBWR 等待 -db file paralle write)。

用戶 I / O 類 -User I/O

此類等待事件通常是由用戶 I / O 操作引起的(比如 db file sequential read)。

三、理解等待事件

每一個等待事件,都表明數據庫的一種活動狀態。從上面的查詢可見,系統內置了很多等待事件,可以通過數據字典 V$EVENT_NAME 去了解每個等待事件。下面通過一個最為常見的等待事件進行說明。

這個等待事件“db file sequential read”, 直譯過來為“數據文件順序讀取”,是屬于“User I/O”類的等待事件。它通常是與單個數據塊相關的讀取操作,大多數情況下讀取一個索引塊或者通過索引讀取一個數據塊,會記錄這個等待。該事件說明在單個數據塊上大量等待,該值過高通常是由于表間連接順序很糟糕,或者使用了非選擇性索引。通過將這種等待與 statspack 報表中已知其它問題聯系起來(如效率不高的 sql),通過檢查確保索引掃描是必須的,并確保多表連接的連接順序來調整,DBCACHESIZE 可以決定該事件出現的頻率。

該等待事件包含了三個參數,分別為:

file#: 代表 oracle 要讀取的文件的絕對文件號

block#: 從這個文件中開始讀取的起始數據塊塊號

blocks: 讀取的 block 數量。通常是 1,表示單個 block 讀取。

通過上面這些參數,關聯數據字典可以確定發生等待事件的對象(即找到了熱點對象)。然后針對不同的情況,有針對性的進行解決。

對等待事件的了解越多,可更加深入理解數據庫運行機制,進而提高整體優化能力。后面,我會介紹一下常見的等待事件。

四、觀察等待事件

系統內置了一些視圖,通過這些視圖可以了解整體(系統級)、局部(會話級)的等待事件發生情況及各類別事件的分類統計。下面針對一些主要的視圖,說明一下。

1、v$event_name

系統支持的等待事件,可以查看等待事件所屬類別、參數的含義等信息。

2、v$system_wait_class

displays the instance-wide time totals for each registered wait class.

等待事件類別的統計信息(系統級)。通過這一視圖,可從全局角度了解系統那類操作等待較多。

3、v$system_event

等待事件的統計信息(系統級)。展開來說,是提供了自實例啟動后各個等待事件的概括。常用于獲取系統等待信息的歷史影象。而通過兩個 snapshot 獲取等待項增量,則可以確定這段時間內系統的等待項。

主要的字段包括:

TOTAL_WAITS

自數據庫啟動到現在,此等待事件總等待次數。

TIME_WAITED

此等待事件的總等待時間(單位:百分之一秒)。這個數據表示從數據庫啟動以來這個等待事件在所有會話(包括已經結束和正保持連接狀態的會話)總的等待事件之和。

AVERAGE_WAIT 

此等待事件的平均等待用時(單位:百分之一秒)。

time_waited/total_waits

TOTAL_TIMEOUTS

此等待事件總等待超時次數。

SQL – 按等待時長查看頂級事件

4、v$session_event

和 v$system_event 相類似,記錄的是會話在其生命周期中各個等待事件的累計值。跟前者相比,增加了 session_id 信息。這些信息也會被同時累積到 v$system_event 中。需要注意的是,當一個會話重新建立時,統計信息將被設置為 0。

5、v$session_wait、v$session

活動會話正在等待的資源或事件信息。在 10g 將這個視圖和 v$session 視圖進行了合并。這是一個尋找性能瓶頸的關鍵視圖。它提供了任何情況下 session 在數據庫中當前正在等待什么。當系統存在性能問題時,本視圖可以做為一個起點指明探尋問題的方向。

需要注意的是,當等待不再存在時,會話先前出現的那些等待的歷史也將消失,從而使得事后診斷非常困難。V$SESSION_EVENT 提供了累積的但不是非常詳細的數據。可以通過歷史視圖 v$session_wait_history 獲得歷史信息。

主要的字段包括:

EVENT

會話當前等待的事件,或者最后一次等待事件。

WAIT_TIME

會話等待事件的時間(單位:百分之一秒)。

值 0: 最后一次等待時間(單位:10ms),當前未在等待狀態。

值 =0: session 正在等待當前的事件。

值 =-1: 最后一次等待時間小于 1 個統計單位,當前未在等待狀態。

值 =-2: 時間統計狀態未置為可用,當前未在等待狀態。

STATE

等待狀態(提供對 wait_time 和 second_in_wait 字段的解釋)

1) waiting:

SESSION 正等待這個事件。

2) waited unknown time:

由于設置了 timed_statistics 值為 false,導致不能得到時間信息。表示發生了等待,但時間很短。

3)wait short time:

表示發生了等待,但由于時間非常短不超過一個時間單位,所以沒有記錄。

4)waited knnow time:

如果 session 等待然后得到了所需資源,那么將從 waiting 進入本狀態。

WAIT_TIME/SECOND_IN_WAIT

Wait_time 和 Second_in_wait 字段值與 state 相關。

1)state=waiting

wait_time 無用,second_in_wait 值是實際的等待時間(單位: 秒)。

2)state=wait unknow time

wait_time 和 second_in_wait 都無用。

3)state=wait short time

wait_time 和 second_in_wait 都無用。

4)state=waiting known time

wait_time 值就是實際等待時間(單位: 秒),second_in_wait 值無用。

6、v$sessionwaithistory

記錄會話最近 n 次等待事件,即 v$session_wait 的歷史記錄。默認是記錄 10 次,可進行修改。

7、v$event_histogram

這個視圖記錄了等待事件的柱狀圖分布,從而可以對一個等待事件具體分布有進一步了解。在 v$session_event 或 v$system_event 視圖記錄的是累積信息以及關于等待的平均值,無法得知個別等待消耗的時間。

下面將會話等待事件與各視圖之間的關系,總結整理如下:

一個會話一次只發生一個等待事件。如果看到了其他的等待事件,那僅僅表示在下一個時間片上發生了等待。在某個時刻只存在一個等待。

v$session_wait 中的 wait_time 和 second_in_wait 字段以秒為單位,而 v$session_event 中的 time_waited 和 average_wait 字段是以百分之一秒為單位。

v$session_wait 的等待事件結束后,v$session_event 的統計信息將會發生改變。

v$session_wait 的統計信息意義不大,因為信息是實時變化的。

當 v$session_wait 里面的等待事件結束時,v$session_wait 中的 seconds_in_wait 字段值被復制到 v$session_event 中 time_waited 字段,而 v$session_event 視圖的 average_time 字段同時也被修改。

五、常見等待事件

Oracle 的等待事件非常多,不同的版本也有些差異。下面對一些常見的等待事件進行說明。希望對大家的日常工作能帶來幫助。

1、buffer busy waits

發生原因:

當一個會話將數據塊從磁盤讀到內存中時,它需要到內存中找到空閑的內存空間來存放這些數據塊,當內存中沒有空閑的空間時,就會產生這個等待。除此之外,還有一種情況就是會話在做一致性讀時,需要構造數據塊在某個時刻的前映像。此時需要申請內存塊來存放這些新構造的數據塊,如果內存中無法找到這樣的內存塊,也會發生這個等待事件。

參數含義:

File#

等待訪問數據塊所在的文件 id 號

Blocks

等待訪問的數據塊號

Id

10g 之前,這個值表示等待事件原因;10g 之后則表示等待事件的類別。

優化方向:根據產生此等待事件的類別不同,優化方向也不太一樣。

數據塊

一般優化方向是優化 SQL,減少邏輯讀、物理讀;或者是減少單塊的存儲數據規模。

數據段頭

一般優化方向是增加 FREELISTS 和 FREELIST GROUPS。確保 FCTFREE 和 PCTUSED 之間的間隙不是太小,從而可以最小化 FREELIST 的塊循環。

撤銷塊

一般優化方向為應用程序,錯峰使用數據對象。

撤銷段頭

如果是數據庫系統管理 UNDO 段,一般不需要干預。如果是自行管理的,可以減少每個回滾段的事務個數。

2、buffer latch

發生原因:

內存中數據塊的存放位置是記錄在一個 Hash 列表當中的。當一個會話需要訪問某個數據塊時,它首先要搜索這個 Hash 列表,從列表中獲得數據塊的地址,然后通過這個地址去訪問需要的數據塊,這個列表 oracle 會使用一個 latch 來保護它的完整性。當一個會話需要訪問這個列表時,需要獲取一個 latch,只有這樣,才能保證這個列表在這個會話的瀏覽當中不會發生改變。如果列表過長,導致會話搜索這個列表花費的時間太長,使其他的會話處于等待狀態。同樣的數據塊被頻繁訪問,就是我們通常說的熱塊問題。

參數含義:

latch addr

會話申請的 latch 在 SGA 中的虛擬地址。

chain#

buffer chains hash 列表中的索引值。當這個參數的值等于 0xffffff 時,說明當前的會話正在等待一個 LRU latch。

優化方向:

可以考慮的優化方向有使用多個 buffer pool 的方式來創建更多的 buffer chains 或者使用參數 db_block_lru_latches 來增加 latch 的數量,以便于更多的會話可以獲得 latch,這兩種方法可以同時使用。

3、db file sequential read

發生原因:

通常是與單個數據塊相關的讀取操作,大多數情況下讀取一個索引塊或者通過索引讀取一個數據塊,會記錄這個等待。可能顯示表的連接順序不佳,或者不加選擇地進行索引。對于大量事務處理、調整良好的系統,這一數值大多是很正常的,但在某些情況下,它可能暗示著系統中存在問題。應當將這一等待統計量與性能報告中的已知問題(如效率較低的 SQL)聯系起來。檢查索引掃描,以保證每個掃描都是必要的,并檢查多表連接的連接順序。

DB_CACHE_SIZE 也是這些等待出現頻率的決定因素。有問題的散列區域 (Hash-area) 連接應當出現在 PGA 內存中,但它們也會消耗大量內存,從而在順序讀取時導致大量等待。它們也可能以直接路徑讀 / 寫等待的形式出現。

參數含義:

file#

代表 oracle 要讀取的文件的絕對文件號

block#

從這個文件中開始讀取的起始數據塊塊號

blocks

讀取的 block 數量。通常是 1,表示單個 block 讀取。

優化方向:

這個等待事件,不一定代表一定有問題。如果能確定是有問題,可以按照下面優化思路。

修改應用,避免出現大量 IO 的 sql,或者減少其頻率。

增加 data buffer,提高命中率。

采用更好的磁盤子系統,減少單個 IO 的響應時間,防止物理瓶頸的出現。

4、db file scattered read

發生原因:

這是一個用戶操作引起的等待事件,當用戶發出每次 I / O 需要讀取多個數據塊這樣的 SQL 操作時,會產生這個等待事件,最常見的兩種情況全表掃描和索引快速掃描。這個名稱中的 scattered(發散)可能會導致很多人認為它是以 scattered 的方式來讀取數據塊的,其實恰恰相反,當發生這種等待事件時,SQL 的操作都是順序地讀取數據塊的,比如 FTS 或 IFFS 方式。其實這里 scattered 指的是讀取的數據塊在內存中的存放方式。它們被讀取到內存中后,是以分散的方式存放在內存中,而不是連續的。

參數含義:

file#

代表 oracle 要讀取的文件的絕對文件號。

block#

從這個文件中開始讀取的起始數據塊塊號。

blocks

讀取的 block 數量。

優化方向:

這種情況通常顯示與全表掃描相關的等待。當全表掃描被限制在內存時,它們很少會進入連續的緩沖區內,而是分散于整個緩沖存儲器中。如果這個數目很大,就表明該表找不到索引,或者只能找到有限的索引。盡管在特定條件下執行全表掃描可能比索引掃描更有效,但如果出現這種等待時,最好檢查一下這些全表掃描是否必要。

5、direct path read

發生原因:

這個等待事件發生在會話將數據塊直接讀取到 PGA 當中而不是 SGA 中的情況,這些被讀取的數據通常是這個會話私有的數據,所以不需要放到 SGA 作為共享數據,因為這樣做沒有意義。這些數據通常是來自于臨時段上的數據,比如一個會話中 SQL 的排序數據,并行執行過程中間產生的數據,以及 Hash join、Merge join 產生的排序數據,因為這些數據只對當前會話的 SQL 操作有意義,所以不需要放到 SGA 當中。當發生 direct path read 等待事件時,意味著磁盤上有大量的臨時數據產生,比如排序、并行執行等操作,或者意味著 PGA 中空閑空間不足。

在 11g 中,全表掃描可能使用 direct path read 方式,繞過 buffer cache,這樣的全表掃描就是物理讀了。在 10g 中,都是通過 gc buffer 來讀的,所以不存在 direct path read 的問題。

參數含義:

file#

文件號

first block#

讀取的起始塊號

block count

以 first block 為起點,連續讀取的物理塊數

優化方向:

有了這個等待事件,需要區分幾種情況。一個方向是增大排序區等手段,一個方向是減少讀取 IO 量或判斷是否通過緩沖區讀的方式更加高效。

6、direct path write

發生原因:

發生在 oracle 直接從 PGA 寫數據到數據文件或臨時文件,這個操作可以繞過 SGA。在磁盤排序中最為常見。對于這種情況應該找到操作最為頻繁的數據文件(如果是排序,很有可能是臨時文件),分散負載。

參數含義:

file#

文件號

first block#

讀取的起始塊號

block count

以 first block 為起點,連續寫入的物理塊數

優化方向:減少 IO 寫入規模。

7、library cache lock

發生原因:

這個等待事件發生在不同用戶在共享池中由于并發操作同一個數據庫對象導致的資源爭用的時候。比如當一個用戶正在對一個表做 DDL 操作時,其他的用戶如果要訪問這張表,就會發生 library cache lock 等待事件,它要一直等到 DDL 操作完畢后,才能繼續操作。

參數含義:

Handle address

被加載的對象的地址。

Lock address

鎖的地址。

Mode

被加載對象的數據片段。

Namespace

被加載對象在 v$db_object_cache 視圖中的 namespace 的名稱。

優化方向:優化方向是查看鎖定對象,減少爭用。

8、library cache pin

發生原因:

這個等待事件和 library cache lock 一樣是發生在共享池中并發操作引起的等待事件。通常來講,如果 oracle 要對一些 pl/sql 或視圖這樣的對象做重新編譯,需要將這些對象 pin 到共享池中。如果此時這個對象被其他的對象持有,就會產生一個 library cache pin 的等待。

參數含義:

Handle address

被加載的對象的地址。

Lock address

鎖的地址。

Mode

被加載對象的數據片段。

Namespace

被加載對象在 v$db_object_cache 視圖中的 namespace 的名稱。

優化方向:優化方向是查看鎖定對象,減少爭用。

9、log file sync

發生原因:

這是一個用戶會話行為導致的等待事件。當一個會話發出一個 commit 命令時,LGWR 進程會將這個事務產生的 redo log 從 log buffer 里寫到磁盤上,以保證用戶提交的信息被安全地記錄到數據庫中。會話發出 commit 指令后,需要等待 LGWR 將這個事務產生的 redo 成功寫入到磁盤之后,才可以繼續進行后續的操作,這個等待事件就叫做 log file sync。當系統中出現大量的 log file sync 等待事件時,應該檢查數據庫中是否有用戶在做頻繁的提交操作。這種等待事件通常發生在 OLTP 系統上。OLTP 系統中存在很多小的事務,如果這些事務頻繁被提交,可能引起大量 log file sync 的等待事件。

優化方向:

提高 LGWR 性能,盡量使用快速磁盤

使用批量提交

適當使用 nologging/unrecoverable 等選項

10、SQL*Net message from client

發生原因:

表明前臺服務器進程等待客戶進行響應。這個等待事件是由于等待用戶進程的響應所引起的,它并不表明數據庫就存在什么不正常。如果網絡出現故障時,這種等待時間就會經常發生。

11、SQL*Net message to client

發生原因:

這個等待事件發生在服務器端向客戶端發送消息的時候。當服務器端向客戶端發送消息產生等待時,可能的原因是用戶端太繁忙,無法及時接收服務器端送來的消息,也可能是網絡問題導致消息無法從服務器端發送給客戶端。

“怎么理解 Oracle 等待事件的分類、發現及優化”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注丸趣 TV 網站,丸趣 TV 小編將為大家輸出更多高質量的實用文章!

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-07-24發表,共計8674字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 岳池县| 贵南县| 抚远县| 丰镇市| 都江堰市| 若羌县| 孟连| 呼图壁县| 甘肃省| 奇台县| 新安县| 尼勒克县| 宜昌市| 嘉义县| 曲周县| 方城县| 从江县| 涿鹿县| 仙游县| 云南省| 牙克石市| 胶南市| 商丘市| 界首市| 仁化县| 冷水江市| 西安市| 西吉县| 达孜县| 嘉鱼县| 高安市| 射阳县| 东城区| 拉孜县| 平顶山市| 江都市| 贵港市| 凉城县| 黄石市| 大关县| 繁昌县|