最近一套12C庫出現(xiàn)大量cursor:mutex X異常等待的故障,借此機會在這里和大家分享下分析過程及后續(xù)處理。先簡單介紹下故障過程,一天數(shù)據(jù)庫突然等待事件異常告警,登上數(shù)據(jù)庫查看異常等待事件發(fā)現(xiàn)大量cursor:mutex X,基于優(yōu)先恢復業(yè)務的原則,將其kill之后數(shù)據(jù)庫恢復正常。后續(xù)開始對故障進行分析及進行后續(xù)處理,欲知詳情,請聽下面分解。
1、查看故障時段AWR:
發(fā)現(xiàn)cursor:mutex X異常等待事件占了54%的DBTIME
2、cursor:mutexx等待事件原理:
cursor正在被解析并嘗試以獨占(exclusive)模式獲取cursormutex時產(chǎn)生的等待即為cursor:mutexx。
引起問題的原因包括頻繁硬解析、highversioncount、cursor失效及未知BUG等。但本質(zhì)上是一些會話長時間持有互斥鎖,以至于其他會話不得不等待資源。如果在保護庫緩存結構的latches/mutexes上發(fā)生爭用,這意味著解析面臨壓力。解析SQL需要更長的時間,因為它無法獲得所需的資源。這會延遲其他操作,并且通常會降低系統(tǒng)的速度。
查看問題剛出現(xiàn)時的歷史會話(DBA_HIST_ACTIVE_SESS_HISTORY)如下:
從上圖我們可以看到多個會話同時執(zhí)行SQL_ID:3t5xt2hkrchpy,a9xqubd880h5n,且堵塞源不停在變,會話相互之間發(fā)生cursor:mutex X等待。
3、查看故障時段的AWR:
從以上圖我們可以看到SQL_ID:3t5xt2hkrchpy執(zhí)行時間及CPU消耗TOP1,其SQL及其他SQL的版本數(shù)都很高。
4、查看故障時段做的hang分析日志如下:
通過hang分析日志我們可以看到Blcoking其他session的會話操作是查找子Currsor,所以故障大概率是由于子Cursor過多,進行查找時發(fā)生等待導致。而產(chǎn)生大量的子Cursor的原因是NLSSettings。
普及下什么是versioncount?
一個SQL第一次執(zhí)行時,會進行硬解析,同時創(chuàng)建parentcursor和childcursor。
當這個SQL時再次執(zhí)行時,首先會對SQL語句進行特殊的hash運算,對應生成一個hashvalue。Hashvalue存放在parentcursor中,然后會用這個hashvalue到paranetcursor的bucket中匹配,如果相同的hashvalue 已存在parentcursor里,則繼續(xù)遍歷這個childcursor,如果可重用,那么就沿用childcursor的信息,如果不能重用,就會重新生成一個新的childcursor。一個parentcursor下childcursor的總數(shù),就是這個SQL的versioncount。
highversion count指的就是childcursor總數(shù)很高。在AWR報告中,默認verioncount超過20的SQL就會顯示在orderby version count中。根據(jù)經(jīng)驗versioncount如果超過100,可能就需要引起注意了。
5、綜上所述,我們發(fā)現(xiàn)本次故障大概率是由于highversion count導致,那為啥這么多SQL的versioncount都這么高呢,初步懷疑是觸發(fā)BUG了,我們這庫是CDB模式,并且多個PDB的字符集不一致,通過MOS查找到一篇類似的文章:
通過SR確認有可能觸發(fā)BUG25054064,該BUG在2020年1月份的DBRU中fixed了,我們只需要打上
Patch31741641: DATABASE OCT 2020 RELEASEUPDATE12.2.0.1.201020即可,因為DBRU都是累積的。
查看其readme提供的BUG修復的連接發(fā)現(xiàn)BUG25054064已在補丁集中。
6、打完補丁之后截止目前為止再沒出現(xiàn)過類似的故障,我們查看SQL的versioncount發(fā)現(xiàn)降低了一個數(shù)量級。
另外由于字符集不匹配導致的highversion count在DocID 2542447.1也詳細介紹了處理方法,用于緩解子Cursor過多查找緩慢導致的等待:
1)通過具體SQL_ID將其從sharedpool清除掉。
SQL>select address,hash_value,version_count from v$sqlarea wheresql_id=a9x5sbz88kmfh;
ADDRESSHASH_VALUE VERSION_COUNT
---------------- -----------------------
000000006BFFAC00 3498659280 2
SQL>exec dbms_shared_pool.purge(,C);
Ex:
SQL>exec dbms_shared_pool.purge(000000006BFFAC00,3498659280,C);
PL/SQLprocedure successfully completed.
2)將_cursor_obsolete_threshold參數(shù)設置為較低的值減少子Cursor數(shù)量,不過這個取決于應用程序需求,_cursor_obsolete_threshold的默認值是8192,可以將其設置為2048或1024,重啟生效。
文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/130070.html
摘要:什么時候會出現(xiàn)線程不安全操作并非原子。只有單個組件,且它是線程安全的。這種情況下,就是的線程安全實際是委托給了整個表現(xiàn)出了線程安全。 當多個線程去訪問某個類時,如果類會表現(xiàn)出我們預期出現(xiàn)的行為,那么可以稱這個類是線程安全的。 什么時候會出現(xiàn)線程不安全? 操作并非原子。多個線程執(zhí)行某段代碼,如果這段代碼產(chǎn)生的結果受不同線程之間的執(zhí)行時序影響,而產(chǎn)生非預期的結果,即發(fā)生了競態(tài)條件,就會...
閱讀 1356·2023-01-11 13:20
閱讀 1707·2023-01-11 13:20
閱讀 1215·2023-01-11 13:20
閱讀 1906·2023-01-11 13:20
閱讀 4165·2023-01-11 13:20
閱讀 2757·2023-01-11 13:20
閱讀 1402·2023-01-11 13:20
閱讀 3671·2023-01-11 13:20