tft每日頭條

 > 生活

 > oracle發展趨勢

oracle發展趨勢

生活 更新时间:2024-09-15 15:10:07

作為一名混迹數據庫江湖十幾年的老 DBA,當你對關系型數據庫的了解越來越深入時,你會發現,ORACLE 數據庫真的是強大到令人發紫!

Oracle 數據庫的強大,不僅體現在其對 ACID 的巧妙實現,其對高并發的完美支持,更重要的是他的可管理性,包括可度量、可回溯,以及出現問題後的問題核查接口和問題檢查方法論,真是強大到令人發紫, 這是其他關系型數據庫短期内還無法超越的。

問題來了!!!!

電話響了,是某銀行一位熟悉的資深 DBA 的來電。

“在嗎?現在應用連接數據庫會 hang 住,sysdba 登陸也會 hang 住,無報錯,該如何處理?”

沒有往日的寒暄和客套,直入主題!

人的聲音是有表情的,從電話那頭急促的語氣,不難判斷,客戶很着急。

可能有些朋友不清楚數據庫登錄 hang 住是怎樣的一種現象,下圖可以腦補一下:

oracle發展趨勢(ORACLE強大的令人發指)1

也就是說,正常的登錄是可以快速看到 “SQL>” 這樣的提示符的,但出現異常時,就會長時間等不到 “SQL>” 這樣的提示符, 這就是所謂的登錄數據庫會 hang 住。

看到這裡,有些朋友開始激動了,要猜一下原因,試一下身手!

1)是不是數據庫歸檔滿了?

答:這… 歸檔滿了,sysdba 登錄會報 ORA - 歸檔錯誤相關的提示!而且注意細節,之前提到了,客戶是資深的 DBA,顯然這種可能性早就被排除掉了, 注意細節啊 ^_^

2)查一下等待事件,看看在等什麼呢?

答:這… 數據庫都連不進去了,怎麼發出 SQL 來查詢呢…

3)alert 日志有什麼明顯報錯麼?

答:在這個 case 中 alert 日志沒有報錯,也沒有明顯問題…

三闆斧用完後,接下來不妨思考個兩三分鐘,如果是你,接下來你要怎麼指揮這場戰鬥…

“别着急,你收兩個 SSD 保存現場,然後殺掉 pmon,先恢複業務,然後把 SSD 的 trace 發我,我來做下 RCA!”

客戶殺完 pmon 進程,數據庫自動重啟後,業務恢複正常。随後将 SSD 發了過來。

這裡有些同學聽到這些術語,有些摸不着頭腦了:

什麼是 SSD?固态盤(不會吧)?

還有什麼是 RCA 呢?

這裡給大家科普一下:

SSD 其實就是 System State Dump, 系統即時狀态 DUMP 的首字母組合,

RCA 就是 Root Cause Analyze, 根因分析,是解決問題的難度要大許多,也有意思許多

為什麼要收集 SSD 呢?

因為原因的不确定性,怎麼能抓到蝴蝶效應中的那隻蝴蝶呢?那就需要足夠的信息!

多年前未掌握 SSD 這個功能的時候,出現問題,喜歡收集 v$session,v$session_wait,v$sqlarea,v$lock 等動态性能的相關信息,然後重啟,但是後來往下分析的時候,發現少收集了什麼信息,導緻分析不順利,後悔莫及…

當時就在想,Oracle 是否有一個一鍵收集的功能:

把想要的,不想要的,全都收集下來呢!答案就是 SSD。

甚至是當 sysdba 無法登陸時,Oracle 依然可以直接 attach 到共享内存,将内存中的即時狀态全部抓取下來,包括系統當前各個進程正在執行什麼、正在等什麼、進城的堆棧等信息,真是強大大令人發紫的一個功能。

SSD 的收集非常簡單,照敲就是了,以下是 SSD 收集的命令

### sqlplus -prelim "/as sysdba"

SQL>oradebug setmypid

SQL>oradebug dump systamstate 266

SQL>-- 等上 30 秒到 1 分鐘

