Skip to content

17화 · 실습과 기록 ​

여기서 하는 일: 지난주 한 시간을 10초 표본으로 펼치고, 같은 한 시간을 다시 만들어 1초 단위로 본다. 블로킹 체인을 과거로 돌려 보고, ADDM의 권고를 표본으로 검증한다. 팩이 없는 현장을 만들어 Statspack으로 같은 한 시간을 읽고, T5 2호(교차검증판)와 진단 도구 4열 대응표를 쓴다.1_사건.md를 읽은 것은 "선배가 하는 걸 지켜본 것"이고, 이 문서를 끝내야 직접 해 본 것이 된다. 개념이 막히면 2_파고들기.md를 펼친다.

시간이 없는 주에는 STEP 0 → 1 → 3 → 11만 한다(약 40분). 런을 다시 돌리지 않는 길이라, 16화 STEP 9의 한 시간이 아직 AWR 보존 기간 8일 안에 있을 때만 쓸 수 있다. 62분 런(STEP 2)은 띄워 두고, 기다리는 동안 STEP 3과 4를 한다.


이 화의 실습 지도 ​

스크립트무엇계정소요
실습/00_준비와_점검.sql16화 종료 상태 · 원본 지문 · 지난주 한 시간(C16-H)이 아직 디스크에 있나 · 메모리 ASH의 범위sqlp수 초
실습/01_Statspack_설치_SYSDBA.sqlStatspack(PERFSTAT)을 FREEPDB1에 설치(있으면 지우고 다시)SYS수 초
★★ 실습/02_구간_스냅샷_SYSDBA.sql + 발사기같은 한 시간(C17-H): AWR 루트 · PDB를 +1 · +61분에, Statspack을 5분마다SYS + sqlp62분
★ 실습/03_지난주_한시간_10초표본.sql지난주(C16-H): 분 · 5분 창 · 한 칸 · 표본 수학 · 누가 막았나 · 막은 쪽의 표본sqlp수 초(런 동안 가능)
실습/03b_지난주_ADDM_SYSDBA.sql지난주 한 시간의 자동 ADDM: Finding · Impact · Rationale(읽기만)SYS수 초(런 동안 가능)
★ 실습/04_이번주_한시간_1초표본.sql이번 주(C17-H): 1초 표본 · 세 줄 나란히 · 표본 수학 · 폭발의 가장자리 · 발생기의 기록sqlp수 초(런 끝나자마자)
★ 실습/05_블로킹_체인_시계열.sql10초마다 본 체인 · 대기 하나하나 · 과거의 트리 · 뿌리 · TX 이름표sqlp수 초
실습/06_ASH_리포트_SYSDBA.sqlashrpt와 같은 리포트: 한 시간(디스크) · 한 시간 1분 칸 · 폭발 5분 → 파일SYS수 초
★ 실습/07_ADDM_검증_SYSDBA.sqladdmrpt와 같은 리포트: 한 시간 ADDM · Finding/Impact · Rationale · ASH로 검증SYS10초
실습/08_시퀀스와_행락_재기.sqlADDM 1위 권고를 혼자 재기 · AWR '행 락 88%'의 문장sqlp20초
실습/08b_권고_적용_런_SYSDBA.sql(선택) 권고(CACHE 1000)를 부하 위에서 시험: 7분 × 2SYS + sqlp15분
실습/09_SQL_Monitor.sqlSQL Monitor의 시작 조건: 기다림 · 5초 · 힌트 · 병렬 · 리포트sqlp20초
★ 실습/10_팩_없는_현장_SYSDBA.sqlCONTROL_MANAGEMENT_PACK_ACCESS = NONE(메모리만) → 무엇이 막히나 → 되돌린다SYS20초
★ 실습/11_Statspack_리포트_SYSDBA.sqlspreport로 같은 한 시간 · 10:30~10:35 → 파일SYS수 초
실습/99_정리_SYSDBA.sql팩 설정 원복 확인 · PERFSTAT 지우기 · 시험 객체 · 16화 종료 상태 확인SYS수 초
16화 실습/03_AWR_리포트_SYSDBA.sql이번 주 한 시간의 AWR 리포트(이름만 C17-H로)SYS수 초

SYS로 돌리는 스크립트. Git Bash에서는 MSYS_NO_PATHCONV=1 docker exec -i ora-hanorder sqlplus -s / as sysdba < …로 돌린다(앞의 변수를 빼면 /가 경로로 바뀐다). PowerShell에서는 Get-Content … -Encoding UTF8 | docker exec -i ora-hanorder sqlplus -s / as sysdba로 돌리고, 그 전에 $OutputEncoding = New-Object System.Text.UTF8Encoding $false를 한 줄 실행한다. 원본 테이블에는 한 줄도 쓰지 않는다. 부하 발생기는 *_LD 작업 테이블에만 쓰고, 08은 스스로 만든 *_C17*에만 쓴다. 발사기가 런 앞뒤로 원본 지문을 찍는다. 인스턴스 설정을 하나 바꿨다가 되돌린다. 10이 CONTROL_MANAGEMENT_PACK_ACCESS를 메모리에서만 NONE으로 바꾼다. spfile은 건드리지 않는다. 99가 한 번 더 확인한다.


STEP 0 — 전제 확인 · 지난 리포트를 다시 연다 (5분) ★ 매주 처음 하는 일 ​

bash
docker start ora-hanorder
docker exec -i ora-hanorder sqlplus -s sqlp/sqlp@localhost/FREEPDB1 < 실습/00_준비와_점검.sql
확인기대☐
[전제] big_rows · big_idx · hist · stlm_rows · last_no · pkg · driver · ld_tabs · driver_alive · c16_left · ld_seq_cache1000000 · 3 · FREQUENCY · 100000 · 0 · VALID · VALID · 3 · 0 · 0 · 20☐
원본 지문T_ORD_BIG 1000000 / 255,398,623,700 · T_ORD_STLM 100000 / 25,519,833,100 · T_STLM_NUM 0☐
설정control_management_pack_access DIAGNOSTIC+TUNING · cpu_count 2 · job_queue_processes 1 · parallel_max_servers 1☐
[지난주] C16-H런이 있고 disk_samples가 1,000 남짓 · OK - STEP 3 can open last week's hour☐
[메모리 ASH]가장 오래된 표본의 시각: 지금부터 한두 시간 전(고리 버퍼)☐
Statspackperfstat_user 0(01이 깐다)☐

