共計(jì) 6275 個(gè)字符,預(yù)計(jì)需要花費(fèi) 16 分鐘才能閱讀完成。
這篇文章給大家介紹 Oracle 中有哪些等待事件,內(nèi)容非常詳細(xì),感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。
1. Buffer busy waits
從本質(zhì)上講,這個(gè)等待事件的產(chǎn)生僅說明了一個(gè)會(huì)話在等待一個(gè) Buffer(數(shù)據(jù)塊),但是導(dǎo)致這個(gè)現(xiàn)象的原因卻有很多種。常見的兩種是:
— 當(dāng)一個(gè)會(huì)話視圖修改一個(gè)數(shù)據(jù)塊,但這個(gè)數(shù)據(jù)塊正在被另一個(gè)會(huì)話修改時(shí)。
— 當(dāng)一個(gè)會(huì)話需要讀取一個(gè)數(shù)據(jù)塊,但這個(gè)數(shù)據(jù)塊正在被另一個(gè)會(huì)話讀取到內(nèi)存中時(shí)。
在新的版本中,第二種情況已經(jīng)被獨(dú)立出來,以 read by other session 取代~
Buffer busy waits 等待事件常見于數(shù)據(jù)庫中存在的熱快的時(shí)候,當(dāng)多個(gè)用戶頻繁地讀取或者修改同樣的數(shù)據(jù)塊時(shí),這個(gè)等待事件就會(huì)產(chǎn)生。如果等待的時(shí)間很長,我們在 AWR 或者 statspack 報(bào)告中就可以看到。
這個(gè)等待事件有三個(gè)參數(shù)。查看有幾個(gè)參數(shù)我們可以用以下 SQL:
SQL select name, parameter1, parameter2, parameter3 from v$event_name where name= buffer busy waits NAME PARAMETER1 PARAMETER2 PARAMETER3 -------------------- ---------- ---------- ---------- buffer busy waits file# block# class#
2.Buffer latch
內(nèi)存中數(shù)據(jù)塊的存放位置是記錄在一個(gè) hash 列表(cache buffer chains)當(dāng)中的。當(dāng)一個(gè)會(huì)話需要訪問某個(gè)數(shù)據(jù)塊時(shí),它首先要搜索這個(gè) hash 列表,從列表中獲得數(shù)據(jù)塊的地址,然后通過這個(gè)地址去訪問需要的數(shù)據(jù)塊,這個(gè)列表 Oracle 會(huì)使用一個(gè) latch 來保護(hù)它的完整性。當(dāng)一個(gè)會(huì)話需要訪問這個(gè)列表時(shí),需要獲取一個(gè) Latch,只有這樣,才能保證這個(gè)列表在這個(gè)會(huì)話的瀏覽當(dāng)中不會(huì)發(fā)生變化。
產(chǎn)生 buffer latch 的等待事件的主要原因是:
Buffer chains 太長,導(dǎo)致會(huì)話搜索這個(gè)列表花費(fèi)的時(shí)間太長,使其他的會(huì)話處于等待狀態(tài)。
同樣的數(shù)據(jù)塊被頻繁訪問,就是我們通常說的熱快問題。
這個(gè)等待事件有兩個(gè)參數(shù):
Latch addr:會(huì)話申請的 latch 在 SGA 中的虛擬地址,通過以下的 SQL 語句可以根據(jù)這個(gè)地址找到它對應(yīng)的 Latch 名稱:
select * from v$latch a,v$latchname b where addr=latch addr and a.latch#=b.latch#;
chain#:buffer chains hash 列表中的索引值,當(dāng)這個(gè)參數(shù)的值等于 s 0xfffffff 時(shí),說明當(dāng)前的會(huì)話正在等待一個(gè) LRU latch。
3.Control file parallel write
當(dāng)數(shù)據(jù)庫中有多個(gè)控制文件的拷貝時(shí),Oracle 需要保證信息同步地寫到各個(gè)控制文件當(dāng)中,這是一個(gè)并行的物理操作過程,因?yàn)榉Q為控制文件并行寫,當(dāng)發(fā)生這樣的操作時(shí),就會(huì)產(chǎn)生 control file parallel write 等待事件。
控制文件頻繁寫入的原因很多,比如:
— 日志切換太過頻繁,導(dǎo)致控制文件信息相應(yīng)地需要頻繁更新。
— 系統(tǒng) I/O 出現(xiàn)瓶頸,導(dǎo)致所有 I/O 出現(xiàn)等待。
這個(gè)等待事件包含三個(gè)參數(shù):
–Files:Oracle 要寫入的控制文件個(gè)數(shù)。
–Blocks:寫入控制文件的數(shù)據(jù)塊數(shù)目。
–Requests:寫入控制請求的 I/O 次數(shù)。
4.Control file sequential read
當(dāng)數(shù)據(jù)庫需要讀取控制文件上的信息時(shí),會(huì)出現(xiàn)這個(gè)等待事件,因?yàn)榭刂莆募男畔⑹琼樞驅(qū)懙模宰x取的時(shí)候也是順序的,因此稱為控制文件順序讀,它經(jīng)常發(fā)生在以下情況:
— 備份控制文件
–RAC 環(huán)境下不同實(shí)例之間控制文件的信息共享
— 讀取控制文件的文件頭信息
— 讀取控制文件其他信息
這個(gè)等待事件有三個(gè)參數(shù):
–File#:要讀取信息的控制文件的文件號。
–Block#:讀取控制文件信息的起始數(shù)據(jù)塊號。
–Blocks:需要讀取的控制文件數(shù)據(jù)塊數(shù)目。
5.Db file parallel read
這是一個(gè)很容易引起誤導(dǎo)的等待事件,實(shí)際上這個(gè)等待事件和并行操作(比如并行查詢,并行 DML)沒有關(guān)系。這個(gè)事件發(fā)生在數(shù)據(jù)庫恢復(fù)的時(shí)候,當(dāng)有一些數(shù)據(jù)塊需要恢復(fù)的時(shí)候,Oracle 會(huì)以并行的方式把他們從數(shù)據(jù)文件中讀入到內(nèi)存中進(jìn)行恢復(fù)操作。
這個(gè)等待事件包含三個(gè)參數(shù):
–Files:操作需要讀取的文件個(gè)數(shù)。
–Blocks:操作需要讀取的數(shù)據(jù)塊個(gè)數(shù)。
–Requests:操作需要執(zhí)行的 I/O 次數(shù)。
6.Db file parallel write
這是一個(gè)后臺等待事件,它同樣和用戶的并行操作沒有關(guān)系,它是由后臺進(jìn)程 DBWR 產(chǎn)生的,當(dāng)后臺進(jìn)程 DBWR 想磁盤上寫入臟數(shù)據(jù)時(shí),會(huì)發(fā)生這個(gè)等待。DBWR 會(huì)批量地將臟數(shù)據(jù)并行地寫入到磁盤上相應(yīng)的數(shù)據(jù)文件中,在這個(gè)批次作業(yè)完成之前,DBWR 將出現(xiàn)這個(gè)等待事件。如果僅僅是這一個(gè)等待事件,對用戶的操作并沒有太大的影響,當(dāng)伴隨著出現(xiàn) free buffer waits 等待事件時(shí),說明此時(shí)內(nèi)存中可用的空間不足,這時(shí)候會(huì)影響到用戶的操作,比如影響到用戶將臟數(shù)據(jù)塊讀入到內(nèi)存中。當(dāng)出現(xiàn) db file parallel write 等待事件時(shí),可以通過啟用操作系統(tǒng)的異步 I/O 的方式來緩解這個(gè)等待。當(dāng)使用異步 I/O 時(shí),DBWR 不在需要一直等到所有數(shù)據(jù)塊全部寫入到磁盤上,它只需要等到這個(gè)數(shù)據(jù)寫入到一個(gè)百分比之后,就可以繼續(xù)進(jìn)行后續(xù)的操作。
這個(gè)等待事件有兩個(gè)參數(shù):
–Requests:操作需要執(zhí)行的 I/O 次數(shù)。
–Timeouts:等待的超時(shí)時(shí)間。
7.Db file scattered read
這個(gè)等待事件在實(shí)際生產(chǎn)庫中經(jīng)常可以看到,這是一個(gè)用戶操作引起的等待事件,當(dāng)用戶發(fā)出每次 I/O 需要讀取多個(gè)數(shù)據(jù)塊這樣的 SQL 操作時(shí),會(huì)產(chǎn)生這個(gè)等待事件,最常見的兩種情況是全表掃描(FTS:Full Table Scan)和索引快速掃描(IFFS:index fast full scan)。
這個(gè)名稱中的 scattered(發(fā)散),可能會(huì)導(dǎo)致很多人認(rèn)為它是以 scattered 的方式來讀取數(shù)據(jù)塊的,其實(shí)恰恰相反,當(dāng)發(fā)生這種等待事件時(shí),SQL 的操作都是順序地讀取數(shù)據(jù)塊的,比如 FTS 或者 IFFS 方式(如果忽略需要讀取的數(shù)據(jù)塊已經(jīng)存在內(nèi)存中的情況)。這里的 scattered 指的是讀取的數(shù)據(jù)塊在內(nèi)存中的存放方式,他們被讀取到內(nèi)存中后,是以分散的方式存在在內(nèi)存中,而不是連續(xù)的。
這個(gè)等待事件有三個(gè)參數(shù):
–File#:要讀取的數(shù)據(jù)塊所在數(shù)據(jù)文件的文件號。
–Block#:要讀取的起始數(shù)據(jù)塊號。
–Blocks:需要讀取的數(shù)據(jù)塊數(shù)目。
8.Db file sequential read
這個(gè)等待事件在實(shí)際生產(chǎn)庫也很常見,當(dāng) Oracle 需要每次 I/O 只讀取單個(gè)數(shù)據(jù)塊這樣的操作時(shí),會(huì)產(chǎn)生這個(gè)等待事件。最常見的情況有索引的訪問(除 IFFS 外的方式),回滾操作,以 ROWID 的方式訪問表中的數(shù)據(jù),重建控制文件,對文件頭做 DUMP 等。這里的 sequential 也并非指的是 Oracle 按順序的方式來訪問數(shù)據(jù),和 db file scattered read 一樣,它指的是讀取的數(shù)據(jù)塊在內(nèi)存中是以連續(xù)的方式存放的。
這個(gè)等待事件有三個(gè)參數(shù):
–File#:要讀取的數(shù)據(jù)塊鎖在數(shù)據(jù)文件的文件號。
–Block#:要讀取的起始數(shù)據(jù)塊號。
–Blocks:要讀取的數(shù)據(jù)塊數(shù)目(這里應(yīng)該等于 1)。
9.Db file single write
這個(gè)等待事件通常只發(fā)生在一種情況下,就是 Oracle 更新數(shù)據(jù)文件頭信息時(shí)(比如發(fā)生 Checkpoint)。當(dāng)這個(gè)等待事件很明顯時(shí),需要考慮是不是數(shù)據(jù)庫中的數(shù)據(jù)文件數(shù)量太大,導(dǎo)致 Oracle 需要花較長的時(shí)間來做所有文件頭的更新操作(checkpoint)。
這個(gè)等待事件有三個(gè)參數(shù):
–File#: 需要更新的數(shù)據(jù)塊所在的數(shù)據(jù)文件的文件號。
–Block#:需要更新的數(shù)據(jù)塊號。
–Blocks:需要更新的數(shù)據(jù)塊數(shù)目(通常來說應(yīng)該等于 1)。
10.Direct path read
這個(gè)等待事件發(fā)生在會(huì)話將數(shù)據(jù)塊直接讀取到 PGA 當(dāng)中而不是 SGA 中的情況,這些被讀取的數(shù)據(jù)通常是這個(gè)會(huì)話私有的數(shù)據(jù),所以不需要放到 SGA 作為共享數(shù)據(jù),因?yàn)檫@樣做沒有意義。這些數(shù)據(jù)通常是來自與臨時(shí)段上的數(shù)據(jù),比如一個(gè)會(huì)話中 SQL 的排序數(shù)據(jù),并行執(zhí)行過程中間產(chǎn)生的數(shù)據(jù),以及 Hash Join,merge join 產(chǎn)生的排序數(shù)據(jù),因?yàn)檫@些數(shù)據(jù)只對當(dāng)前的會(huì)話的 SQL 操作有意義,所以不需要放到 SGA 當(dāng)中。當(dāng)發(fā)生 direct path read 等待事件時(shí),意味著磁盤上有大量的臨時(shí)數(shù)據(jù)產(chǎn)生,比如排序,并行執(zhí)行等操作。或者意味著 PGA 中空閑空間不足。
這個(gè)等待事件有三個(gè)參數(shù):
–Descriptor address: 一個(gè)指針,指向當(dāng)前會(huì)話正在等待的一個(gè) direct read I/O。
–First dba: descriptor address 中最舊的一個(gè) I/O 數(shù)據(jù)塊地址。
–Block cnt: descriptor address 上下文中涉及的有效的 buffer 數(shù)量。
11.Direct path write
這個(gè)等待事件和 direct path read 正好相反,是會(huì)話將一些數(shù)據(jù)從 PGA 中直接寫入到磁盤文件上,而不經(jīng)過 SGA。
這種情況通常發(fā)生在:
— 使用臨時(shí)表空間排序(內(nèi)存不足)
— 數(shù)據(jù)的直接加載(使用 append 方式加載數(shù)據(jù))
— 并行 DML 操作。
這個(gè)等待事件有三個(gè)參數(shù):
–Descriptor address: 一個(gè)指針,指向當(dāng)前會(huì)話正在等待的一個(gè) direct I/O.
–First dba: descriptor address 中最舊的一個(gè) I/O 數(shù)據(jù)塊地址。
–Block cnt: descriptor address 上下文中涉及的有效地 buffer 數(shù)量。
12.Enqueue
Enqueue 這個(gè)詞其實(shí)是 lock 的另一種描述語。當(dāng)我們在 AWR 報(bào)告中發(fā)現(xiàn)長時(shí)間的 enqueue 等待事件時(shí),說明數(shù)據(jù)庫中出現(xiàn)了阻塞和等待,可以關(guān)聯(lián) AWR 報(bào)告中的 enqueue activity 部分來確定是哪一種鎖定出現(xiàn)了長時(shí)間等待。
這個(gè)等待事件有 2 個(gè)參數(shù):
–Name:enqueue 的名稱和類型。
–Mode:enqueue 的模式。
13.Free buffer waits
當(dāng)一個(gè)會(huì)話將數(shù)據(jù)塊從磁盤讀到內(nèi)存中時(shí),它需要到內(nèi)存中找到空閑的內(nèi)存空間來存放這些數(shù)據(jù)塊,當(dāng)內(nèi)存中沒有空閑的空間時(shí),就會(huì)產(chǎn)生這個(gè)等待;除此之外,還有一種情況就是會(huì)話在做一致性讀時(shí),需要構(gòu)造數(shù)據(jù)塊在某個(gè)時(shí)刻的前映像(image),此時(shí)需要申請內(nèi)存來存放這些新構(gòu)造的數(shù)據(jù)塊,如果內(nèi)存中無法找到這樣的內(nèi)存塊,也會(huì)發(fā)生這個(gè)等待事件。
當(dāng)數(shù)據(jù)庫中出現(xiàn)比較嚴(yán)重的 free buffer waits 等待事件時(shí),可能的原因是:
–data buffer 太小,導(dǎo)致空閑空間不夠
— 內(nèi)存中的臟數(shù)據(jù)太多,DBWR 無法及時(shí)將這些臟數(shù)據(jù)寫到磁盤中以釋放空間
這個(gè)等待事件包含 2 個(gè)參數(shù):
–File#:需要讀取的數(shù)據(jù)塊所在的數(shù)據(jù)文件的文件號。
–Block#:需要讀取的數(shù)據(jù)塊塊號。
— 查詢阻塞的語句:
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(+);
14.Latch free
在 10g 之前的版本里,latch free 等待事件代表了所有的 latch 等待,在 10g 以后,一些常用的 latch 事件已經(jīng)被獨(dú)立了出來:
這個(gè)等待事件有三個(gè)參數(shù):
–Address: 會(huì)話等待的 latch 地址。
–Number:latch 號,通過這個(gè)號,可以從 v$latchname 視圖中找到這個(gè) latch 的相關(guān)的信息。
15.Library cache lock
這個(gè)等待時(shí)間發(fā)生在不同用戶在共享中由于并發(fā)操作同一個(gè)數(shù)據(jù)庫對象導(dǎo)致的資源爭用的時(shí)候,比如當(dāng)一個(gè)用戶正在對一個(gè)表做 DDL 操作時(shí),其他的用戶如果要訪問這張表,就會(huì)發(fā)生 library cache lock 等待事件,它要一直等到 DDL 操作完成后,才能繼續(xù)操作。
這個(gè)事件包含四個(gè)參數(shù):
–Handle address: 被加載的對象的地址。
–Lock address:鎖的地址。
–Mode:被加載對象的數(shù)據(jù)片段。
–Namespace:被加載對象在 v$db_object_cache 視圖中 namespace 名稱。
關(guān)于 Oracle 中有哪些等待事件就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯(cuò),可以把它分享出去讓更多的人看到。