聊聊昨天說的那個ORA-4030
?昨天有朋友看了我的文章提問CHATGPT能不能解讀AWR報告。怎么說呢,我們先來看一個例子。
我輸入了一個AWR報告的TOP 10 EVENT,看看CHATGPT如何解讀吧。
如果說解讀AWR的TOP EVENTS數據,我想CHATGPT不會比一些人類DBA差了,實際上最初的時候我也是如此解讀AWR報告的,只不過AWR報告不僅僅需要能解讀,還需要能分析,能夠把AWR中各種相關的數據綜合起來分析,才能從AWR報告中分析出深層次的問題。對于一些十分明顯的問題,僅僅從TOP EVENT就可以看出來了,而絕大多數復雜的問題,是無法從這些地方找出答案的。這一點CHATGPT肯定做不到,甚至大多數人類DBA也做不到。不過如果經過足夠的訓練,CHATGPT也可能能做到。
實際上,臨時表空間的直接路徑讀寫肯定是與非優化的大排序有關,如果我來解讀AWR的時候,遇到這個情況,肯定要去翻PGA相關的數據。從而發現存在一些大SQL的硬盤排序過多。
要想讓CHATGPT做到這一點,不僅僅需要更多的訓練,更需要高水平的DBA采用正確的方法與它對話,引導它向正確的方向上計算,從而完成深度的解讀。
我們還是回到昨天提到的那個案例,對于DBA來說,ORA-4030可能是一個十分明確的問題,我也一直是如此認為的。ORA-4030不外乎物理內存耗盡,操作系統ULIMIT限制,操作系統根目錄空間等因素。直到上星期一個客戶的一個具有1.5TB的超大內存系統報ORA-4030錯誤我才認識到以前知識的局限性。
客戶的一個數據庫系統出現了一些ORA-4030報警,都集中在采集TOP SQL的監控系統中,普通業務模塊并未報警。
當時的報錯場景是有些奇怪的,從SWAP INFORMATION上看,這個報錯十分沒有道理。物理內存還有近400GB的FREE,SWAP基本沒用。但是在執行一條訪問v$sql的語句的時候,出現了無法映射內存的錯誤。
當時的報錯信息是這樣的,報錯位置是:kxs-heap-w,kqlfto,kqlfo:kqlfoobj。Kxs-heap-w的含義是執行SQL的時候分配一個內存用于寫入,kqlfto是數據庫內核與OS BUFFER之間的緩沖。Kqlfoobj是從SGA向PGA/UGA寫入數據時產生的。串聯起來是當會話在執行SQL語句的時候,從SGA向會話私有內存輸出數據的時候,無法分配內存。從下面的TOP 10內存使用情況看,kqlfto:kqlfoobj占了72%,達到2935MB。反推一下,總的進程內存大約是4076MB。
經過分析后,當時我們認為通過調整vm.max_map_count可以解決這個問題,不過用戶暫時不同意調整。于是我們只能從另外一個角度去做調整。當時發現報錯的實例的SQLAREA特別大,于是在業務不忙的時候刷新了一下共享池,讓130多GB的SQLAREA變得正常了,訪問V$SQL采集SQL的功能才恢復了正常。采用這種處置方式的原理是SQLAREA中數據少了,向PGA輸出數據時,PGA就不會達到4G的限制了。實際上這個案例最終還是要通過調整OS或者數據庫參數來解決。
事后分析的時候,我們在MOS上也查到了大量的NOTES。這個問題是和Oracle的實內存分配(非共享內存分配)有關的。
_realfree_heap_pagesize_hint(12c之后,這個參數改名為_realfree_heap_pagesize)是 Oracle 數據庫中的一個參數,用于設置非共享內存管理器的頁面大小。真正的空閑內存管理器用于管理數據庫用于PL / SQL內存和其他非共享內存的真實內存(非SGA)。其默認大小是64KB。因為RHEL操作系統的vm_max_map_count是65530,能夠影射的內存大小是有限的,Oracle的_realfree_heap_pages參數定義了每個影射的塊大小,Oracle 11g默認是64K,所以PGA中最多可以影射4GB的物理內存。如果超出這個限制,就會因為max_map_count的限制而無法分配內存。
Oracle官方的解決方案是加大_realfree_heap_pagesize_hint或者修改max_map_count。調整任何一個參數都可以讓Oracle PGA能夠MAP更多的物理內存。
根據這個情況,我們需要更新ORA-4030的知識庫,增加故障模型中的診斷路徑,把相關的Oracle參數,OS參數等因素加入進去,同時在數據庫巡檢時增加對這方面的分析與診斷。知識就是這樣通過不斷地迭代,日益完善的。運維知識完善的基礎是來自于生產一線的運維案例。?