SQL>oradebug dump systamstate 266

SQL>oradebug tracefile_name

接下來就帶領大家一起去分析 SSD,做根因分析,你會發現工作是一件多麼有趣的事情。

1. 查看登陸進程在等什麼

從 xxdb_ora_33030248.trc 中搜索 "waiting for" 可以看到:

oracle發展趨勢(ORACLE強大的令人發指)2

可以看到:

1)有N 個進程都在等 LATCH:librarycache,latch, 并且 latch 是同一個即 70000006b9d8008

2) 1個進程在等 cursor:pin X,即在等待 cursor 類型的 mutex

3) latch 等待的時間已經長達達到 3723 秒

這裡不難看出:

由于登陸的時候,要執行包括驗證用戶、獲取權限等内部的 SQL(遞歸 SQL),但是在發出 SQL 後,由于長時間無法獲取 latch:library cache 這樣的資源,因此登陸看上去就像 hang 住了一樣… 接下來,我們隻需要找到無法 latch:library cache 的原因,就可以解開數據庫 hang 住的真相了!

2. 第一次頭腦風暴

看到這裡,也許有同學迫不及待地又想再試試身手:

是不是硬解析的問題?

可以看到:

當客戶端發出的 SQL 到達數據庫的服務進程後,要先在 shared pool 中去找内存中是否存在該 SQL 和執行計劃,如果存在則拿到執行計劃直接執行即可。

那麼 oracle 是如何查找的呢?就是對 SQL 文本計算 hash 值後,獲取 latch:library cache(11g 中則采用 mutex 代替),對對應的鍊表進行掃描即可。

因此,軟解析也會申請該 latch。

所以,不能說是簡單的硬解析的問題,一切都有可能 。

BTW, 筆者面試過很多人,其實更像看到的是分析問題的方法論,而不是使勁的猜…

為什麼呢?我們總會遇到很多經驗範圍之外的事情,怎麼可能猜出自己不知道的事情呢?

3. 找原因,Orale 就是這麼簡單!

既然長時間無法獲取 latch, 那麼是誰在持有 latch 呢?

需要說明的是,當無法獲取 latch:library cache 的時候,Oracle 在實現上,會将自己放到 latch 的等待着列表 waiter list 當中,那麼自然也就有一個對應的持有者列表,

這麼做的原因在于,當持有者使用完該 latch 後,到等待者列表中喚醒等待的進程即可。同時,Oracle 在做 SSD 的時候,就已經把持有者給打印到 trace 裡了。

搜索 "waiting for 70000006b9d8008 Childlibrary"

可以看到 “possible holder pid = 19ospid=10027060”,即持有者是 pid = 19 ospid=10027060

oracle發展趨勢(ORACLE強大的令人發指)3

接下來,我們需要去看看 latch 持有者即 pid = 19 ospid=10027060 的進程在做什麼

4. 持有 latch 的人去哪了?

搜索 “ospid:10027060”,就可以看到 LATCH 持有者的進程的詳細信息了

包括進程名,在執行什麼 SQL,進程狀态是什麼,在等什麼資源…

oracle發展趨勢(ORACLE強大的令人發指)4

可以看到:

Pid=19,spid=10027060 的進程,是 ORACLE 的一個 JOB SLVAE 進程 j001,

由于他在持有 latch, 導緻了很多進程需要等待,

holding (efd=5) 70000006b9d8008 Child library cache

乘勝追擊,進一步查看該進程在等什麼資源:

oracle發展趨勢(ORACLE強大的令人發指)5

可以看到:

該進程對應的 SID 是 534,當前實際上并沒有在等待任何資源,因為 last wait 表示的是上一次的等待了。長時間持有 latch:library cache, 導緻 N 個進程登陸執行内部 SQL 的時候無法獲取 latch, 繼而無法登陸,但是,進程持有者 PID=19,SID=534,又沒有在等待任何資源,SQL:0 表示當前沒有在執行任何 SQL。

