當前位置:
首頁 > 最新 > 性能分析之子鎖存器到SQL

性能分析之子鎖存器到SQL

這幾天碰到一個事情,有必要記錄一下。

在一個項目中,壓力測試工具中一個業務響應時間變長,資料庫(oracle)CPU使用率99%以上。

從AWR報告上看到如下信息:

在性能項目的溝通中,經常是在這樣的時候,我們就去告訴開發說現在的狀態是CPU使用率高,把AWR報告往開發那裡一發,性能團隊的人員就喝咖啡去了。

但是性能如果只是做到這裡,溝通其實沒有在同一個界面上。

在這個典型的溝通過程中,上述結果也確實發給開發了。

開發反饋說,是因為在場景執行過程中表的數據量發生了變化,導致了SQL的執行計劃發生了變化,進而導致了SQL慢,進而導致了latch: cache buffers chains的出現。所以要解決的話,要對資料庫進行一次analyze,然後再測試。

在上述的背景中,看似沒有漏洞,合情合理。

但是,

恰好碰到我這偏執的人,我要看到證據鏈

在溝通的來往中,我並沒有看到證據鏈,這是我覺得不好的地方。哪裡沒有證據呢?就是數據量發生了變化導致了SQL的執行計劃發生了變化。

如果有這樣的懷疑,就要去證明這個懷疑是對的。

於是我查了SQL計劃的歷史變更記錄。

根據SQLID查看執行計劃的變更記錄:

selectDISTINCTSQL_ID,PLAN_HASH_VALUE,TO_CHAR(TIMESTAMP,"yyyymmdd hh24:mi:ss")TIMESTAMPfromdba_hist_sql_planwheresql_id="1wfsd2q8wc5uu"orderbyTIMESTAMP;

SQL_ID PLAN_HASH_VALUE TIMESTAMP

查詢更詳細的執行記錄變更記錄(我把結果中的時間戳刪掉了,為了格式整齊點):

selectplan_hash_value,id,operation,options,object_name,depth,cost,TO_CHAR(TIMESTAMP,"yyyymmdd hh24:mi:ss")fromdba_hist_sql_planwheresql_id="1wfsd2q8wc5uu"andplan_hash_valuein(4188019746)orderbyID,TIMESTAMP;

PLAN_HASH_VALUEIDOPERATIONOPTIONSOBJECT_NAMEDEPTHCOST

這個SQL的執行計劃,只有4月1日一條記錄,在最近幾天的測試中,並沒有發生變更。

這就是我要說的證據鏈,當給出執行計劃發生變化這個結論時,就必須給出證明,而實際的數據證明這個結論是錯的。

下面我們就來分析下怎麼才是對的。

既然是latch: cache buffers chains,首先我們得知道這個值是什麼意思。

簡單回憶下latch的原理(如下部分是在網上抄的):

當一個數據塊讀入到SGA中時,該塊的塊頭(BUFFERHEADER)會放置一個HASHBUCKET的鏈表(HASHCHAIN)中。該內存結構由一系列cachebuffers chains的子latch保護。對BUFFERCACHE中的塊,要SELECT/UPDATE/INSERT/DELETER等操作都得先獲得cachebuffers chains的子latch,以保證對CHAIN的排他訪問。若在過程中發生爭用,就會出現latch:cache buffers chains事件。

這個值的出現有兩個含義:

SQL的執行效率低:因為SQL低效,在並發會話時,無法得到相同的數據集,SQL執行時帶有高BUFFER_GETS會導致latch爭用。

數據熱塊。

這是兩個完全不同的處理方向。

第一個處理方向,考慮到近期場景執行得比較頻繁,資料庫變更較多,所以先把資料庫做個整體的分析,再來測試下。經過證明之後,發現果然分析了整庫之後,時間刷刷的降低了很多,然後就把存儲的IO壓到80%以上了。

雖然開發說執行計劃變更是錯的,但是分析整庫的處理方法是對的。

套用大話西遊里說的:我猜中了結尾,但是沒有蒙對過程。

看到這裡,是不是覺得問題解決了?可以收工了?很開心的喝咖啡去了?

但是,我又偏執了。我考慮了下參數化的邏輯,我覺得數據熱塊應該是存在的。現在之所以沒有暴露出來,是因為IO跟不上了。所以我要判斷下,如果IO夠用的話,熱塊會不會成為下一個瓶頸。於是,接著查。

先看看爭用是否嚴重:

selectround((misses / gets) *100) ||"%",

round(100* immediate_misses /(immediate_gets + immediate_misses))||"%"

fromv$latch

wherename="cache buffers chains";

round((misses / gets) *100) ||"%"的值是3%。可見還是有一些熱度的。

再來查下子鎖存器視圖,看是否有熱塊。看看傾斜度。

select*from(selectaddr,child#,gets,misses,sleepsfromv$latch_childrenwherename="cachebuffers chains"orderbysleepsdesc)whererownum

傾斜度是有的。再看下對象的熱度:

selecthladdr,

obj,

(selectobject_name

fromdba_objects

where(data_object_idisnull

andobject_id = x.obj)ordata_object_id = x.objandrownum=1)asobject_name, dbablk, tch

fromx$bh x

orderbytchdesc;

TCH是touch count,此值越高,則熱度越高。

查找引起熱塊的SQL。

select*

from(selectcount(*),

sql_id,

nvl(o.object_name, ash.current_obj#) objn,

substr(o.object_type,,10) otype,

CURRENT_FILE# fn,

CURRENT_BLOCK# blockn

fromv$active_session_history ash, all_objects o

whereeventlike"latch: cache buffers chains"

ando.object_id(+) = ash.CURRENT_OBJ#

GROUPBYSQL_ID,

current_obj#,

current_file#,

current_block#,

o.object_name,

o.object_type

orderbycount(*)desc)

whererownum

根據SQLID查一下SQL的文本,果然就是我們用到的那個查詢業務SQL。

在性能分析中,我們太容易給自己定個範圍或圈套了。有時覺得這個事情不該是自己做的。

如果單從職場的角度說,這樣想並無不妥。

但是如果從技術角度說,這樣想就必然會導致自己的能力受限。

所以不用給技術下個定義,在個人能力能達到的地方,都盡量去做,學無止境。

而從現象到瓶頸的性能分析是最需要一個人有足夠的知識寬度的,因為你不知道在尋找瓶頸的過程中會遇到什麼樣的知識弱點。

今天碰到的是oracle,明天碰到mysql、HBase怎麼辦?啥也別想,二話不說,辦它就對了。

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 7DGroup 的精彩文章:

TAG:7DGroup |