Skip to content
튜닝 연습Lock과 동시성 제어
LOCK-046

토요일 오후 반품을 막던 UPDATE를 끊었는데 반품은 30분이 지나도 풀리지 않는다

중급UPDATE유통541 / 700

상황 ​

본사 레거시 유통은 이번 주에 판매상품에 판매 금액 칸 SLE_AMT를 더했다. 토요일 13:30, 전산 담당자가 금요일 밤에 돌리기로 했던 칸 채우기 UPDATE를 잊은 것을 알고 SQL*Plus에서 바로 돌렸다. 30분쯤 지나자 매장 여섯 곳에서 반품 처리가 멈췄다는 전화가 왔다. 14:02에 DBA가 그 세션을 끊었다. 그런데 반품은 14:11에도 풀리지 않았고, 운영팀이 다음 조치안을 올렸다. "프로세스를 OS에서 죽이고, 그래도 안 되면 재기동하면 바로 풀리지 않을까요?"

테이블과 인덱스 ​

  • CF11 판매상품: 1,096,708행 · 8,204블록 · CF11_PK (SLE_NO, ITM_NO) · 이번 주에 더한 SLE_AMT(문제 설정)는 비어 있고 인덱스가 없다
  • CF11은 2019년 서버 이전 때 매장별로 다시 담아서 물리 순서가 날짜순이 아니다. 지난주 판매도 블록 곳곳에 흩어져 있다
  • POS는 반품이면 그 판매상품 줄의 SLE_QTY를 UPDATE한다. 토요일 오후 반품은 매장 여섯 곳을 합쳐 시간당 20건 안팎이다
  • 운영 DB는 19c EE · CPU 4개 · FAST_START_PARALLEL_ROLLBACK 기본값(LOW) · 감시 스크립트가 1분마다 V$SESSION_LONGOPS와 V$TRANSACTION을 기록해 둔다

원본 SQL ​

sql
-- 13:30 전산 담당자 (SQL*Plus · SID 77) · 새 칸 채우기 · COMMIT 은 끝에 한 번
UPDATE CF11
   SET SLE_AMT = SLE_QTY * SLE_UPRC;
COMMIT;

-- 14:02:30 DBA · 반품이 멈췄다는 전화를 받고
ALTER SYSTEM KILL SESSION '77,4410' IMMEDIATE;

-- 14:12 운영팀의 다음 조치안 · ① 서버 프로세스를 OS 에서 죽인다 (kill -9) ② 그래도 안 풀리면 재기동
SHUTDOWN ABORT
STARTUP

실행계획 학습용 예시 · 되감기 비용은 교재 12화 §5의 첫 5분 ​

xplan
[토요일 시간표]
시각        전산 담당자 (SID 77)                               매장 POS 반품                              DBA
13:30:00    UPDATE CF11 … 시작 · 블록 순서로 행을 고치며 잠근다
13:35 ~                                                        고칠 판매 줄이 이미 고친 블록에 있으면 기다림
14:01                                                          기다리는 반품 9건 · 길게는 21분 · 매장 전화
14:02:30                                                                                                  ALTER SYSTEM KILL SESSION '77,4410' IMMEDIATE
14:02:31    STATUS KILLED · 되감는 중                            계속 기다림 (BLOCKING_SESSION 77)
14:11                                                          계속 기다림                                운영팀 조치안 접수

[V$SESSION_LONGOPS · 14:02:10 · SID 77 (감시 기록 · 끊기 전에 아무도 보지 않았다)]
OPNAME       TARGET     SOFAR   TOTALWORK   UNITS    ELAPSED_SECONDS   TIME_REMAINING
Table Scan   PUP.CF11   6,400       8,204   Blocks             1,930              544

[V$TRANSACTION · SID 77 (감시 기록)]
시각        STATUS (V$SESSION)   START_TIME   USED_UBLK   USED_UREC
14:02:20    ACTIVE               13:30:00        10,690     855,300
14:10:00    KILLED               13:30:00         8,350     667,800
14:11:00    KILLED               13:30:00         8,040     642,800

[V$SESSION · 14:11:00 · 기다리는 세션]
SID   PROGRAM      EVENT                            SECS   BLOCKING_SESSION   하는 문장
103   POS_02_01    enq: TX - row lock contention     544   77                 UPDATE CF11 SET SLE_QTY = SLE_QTY - :1 WHERE SLE_NO = :2 AND ITM_NO = :3
118   POS_05_02    enq: TX - row lock contention     310   77                 (같은 문장)
…     (반품 10건 더 · 모두 BLOCKING_SESSION 77)

문제 ​

  1. 77을 끊었는데도 반품이 계속 기다리는 이유를 설명하고, 감시 기록으로 반품이 언제 풀릴지 어림하시오.
  2. 14:02에 끊은 판단과 운영팀의 조치안 두 가지를 평가하고, 지금 할 일을 SQL과 함께 쓰시오.
  3. 칸 채우기를 다시 돌릴 방법과, 다음에 큰 트랜잭션을 끊기 전에 무엇을 볼지 쓰시오.
원본 SQL을 고쳐 쓰세요. 인덱스 DDL과 힌트도 쓸 수 있습니다.
무엇이 문제였고 왜 이렇게 고쳤는지 쓰세요.0자