verdict가 GONE이면 지난주 런이 보존 기간 8일을 넘긴 것이다. 이때는 STEP 3을 건너뛰고, STEP 5가 끝난 뒤 03을 이번 주 런으로 돌린다: sed 's/C16-H/C17-H/' 실습/03_지난주_한시간_10초표본.sql | docker exec -i ….

지난 리포트를 연다. 16화 3_실습과_기록.md의 T5-001을 펴고, 8번 4행 "행 락 5.5%, 부차적"과 5번 칸 "이 리포트로 말할 수 없는 것: 언제 · 누가"에 연필로 동그라미를 친다. 오늘 그 1호는 고치지 않는다. 2호(STEP 11)에서 옆에 정정을 단다.


STEP 1 — 예측을 봉인한다 (5분) ​

Q1. 지난주 한 시간의 'enq: TX 5.5 %' (599초) 를 5분 칸 12개로 나누면, 가장 큰 칸은 몇 % 일까?        ______
Q2. 디스크(DBA_HIST)의 ASH 표본 하나는 DB Time 몇 초를 대신할까? 메모리(V$) 표본 하나는?          ______ / ______
Q3. 그 폭발 5분 동안 DB CPU 는 초당 얼마였을까? (지난주 한 시간 평균 1.84)                         ______
Q4. 행 락을 일으킨 '막은 세션' 은 ASH 표본에 몇 장 찍혔을까?                                        ______
Q5. ADDM 1위 'Sequence Usage' 의 권고대로 시퀀스 캐시를 20 → 1000 으로 키우면 DB Time 은 얼마나 줄까?  ______
Q6. CONTROL_MANAGEMENT_PACK_ACCESS = NONE 이면 AWR 리포트(AWR_REPORT_TEXT)는 에러가 날까?          예 / 아니오
▶ 적고 나서 펼치기
  • Q1: 100%(10:30~10:35). 나머지 11칸은 0%다. 한 시간 한 칸으로는 5.7%(ASH 표본으로 센 몫)다.
  • Q2: 디스크 10초, 메모리 1초. 실측: 디스크 60장 × 10 = 600초 vs AWR 599.0초.
  • Q3: 0에 가깝다(ON CPU 표본 0장). 2.01 × 55 ÷ 60 = 1.84는 55분의 2.01과 5분의 0을 섞은 평균이다.
  • Q4: 0장. 쉬고 있었다(PL/SQL lock timer = Idle). 막힌 쪽 표본의 BLOCKING_SESSION에 이름만 남는다.
  • Q5: 줄지 않는다(5분 DB time 900.7 → 902.2초). ADDM은 같은 권고를 다시 한다. 시퀀스를 안 부르는 부하에서도 그 깃발이 켜진다.
  • Q6: 아니오. 리포트는 나온다. 막히는 것은 ADDM(ORA-13716), 새 ASH 표본, 새 SQL Monitor 감시뿐이다. 그래도 팩이 없는데 쓰면 위반이다.

STEP 2 — Statspack을 깔고, 같은 한 시간을 다시 띄운다 (5분 + 62분) ★★ ​

먼저 Statspack을 깐다. 오후(STEP 10)에 쓸 도구지만, 02가 런 동안 5분마다 스냅샷을 찍으려면 지금 깔려 있어야 한다.

bash
MSYS_NO_PATHCONV=1 docker exec -i ora-hanorder sqlplus -s / as sysdba < 실습/01_Statspack_설치_SYSDBA.sql
01의 출력기대☐
[1]PERFSTAT not installed - nothing to drop(두 번째부터는 PERFSTAT dropped)☐
[3]PERFSTAT_USER 1 · STATUS VALID · TABLES_ 73 · SNAPSHOTS 0 · INVALID_ 0 · CON_NAME FREEPDB1☐

창을 두 개 띄운다. 어느 쪽을 먼저 띄워도 된다. 02는 런이 시작되기를 10분까지 기다린다. 단, 런이 시작되고 55초 안에 02가 떠 있어야 S1을 놓치지 않는다.

창 1: 발사기(환경 폴더에서) · 16화 STEP 9와 같은 인자, NOTE만 C17-H

bash
cd 10_본편_튜너의_1년/00_자료준비/고객사/L1_ora-hanorder
PROFILE=SPIKE MINUTES=62 SESSIONS=3 THINK_MS=0 SPIKE_AT=31 SPIKE_LEN=5 SPIKE_KIND=LOCK HOLD_SEC=10 SEED=15 NOTE=C17-H ./05_부하_돌리기.sh
powershell
Set-Location 10_본편_튜너의_1년\00_자료준비\고객사\L1_ora-hanorder
.\05_부하_돌리기.ps1 -LoadProfile SPIKE -Minutes 62 -Sessions 3 -ThinkMs 0 -SpikeAt 31 -SpikeLen 5 -SpikeKind LOCK -HoldSec 10 -Seed 15 -Note C17-H

창 2: 스냅샷(이 화의 폴더에서)

bash
MSYS_NO_PATHCONV=1 docker exec -i ora-hanorder sqlplus -s / as sysdba < 실습/02_구간_스냅샷_SYSDBA.sql
powershell
Get-Content 실습\02_구간_스냅샷_SYSDBA.sql -Encoding UTF8 | docker exec -i ora-hanorder sqlplus -s / as sysdba
02의 출력기대☐
[1]run N C17-H started … (now +0 s) · S1 at +60 s · statspack every 300 s · S2 at +3660 s☐
[2]S1 awr root … awr pdb …(번호 둘은 서로 다르다) · +1 statspack 1☐
[3]+6 statspack 2 … +56 statspack 12: 5분마다 한 줄☐
[4]S2 awr root … awr pdb … · +61 statspack 13☐

⚠️ 이 62분 동안에는 10을 돌리면 안 된다. NONE이 되면 ASH가 표본을 멈춘다. 02는 표시 시각까지 한 번에 잔다. 0.5초마다 깨어나는 대기 루프는 깨어날 때마다 CPU 차례를 기다리기 때문에, 그 기다림이 DB Time에 섞인다. 이 화를 준비하면서 실측한 일이다(2_파고들기 §15).

