어떻게 CPU 고도 소모(100%)의 데이터베이스 문 제 를 진단 하고 해결 합 니까?


이 편 은 내 가 오래된 블 로그 에서 베 낀 것 으로 먼저 수집 해서 중요 한 때 에 쓸 수 있다.
http://www.eygle.com/archives/2004/10/howto_getsql_which_cost_most_cpu.html
많은 경우 에 우리 서버 는 CPU 소모 100%의 성능 문 제 를 겪 을 수 있 습 니 다.시스템 의 이상 을 제거 합 니 다.이런 문 제 는 시스템 에 성능 이 떨 어 지고 심지어 잘못된 SQL 문구 가 존재 하기 때문에 대량의 CPU 를 소모 하기 때 문 입 니 다.
본 고 는 하나의 사례 를 통 해 이러한 SQL 을 어떻게 포착 하 는 지 에 대해 통용 되 는 방법 을 제시한다.
문제 설명:시스템 CPU 고도 소모,시스템 운행 느 린 OS:Sun Solaris 8 Oracle:Oracle 9203
1.우선 Top 명령 으로 보기
$ top

load averages:  1.61,  1.28,  1.25                     HSWAPJSDB             10:50:44
172 processes: 160 sleeping, 1 running, 3 zombie, 6 stopped, 2 on cpu
CPU states:     % idle,     % user,     % kernel,     % iowait,     % swap
Memory: 4.0G real, 1.4G free, 1.9G swap in use, 8.9G swap free

   PID USERNAME THR PR NCE  SIZE   RES STATE   TIME FLTS    CPU COMMAND
 20521 oracle     1 40   0  1.8G  1.7G run     6:37    0 47.77% oracle
 20845 oracle     1 40   0  1.8G  1.7G cpu02   0:41    0 40.98% oracle
 20847 oracle     1 58   0  1.8G  1.7G sleep   0:00    0  0.84% oracle
 20780 oracle     1 48   0  1.8G  1.7G sleep   0:02    0  0.83% oracle
 15828 oracle     1 58   0  1.8G  1.7G sleep   0:58    0  0.53% oracle
 20867 root       1 58   0 4384K 2560K sleep   0:00    0  0.29% sshd2
 20493 oracle     1 58   0  1.8G  1.7G sleep   0:03    0  0.29% oracle
 20887 oracle     1 48   0  1.8G  1.7G sleep   0:00    0  0.13% oracle
 20851 oracle     1 58   0  1.8G  1.7G sleep   0:00    0  0.10% oracle
 20483 oracle     1 48   0  1.8G  1.7G sleep   0:00    0  0.09% oracle
 20875 oracle     1 45   0 1064K  896K sleep   0:00    0  0.07% sh
 20794 oracle     1 58   0  1.8G  1.7G sleep   0:00    0  0.06% oracle
 20842 jiankong   1 52   2 1224K  896K sleep   0:00    0  0.05% sadc
 20888 oracle     1 55   0 1712K 1272K cpu00   0:00    0  0.05% top
 19954 oracle     1 58   0  1.8G  1.7G sleep  84:25    0  0.04% oracle


우 리 는 도시 진입 목록 에 두 개의 높 은 CPU 소모 가 있 는 Oracle 이 도시 에 들 어가 각각 47.77%와 40.98%의 CPU 자원 을 소모 한 것 을 발견 했다.
 
2.문제 가 있 는 프로 세 스 정 보 를 찾 습 니 다.
 
$ ps -ef|grep 20521
  oracle 20909 20875  0 10:50:53 pts/10   0:00 grep 20521
  oracle 20521     1 47 10:43:59 ?        6:45 oraclejshs (LOCAL=NO)
$ ps -ef|grep 20845
  oracle 20845     1 44 10:50:00 ?        0:55 oraclejshs (LOCAL=NO)
  oracle 20918 20875  0 10:50:59 pts/10   0:00 grep 20845


원 격 으로 연 결 된 두 사용자 프로 세 스 인지 확인 하 십시오.
3.나의 getsql.sql 스 크 립 트 에 익숙해 지기
 
