데이터베이스 연구실.log

프로세스와 자원 사용 확인

top 머리 다섯 줄과 프로세스 목록 읽기, load average와 CPU, 메모리, I/O 병목 구분, OS PID를 Oracle 세션, SQL로 잇기, sar의 CPU, 코어, 메모리, 스왑, 큐, 디스크, 네트워크 기록

topuptimepsvmstatsarswapSPIDdb_writer_processes

#핵심 요약

top은 "지금 이 순간", sar는 하루 전체를 시간순으로 남겨 "언제" 이상이 있었는지 되짚을 때 씀

느릴 때는 uptime(load와 코어 수 비교) → free -m(메모리, 스왑) → ps --sort=-%cpu(누가 CPU를 쓰나) → top -b(us, wa 비율) 순서로 CPU 경합, I/O 대기, 메모리 부족을 가름

CPU를 많이 쓰는 oracle_<PID>_<SID> 프로세스는 V$PROCESS.SPID로 세션과 SQL_ID를 찾아 원인 SQL까지 이음

평균은 피크를 가리므로 시간대별 줄, 코어별 값, 응답 시간(await)을 따로 봄

#개념과 동작 원리

top 출력 행 자원 사용 지표
1번째 (시각, up, users, load average) 1, 5, 15분 평균 부하, 코어 수(nproc)보다 크면 과부하
2번째 Tasks running, sleeping(Oracle 백그라운드 대부분), zombie
3번째 %Cpu(s) us 사용자, sy 커널, id 유휴, wa I/O 대기, st 가상화에서 빼앗긴 시간
4번째 Mem total, free, used, buff/cache
5번째 Swap used가 0보다 크고 늘어나면 메모리 부족 신호, avail Mem이 실제 여유
증상 의심하는 병목
load가 코어 수를 넘고 us 높음, wa 낮음, 스왑 0 CPU 경합(무거운 SQL 여러 개)
load 높고 wa 높음, id 남음 디스크 응답 대기
free, avail 작고 스왑 used 증가, wa 동반 메모리 부족과 스와핑

스왑은 RAM이 모자랄 때 커널이 당장 안 쓰는 페이지를 디스크의 스왑 영역으로 옮겨 두는 완충 장치이며, 디스크라 RAM보다 수백~수천 배 느림
스왑 아웃만 있고 값이 고정이면 예전에 밀려난 페이지가 남은 것이고, 스왑 인이 계속 생기면 지금 필요한 페이지를 디스크에서 다시 읽는 중이라 응답이 늦어짐

#필수 명령어 또는 SQL

#지금 상태 보기 (top, uptime, free, ps)

Linux Bash (oracle)조회만 함
uptime
nproc
free -m
ps -eo pid,user,%cpu,%mem,comm --sort=-%cpu | head
top -b -n 1 | head -20
vmstat 1 5
ps -ef | grep ora_ | grep -v grep | wc -l
pgrep -f dbw0

결과 해석:

실습 기록: 유휴 서버는 load 0.07, id 99.5%, 스왑 0이었고, scott 세션에서 emp를 조인 조건 없이 14번 콤마 조인하자 load 1.07, 서버 프로세스 하나가 %CPU 96.7, 상태 R로 나옴

수업 시나리오의 해석 예: 4코어에 load 9.42인데 wa 56.8%면 CPU 연산이 아니라 디스크 응답을 기다리는 줄이고, 4코어에 load 16과 us 94%, 스왑 0이면 CPU 경합임

vmstat의 si, so(스왑 인, 아웃)가 수천 KB/s로 계속 나오면 스왑 스래싱이고, swpd가 늘어나는지도 봄

진짜 과부하에서는 top조차 뜨지 않을 수 있어 장애가 의심되면 미리 띄워 둠

ps -ef | grep ora_*처럼 따옴표 없이 쓰면 셸이 *를 먼저 펼칠 수 있어 grep 'ora_'로 씀

#부하 기록 남기기

Linux Bash (oracle)객체 또는 설정을 변경함
mkdir -p ~/loadchk_lab ~/monitor
cat > ~/loadchk_lab/log_uptime.sh << 'EOF'
#!/bin/bash
uptime >> ~/loadchk_lab/uptime_snapshot.log
EOF
chmod 750 ~/loadchk_lab/log_uptime.sh
for i in {1..8}; do ~/loadchk_lab/log_uptime.sh; sleep 10; done
top -b -n 1 > ~/monitor/top_$(date +%Y%m%d_%H%M%S).log

결과 해석:

uptime을 주기적으로 기록해 load가 오른 시각을 확인함
실습은 10초 간격 8번으로 줄여 보고, 운영에서는 cron에 10분 간격 같은 주기로 등록함

top -b -n 1은 배치 모드로 한 번만 찍어 파일로 남기며, 외부 솔루션이 CPU를 과하게 쓸 때 근거 자료로 보낼 수 있음

수업은 이 명령들을 read, case 점검 메뉴 스크립트의 번호에 하나씩 붙여 감

#OS 프로세스에서 Oracle 세션과 SQL로

SQL*Plus (SYSDBA)조회만 함
SELECT s.sid, s.serial#, s.username, s.program, s.module, s.sql_id, p.spid
  FROM v$session s
  JOIN v$process p ON s.paddr = p.addr
 WHERE p.spid = '<OS_PID>';

SELECT sql_id, executions, cpu_time, elapsed_time, buffer_gets, rows_processed, sql_text
  FROM v$sql
 WHERE sql_id = '<SQL_ID>';

결과 해석:

top의 PID가 V$PROCESS.SPID이며, PADDR = ADDR로 세션을 찾아 SQL_ID와 실행 통계를 봄

