国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發 > 綜合 > 正文

一次診斷和解決CPU利用率高的問題分析

2024-07-21 02:05:45
字體:
來源:轉載
供稿:網友
  • 本文來源于網頁設計愛好者web開發社區http://www.html.org.cn收集整理,歡迎訪問。

  • 本文作者: allan ([email protected] )

     

    oracle數據庫經常會遇到cpu利用率很高的情況,這種時候大都是數據庫中存在著嚴重性能低下的sql語句,這種sql語句大大的消耗了cpu資源,導致整個系統性能低下。當然,引起嚴重性能低下的sql語句的原因是多方面的,具體的原因要具體的來分析,下面通過一個實際的案例來說明如何來診斷和解決cpu利用率高的這類問題。

    操作系統:solairs8

    數據庫:oracle9.2.0.4

    問題描述:現場工程師匯報數據庫非常慢,幾乎所有應用操作均無法正常進行。

    首先登陸主機,執行top發現cpu資源幾乎消耗殆盡,存在很多占用cpu很高的進程,而內存和i/o都不高,具體如下:

    last pid: 26136;  load averages:  8.89,  8.91,  8.12                                                                       

    216 processes: 204 sleeping, 8 running, 4 on cpu

    cpu states:  0.6% idle, 97.3% user,  1.8% kernel,  0.2% iowait,  0.0% swap

    memory: 8192m real, 1166m free, 14m swap in use, 8179m swap free

    pid username thr pri nice  size   res state   time    cpu command

    25725 oracle     1  50    0 4550m 4508m cpu2   12:23 11.23% oracle

    25774 oracle     1  41    0 4550m 4508m run    14:25 10.66% oracle

    26016 oracle     1  31    0 4550m 4508m run     5:41 10.37% oracle

    26010 oracle     1  41    0 4550m 4508m run     4:40  9.81% oracle

    26014 oracle     1  51    0 4550m 4506m cpu6    4:19  9.76% oracle

    25873 oracle     1  41    0 4550m 4508m run    12:10  9.45% oracle

    25723 oracle     1  50    0 4550m 4508m run    15:09  9.40% oracle

    26121 oracle     1  41    0 4550m 4506m cpu0    1:13  9.28% oracle

    于是先查看數據庫的告警日志alert文件,并沒有發現有什么錯誤存在,日志顯示數據庫運行正常,排除數據庫本身存在問題。

    然后查看這些占用cpu資源很高的oracle進程究竟是在做什么操作,使用如下sql語句:

    select sql_text,spid,v$session.program,process  from

    v$sqlarea,v$session,v$process

    where v$sqlarea.address=v$session.sql_address

    and v$sqlarea.hash_value=v$session.sql_hash_value

    and v$session.paddr=v$process.addr

    and v$process.spid in (pid);

    用top中占用cpu很高的進程的pid替換腳本中的pid,得到相應的oracle進程所執行的sql語句,發現占用cpu資源很高的進程都是執行同一個sql語句:

    select d.domainname,d.mswitchdomainid, a.serviceid,a.servicecode,a.usertype,a.status,a.notifystatus,to_char(a.datecreated,'yyyy-mm-dd hh24:mi:ss') datecreated,vipflag,status2,customertype,customerid  from service a, gatewayloc b, subbureaunumber c, mswitchdomain d   where b.mswitchdomainid = d.mswitchdomainid and b.gatewaysn = c.gatewaysn  and a.servicecode like c.code||'%' and a.servicespecid=1 and a.status!='4' and a.status!='10'  and a.servicecode like '010987654321%' and subsidiaryid=999999999

    基本上可以肯定是這個sql引起了系統cpu資源大量被占用,那究竟是什么原因造成這個sql這么大量占用cpu資源呢,我們先來看看數據庫的進程等待事件都有些什么:

    sql> select sid,event,p1,p1text from v$session_wait;

           sid event       p1 p1text

    ---------- ----------------------------------------------------------------

            12 latch free  4.3982e+12 address

            36 latch free  4.3982e+12 address

            37 latch free  4.3982e+12 address

            84 latch free  4.3982e+12 address

           102 latch free  4.3982e+12 address

           101 latch free  4.3982e+12 address

            85 latch free  4.3982e+12 address

           106 latch free  4.3982e+12 address

           155 latch free  4.3982e+12 address

           151 latch free  4.3982e+12 address

           149 latch free  4.3982e+12 address

           147 latch free  4.3982e+12 address

             1 pmon timer  300 duration

    從上面的查詢我們可以看出,大都是latch free的等待事件,然后接著查一下這些latch的等待都是什么進程產生的:

    sql> select spid from v$process where addr in

     (select paddr from v$session where sid in(84,102,101,106,155,151));

    spid

    ------------

    25774

    26010

    25873

    25725

    由此看出latch free這個等待事件導致了上面的那個sql語句都在等待,占用了大量的cpu資源。我們來看看究竟主要是那種類型的latch的等待,根據下面的sql語句:

    sql> select latch#, name, gets, misses, sleeps

         from v$latch

         where sleeps>0

         order by sleeps;

    latch#  name                          gets     misses      sleeps  

    ---------- ----------------------------------------------------------------

        15   messages                       96876       20          1    

       159   library cache pin allocation   407322      43          1    

       132   dml lock allocation            194533      213         2    

         4   session allocation             304897      48          3    

       115   redo allocation                238031      286         4    

        17   enqueue hash chains            277510      85          5    

         7   session idle bit               2727264     314         16   

       158   library cache pin              3881788     5586        58   

       156   shared pool                    2771629     6184        662  

       157   library cache                  5637573     25246       801  

        98   cache buffers chains           1722750424  758400      109837

    由上面的查詢可以看出最主要的latch等待是cache buffers chains,這個latch的等待表明數據庫存在單獨的block的競爭這些latch,我們來看這個latch存在的子latch及其對應的類型:

    sql> select addr, latch#, gets, misses, sleeps

         from v$latch_children 

         where sleeps>0         

         and latch# = 98  

         order by sleeps desc;

    addr                 latch#       gets     misses     sleeps

    ---------------- ---------- ---------- ---------- ----------

    000004000a3dfd10         98   10840661      82891        389

    000004000a698c70         98     159510          2        244

    0000040009b21738         98  104269771      34926        209

    0000040009b227a8         98  107604659      35697        185

    000004000a3e0d70         98    5447601      18922        156

    000004000a6c2bd0         98     853375          7        134

    0000040009b24888         98   85538409      25752        106

    ……………

    接著我們來查看sleep較多的子latch對應都有哪些對象:

    sql> select distinct a.owner,a.segment_name,a.segment_type from

         dba_extents a,

    (select dbarfil,dbablk

    from x$bh

    where hladdr in

         (select addr

         from (select addr

         from v$latch_children

         order by sleeps desc)

         where rownum < 5)) b

    where a.relative_fno = b.dbarfil

    and a.block_id <= b.dbablk and a.block_id + a.blocks > b.dbablk;

    owner                    segment_name                    segment_type

    ---------------------------------------------------------------------------

    test                    i_service_servicespecid              index

    test                    i_service_subsidiaryid               index

    test                    service                              table

    test                    mswitchdomain                        table

    test                    i_service_sc_s                       index

    …………………

    我們看到在開始的那個sql語句中的幾個對象都有包括在內,于是來看看開始的那個sql的執行計劃:

    sql> set autotrace trace explain

    sql>select d.domainname,d.mswitchdomainid, a.serviceid,a.servicecode,a.usertype,a.status,a.notifystatus,to_char(a.datecreated,'yyyy-mm-dd hh24:mi:ss') datecreated,vipflag,status2,customertype,customerid  from service a, gatewayloc b, subbureaunumber c, mswitchdomain d   where b.mswitchdomainid = d.mswitchdomainid and b.gatewaysn = c.gatewaysn  and a.servicecode like c.code||'%' and a.servicespecid=1 and a.status!='4' and a.status!='10'  and a.servicecode like '010987654321%' and subsidiaryid=999999999;

    execution plan

    ----------------------------------------------------------

       0      select statement optimizer=choose

       1    0   nested loops

       2    1     nested loops

       3    2       nested loops

       4    3         table access (full) of 'subbureaunumber'

       5    3         table access (by index rowid) of 'gatewayloc'

       6    5           index (unique scan) of 'pk_gatewayloc' (unique)

       7    2       table access (by index rowid) of 'mswitchdomain'

       8    7         index (unique scan) of 'pk_mswitchdomain' (unique)

       9    1     table access (by index rowid) of 'service'

      10    9       and-equal

      11   10         index (range scan) of 'i_service_servicespecid' (non

              -unique)                

      12   10         index (range scan) of 'i_service_subsidiaryid' (non-

              unique)

    根據開始查到的引起latch free等待中的對象和sql語句的執行計劃,覺得service表上的索引有問題,似乎存在了過多的掃描,于是將同樣的sql語句在別的地市的同樣的數據庫上執行一下,查看相應的執行計劃:

    sql> set autotrace trace explain

    sql>select d.domainname,d.mswitchdomainid, a.serviceid,a.servicecode,a.usertype,a.status,a.notifystatus,to_char(a.datecreated,'yyyy-mm-dd hh24:mi:ss') datecreated,vipflag,status2,customertype,customerid  from service a, gatewayloc b, subbureaunumber c, mswitchdomain d   where b.mswitchdomainid = d.mswitchdomainid and b.gatewaysn = c.gatewaysn  and a.servicecode like c.code||'%' and a.servicespecid=1 and a.status!='4' and a.status!='10'  and a.servicecode like '010987654321%' and subsidiaryid=999999999;

    execution plan

    ----------------------------------------------------------

       0      select statement optimizer=choose

       1    0   table access (by index rowid) of 'service'

       2    1     nested loops

       3    2       nested loops

       4    3         nested loops

       5    4           table access (full) of 'subbureaunumber'

       6    4           table access (by index rowid) of 'gatewayloc'

       7    6             index (unique scan) of 'pk_gatewayloc' (unique)

       8    3         table access (by index rowid) of 'mswitchdomain'

       9    8           index (unique scan) of 'pk_mswitchdomain' (unique)

      10    2       index (range scan) of 'i_service_sc_s' (non-unique)

    對比兩個執行計劃,發現索引i_service_servicespecid和i_service_subsidiaryid是不應該走的,于是又對比了兩個地方service表上的索引個數:

    sql> select index_name from user_indexes where table_name='service';

    index_name

    ------------------------------

    i_service_accountnum

    i_service_cid

    i_service_dateactivated

    i_service_priceplanid

    i_service_sc_s

    i_service_servicecode

    i_service_servicespecid

    i_service_subsidiaryid

    pk_service_sid

    sql> select index_name from user_indexes where table_name='service';

    index_name

    ------------------------------

    i_service_accountnum

    i_service_cid

    i_service_dateactivated

    i_service_sc_s

    i_service_servicecode

    pk_service_sid

    發現存在問題的數據庫中的service表上不知道怎么多出了i_service_priceplanid、i_service_servicespecid 、i_service_subsidiaryid三個索引,而這些索引就是導致了開始那個sql語句用了不該用的索引,引起latch free等待和cpu占用很高的罪魁禍首,于是刪除了那三個索引,重新執行相應的sql語句,很快就得出了結果,cpu的利用率也馬上下降為正常了,觀察結果如下:

    last pid: 26387;  load averages:  1.61, 1.38, 1.21                                                                      

    195 processes: 194 sleeping, 1 on cpu

    cpu states: 96.2% idle,  1.6% user,  1.7% kernel,  0.5% iowait,  0.0% swap

    memory: 8192m real, 1183m free, 14m swap in use, 8179m swap free

    pid username thr pri nice  size   res state   time    cpu command

    26383 oracle     1  59    0 4550m 4506m sleep   0:12  4.52% oracle

      409 root      15  59    0 7168k 7008k sleep 173.1h  0.53% picld

    25653 oracle     1  59    0 4550m 4508m sleep   2:12  0.48% oracle

    26384 root       1  59    0 2800k 1912k cpu2    0:00  0.21% top-3.5b8-sun4u

    25569 oracle     1  59    0 4550m 4508m sleep   0:12  0.09% oracle

    25717 oracle     1  59    0 4550m 4507m sleep   0:07  0.05% oracle

    25571 oracle     1  59    0 4550m 4507m sleep   0:10  0.04% oracle

    25681 oracle     1  59    0 4550m 4508m sleep   0:10  0.04% oracle

    25544 oracle     1  58    0 4554m 4501m sleep   0:14  0.03% oracle

    25703 oracle     1  59    0 4550m 4506m sleep   0:23  0.03% oracle

    ………………

    對于cpu利用率過高的情況,如果是sql語句性能比較低下引起的基本上都可以按照這個思路來診斷和解決問題,當然具體問題還得具體分析,解決問題的方法也有很多種,這里不過是拋磚引玉一下,只要能最終達到我們解決問題的目的就可以了。

     

     

     

     

     

     

     

     

     

     

     

     

    作者簡介:

     

    照片

    暫缺

    網名coolyl

    csdn emag oracle電子雜志主編

    現任itpub oracle管理版版主。

    擅長數據庫的維護,對于數據庫的安裝,調整,備份方面有自己獨到的經驗。同時也給一些國內的大型企業做過oracle的培訓,有一定的培訓經驗。

    曾做過很多大型項目的數據庫維護和支持工作,對oracle的維護有相當多的實際經驗,善于現場解決問題。

    曾任職于國內某大型軟件企業做oracle數據庫的技術支持,客戶遍及全國各個行業,尤其是電信,政府行業。

    現任職于某外資電信企業華北區分公司,dba,負責華北區40多個數據庫系統的維護,對大型數據庫管理經驗豐富。

     

    《oracle數據庫dba專題技術精粹》一書的主編及主要作者.

     

    mail地址: [email protected]
    發表評論 共有條評論
    用戶名: 密碼:
    驗證碼: 匿名發表
    主站蜘蛛池模板: 长乐市| 东方市| 定南县| 南昌市| 杭州市| 和林格尔县| 天门市| 赣榆县| 绥江县| 托克逊县| 彭泽县| 界首市| 淄博市| 抚州市| 赣州市| 班戈县| 会泽县| 平塘县| 紫金县| 广饶县| 陆丰市| 顺平县| 彭山县| 鲜城| 兴安县| 民权县| 始兴县| 申扎县| 定兴县| 和政县| 景宁| 安龙县| 盐池县| 新竹县| 饶阳县| 闸北区| 金寨县| 英德市| 大竹县| 武陟县| 安仁县|