DB 서버 CPU 사용률이 높다는 연락
DB에 하나의 서버만 사용하는게 아니다 보니
어디서 과부화를 걸었는지 파악이 필요하다
SELECT * FROM v$session a;
SELECT * FROM v$sqlarea b;
SELECT * FROM v$process c;
위 3개 테이블에서 정보 검색이 가능하지만
오라클에서는 쿼리조회로 어디 서버에서 접속했는지 확실한 정보(IP)가 없었다.
접속 사용자 명이 나오기는 하지만 중복이 가능함으로 주의가 필요하다
SELECT A.STATUS
, A.USERNAME
, A.SID
, A.SERIAL#
, A.MACHINE
, A.PORT
, B.SQL_FULLTEXT
, B.DISK_READS
, B.BUFFER_GETS
, B.USER_IO_WAIT_TIME
, B.ROWS_PROCESSED
, B.EXECUTIONS
, B.CPU_TIME
FROM V$SESSION A, V$SQLAREA B
WHERE A.SQL_HASH_VALUE = B.HASH_VALUE
AND A.SQL_ADDRESS = B.ADDRESS
ORDER BY B.USER_IO_WAIT_TIME DESC;
위 테이블 컬럼 하나하나 보면서 내가 원하는 데이터라고 판단되어 만든 쿼리
현재 서버에서 실행 중인 쿼리를 조회 시, 누가 얼마나 조회를 했는지 추측가능한 정도의 정보가 보여진다.
show processList;
mysql은 현재 처리중인 process
를 쉽게 확인가능하며 접속한 IP정보까지 보여주고 있다.
웹 서버랑 DB서버가 다르게 구성되어 있다면
당연히 데이터를 주고 받는 통신이 연결이 되어있을 것 이니 조회해 보자
lsof -i TCP:$port
lsof -i | grep $pid or $ip or $name
netstat -an | grep $port
명령어 검색 시 DB 서버와 통신이 열린 포트를 확인할 수 있다.
여기서 포트 정보는 위 쿼리에서 조회한 포트 정보와 동일한 정보이다.
쿼리 조회로 시간과 CPU를 많이 잡아먹는 사용자 또는 특정 라인을 찾았더라면 종료 또는 다른 처리를 해야한다.
무작정 DB에서 특정 session
에 대해 process kill을 해버린다면 DB에서는 종료되어 사라질 지 몰라도, 해당 값을 기달리고 있는 웹 서버에서는 netstat 상태가 CLOSE_WAIT
로 무한 대기에 빠질지 모른다.
CLOSE_WAIT
에 빠진 웹 서버는 웹이 재기동이 되지 않는 한 처리할 방법이 없다....
심지어 Connection pool
조차 반환이 안될 수 있다.
쿼리를 실행시킨 웹 서버의 Thread
를 종료하는게 좋을 것 같다는 생각이 든다.