기다리는 동안 STEP 3과 4를 한다.


STEP 3 — (런 동안) 지난주의 한 시간을 10초 표본으로 (15분) ★ ​

bash
docker exec -i ora-hanorder sqlplus -s sqlp/sqlp@localhost/FREEPDB1 < 실습/03_지난주_한시간_10초표본.sql > last_week.txt

가벼운 쿼리다. 디스크의 표본 천 줄 남짓을 셀 뿐이라 런의 숫자를 흔들지 않는다.

03기대(교재 실측 · 지난주 C16-H)☐
[1] 런 · 스냅샷S1 · S2 사이에 스냅샷 하나(정각 자동) · AWR enq: TX 853 waits · 599초 · 702.2ms☐
[2] 분 단위57칸이 표본 18(AAS 3) · 31~35분(10:30~10:34) 다섯 칸이 12, 전부 ENQ_TX · ON_CPU 0☐
[3] 5분 창10:30~10:35: 표본 60 · AAS 2 · CPU 0% · enq: TX 100% · 나머지 11칸 0%☐
[3] 한 칸1,050 · AAS 2.92 · CPU 63.8% · enq: TX 5.7%☐
[4] 표본 수학DB time 1,050 × 10 = 10,500 vs 10,504.5 · DB CPU 6,680 vs 6,624.2 · enq: TX 600 vs 599☐
[5] 누가 막았나N1 hotfix · 9ph8h7j79zbh7 · 막은 쪽 SID · SERIAL# = session 1 · T_STLM_NUM_LD · 표본 60 · 기다린 세션 2☐
[6] 막은 쪽의 표본1 before · 3 after 두 줄만 나온다. 2 spike 줄이 없다(0장)☐
☐ 5분 창 표와 한 칸을 나란히 적었다 — 같은 표본 1,050개가 5.7 % 도 되고 100 % 도 된다
☐ 2.01 × 55 ÷ 60 을 계산했다 — 16화가 본 DB CPU 1.84 의 정체
☐ 막은 쪽이 표본에 없는 이유를 한 줄로 적었다 (Idle 대기는 찍히지 않는다)
☐ 16화의 의문 'RUN_SESSION(1) 만 300초 짧다' 를 이 표로 풀었다

STEP 4 — (런 동안) 지난주의 ADDM을 읽는다 · 블로킹 트리를 한 장 찍는다 (15분) ​

① 지난주 한 시간의 자동 ADDM. 스냅샷마다 저절로 돌아가 있다. 지난주 S1에서 시작하는 과제를 읽기만 한다(새 과제를 만들지 않으니 가볍다).

bash
MSYS_NO_PATHCONV=1 docker exec -i ora-hanorder sqlplus -s / as sysdba < 실습/03b_지난주_ADDM_SYSDBA.sql > addm_last_week.txt
확인기대(교재)☐
[1] 과제ADDM:<dbid>_1_<S1 다음 번호> · AUTO☐
[2] Finding · ImpactSequence Usage 8,451.5초 · 2.65 · 88.06 · Top SQL 2.32 · 77.15 · Resource Manager .69 · 22.88 · Row Lock Waits 599초 · .19 · 6.24 · Checkpoints .18 · PL/SQL .1☐
[3] Row Lock Waits의 RationaleThe session with ID 175 and serial number 62822 … responsible for 100%: 03 [5]의 막은 세션과 같다 · Impact 599초 = 03 [1]의 enq: TX 599초☐
[3] Sequence UsageRationale 줄이 없다 · [4]의 Action "Use a larger cache size"☐

② (선택) 폭발 한가운데(런 +33분쯤)에 12화의 블로킹 트리를 한 장 찍는다. 지금 V$SESSION을 찍어 두면 STEP 6에서 ASH로 다시 그린 트리와 나란히 놓을 수 있다. 쿼리는 12화 2_파고들기 §5를 그대로 쓴다(읽기만 한다).

기대(교재 · 이 화를 준비하며 같은 자리에서 찍은 것)☐
뿌리 하나: ACTION N1 hold · CLIENT_IDENTIFIER LD<런>-S1 · PL/SQL lock timer☐
그 밑에 둘: N1 hotfix · enq: TX - row lock contention · BLOCKER = 뿌리☐
V$LOCK: 뿌리 TX LMODE 6 · BLOCK 1 · 둘 REQUEST 6 · 같은 usn / slot / wrap☐

STEP 5 — (런 끝 · 곧바로) 같은 한 시간을 1초 표본으로 (10분) ★ ​

발사기 창에 == [9] 남은 드라이버 세션 (기대 0)이 뜨면 곧바로 돌린다.

bash
docker exec -i ora-hanorder sqlplus -s sqlp/sqlp@localhost/FREEPDB1 < 실습/04_이번주_한시간_1초표본.sql > this_week.txt
04기대(교재 실측 · R2)☐
[1]OK - spike window is in memory · OLDEST_MIN_NO가 14 안팎(교재 13.6 · 15.3. 앞쪽은 이미 덮어써졌다)☐
[2] 분 단위 · 세 줄메모리가 덮은 분부터 M_SAMPLES 180 · 31~35분 120 · 전부 M_ENQ_TX · D_ · L_ 열도 같은 자리에 같은 모양☐
[3] 5분 창10:30~10:35: M_SAMPLES 600 · AAS 2 · M_TX_PCT 100 안팎(교재 99.8) · D_TX_PCT 98~100 · L_TX_PCT 100☐
[3] 한 칸D(이번 주) · L(지난주) 둘 다 ENQ_TX_PCT 5.7 안팎☐
[4] (가) enq: TX메모리 600장 안팎 · 디스크 60장 안팎 → 600 · AWR 599초 안팎 · waits 900~1,100(교재 599 · 59 · 598.8 · 1,061)☐
[4] (나) DB time · DB CPU메모리 표본 수 ≈ AWR 초(교재: 9.1분 구간 1,639 vs 1,643.2 · 1,082 vs 1,094.9)☐
[5] 가장자리메모리 첫 표본이 SPIKE_FROM 1,860초 바로 뒤 · 마지막이 2,160 바로 앞(교재 1,860.1 · 2,159.2)☐
[6] 발생기의 기록31~35분 Q1 수십 번 · N1_HOLD 6/분 · N1 hold 30 × 약 10,000ms · N1 hotfix 50번 안팎 × 10~13초(교재 56 × 10.69초). 지난주와 같은 모양☐
☐ 세 줄(이번 주 1초 · 이번 주 10초 · 지난주 10초)이 같은 분에 같은 모양인 것을 확인했다 — 결정적인 부하
☐ 메모리 표본 수와 AWR 의 초가 맞는 것을 확인했다 — 1초 표본 한 장 ≈ 1초