세 터미널에서 각각 무거운 SQL을 돌리고 top에서 그중 하나의 서버 프로세스만 kill하는 실습도 했으나, 운영에서는 ALTER SYSTEM KILL SESSION으로 세션을 끝내는 것이 먼저임
OS에서 서버 프로세스를 죽이면 그 세션의 미완료 트랜잭션은 롤백됨

수업 자료에는 DB가 완전히 멈춰 SYSDBA 접속도 안 될 때 PMON을 죽이는 과제가 있으며, 이는 인스턴스 전체를 비정상 종료시키는 마지막 수단이라 실습 VM에서 alert 로그를 tail -f로 보며만 함

과거 특정 시간대에 DB 안에서 무슨 일이 있었는지는 @?/rdbms/admin/awrrpt.sql로 그 구간 AWR 리포트를 만들어 봄

#DBWR 수 늘리기

SQL*Plus (SYSDBA)인스턴스 또는 서비스 중단이 필요함
SHOW PARAMETER db_writer_processes
ALTER SYSTEM SET db_writer_processes = 2 SCOPE = SPFILE;
SHUTDOWN IMMEDIATE
STARTUP
Linux Bash (oracle)조회만 함
pgrep -f dbw0
pgrep -f dbw1

결과 해석:

실습 기록: 1이던 값을 2로 바꾸고 재기동하자 ora_dbw0_*, ora_dbw1_* 두 프로세스가 보임

db_writer_processes는 정적 파라미터라 SCOPE = SPFILE 뒤 재기동해야 반영됨
더티 버퍼를 디스크에 쓰는 속도가 실제로 부족한지(free buffer waits 등) 확인한 뒤 늘림

#sar로 과거 기록 보기

Linux Bash (oracle)조회만 함
sar -u
sar -f /var/log/sa/sa21
sar -u -s 01:00:00 -e 03:00:00
sar -P ALL -f /var/log/sa/sa08 -s 02:20:00 -e 02:21:00
sar -P ALL 1 100
sar -r
sar -S
sar -W
sar -q
sar -d -p
sar -n DEV
sar -n EDEV

결과 해석:

옵션 자원 사용 지표 판단 기준
-u CPU %user, %iowait, %idle Average만 보지 말고 튀는 시간대 줄을 찾음
-P ALL 코어별 CPU 평균 25%라도 코어 하나가 90%면 단일 스레드 병목
-r 메모리 kbavail, kbcached %memused가 아니라 kbavail로 판단
-S, -W 스왑 사용량, 초당 스왑 인, 아웃 used 증가와 pswpin/s가 0보다 큰지
-q runq-sz, ldavg-1, 5, 15, blocked load가 높아도 runq-sz 낮고 blocked 높으면 I/O 대기
-d -p 장치별 tps, await, %util 양(tps)이 아니라 응답 지연(await)으로 판단
-n DEV, EDEV 인터페이스별 송수신량, 오류, 드롭 회선 대비 사용량과 오류 0 여부

/var/log/sa/saDD의 DD가 날짜이며, 보관 일수는 OL 7에서 /etc/sysconfig/sysstat의 HISTORY로 정함
수업 과제는 한 달 보관을 두 달로 늘리는 것이었으며 정답은 적혀 있지 않음

실습 기록: sar -u에서 10:10, 11:20, 12:0012:10, 15:10 이후 %user가 711%로 오른 시간대를 찾고, 그 시간대의 AWR 리포트로 DB 안의 원인을 확인하는 흐름임

-P ALL 예는 RMAN 압축 백업을 채널 하나로 돌려 압축 연산이 코어 하나에 몰린 경우를 가정함

수업 자료의 -r 예 해석: kbavail이 계속 줄고 kbcached까지 함께 줄면 커널이 캐시를 회수할 만큼 압박받는 것이고, %memused가 96%여도 kbavail이 크고 평탄하면 파일 캐시가 많을 뿐 정상임
증설은 하루 내내 kbavail이 회복되지 않음, %swpused 증가, pswpin/s 지속이 여러 날 함께 보일 때 판단함

메모리가 끝까지 바닥나면 커널의 OOM Killer가 프로세스를 강제로 끝내며, Oracle 백그라운드가 대상이 되면 인스턴스가 내려감
dmesg, /var/log/messages의 Out of memory: Kill process로 확인함

-q의 ldavg-1 < ldavg-5 < ldavg-15는 지나간 피크가 가라앉는 중이라는 뜻이라, 원인을 찾으려면 더 앞 시간대를 조회함

-d에서 tps가 큰 장치가 아니라, tps는 작은데 await가 100ms를 넘고 %util이 90%대인 장치가 문제임
수업 자료의 가상 AWR 예는 그런 디스크 위 데이터 파일 하나만 Av Rd(ms)가 88ms로 튀어 db file sequential read 평균을 끌어올린 경우를 보여 주며, 파일 경로를 V$DATAFILE과 df, lsblk로 장치에 매핑해 확인함

#사용 조건과 주의사항

sar 예시 값 상당수는 수업용 가상 결과이므로 판단 방법을 익히는 용도로만 읽음

원인 SQL은 CPU 기록과 같은 시간대의 AWR, ASH, SQL 실행 통계로 확인함

부하 생성 명령과 프로세스 강제 종료는 운영 서버에서 하지 않음

SEO_HKabsumveritas@gmail.comBuilt with Claude Code & Codex

마지막 갱신 개인 학습 기록이며 운영 환경 적용 전 공식 문서 확인 필요

두 글자 이상 입력, 위아래 화살표로 이동하고 Enter로 열기