生無可戀了,那我怎麼知道進程持有者在做什麼呢,這還怎麼往下查呢…

提示:這裡請記住 latch 的持有者,SID 是 534,534!

5.陷入僵局

還記得麼,Oracle 有一套方法論,那麼方法論就是查看 call stack, 通過查看進程調用的函數軌迹,就可以判斷出來,當前進入了哪一種場景。

但是由于客戶一着急,收集的 SSD 的 level 不夠,因為沒有打印每個進程的 call stack!

這可如何是好啊, 難道問題要陷入僵局..

如果是你,接下來,會怎麼往下打這一場仗

6.細節決定成敗

如圖所示:

oracle發展趨勢(ORACLE強大的令人發指)6

紅色加框部分顯示,該進程的狀态處于 DEAD 狀态!即持有 latch 的那個進程已經死掉了!

看到這裡:

有些朋友又要蒙圈了,“這是什麼情況?”

有些朋友可能已經開始有點想法了,心裡在嘿嘿樂…

沒錯,實際上,這已經設計到道和術的問題。

技術層面上,一路找到最終的阻塞者後,已經進行不下去了!

接下來,大家不妨停下來,思考一下:

原理層面呢?

學了那麼多體系架構的東西,怎麼用到生産問題中呢?

是否可以運用原理幫助解開這個數據庫挂起的問題呢?

我面試候選 DBA 的時候,喜歡問原理。

很多候選 DBA 答不上來的時候,總喜歡解釋道,而且是很坦然的解釋到:

不好意思,過去從來不關注原理, 熟練操作就可以了!

聽到這些回答,本人總會語重心長的讓對方做一道故障題,不掌握原理是不可能解開的,結果很顯然的,候選人自然答不上來,之後我會演示問題處理和分析過程,候選人往往都會重新定義對道和術的認知,孺子可教...

工程師熟練操作是基礎,,但是從中級工程師到高級工程師,再到資深工程師,深入原理是一道坎,能将原理熟練應用到實際分析中又是一道坎。什麼時候跨過坎了,層次也就不一樣了。很多 DBA 因為沒有人點撥,可能永遠過不了那道坎…

7. 振聾發聩的一問!

為什麼進程死掉了,但是進程還在持有 latch 資源不釋放?

PMON 做什麼去了?他是幹什麼吃的…

是的!這就是問題的關鍵!當聽到這麼一個振聾發聩的驚天一問時,恭喜你,跨過了一道坎!

如果已經提示到這個程度,依然無法發出這麼一個疑問,實在是!

8. 看看 PMON 在做什麼

搜索(PMON),就可以找到 SSD 中 PMON 進程的相關信息。如下所示:

oracle發展趨勢(ORACLE強大的令人發指)7

可以看到:

PMON 正在等待 cursor:pin x,即申請模式為獨占,類型為 cursor 的 mutex

waiting for 'cursor: pin X'

該 mutux 的 IDN 是 idn=ad39e34, 即 hash 值

由于 PMON 被阻塞, 卡住了,因此自然沒有機會去清理死去進程所持有的 LATCH 了!

我們繼續真相又進了一步!

隻需要集中精力,需要繼續到底是是哪個進程,持有了 idn=ad39e34 的 mutex, 導緻 PMON 被長時間阻塞了,就可以解開問題的真相了!

接下來,大家不妨停下來,思考一下:

上圖中,但是 BLOCKING_SESS=0X0,這裡無法直接查看是誰阻塞了 PMON 進程。

那麼如果是你,你會怎麼往下查呢

……

9. 誰阻塞了 PMON

由于 PMON 進程以獨占方式申請

類型為 cursor 的 mutex 被阻塞,顯然該 MUTEX 正在被某個進程以獨享或獨占方式長時間持有。這顯然是不正常的。畢竟 MUTEX 是一種輕量級的資源。

接下來,我們在 TRACE 中搜索 "idn ad39e34 oper",結果如下所示

Mutex 70000003eec4be0(534, 0) idn ad39e34 oper GET_EXCL