STEP 6 — 블로킹 체인을 과거로 (10분) ★ ​

bash
docker exec -i ora-hanorder sqlplus -s sqlp/sqlp@localhost/FREEPDB1 < 실습/05_블로킹_체인_시계열.sql
05기대(교재 실측)☐
[1] 10초마다+31:00 ~ +35:50 서른 칸이 전부 SAMPLES 20 · WAITING 20 · ON_CPU 0 · WAITERS S2,S3 · BLOCKERS S1 · 앞뒤 칸은 30 · 0☐
[2] 대기 하나하나S2 → S1 · S3 → S1 각각 30번 · 평균 · 최대 · 최소 10초☐
[3] 과거의 트리뿌리 (no sample - idle?) = S1 · 그 밑에 S2 · S3(N1 hotfix · enq: TX). STEP 4 ②의 V$SESSION 트리와 같은 모양이고, 뿌리 한 줄만 다르다☐
[4] 뿌리폭발 전 마지막 표본 +30:59 근처 · 폭발 뒤 첫 표본 +36:00 근처 · S1_SAMPLES_IN_SPIKE 0☐
[5] TX 이름표P1_HEX 54580006 · LOCK_TYPE TX · REQ_MODE 6 · DISTINCT_TX 30 · 표본 600☐
☐ 12화의 블로킹 트리를 과거로 돌릴 수 있다는 것, 그리고 뿌리는 이름만 남는다는 것을 한 줄로 적었다
☐ DISTINCT_TX 30 을 발생기의 'N1 hold 30번' 과 맞췄다

STEP 7 — ASH 리포트 · 그리고 AWR 리포트의 뒤쪽 (10분) ​

bash
MSYS_NO_PATHCONV=1 docker exec -i ora-hanorder sqlplus -s / as sysdba < 실습/06_ASH_리포트_SYSDBA.sql > ash_C17H.txt
sed 's/C16-A/C17-H/' ../16화_처음으로_시스템_전체를_본다/실습/03_AWR_리포트_SYSDBA.sql | MSYS_NO_PATHCONV=1 docker exec -i ora-hanorder sqlplus -s / as sysdba > awr_C17H.txt
powershell
Get-Content 실습\06_ASH_리포트_SYSDBA.sql -Encoding UTF8 | docker exec -i ora-hanorder sqlplus -s / as sysdba > ash_C17H.txt
(Get-Content ..\16화_처음으로_시스템_전체를_본다\실습\03_AWR_리포트_SYSDBA.sql -Encoding UTF8) -replace 'C16-A','C17-H' | docker exec -i ora-hanorder sqlplus -s / as sysdba > awr_C17H.txt

ash_C17H.txt에서 찾을 것(편집기로 검색)

리포트칸기대(교재)☐
[A] 한 시간 · 디스크머리 Data SourceBegin · End 둘 다 DBA_HIST_ACTIVE_SESS_HISTORY☐
[A]Activity Over Time벽시계 5분 칸: 폭발이 걸친 칸(하나 또는 둘)에 enq: TX · 나머지 칸은 CPU + Wait for CPU · resmgr:cpu quantum☐
[A]Top Blocking SessionsS1이 한 시간 내내 '활성 90% 안팎'으로 보인다 · CKPT(enq: RO)가 S1보다 위일 수 있다☐
[B] 한 시간 · 1분 칸Activity Over Time폭발 다섯 칸이 enq: TX로 채워진다☐
[C] 폭발 5분머리Data Source V$ACTIVE_SESSION_HISTORY · Sample Count 600 안팎 · AAS 2.0☐
[C]Top User Events · Top DB Objectsenq: TX 98~100% · SQLP.T_STLM_NUM_LD☐
[C]Top Blocking SessionsS1의 SID,SERIAL# · # Samples Active 0/300 또는 1/300☐
[C]Top Phases of ExecutionSequence Load가 99~100%. STEP 8에서 재는 깃발☐

awr_C17H.txt에서 찾을 것: 16화에서 읽지 않은 뒤쪽

칸기대☐
④ enq: TX - row lock contention5.4% 안팎 · 평균 650~700ms. 16화와 같은 모양☐
Wait Event Histogram(마이크로초 칸 · 2분 칸)enq: TX의 90% 넘게가 512µs 미만 · 6~7%(60번)가 8~16초☐
Segments by Row Lock WaitsOPTSTAT_HIST_CONTROL$ 88% 안팎(횟수)☐
뒤쪽 Active Session History (ASH) Report → Activity Over Timeash_C17H.txt [A]와 같은 칸☐

⚠️ 06은 한 시간을 l_data_src => 2(디스크)로 뽑는다. 앞쪽이 메모리에서 밀려난 한 시간을 이 인자 없이 뽑으면 표본이 몇 분의 1로 줄고 enq: TX가 아예 없는 리포트가 에러 없이 나온다(교재 실측: 313 표본 · AAS 0.87). 머리의 Data Source 두 줄부터 본다.


STEP 8 — ADDM을 검증한다 · 1위의 권고를 재 본다 (20분 · 선택 +15분) ★ ​