SELECT   /*+ ORDERED */
         sql_text
    FROM v$sqltext a
   WHERE (a.hash_value, a.address) IN (
            SELECT DECODE (sql_hash_value,
                           0, prev_hash_value,
                           sql_hash_value
                          ),
                   DECODE (sql_hash_value, 0, prev_sql_addr, sql_address)
              FROM v$session b
             WHERE b.paddr = (SELECT addr
                                FROM v$process c
                               WHERE c.spid = '&pid'))
ORDER BY piece ASC
/

여기 서 우 리 는 3 개의 보기 와 관련 되 어 있 으 며,그 관련 데 이 터 를 가 져 옵 니 다.먼저 pid,즉 process id 를 입력 해 야 합 니 다.즉,Top 또는 ps 에서 우리 가 본 PID 입 니 다.pid 와 v$process.spid 를 통 해 우 리 는 Process 에 관 한 정 보 를 얻 을 수 있 습 니 다.v$process.addr 를 통 해 v$session.padr 와 연 결 됩 니 다.우 리 는 session 과 관련 된 모든 정 보 를 얻 을 수 있 습 니 다.v$sqltext 를 결합 하면 현재 session 에서 실행 중인 SQL 문 구 를 얻 을 수 있 습 니 다.
v$process 보 기 를 통 해 우 리 는 운영 체제 와 데이터 베 이 스 를 연결 할 수 있 습 니 다.
 
4.데이터베이스 연결,문제 sql 및 프로 세 스 찾기
Top 에서 우리 가 관찰 한 PID 를 통 해 나의 getsql 스 크 립 트 를 응용 하면 다음 과 같은 결 과 를 얻 을 수 있 습 니 다.
$ sqlplus "/ as sysdba"

SQL*Plus: Release 9.2.0.3.0 - Production on Mon Dec 29 10:52:14 2003

Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.


Connected to:
Oracle9i Enterprise Edition Release 9.2.0.3.0 - 64bit Production
With the Partitioning, OLAP and Oracle Data Mining options
JServer Release 9.2.0.3.0 - Production

SQL> @getsql
Enter value for spid: 20521
old  10: where c.spid = '&pid'
new  10: where c.spid = '20521'

SQL_TEXT
----------------------------------------------------------------
select * from (select VC2URL,VC2PVDID,VC2MOBILE,VC2ENCRYPTFLAG,S
ERVICEID,VC2SUB_TYPE,CISORDER,NUMGUID,VC2KEY1, VC2NEEDDISORDER,V
C2PACKFLAG,datopertime from hsv_2cpsync where datopertime<=sysda
te and numguid>70000000000308 order by NUMGUid) where rownum<=20


그렇다면 이 코드 는 현재 CPU 를 미 친 듯 이 소모 하고 있 는 주범 이다.다음 에 해 야 할 일 은 이 코드 의 문 제 를 찾 아 최적화 로 효율 을 높이 고 자원 소 모 를 줄 일 수 있 는 지 를 보 는 것 이다.
 
5.더 나 아가 우 리 는 dbms 를 통 해시스템 패키지 추적 프로 세 스
SQL> @getsid Enter value for spid: 20521 old 3: select addr from v$process where spid = &spid) new 3: select addr from v$process where spid = 20521) SID SERIAL# USERNAME MACHINE ---------------------------------------------------------------- 45 38991 HSUSER_V51 hswapjsptl1.hurray.com.cn SQL> exec dbms_system.set_sql_trace_in_session(45,38991,true); PL/SQL procedure successfully completed. SQL> !  
6.한 가지 설명
많은 경우 에 높 은 CPU 소 모 는 문제 SQL 로 인해 발생 하기 때문에 이런 SQL 을 찾 으 면 문제 의 소 재 를 찾 을 수 있 고 최적화 조정 을 통 해 문 제 를 해결 할 수 있다.
그러나 가끔 은 CPU 를 가장 많이 소모 하 는 프로 세 스 가 배경 프로 세 스 라 는 것 을 알 수 있 습 니 다.이것 은 보통 이상,BUG 또는 회복 후의 이상 으로 인해 발생 하 는 것 이 므 로 구체 적 인 문 제 를 구체 적 으로 분석 해 야 합 니 다.

좋은 웹페이지 즐겨찾기