Mutex 70000003eec4be0(534, 0) idn ad39e34 oper EXCL

可以看到:

該 MUTEX 上有兩個操作, OPER 即 Operation, 操作。

一個進程正在以獨占方式持有, 即 oper EXCL

另外一個進程正以獨占方式申請,oper GET_EXCL,Get 表示申請, 因此發生阻塞。該進程就是 PMON 進程。

紅色底紋部分的 534,就表示 MUTEX 的持有者,即 SID=534!

沒錯!SID=534 就是我們之前持有 latch:library cache 資源但已經死去的進程!

就是哪個等着被 PMON 清理的死去的進程!

10. 分析總結

綜合上述分析,總結如下:

1) N 個進程無法登陸,是因為無法獲得 latch:library cache 資源,該資源被一個死去的 SID=534 的進程持有了, 還沒釋放!

2) 按照原理,PMON 有義務去清理死去的 SID=534 的進程所持有的資源(latch 等).

3) 但是 PMON 隻有一個,PMON 正在等'cursor:pin X', 即以獨占方式申請類型為 cursor 的 mutex. 所以騰不出手來清理死去的 SID=534 的進程.

4) 正是 SID=534 持有 MUTEX,阻塞了 PMON !

假設說步驟 1,2 還合理的話,但是步驟 3 和 4 就毀三觀了!

總結起來就一句話,PMON 要去給死去的進程收屍,但是要獲得死去進程的同意!

這太不合理,太不科學了!為什麼會這樣呢…

很簡單,命中 BUG!

11. 輕松找 BUG

分析到這裡,掌握了問題的本質,那麼找 BUG 起來就很簡單了!

ORACLE 有一個強大的知識庫,記錄了全球客戶提交過的 CASE,裡面包含了 BUG 庫!

怎麼找到具體的 BUG 呢?

接下來不妨思考個 1 分鐘,如果是你,接下來你要怎麼定搜索關鍵字呢…


這裡,以 “pmon cursor dead” 做為關鍵字(其他關鍵字也可以),檢索 BUG。

很快,一個 BUG 的标題引起了注意:

Bug 8426816 PMON may hang cleaning up a dead process (rare)

點開 BUG,描述如下:

oracle發展趨勢(ORACLE強大的令人發指)8

怎麼樣,看完了吧,這不就是我們這個問題麼!

an instance hang may result due to PMON getting

blocked when attempting to clean up a failed process.

從現象到問題本質完全吻合!版本 10.2.0.4 也完全吻合!

當 PMON 要以 X 模式即獨占模式申請 MUTEX(cursor:pin X 就是一種 mutex)去清理一個死去進程的時候,該 MUTEX 被死去進程持有!從而導緻了數據庫 HANG 的情況!

問題原因與經驗總結

故障過程總結:

1) SID=534 的進程在持有 latch:library cache 和 mutex 等資源的時候進程死去

2) PMON 有義務清理該進程所持有的資源,如 mutex

3) 由于命中 BUG 5377099 ,導緻 PMON 無法獲得 MUTEX,被死去的進程 534 阻塞

4) 因此 SID=534 的死去進程長時間持有 latch:library cache, 導緻其他用戶執行遞歸

SQL,無法被軟解析,繼而無法登陸,即數據庫出現了 HANG 的故障!

經驗總結:

1) 運維公式 = 快速收集系統即時狀态信息 恢複業務

2) 快速收集系統即時狀态信息的目的是做 RCA,根因分析,以便在大規模數據庫運維中可以預防其他數據庫也出現類似問題。

3) 不定期做補丁分析,發現嚴重的 BUG,提前預防。

4)技巧重要,原理更重要。

通過這樣一個案例,你不難發現,ORACLE 的 SSD 功能,真是強大的令人發指!

,

更多精彩资讯请关注tft每日頭條,我们将持续为您更新最新资讯!

查看全部

相关生活资讯推荐

热门生活资讯推荐

网友关注

Copyright 2023-2024 - www.tftnews.com All Rights Reserved