bash
MSYS_NO_PATHCONV=1 docker exec -i ora-hanorder sqlplus -s / as sysdba < 실습/07_ADDM_검증_SYSDBA.sql > addm_C17H.txt
docker exec -i ora-hanorder sqlplus -s sqlp/sqlp@localhost/FREEPDB1 < 실습/08_시퀀스와_행락_재기.sql
07기대(교재 실측)☐
[1]C17H_HOUR · S1 · S2 · COMPLETED☐
[2] Summary1 Sequence Usage 2.85 | 97.54 · 2 Top SQL 2.26 | 77.32 · 3 RM .6 | 20.45 · 4 Checkpoints .19 · 5 Row Lock Waits .17 | 5.68 · 6 User I/O · (PL/SQL Execution이 있으면 대기 루프가 섞인 것)☐
[4] Row Lock Waits의 Rationale9ph8h7j79zbh7 blocked · session with ID … serial number …☐
[4] Sequence UsageRationale 없음☐
1위의 숫자인스턴스 Time Model sequence load elapsed time 초 = Sequence Usage IMPACT_SEC(교재 10,277.5 = 10,277.5)☐
[5] (가)WHO = run N session 1 · ASH_PCT_OF_TX_BY_HIM 100☐
[5] (나)TX_SAMPLES_HOUR 600 안팎 · TX_AAS_HOUR .17 · IN_SPIKE = TX_SAMPLES_HOUR · TX_AAS_IN_SPIKE 2☐
[5] (다)모든 ACTION의 PCT_Y가 100. N1 hotfix도 그렇다(그 표본은 전부 FOR UPDATE 대기)☐
[5] (라)N1 rev01 INSERT: 수십 초(교재 31.1초) · 1만 초가 아니다☐
08기대(교재 실측)☐
[2] A~F여섯 판 모두 sequence load 0.00 s · IN_SEQUENCE_LOAD=Y 0 · DB time 3초 안팎(E는 0.01초) · CACHE 20과 1000이 같다☐
[3] KSXMAPPEND x10 (no truncate) 1 · TRUNCATE x10 0 · TRUNCATE + APPEND x10 10 · COL_NOTES STATS_ON_LOAD · 한 번에 수십 µs☐
[4]c17_left 0☐

(선택) 08b: 권고를 부하 위에서 시험한다. 창 2에 08b를 먼저 띄우고, 창 1에서 발사기를 돌린다. 두 판을 돌리는데, 첫째 판은 그대로, 둘째 판은 cache = 1000으로 한다.

bash
MSYS_NO_PATHCONV=1 docker exec -i ora-hanorder sqlplus -s / as sysdba < 실습/08b_권고_적용_런_SYSDBA.sql                                                     # 창 2 · 첫째 판
sed 's/^DEFINE cache = 20$/DEFINE cache = 1000/' 실습/08b_권고_적용_런_SYSDBA.sql | MSYS_NO_PATHCONV=1 docker exec -i ora-hanorder sqlplus -s / as sysdba   # 창 2 · 둘째 판
PROFILE=STEADY MINUTES=7 SESSIONS=3 THINK_MS=0 NOTE=C17-S ./05_부하_돌리기.sh                                                                              # 창 1 · 판마다 (L1 폴더)
08bCACHE 20(교재)CACHE 1000(교재)내 값☐
DB time(5분)900.7초902.2초☐
sequence load721.5초717.8초☐
ADDM Sequence Usage2.41 AAS · 80.1%2.39 AAS · 79.56%(같은 권고)☐
N1 rev01 INSERT1.98초2.87초☐
[3] 되돌린 뒤CACHE_SIZE 20CACHE_SIZE 20☐

(덤) 발사기 가중치에서 N1을 빼고(WEIGHTS=Q1=30,Q2=5,Q3=10,Q4=40,N1=0,P1=1) 첫째 판처럼 돌려 보자. 시퀀스를 한 번도 안 불러도 깃발이 켜지는 세션이 나온다(교재: 3분 런에서 세션 1이 +136초).

☐ ADDM 의 Finding 마다 '채택 / 기각 / 보류' 와 그 근거(어느 표본을 셌나)를 적었다 — STEP 11 T5 2호 4번 칸
☐ Sequence Usage 를 기각한 이유를 두 줄로 — 그 칸이 SQL 의 시간과 맞지 않는다 · 권고를 해도 그대로다
☐ '행 락 88 %' 가 횟수였다는 것을 08 [3] 과 히스토그램으로 적었다

STEP 9 — SQL Monitor는 무엇을 잡나 (10분) ​

bash
docker exec -i ora-hanorder sqlplus -s sqlp/sqlp@localhost/FREEPDB1 < 실습/09_SQL_Monitor.sql > sqlmon.txt
09기대(교재 실측)☐
[1] 런 동안 감시된 것RUN_SESSION(n) 셋: S1만 300초 짧다(교재 3,420 vs 3,720) · FOR_UPDATE_MONITORED 0 · N1 hotfix 평균 10~13초☐
[2] M2a · M2b · M2c1.5초 → MONITORED_NOW 0 · 8초 → 1 · Q2 rev00 0.27초(Buffers 1,026,838) → 0☐
[3] M30.03초 · /*+ MONITOR */ → 1☐
[4] M4실행계획에 PX 줄이 없다(직렬) · Queries Parallelized 0 · 감시 0 · parallel_max_servers 1☐
[5] 리포트Global Information · Global Stats(Elapsed ≈ CPU) · SQL Plan Monitoring Details · First Refresh Time이 시작 6초쯤 뒤☐
☐ 'SQL Monitor 의 5초는 CPU + I/O 다 — 기다림은 안 센다' 를 [1] 의 0 으로 확인했다
☐ Free 에서 병렬 조건을 볼 수 없다는 것을 [4] 로 확인했다 (대규모 EE 환경은 별권)

STEP 10 — 팩이 없는 현장을 만든다 · Statspack으로 같은 한 시간 (20분) ★ ​

① 무엇이 막히나. 런이 끝난 뒤에만 돌린다.

bash
MSYS_NO_PATHCONV=1 docker exec -i ora-hanorder sqlplus -s / as sysdba < 실습/10_팩_없는_현장_SYSDBA.sql
10기대(교재 실측)☐
[0]DIAGNOSTIC+TUNING(메모리 · spfile)☐
[1]NONE · ISMODIFIED SYSTEM_MOD☐
a · b · c · hOK: 스냅샷 · AWR 리포트 · ASH 리포트 · DBA_HIST 조회가 된다☐
dORA-13716: Diagnostic Package License is needed for using this feature.☐
f0 samples: ASH가 새 표본을 안 찍는다☐
g0 row(s): SQL Monitor가 새로 감시하지 않는다☐
i · jOK: V$ 뷰 · Statspack 스냅샷☐
[3]DIAGNOSTIC+TUNING(메모리 · spfile) · a OK · f 3 samples · pack_access_now DIAGNOSTIC+TUNING☐

