中午的時候,咱們生產上的某個數據庫,cpu一直居高不下html
經過例如如下的sql語句,咱們查看當時數據庫的等待,爭用的狀況:sql
select s.SID, s.SERIAL#, 'kill -9 ' || p.SPID, s.MACHINE, s.OSUSER, s.PROGRAM, s.USERNAME, s.last_call_et, a.SQL_ID, s.LOGON_TIME, a.SQL_TEXT, a.SQL_FULLTEXT, w.EVENT, a.DISK_READS, a.BUFFER_GETS from v$process p, v$session s, v$sqlarea a, v$session_wait w where p.ADDR = s.PADDR and s.SQL_ID = a.sql_id and s.sid = w.SID and s.STATUS = 'ACTIVE' order by s.last_call_et desc;
從event可以看到,是latch 的爭用致使的緣由數據庫
經過假設的sql,查看是什麼樣的latch緩存
select * from v$session_wait where event like 'latch free';
P2就是 這個latch的name。經過v$latchname這個視圖就可以知道哪一個詳細的latchsession
1:45:55 PM SQL> select * from v$latchname where latch#=164; LATCH# NAME HASH ---------- ---------------------------------------------------------------- ---------- 164 simulator hash latch 2233208730
查看latch的歷史狀況併發
2:11:59 PM SQL> select name,gets,misses,sleeps from v$latch where sleeps >0 order by sleeps desc; NAME GETS MISSES SLEEPS ---------------------------------------------------------------- ---------- ---------- ---------- simulator hash latch 4827860212 135426899 10890947 cache buffers chains 1619822817 2850976006 4747728 gc element 4660052091 25748270 175073 resmgr:schema config 91872524 153968 95708 ges resource hash list 174151449 1070556 55459 Real-time plan statistics latch 40953155 651496 44527 call allocation 3301878 265908 43501 row cache objects 336300485 4970324 19366
這個simulator hash latch已是顯著的latch部分post
eagle在他的站點上有篇文章講到了關於simulator這個性能
http://www.eygle.com/archives/2011/11/simulator_lru_latch.htmlspa
simulator意爲模擬。也就是說當Oracle在內存中進行數據塊處理時。實際上還會在預先分配的Buffer中進行相關信息記錄,如DBA信息,當數據塊被老化以後,下次讀取時。假設請求的數據在Simulator內存中存在,則以爲繼續緩存該數據塊是有意義的,經過監控並模擬統計這些操做,並對計算結果加權運算。就可以實現對於內存的調整建議。code
在模擬過程當中。也是經過Latch來實現的,相關的Latch就有 simulator lru latch 、 simulator hash latch等.
就Buffer Cache而言。假設系統中該類爭用嚴重,則可以考慮關閉db_cache_advice。消除這部份內部操做對於性能的影響。
下面是一個相關BUG。在該Bug中,由於DB_CACHE_ADVICE的開啓致使了嚴重的simulator lru latch的競爭:
Bug 5918642 Heavy latch contention with DB_CACHE_ADVICE on
This note gives a brief overview of bug 5918642.
The content was last updated on: 01-APR-2008
Click here for details of each of the sections below.
Affects:
Product (Component) Oracle Server (Rdbms) Range of versions believed to be affected Versions < 11.2 Versions confirmed as being affected Platforms affected Generic (all / most platforms affected) Fixed:
This issue is fixed in
Symptoms:
Related To:
- Performance Monitoring
- DB_CACHE_ADVICE
Description
High simulator lru latch contention can occur when db_cache_advice is set to ON if there is a large buffer cache. Workaround: Set db_cache_advice to OFF
固然,這個僅僅是治標不治本的作法,這個是顯現的表象的問題。根源的問題仍是這個sql語句有問題
當一個數據塊讀入到sga中時,該塊的塊頭(buffer header)會放置在一個hash bucket的鏈表(hash chain)中。該內存結構由一系列cache buffers chains子latch保護(又名hash latch或者cbc latch)。對Buffer cache中的塊,要select或者update、insert,delete等。都得先得到cache buffers chains子latch,以保證對chain的排他訪問。
若在過程當中發生爭用,就會等待latch:cache buffers chains事件。
產生緣由: 1. 低效率的SQL語句(主要體現在邏輯讀太高) 在某些環境中,應用程序打開運行一樣的低效率SQL語句的多個併發會話。這些SQL語句都設法獲得一樣的數據集,每次運行都帶有高 BUFFER_GETS(邏輯讀取)的SQL語句是基本的緣由。
相反,較小的邏輯讀意味着較少的latch get操做,從而下降鎖存器爭用並改善性能。注意v$sql中BUFFER_GETS/EXECUTIONS大的語句。 2.Hot block 當多個會話反覆訪問一個或多個由同一個子cache buffers chains鎖存器保護的塊時。熱塊就會產生。
當多個會話爭用cache buffers chains子鎖存器時,就會出現這個等待事件。有時就算調優了SQL,但多個會話同一時候運行此SQL,那怕僅僅是掃描特定少數塊,也是也會出現HOT BLOCK的。
SELECT P935.SEQUENCEID, null FA_SEQUENCEID, P935.ORDERID, P935.ORGORDERID, P935.PRODUCTNAME, P935.PRODUCTNUM, P935.ORDERTIME, P935.LASTUPDATETIME, P935.ORDERSTATUS, P935.MEMO, 935 orderCode, P935.PAYERACCTCODE, P935.PAYERACCTTYPE, P935.PAYEEACCTCODE PLATACCTCODE, P935.PAYEEACCTTYPE PLATACCTTYPE, P936.PAYEEACCTCODE, P936.PAYEEACCTTYPE, EXT935.PAYER_DISPLAYNAME, EXT935.PAYER_NAME, EXT935.PAYER_IDC, EXT935.PAYER_MEMBERTYPE, EXT936.PAYER_DISPLAYNAME PLAT_DISPLAYNAME, EXT936.SUBMITNAME PLAT_NAME, EXT936.PAYER_IDC PLAT_IDC, EXT936.PAYER_MEMBERTYPE PLAT_MEMBERTYPE, EXT936.PAYEE_DISPLAYNAME, EXT936.PAYEE_NAME, EXT936.PAYEE_IDC, EXT936.PAYEE_MEMBERTYPE, P935.PAYEEDISPLAYNAME WEBSITENAME, CASE WHEN (SELECT count(*) FROM PAYMENTORDER P936 WHERE P936.Ordercode = 936 and P936.Orderstatus = 0 AND <span style="color:#ff0000;">P936.Relatedsequenceid = P935.SEQUENCEID</span>) > 0 THEN 0 ELSE 1 END AS SHARINGRESULT, CASE D935.Dealcode WHEN 210 then 14 else D935.DEALTYPE end PAYMETHOD, D935.DEALAMOUNT, G935.EXT1, G935.Ext2, G935.PAYERCONTACTTYPE, G935.PAYERCONTACT, NVL(D935.PAYEEFEE, 0) PAYEEFEE, NVL(D935.PAYERFEE, 0) PAYERFEE, nvl(MS936.PAYEEFEE, 0) PLATFORMFEE, P935.VERSION FROM PAYMENTORDER P935, PAYMENTORDER P936, DEAL D935, GATEWAYORDER G935, MSGATEWAYSHARINGORDER MS936, PAYMENTORDEREXT EXT935, PAYMENTORDEREXT EXT936 WHERE P936.ORDERCODE = 936 AND P935.ORDERCODE = 935 AND P936.RELATEDSEQUENCEID = to_char(P935.SEQUENCEID) AND P935.SEQUENCEID = G935.SEQUENCEID(+) AND P935.SEQUENCEID = D935.ORDERSEQID(+) AND P935.SEQUENCEID = EXT935.ORDERSEQID(+) AND P936.SEQUENCEID = EXT936.ORDERSEQID(+) AND P936.SEQUENCEID = MS936.SEQUENCEID(+) AND MS936.SHARINGTYPE = 1 AND P935.SEQUENCEID = :1 UNION SELECT P938.SEQUENCEID, P935.SEQUENCEID FA_SEQUENCEID, P938.ORDERID, P938.ORGORDERID, P935.PRODUCTNAME, P935.PRODUCTNUM, P938.ORDERTIME, P938.LASTUPDATETIME, P938.ORDERSTATUS, P938.MEMO, 938 orderCode, P938.PAYERACCTCODE, P938.PAYERACCTTYPE, P938.PAYEEACCTCODE PLATACCTCODE, P938.PAYEEACCTTYPE PLATACCTTYPE, P938.PAYEEACCTCODE, P938.PAYEEACCTTYPE, EXT938.PAYER_DISPLAYNAME, EXT938.PAYER_NAME, EXT938.PAYER_IDC, EXT938.PAYER_MEMBERTYPE, EXT938.PAYEE_DISPLAYNAME PLAT_DISPLAYNAME, EXT938.SUBMITNAME PLAT_NAME, EXT938.PAYEE_IDC PLAT_IDC, EXT938.PAYEE_MEMBERTYPE PLAT_MEMBERTYPE, EXT938.PAYEE_DISPLAYNAME, EXT938.PAYEE_NAME, EXT938.PAYEE_IDC, EXT938.PAYEE_MEMBERTYPE, P935.PAYEEDISPLAYNAME WEBSITENAME, null SHARINGRESULT, D938.DEALTYPE PAYMETHOD, D938.DEALAMOUNT, G935.EXT1, G935.Ext2, G935.PAYERCONTACTTYPE, G935.PAYERCONTACT, NVL(D938.PAYEEFEE, 0) PAYEEFEE, NVL(D938.PAYERFEE, 0) PAYERFEE, 0 PLATFORMFEE, P935.VERSION FROM PAYMENTORDER P935, PAYMENTORDER P938, DEAL D938, GATEWAYORDER G935, PAYMENTORDEREXT EXT938 WHERE P935.ORDERCODE = 935 AND P938.ORDERCODE = 938 AND P938.RELATEDSEQUENCEID = to_char(P935.SEQUENCEID) AND P935.SEQUENCEID = G935.SEQUENCEID(+) AND P938.SEQUENCEID = D938.ORDERSEQID(+) AND P938.SEQUENCEID = EXT938.ORDERSEQID(+) AND P935.SEQUENCEID = :2
分析上面的sql,上面標紅的地方。等號左邊是varchar2的數據類型,括號右邊是number的數據類型。會致使數據類型的隱式轉換,形成極大的性能影響
聯繫研發。改動了sql語句,問題解決