⚠️ 마지막 줄이 DIAGNOSTIC+TUNING이 아니면 바로 99를 돌려 되돌린다. 10은 spfile을 바꾸지 않으므로 재시작해도 spfile 값으로 돌아온다.

② Statspack으로 같은 한 시간을 본다.

bash
MSYS_NO_PATHCONV=1 docker exec -i ora-hanorder sqlplus -s / as sysdba < 실습/11_Statspack_리포트_SYSDBA.sql > sp_C17H.txt
11[A] 한 시간(교재)[B] 10:30~10:35(교재)☐
[0] 스냅샷13장: RUN_MIN 1.03 · 6 · 11 · … · 56 · 61.05-- [A] hour : 1 -> 13 / [B] 10:30-10:35 : 7 -> 8☐
Elapsed · Av Act Sess60.02분 · 2.95.00분 · 2.0☐
DB time · DB CPU175.51분 · 110.50분10.10분 · 0.11분☐
Top 5 Timed Events의 enq: TX1,060 waits · 599초 · 565ms · 5.7%143 waits · 599초 · 4,187ms · 99.5%☐
ASH 절없다없다. 칸을 좁혔으니 보인다☐
☐ 'NONE 이 막는 것 셋 · 막지 않는 것 넷' 을 적었다 — 그리고 막지 않는다고 써도 되는 게 아니라는 것
☐ Statspack 의 한 시간이 AWR 의 한 시간과 같은 평균의 함정을 가진다는 것, 5분 스냅샷이면 그 5분이 보인다는 것을 적었다
☐ 팩 없는 현장에서 '언제' 를 보는 법 둘(스냅샷 간격 · 블로킹 트리 주기 저장)을 적었다

STEP 11 — T5 2호 (교차검증판) · 진단 도구 4열 대응표 ★ 오늘의 산출물 ​

양식: T5_시스템_성능_리포트.md (17화 개정: 4 · 5 · 7번) · 진단도구_4열_대응표.md (17화 제정)

11-1. T7 워크로드 프로파일 — 2호 (WP-17H · WP-17S) ​

#항목WP-17HWP-17S (선택)
1ID · 목적WP-16H의 재현: 같은 한 시간을 1초 표본으로 보려고ADDM 권고(시퀀스 캐시)를 부하 위에서 견주려고
2대상 · 데이터16화 종료 상태(WP-16H와 같다)같다
3세션 구성WP-16H와 같다: 3세션 · 기본 가중치 · SPIKE_KIND=LOCK · HOLD_SEC=103세션 · 기본 가중치 · STEADY
4시간 구성런 62분 · S1 +1:00 · S2 +61:00 · Statspack +1 ~ +61 5분마다런 7분 · 스냅샷 +1 · +6
5입력값 분포SEED 15(WP-16H와 같다)같다
6명령PROFILE=SPIKE MINUTES=62 SESSIONS=3 THINK_MS=0 SPIKE_AT=31 SPIKE_LEN=5 SPIKE_KIND=LOCK HOLD_SEC=10 SEED=15 NOTE=C17-H ./05_부하_돌리기.sh + 02PROFILE=STEADY MINUTES=7 SESSIONS=3 THINK_MS=0 NOTE=C17-S ./05_부하_돌리기.sh + 08b(cache 20 · 1000)
7성공 판정에러 0 · 지문 앞 = 뒤 · 남은 세션 0 · WP-16H와 같은 모양(04 [2]의 세 줄)에러 0 · SQ_STLM_LD CACHE 20으로 되돌림
8정리END_RUN · 99(PERFSTAT 지우기) · AWR 스냅샷 · 런 기록은 남긴다08b [3]
9운영과 다른 점WP-16H의 ① ~ ⑥ 그대로 + ⑦ 폭발은 모델이다. 운영의 6/17에 무엇이 번호 행을 쥐었는지는 모른다(그 기록은 지워졌다). 12화의 구조를 넣었을 뿐이다⑧ 7분 · 5분 구간. 깃발이 켜지는 시점이 판마다 다르다
10리포트T5-002T5-002 4번 칸

11-2. T5 시스템 성능 리포트 2호 — T5-002 (교차검증판) ​

1호(T5-001)는 고치지 않는다. 1호의 결론 옆에 무엇이 왜 틀렸는지를 적는다. 1호의 구간(WP-16H)과 같은 모양의 구간(WP-17H)을 다시 만들어 두 도구로 교차 검증한다.

1. 구간

항목값
대상 구간WP-16H(16화 · 디스크 10초 표본) · WP-17H(이 화 · 메모리 1초 + 디스크 10초). 같은 인자 · 같은 씨앗
리포트CDB$ROOT AWR 리포트 · ASH 리포트(06) · ADDM(07) · Statspack(11)
스냅샷런 +1:00(S1) · +61:00(S2). 사이에 정각 자동 스냅샷 하나 · Statspack 5분마다 13장
Elapsed · DB Time · AAS60.0분 · 181.09분 · 3.02(16화) / 60.0분 · 175.60분 · 2.93(이 화 · R2)
구간 안의 사건10:30~10:35(런 +31 ~ +36): 번호 행 하나를 둘러싼 블로킹 체인 · 5분

2. 워크로드 프로파일: WP-16H(T7-001) · WP-17H(T7-002) · 운영과 다른 점은 T7 9번 ① ~ ⑦

3. 9칸: 1호에서 바뀐 칸만

#칸1호의 결론2호에서 무엇으로 다시 봤나2호의 결론
①머리CPU 2개에 평균 3.02명ASH 5분 창55분은 AAS 3.00 · 10:30~10:35는 2.00. 그 5분은 아무도 CPU를 쓰지 않았다
②Load ProfileDB CPU 1.84(조금 덜 바빴다)같은 표본의 CPU 몫2.01 × 55 ÷ 60 = 1.84. 5분 동안 0
④Top FG Eventsenq: TX 5.5% · 평균 702ms · 부차적ASH 5분 창 · 이벤트 히스토그램5분 창 100% · 853번 = 8~16초 60번 + 4ms 미만 793번. 702ms짜리는 없다
⑦SQL ordered by락을 기다린 SQL은 목록에 없다ASH(SQL_ID)9ph8h7j79zbh7(FOR UPDATE · 채번 테이블): 표본 60(L) · 600(1초)
⑧Segments행 락의 88%는 SYS 통계 테이블ASH CURRENT_OBJ# · 08 [3] · 히스토그램그 88%는 횟수(P1의 온라인 통계 · 한 번에 수십 µs) · 시간의 100%는 T_STLM_NUM_LD
⑨대조하지 않았다발생기 기록(V_LD_MINUTE)31~35분 Q1이 분당 약 11,000 → 15~31 · N1 hold 30 × 10초 · N1 hotfix 47 × 12.7초(16화). ASH와 맞다

4. ADDM 권고와 채택 · 기각 사유

Finding · ImpactRecommendationRationale의 사실ASH로 다시 센 값판정
Row Lock Waits · .19(L) · .17(R2) AAST_STLM_NUM_LD의 행 경합: 막힌 SQL로 원인 추적막은 세션 175 · 62822(L) · 223 · 41986(R2) 100%기다린 표본 전부 그 세션 · 그 5분에 AAS 2.00채택. Impact는 평균이라 순위로 중요도를 정하지 않는다
Sequence Usage · 2.65(L) · 2.85(R2) AASUse a larger cache size(없음). 시간 모델 sequence load와 같은 초깃발 IN_SEQUENCE_LOAD가 시퀀스와 무관한 표본에도 켜져 있다(FOR UPDATE 대기 100%) · 그 시퀀스를 쓰는 INSERT는 31.1초 · 권고(CACHE 1000)를 따라도 DB time, 그 줄, ADDM 권고가 그대로 · 시퀀스를 안 불러도 켜진다기각: 다른 칸과 맞지 않는 칸
Top SQL StatementsSQL Tuning Advisor(Q2 · Q3 · …)실행 수 · 평균 경과16화 ⑦과 같은 이야기보류 → 18화
Resource Manager CPU Throttling리소스 계획 검토Scheduler16화 ⑤ 23.8%와 같다채택(1호와 같은 결론)
PL/SQL Execution(L)SYS.DBMS_SESSION.SLEEP 271초루트16화 02의 대기 루프측정 도구가 남긴 흔적이라 무시 · 02를 고쳤다

5. 구간 안의 시간 분포: 평균이 가린 것

항목값
창5분 창 12개(운영 시계 10:00~11:00) + 한 칸
표본지난주 디스크 10초 · 이번 주 메모리 1초 + 디스크 10초
폭발10:30~10:35: enq: TX 100% · AAS 2.00 · CPU 0%(한 칸으로는 5.7%)
블로킹 체인막은 쪽 = 런의 세션 1(N1 hold · 번호 행을 10초씩 30번) · 막힌 쪽 = 세션 2 · 3(N1 hotfix · 10초 대기 × 30번씩) · 막은 쪽의 표본 0(Idle)
도구03 · 04 · 05 · ASH 리포트(06 [C]) · Statspack 5분 스냅샷(11 [B] 99.6%)

6. 개선 전후 비교: 해당 없음(이 화에서는 고치지 않았다. 08b는 권고를 시험한 것이다: CACHE 20 → 1000 · DB time 900.7 → 902.2초)

7. 팩 라이선스: Free · DIAGNOSTIC+TUNING. 10에서 메모리만 NONE으로 바꿔 시험하고 되돌렸다(spfile은 그대로). 팩이 없는 서버(버거 POS · SE2)에는 AWR · ASH · ADDM을 쓰지 않고 Statspack을 쓴다.

8. 결론과 다음 행동

#정정 · 후보근거다음 절차검증리스크
11호 8번 4행 정정: '행 락 5.5%, 부차적' → '10:30~10:35 5분 동안 정산 등록이 전부 멈춘 블로킹 체인(그 5분 100%)'3번 ① ④ · 5번조민우 씨에게 정정 회신 · 운영의 6/17은 기록이 지워져 확인할 수 없다고 밝힌다——
2운영: 민원이 오면 그 시각의 ASH를 바로 저장(ASH 리포트 5분 · DBA_HIST가 지워지기 전)6/17 기록 소멸(보존 8일)운영팀 절차(박팀장이 요청함)다음 민원 때 리포트가 남았나저장 공간 · 진단 팩 계약 확인
3운영: 블로킹 트리 1분 감시(12화 T4 1호 재발방지 3번)가 실제로 도는지5번 · 팩 없는 현장의 대안운영팀 확인감시 기록에 30초 넘는 막힘이 남나—
4ADDM Sequence Usage: 조치하지 않는다4번 기각——그대로 두면 ADDM이 스냅샷마다 1위로 띄운다. 리포트를 받는 사람에게 이 2호를 같이 준다
5버거 POS(SE2) 진단: Statspack7번Statspack 설치 · 스냅샷 간격 5~15분 · spreport9칸 순서로 읽되 ASH 칸은 스냅샷 간격으로 대신운영 서버 설치는 그쪽 IT 승인 필요

9. 정합성 회귀: 해당 없음. 이 화에서는 SQL을 고치지 않았다. 08과 08b는 복사본 시퀀스와 드라이버 시퀀스(작업 객체)만 바꾸고 되돌렸다(SQ_STLM_LD CACHE 20 확인).

11-3. 진단 도구 4열 대응표 — 1판 ​

양식의 표를 그대로 채운다. 실측 칸에는 내가 잰 지난주와 이번 주 값을 적는다. 교재의 1판은 진단도구_4열_대응표.md의 '17화 실측' 열에 있다.


STEP 12 — 서술 답안 (400~600자) ​

조민우 씨에게 보내는 정정 회신. "락은 부차적이라고 쓰셨던데, 그날 정말 화면이 다 멈췄어요."

▶ 선배의 첨삭 포인트 (쓰고 나서)

① 정정을 첫 문장에 쓴다. "지난주 리포트의 '부차적'은 정정합니다." 변명보다 정정이 먼저다.

② 왜 틀렸는지를 현업의 말로 쓴다. "한 시간짜리 기록에서는 5분 동안 멈춘 것이 '한 시간의 5%'로 희석됩니다." 평균, 칸, 표본 같은 단어는 빼도 된다.

③ 확인한 것과 확인하지 못한 것을 나눈다. 연습 DB에서 같은 모양을 다시 만들어 확인한 것은 '5분 동안 전부 멈추고, 한 시간 기록에는 5%로 남는다'는 점이다. 운영의 6/17에 무엇이 번호를 쥐었는지는 기록이 지워져 모른다. 모른다고 쓴다.

④ 다음에 무엇을 해 달라고 할지 쓴다. "다음에 멈추면 시각만 바로 알려 주세요." 현업이 해 줄 수 있는 가장 값진 일은 시각을 알려 주는 것이다.


STEP 13 — 파인만 자가설명 ​

1단 백지 설명 → 2단 막힘 태그(최소 1개) → 3단 원천 복귀 → 4단 재설명.

태그전형적인 문장
#인과"같은 표본이 왜 5.7%도 되고 100%도 되는지 말로 못 하겠다" → §4 · §5
#수치"표본 60개가 왜 600초인지 손으로 못 보이겠다" → §2
#용어"Rationale과 Recommendation의 차이를 설명하다 막혔다" → §8
#절차"팩이 없는 서버에서 '언제'를 보려면 무엇을 미리 해 둬야 하나" → §11.3

4단 되묻기 3문 (오늘 버전) ​

  1. 조건 반전: "폭발이 5분이 아니라 30초였다면, 디스크의 10초 표본으로 보였을까? 메모리의 1초 표본으로는?"
  2. 반례 요구: "막은 쪽이 ASH에 찍히는 경우는? 그때 그 표본으로 무엇을 알 수 있나?"
  3. 측정 지목: "ADDM 1위를 기각하려면 무엇을 재야 하나? 이 화에서 잰 세 가지는?"

태그는 _막힘로그.md로 옮긴다.


정리 — 16화 종료 상태로 ​

bash
MSYS_NO_PATHCONV=1 docker exec -i ora-hanorder sqlplus -s / as sysdba < 실습/99_정리_SYSDBA.sql

기대: [1] already DIAGNOSTIC+TUNING(메모리 · spfile) · [2] PERFSTAT dropped · perfstat_left 0 · stats_synonyms_left 0 · stats_views_left 0 · [3] c17_left 0 · ld_seq_cache 20 · [4] 1000000 · 3 · FREQUENCY · 100000 · 0 · VALID · VALID · 0 · 원본 지문이 STEP 0과 같다 · 런 기록 C16-H · C17-H가 남아 있다.

남기는 것: AWR 스냅샷(보존 8일) · ADDM 과제 C17H_HOUR · 부하 발생기 런 기록. 지우는 것: PERFSTAT(Statspack은 이 화에서 쓴 도구다. 다시 쓰려면 01을 돌린다). 바꾼 인스턴스 설정은 CONTROL_MANAGEMENT_PACK_ACCESS 하나로, 10이 메모리에서만 바꾸고 되돌렸다. AWR 간격과 보존 기간은 바꾸지 않았다.


완료 체크리스트 ​

  • [ ] STEP 0: 전제 · 원본 지문 · 지난주 한 시간의 보존 · T5-001의 8번 4행에 동그라미
  • [ ] STEP 1: 보기 전에 예측 6개를 적었다
  • [ ] STEP 2: Statspack을 깔고 62분 런을 띄웠다 · 02의 스냅샷 줄 13개
  • [ ] STEP 3: 지난주 한 시간의 5분 창 표와 한 칸을 나란히 적었다 · 막은 쪽의 표본 0
  • [ ] STEP 4: 지난주 ADDM의 Row Lock Waits Rationale을 03 [5]와 맞췄다
  • [ ] STEP 5: 런이 끝나자마자 1초 표본 · 세 줄이 같은 모양 · 표본 수 ≈ AWR 초
  • [ ] STEP 6: 10초마다 본 체인 · 과거의 트리 · TX 30개
  • [ ] STEP 7: ASH 리포트의 Activity Over Time · AWR 리포트 뒤쪽의 같은 칸 · 히스토그램
  • [ ] STEP 8: ADDM Finding마다 채택 · 기각 · 보류 · Sequence Usage 기각의 근거
  • [ ] STEP 9: SQL Monitor가 FOR UPDATE 대기를 잡지 않은 것 · 5초 · 힌트 · 병렬(Free ✗)
  • [ ] STEP 10: NONE에서 막힌 셋 · 막히지 않은 넷 · 되돌렸다 · Statspack 한 시간 vs 5분
  • [ ] STEP 11: T5-002 · T7-002 · 4열 대응표 1판
  • [ ] STEP 13: 막힘 태그 최소 1개를 _막힘로그.md에 옮겼다
  • [ ] 정리: 99 · 팩 설정 DIAGNOSTIC+TUNING · PERFSTAT 0 · SQ_STLM_LD CACHE 20

완결성 게이트: STEP 11의 T5-002 4번(ADDM 채택 · 기각)과 5번(구간 안의 시간 분포), 그리고 STEP 10의 원복 확인이 비어 있으면 이 화는 미완성이다.


다음 화로 넘기는 상태 ​

무엇값
ora-hanorder 원본변화 없음: 16화 종료 상태(15화 종료 상태 + 16화의 런 기록 · AWR)
남긴 것AWR 스냅샷(C16-H · C17-H · C17-S) · ADDM 과제 · 런 기록(NOTE C17-H · C17-S)
지운 것PERFSTAT · *_C17* 시험 객체
인스턴스 설정CONTROL_MANAGEMENT_PACK_ACCESS DIAGNOSTIC+TUNING(10이 메모리에서만 바꿨다가 되돌림) · SQ_STLM_LD CACHE 20
리비전없다. 이 화에서는 SQL을 고치지 않았다(진단만 했다)
새 양식T5 2호(교차검증판) · 진단 도구 4열 대응표(제정) · T5 개정(4 · 5 · 7번)
열어 둔 것그동안 쓴 리포트 전부 · 표준(T6) · SQL Tuning Advisor · Q2 보류안 → 18화 · IN_SEQUENCE_LOAD 깃발이 켜지는 조건 → 열어 둔다

다음 → 18화 「튜너가 되는 날」: 그동안 쓴 리포트를 전부 꺼내 무엇이 표준이 될지 고른다. 그리고 한 번도 본 적 없는 스키마를 혼자 진단한다.