Intent Modes
Intent Modes(의도 잠금) 는 다중 그라뉼러리티 잠금 (MGL) 에서 상위 노드에 " 하위에서 어떤 락을 걸 계획인지 " 를 선행 표명하는 경량 잠금이다.
기본형은 IS(하위에 S 예고), IX(하위에 X 예고), SIX(테이블은 공유 읽기 허용 + 일부 하위는 배타 갱신) 이며, 트랜잭션은 하위 락을 잡기 전에 반드시 대응되는 의도 락을 상위에 먼저 획득한다 (예: 행 X → 테이블 IX, 행 S → 테이블 IS).
이 구조 덕분에 엔진은 상위 수준에서 Lock Compatibility Matrix만 조회해 대규모 작업 (테이블 스캔·DDL) 과 미세 작업 (개별 행 갱신) 의 충돌 여부를 빠르게 판정하고, 불필요한 광역 차단을 피한다.
의도 락은 2PL과 결합해 직렬가능성 달성에 기여하며, 에스컬레이션·파티셔닝 같은 운영 전략과도 잘 맞는다.
MVCC를 쓰는 엔진에서도 DDL/테이블 락, 인덱스 범위 잠금 등에는 의도 락 규칙이 여전히 적용된다.
실무에서는 " 가능한 가장 약한 모드 " 를 선택하고, 접근 범위를 인덱스로 좁히며, 락/대기 지표로 교착과 에스컬레이션을 상시 점검하는 것이 핵심이다.
의도 잠금: 개념·관계·실무 통합
의도 잠금은 “아래에서 어떤 락을 잡을지” 를 위에 먼저 알려, 빠르고 안전하게 동시성을 높이는 기술.
- 상위에 IS/IX/SIX를 켜고 → 하위에 S/X를 잡는다 → 표 (호환성) 로 허용/충돌을 즉시 판단 → 끝나면 한꺼번에 해제.
- 단건 갱신은 IX+X, 대규모 스캔은 IS+S(또는 범위락), 스키마 변경은 강한 상위 락. 병목은 관측→임계 조정으로 푼다.
의도 잠금 핵심 개념
| 개념 (한글·약어) | 정의 | 왜 중요한가 | 핵심 규칙/포인트 | 대표 상황 |
|---|---|---|---|---|
| 의도공유잠금 (IS) | 하위에서 S 를 잡을 의도 | 상위에서 빠른 판정 | IS 는 IS/IX/S/SIX 와 주로 호환 | 읽기 전용 스캔 시작 |
| 의도배타잠금 (IX) | 하위에서 X(또는 갱신) 의도 | 충돌 국소화·업데이트 준비 | IX 는 S/SIX/X 와 충돌, IS/IX 와 호환 | OLTP 단건 업데이트 |
| 공유 + 의도배타 (SIX) | 상위 S+ 하위 일부 X | 대량 읽기 + 부분 수정 | 대부분과 충돌 (강한 보호) | 보고서 + 부분 갱신 |
| 호환성 매트릭스 | 모드 간 공존 표 | 즉시 Grant/Wait 판정 | " 요청×보유 " 전원 호환 시 부여 | 모든 요청 공정 처리 |
| 2 단계잠금 (2PL) | 확장→수축 규율 | 직렬 가능 충분조건 | 축소기 진입 후 신규 획득 금지 | 트랜잭션 전반 규율 |
| 락 변환/에스컬레이션 | S→X, 하위→상위 승격 | 메모리·메타락 절감 | 동시성 손실·데드락 주의 | 대량 행 갱신 |
| 범위/프레디케이트/넥스트 - 키 | 범위 단위 보호 | 팬텀 차단·직렬화 | 필요한 구간에만 사용 | 고정밀 집계·검증 쿼리 |
| 데드락/기아 | 순환 대기/우선순위 불균형 | 가용성·SLO 보호 | 탐지·예방·타임아웃·순서고정 | 고경합 트래픽 |
IS/IX/SIX 는 신호, S/X 는 실행이다. 매트릭스가 즉시 판정을, 2PL 이 시간 규율을, 범위락이 팬텀 방지를 담당한다. 에스컬레이션과 업그레이드는 효율 vs 동시성의 교환이다.
의도 잠금 상호관계 매핑표
| From → To | 관계/방향성 | 목적 (무엇을 위해) | 효과 (어떤 결과) | 비고 |
|---|---|---|---|---|
| 의도잠금 → 호환성 매트릭스 | " 신호→판단 " | 상위 단계 즉시 충돌 판정 | 불필요 탐색 감소·대기 단축 | IS/IX/SIX 가 선행 |
| 의도잠금 → 2PL | " 획득 규율 " | 상→하 순서로 안전 확장 | 업그레이드 충돌 감소 | 확장기 준수 |
| 의도잠금 ↔ 에스컬레이션 | " 승격 보호 " | 승격 시 안전성 확보 | 예측 가능 튜닝 | 임계 기반 |
| 범위잠금 ↔ 의도잠금 | " 정밀 적용 " | 팬텀 방지 대상 한정 | 차단 최소화 | 인덱스와 결합 |
| 업그레이드 → 데드락 | " 위험 경로 " | S→X 시 사이클 예방 | 순서 고정·분리 설계 | 고경합 구간 |
| 관측 (뷰) → 튜닝 (정책) | " 피드백 루프 " | 병목 식별·임계 조정 | 처리량↑·지연↓ | 운영 반복 |
의도 잠금은 관계의 허브다. " 신호→판단→규율→승격→정밀화→관측·튜닝 " 의 루프가 성능과 정합성을 함께 끌어올린다.
의도 잠금의 실무 적용 맵
| 개념 | 무엇 (실체) | 어떻게 (절차/패턴) | 왜 (효과/지표) | 위험/주의 | 체크리스트 |
|---|---|---|---|---|---|
| IS | 읽기 의도 신호 | 트랜잭션 시작 시 상위에 IS | 대기율↓, 스캔 공존↑ | 상위 락 과도 남용 주의 | " 읽기면 IS 먼저?" |
| IX | 갱신 의도 신호 | 상위 IX 후 행/키 X | 충돌 국소화·응답 안정 | IX↔S 충돌로 스캔 지연 | “IX 후 바로 X?” |
| SIX | S+ 부분 X | 테이블 S + 일부 X | 리포트 + 부분 수정 최적 | 광범위 차단 위험 | " 정말 SIX 가 필요한가?" |
| 호환 매트릭스 | 판정 표 | 요청×보유 전원 호환 검사 | 즉시 Grant/Wait | 표 불일치 해석 금지 | " 표대로 해석?" |
| 2PL | 시간 규율 | 확장기→축소기 | 직렬 가능성·예측성 | 축소기 이후 획득 금지 | " 축소기 진입 시점?" |
| 에스컬레이션 | 승격 | 임계 초과 시 상위 승격 | 메타락/메모리 안정 | 동시성 급락 | " 임계값·시간대?" |
| 범위락 | 범위 보호 | 키 - 레인지 잠금 | 팬텀 0, 정확성↑ | 스캔 차단↑ | " 정말 직렬 구간?" |
| 데드락 관리 | 탐지/예방 | 순서 고정·타임아웃 | 가용성·SLO 보호 | 과도 중단/기아 | " 정책 균형?" |
| 관측/튜닝 | 뷰·이벤트·지표 | 보유/대기/대기체인 분석 | 병목 제거·SLA 준수 | 과최적화 경계 | " 지표 세트 정했나?" |
IS/IX/SIX 는 언제·어디서 락을 강하게 쓸지 선언하게 해준다. 운영은 매트릭스·2PL·에스컬레이션·범위락을 정책으로 엮고, 관측으로 피드백한다.
Lock Compatibility Matrix
| IS | IX | S | SIX | X | |
|---|---|---|---|---|---|
| IS | ✔ | ✔ | ✔ | ✔ | ✘ |
| IX | ✔ | ✔ | ✘ | ✘ | ✘ |
| S | ✔ | ✘ | ✔ | ✘ | ✘ |
| SIX | ✔ | ✘ | ✘ | ✘ | ✘ |
| X | ✘ | ✘ | ✘ | ✘ | ✘ |
핵심 기억법
X=올금지, SIX=IS 만 허용, S=IS/S 만, IX=IS/IX 만, IS=거의 다 허용 (단 X 제외)
기초 조사 및 개념 정립
의도 락을 이해하기 위한 최소 단위
의도 락은 " 이 테이블 안쪽에서 이런 종류의 락을 곧 쓸 거야 " 를 미리 알리는 신호다. 그래서 락 관리자는 굳이 모든 행을 살피지 않고도 충돌 여부를 빨리 판단한다.
작업 순서는 항상 상위부터 (예: 테이블에 IS/IX/SIX) 잠그고, 그다음 하위 (행) 에 S/X 를 건다.
많은 읽기와 일부 쓰기가 섞이면 테이블에 SIX 를, 실제 수정할 행에 X 를 걸어 불필요한 대기와 교착을 줄인다.
의도 락의 개념과 동작 핵심
- 정의: 의도 모드 (Intent Modes, IS/IX/SIX) 는 다단계 락킹에서 트랜잭션이 하위 객체 (페이지·행 등) 에 S/X 를 걸기 전에 상위 객체 (테이블·파티션 등) 에 그 의도를 미리 표시하는 락이다.
- 목적: 상위 수준에서의 빠른 호환성 판정과 충돌 차단, 락 에스컬레이션의 안전한 경로 확보, 대규모 동시성에서의 탐색 비용 절감.
- 동작 원리
- 획득 순서: 부모 (상위) → 자식 (하위).
- 호환성: 상위의 IS·IX·SIX 와 기존 락의 조합을 매트릭스 기준으로 평가해 하위 락 시도를 허/불허.
- 결합: 2PL 과 결합해 직렬가능성을 보장하고, 필요 시 키 - 범위/스냅샷 등과 함께 범위 일관성 보강.
- SIX 포인트: 테이블 수준 대량 읽기 (S) 와 일부 행 갱신 (X) 을 병행해야 할 때, 상위는 SIX, 하위는 X 로 충돌을 최소화한다.
의도 모드의 구조, 규칙, 효용
- 구조
- 계층: 데이터베이스/스키마 → 테이블/파티션 → 페이지 → 행 (→ 인덱스 키)
- 유형: IS(하위 S 의도), IX(하위 X 의도), SIX(상위 S + 하위 X 의도)
- 규칙
- 획득: 상위 의도 → 하위 실제 (S/X) 순서 고정
- 호환: IS 는 대체로 S 와, IX 는 상위 X·S 와 충돌 가능, SIX 는 상위 공유 허용 범위 내에서 하위 배타 의도를 공표
- 에스컬레이션: 미세 락이 많아지면 상위로 승격되며, 의도 락이 이 경로를 안전하게 만든다
- 효용
- 탐색 비용 절감: 상위에서 빠르게 " 여기 아래쪽에 X 를 쓰려는 중인지 " 확인 가능
- 동시성 향상: 허용되는 조합을 늘리고 불필요한 전역 잠금을 피함
- 직렬성 기반: 2PL 과 결합 시 직렬가능성을 확보하며, 범위 정확성은 키 - 범위/스냅샷으로 보강
의도 락의 탄생과 현대적 진화
Intent Modes 는 계층형 데이터 자원(테이블→페이지→행) 에서 “아래에서 S/X 를 잡을 예정” 이라는 ** 의도 (IS/IX/SIX)** 를 상위에 미리 표시해 충돌을 즉시 식별하게 만든다. 이렇게 하면 테이블 전수락으로 동시성이 떨어지는 문제와, 행 단위로만 관리해 락 수·탐색 비용이 커지는 문제를 동시에 줄인다. 이후 상용 DB 는 락 에스컬레이션·큐 공정성을 더해 운영성을 높였고, MVCC와 결합해 읽기는 버전, 쓰기는 Intent+ 락으로 정합성과 처리량을 함께 얻는다. 최신 엔진은 키 - 범위/넥스트키/U 락을 더해 팬텀 방지·교착 완화까지 노린다.
등장 배경
- 대형 다중 사용자 시스템에서 SG 락의 병목과 행락의 오버헤드가 동시에 문제였다.
- 두 극단의 비용 문제
- 거친 세밀도 (테이블락): 경합·대기 확대로 처리량 급감.
- 세밀한 세밀도 (행락): 락 수·탐색 비용·메모리·교착 빈도 폭증.
- 핵심 아이디어: 상위 (테이블/페이지) 에서 IS/IX/SIX로 **" 하위에서 S/X 를 잡을 의도 “**를 표기해, 상위 수준에서 즉시 충돌 여부를 판단하고 불필요한 탐색을 차단.
- 그 결과, 스캔·DDL·OLTP가 공존하는 환경에서도 예측가능성과 처리량을 확보할 수 있었다.
발전 과정
- 다중 그레뉼러리티 이론 제시 (1970s 중반)
- 등장 이유: SG 의 과도한 경합·탐색 비용 해결.
- 개선점: **의도 신호 (IS/IX/SIX)**로 상위에서 빠른 충돌 판정·탐색 회피.
- 상용 DB 채택 (1980s–1990s)
- 등장 이유: 대형 OLTP 확산, 락 메모리와 대기 관리 필요.
- 개선점: 에스컬레이션 정책·락 큐 공정성·모니터링 도입으로 운영 안정성 향상.
- MVCC 확산과 하이브리드 (2000s)
- 등장 이유: 읽기 병렬성 극대화 요구.
- 개선점: 읽기=버전, 쓰기/DDL/범위=Intent+ 락으로 정합성과 처리량 균형.
- 범위·업데이트 락 등 현대 확장 (2010s–현재)
- 등장 이유: 팬텀 방지·변환 교착 완화 요구.
- 개선점: 키 - 범위/넥스트키/U 락 등으로 직렬가능성과 교착 감소 동시 달성.
| 단계 | 시기 | 왜 등장했는가 | 어떤 개선이 이뤄졌나 | 남은 과제 |
|---|---|---|---|---|
| 이론 제안 | 1970s 중반 | SG 병목·행락 오버헤드 | IS/IX/SIX 로 상위에서 빠른 충돌 판정 | 규칙 설계·튜닝 필요 |
| 상용화 | 1980s–1990s | 대규모 OLTP 운영성 요구 | 에스컬레이션·락 큐 공정성·모니터링 | 승격 임계·공정성 트레이드오프 |
| MVCC 결합 | 2000s | 읽기 병렬성 확대 | 읽기=버전, 쓰기=Intent+ 락 하이브리드 | 버전 GC·쓰기 경합 관리 |
| 현대 확장 | 2010s–현재 | 직렬가능성·교착 완화 | 키 - 범위/넥스트키/U 락 도입 | 비용·복잡도 관리 |
timeline title Intent Modes 발전 연대표 1970s 중반 : 다중 그레뉼러리티 락 이론 제시(IS/IX/SIX) 1980s–1990s : 상용 DB 채택 · 에스컬레이션/모니터링 도입 2000s : MVCC 확산 · 읽기-쓰기 하이브리드 정착 2010s–현재 : 키-범위/넥스트키/U 락 등 확장 · 교착 완화
Intent Modes 는 SG 병목 vs 행락 오버헤드의 딜레마를 상위 의도 신호로 해소하고, 상용화 과정에서 운영 안정성, MVCC 결합으로 읽기 병렬성, 현대 확장으로 직렬가능성·교착 완화까지 확보했다.
의도 모드로 여는 동시성·안정성의 균형
의도 모드는 " 행/페이지 같은 하위 자원에 S/X 락을 걸 계획 " 을 테이블 같은 상위 자원에 미리 표시하는 장치다.
덕분에 엔진은 하위 전체를 훑지 않고도 상위에서 허용/대기를 즉시 판단한다.
읽기는 함께, 갱신은 충돌 시 조기 차단하도록 유도해 처리량을 높이고, 락 획득 순서를 규율해 교착 가능성을 낮춘다.
다량의 미세 락은 상위 락으로 승격해 운영 비용을 제어한다.
의도 모드가 푸는 핵심 문제
| 문제 | 기존 한계 | 의도 모드의 개선 방식 | 기대 효과 | 관찰 지표 |
|---|---|---|---|---|
| 비싼 충돌 검사 | 하위 전수 검사 필요 | 상위 IS/IX/SIX 로 즉시 판정 | 판정 비용·지연 감소 | 평균 대기시간, 대기 큐 길이 |
| 동시성 저하 | 읽기/갱신 혼재 시 경합↑ | S 허용, IX 로 갱신 충돌 조기 신호 | 처리량 증가, P95 지연 감소 | TPS/QPS, P95/P99 latency |
| 교착상태 | 불규칙 락 순서 | 상→하 획득 규율화 | 교착 빈도 감소 | 데드락 수, 타임아웃 수 |
| 메타데이터 폭주 | 락 수·메모리 증가 | 에스컬레이션 연동 | 메모리·락 수 안정화 | 락 수, 메모리 사용량 |
| DDL 충돌 | 늦은 충돌 발견 | 상위에서 호환성 즉시 노출 | 배포/운영 리스크 감소 | 실패/롤백 건수, 변경창 지연 |
의도 모드는 상위에서의 즉시 판정과 획득 순서 정규화로 경합·교착·오버헤드를 동시에 줄이고, 에스컬레이션과 결합해 운영 비용을 예측 가능하게 만든다.
의도 모드의 핵심 목적 일람
- 상위 노드에서 하위 잠금 의도를 명시해 충돌을 빠르게 판정
- 대규모 동시성 환경에서 성능과 일관성의 균형 확보
- 잠금 순서의 규율화로 교착 확률과 대기 시간을 낮춤
- 에스컬레이션과 연동해 자원 사용량을 예측 가능하게 관리
- DDL·OLTP·분석 쿼리의 공존 시 시스템 안정성 제고
| 목적 | 정의 | 구현 포인트 | 성공 기준 |
|---|---|---|---|
| 빠른 충돌 판정 | 하위 잠금 의도의 상위 표기 | IS/IX/SIX 호환성 표 | 대기율·판정시간 감소 |
| 동시성·일관성 균형 | 읽기 병행·갱신 고립 | S↔S 허용, IX 충돌 차단 | TPS↑, 오류·팬텀 0 에 근접 |
| 교착 위험 축소 | 락 순서 정규화 | 상→하 획득, 동일 순서 준수 | 데드락/타임아웃↓ |
| 자원 사용 제어 | 락 수·메모리 안정화 | 에스컬레이션 임계치 설계 | 락 수·메모리 변동폭↓ |
| 운영 안정성 | DDL/OLTP 공존 | 상위 호환성 즉시 노출 | 배포 실패·롤백 건수↓ |
목적은 성능·안정·예측 가능성의 동시 달성이다. 구현 포인트는 IS/IX/SIX 운용 규칙과 에스컬레이션·획득 순서 설계다.
문제와 목적의 1:1 연결 맵
| 해결하는 문제 | 대응 목적 | 연결 고리 (메커니즘) |
|---|---|---|
| 비싼 충돌 검사 | 빠른 충돌 판정 | 상위 의도 신호와 호환성 표 |
| 동시성 저하 | 동시성·일관성 균형 | S 허용, IX 로 갱신 충돌 차단 |
| 교착상태 | 교착 위험 축소 | 상→하 획득, 동일 순서 규율 |
| 메타데이터 폭주 | 자원 사용 제어 | 에스컬레이션 임계·정책 |
| DDL 충돌 | 운영 안정성 | 상위에서 호환성 즉시 노출 |
각 문제는 하나의 목적과 직결되며, 의도 신호·획득 순서·에스컬레이션이 연결 축을 이룬다.
Intent Modes 의 필수 전제와 운영조건
Intent Modes 가 제대로 작동하려면 위계적 자원 구조가 먼저 있어야 한다. 트랜잭션은 하위 락 (S/X) 을 잡기 전에 상위에 IS/IX/SIX로 " 잠글 계획 " 을 알리고, 엔진은 락 호환성 매트릭스로 즉시 허용/대기를 판정한다. 이를 위해 내부에는 빠른 Lock Manager(메모리 락 테이블, 해시/트리 인덱스, 대기열, 데드락 탐지) 가 필요하고, 외부에는 관측 도구와 알림/테스트 체계가 필요하다. 순수 S/X 또는 MVCC 만으로는 계층 신호가 부족하므로, Intent Modes 는 상·하위 일관성과 대규모 OLTP 의 예측 가능한 성능을 위한 필수 전제다.
Intent Modes 전제와 요구 핵심
기술적 전제 조건
계층적 자원 모델 (테이블→페이지→행)
- 근거: 의도락은 " 상위에 신호, 하위에 실제 잠금 " 구조를 전제.
- 차별점: 단일 그라뉼러리티 (테이블 전용 잠금) 대비 충돌 표면을 더 미세하게 분산.
의도 락 모드 집합과 호환성 매트릭스 완비
- 근거: IS/IX/SIX 가 있어야 상위에서 빠른 충돌 배제가 가능 (결정표 기반 O(1) 판정).
- 차별점: 순수 S/X 체계만으로는 상·하위 레벨 일관 신호가 부족.
고성능 Lock Manager 와 메모리 락 테이블
- 근거: (자원, 모드, 트랜잭션) 기준의 빠른 조회/삽입/갱신·대기열 관리 필요.
- 차별점: 느린 카탈로그/디스크 접근 기반 관리 대비 대기·경합 급증 억제.
격리수준·2PL 연동
- 근거: 매트릭스는 " 부여 규칙 “, 직렬가능성은 2PL 등 프로토콜로 달성.
- 차별점: 낙관적 CC/MVCC 는 읽기 - 쓰기 충돌 완화에 강점이나, 계층 신호·DDL 보호는 별개.
데드락 탐지/회피·타임아웃
- 근거: 의도락 존재 여부와 무관하게 대기 그래프 순환은 발생 가능.
- 차별점: 단순 테이블락 환경보다 그래프가 커져 탐지 필요성↑.
관측·진단 인터페이스
- 근거: 호환 실패 원인·리드 블로커 확인이 실무 필수.
- 차별점: 블랙박스형 엔진은 튜닝/장애 대응 난이도↑.
시스템/운영 요구사항
빠른 해시/트리 인덱스 기반 락 조회
- 근거: 대기/부여 결정이 트랜잭션 지연의 주된 상수항.
- 차별점: 선형 스캔 구조는 고동시성에서 병목.
락 에스컬레이션/디에스컬레이션 정책
- 근거: 락 수·메모리 한도를 넘지 않도록 자동 승격 필요.
- 차별점: 무정책 환경은 광범위 락 남발 또는 메모리 고갈.
트랜잭션·배치 설계 지침
- 근거: 짧은 트랜잭션/일관된 락 순서가 교착·대기 완화.
- 차별점: MVCC 단독 사용 대비 쓰기 경합이 높은 OLTP 에 효율적.
모니터링·알림·리그레션 테스트
- 근거: 스키마/인덱스 변경은 호환성·범위 충돌 양상을 바꿈.
- 차별점: 사전/사후 테스트 없이는 성능 회귀 리스크 큼.
Intent Modes 운영 전제·요구 일람
| 구분 | 항목 | 내용/설명 | 근거 (원리) | 관련 기술 대비 차이점 | 검증 포인트 |
|---|---|---|---|---|---|
| 기술 전제 | 계층적 자원 모델 | 테이블→페이지→행 부모 - 자식 정의 | 의도락은 상위 신호·하위 잠금 전제 | 단일 그라뉼러리티 대비 충돌 분산 | 부모 포인터/식별자 무결성 |
| 기술 전제 | 의도락 모드·호환성 표 | IS/IX/SIX(+S/X/NL) 완비 | 결정표 기반 O(1) 판정 | S/X 만으론 상하위 신호 부족 | 매트릭스 일관성 테스트 |
| 기술 전제 | Lock Manager/메모리 락 테이블 | (자원,모드,TX) 키로 빠른 조회·대기열 | 경합 시 상수 지연 최소화 | 카탈로그 의존 대비 저지연 | 평균/최대 조회 지연 |
| 기술 전제 | 격리수준·2PL 연동 | 부여 규칙 + 프로토콜 결합 | 직렬가능성 보장 경로 확보 | MVCC 단독과 상보 | 격리별 충돌/팬텀 시나리오 |
| 운영 요구 | 데드락 탐지/타임아웃 | WFG·타임아웃 정책 | 순환 대기 해소 | 단순 테이블락보다 필수성↑ | 탐지 주기·롤백 비율 |
| 운영 요구 | 에스컬레이션 정책 | 락 수/메모리 한도 관리 | 광범위 락 남발 방지 | 무정책 대비 안정성↑ | 승격 임계·부작용 모니터 |
| 운영 요구 | 모니터링/알림 | 보유·대기·리드블로커 가시화 | 원인→대응 루프 단축 | 블랙박스 대비 튜닝 용이 | 대기시간·데드락/타임아웃 |
| 운영 요구 | 릴리스 전후 테스트 | 스키마/인덱스 변경 검증 | 범위·호환성 변화 흡수 | 사전 테스트 無 대비 리스크↓ | 회귀 케이스 통과율 |
핵심은 **계층·모드·관리 (전제)**와 **탐지·정책·관측·검증 (운영)**을 함께 갖추는 것. 이 조합이 있어야 Intent Modes 가 성능과 예측 가능성을 동시에 제공한다.
의도 잠금의 본질: 신호·판정·승격의 조화
- 무엇: IS/IX/SIX 는 " 아래에서 어떤 락을 잡을지 " 를 위에서 먼저 알리는 신호다.
- 왜: 상위에서 한 번의 표 조회로 충돌 가능성을 즉시 판단하고, 하위 탐색·재시도 비용을 줄인다.
- 어떻게: 상→하 순서로 의도→실제 (S/X) 락을 잡고, 필요 시 승격한다. 업그레이드는 최소화한다.
- 실무 감각: 리드가 많고 소수 갱신이면 SIX가 유리, 라이터가 많다면 IX+ 행 X가 안전. 팬텀은 범위락을 병행한다.
의도 잠금: 작동 원리와 실무 차별점
위계 전파와 O(1) 판정의 결합
의도 락은 조상 노드에 의도 신호를 남겨 상위 수준에서 compat[M_req][M_hold] 만 보면 된다.
이 상수시간 판정 덕분에 Grant/Wait 결정이 단순·빠르며, 하위 노드 전수 검사를 줄인다.
동일 그레뉼러리티만 쓰는 방식보다 탐색·대기 비용이 체계적으로 낮다.
승격·업그레이드의 안전판
다량의 하위 락을 상위 락으로 에스컬레이션할 때, 상위에 이미 IS/IX/SIX 가 걸려 있으면 호환성 판단과 차단 폭을 예측 가능하게 제어할 수 있다.
반대로 의도 락 없이 S→X 업그레이드는 교착의 단골 경로가 된다.
SIX 의 자리와 한계
SIX는 " 리드 대다수 + 소수 갱신 " 을 한 트랜잭션에서 처리할 때 쓰인다.
리더는 공존 (상위 S), 라이터는 직렬화 (하위 일부 X) 되어 데드락·경합이 줄어 응답 안정성을 준다.
다만 라이터가 다수인 워크로드에선 테이블 수준 차단으로 병목이 될 수 있어, IX+ 행 X나 파티션 분리가 더 낫다.
범위락과 직렬성 요구 구간
팬텀은 행 단위 호환성만으로는 잡히지 않는다. 키 - 레인지/넥스트 - 키 같은 범위 기반 잠금으로 직렬성 구간을 보호하되, 의도 락으로 적용 범위를 상위에서 한정하여 차단을 최소화한다. MVCC 와 병행 시에도 직렬성이 필요한 구간에선 범위락이 결정적이다.
운영 관측과 표준성
보유/대기/대기체인, 데드락 그래프, 에스컬레이션 카운터 등 운영 메트릭이 풍부하다.
애플리케이션 락이나 분산 락과 달리 데이터 무결성과 직접 결합되어, 장애 재현·원인 분석·튜닝 루프가 표준화되어 있다.
의도 잠금 특징·근거·차별점 정리
| 특징 | 기술적 근거 | 장점 | 한계/주의 | 다른 기술과의 차별점 | 대표 활용 |
|---|---|---|---|---|---|
| 위계 전파 (상→하) | 조상 - 자손 의도 신호 | 상위에서 즉시 판정, 탐색 감소 | 의도 메타데이터 비용 | 단일 그레뉼러리티보다 공존성↑ | 대부분의 OLTP |
| O(1) 호환성 판정 | 정적 5×5 매트릭스 | 예측 가능·빠른 Grant/Wait | 매트릭스 해석 오류 주의 | 규칙 추정보다 단순·일관 | 고경합 테이블 |
| 교착 위험 완화 | 순서 규율·업그레이드 최소화 | 사이클 확률↓ | 완전 제거는 아님 | 순수 탐지/타임아웃 대비 사전 억제 | 장시간 트랜잭션 |
| 에스컬레이션 안전 | 상위 IS/IX/SIX 선점 | 승격 시 충돌 예측 용이 | 동시성 급락 가능 | 의도 없음 대비 리스크 낮음 | 배치/대량 갱신 |
| SIX 활용 | S+ 부분 X | 리더 공존·라이터 직렬화 | 라이터 많으면 병목 | IX+ 행 X 대비 경합↓(소수 라이터) | 리드 90%+ 워크로드 |
| 범위락 결합 | 키 - 레인지/넥스트 - 키 | 팬텀 0, 정합성↑ | 차단 폭 커질 수 있음 | MVCC 단독 대비 직렬성 보장 | 검증·집계 구간 |
| 운영 가시성 | 락 테이블/대기 큐/그래프 | 튜닝·재현·분석 용이 | 과최적화 주의 | 앱 락 대비 데이터 일관성 친화 | 장애 분석/튜닝 |
- 의도 잠금은 신호 (상위) 와 ** 행동 (하위)** 를 분리해 빠른 판정·안전한 승격·예측 가능한 동시성을 만든다. 팬텀 구간은 범위락으로, 라이터 패턴은 SIX vs IX+ 행 X로 분기해 선택한다.
의도 락으로 만드는 예측 가능한 동시성
의도 락은 " 이 위계 아래에서 어떤 종류의 잠금을 쓸지 " 를 미리 알리는 표지판이다. 이 표지판 덕분에 락 관리자는 충돌을 위에서 빠르게 판정하고, 실제로 잠글 대상만 하위에서 좁혀 잡는다. 그래서 대량 동시성 환경에서도 불필요한 대기와 전역 배타를 줄이고, 예측 가능한 성능과 일관성을 유지할 수 있다.
의도 락의 설계 이유와 품질 목표
왜 필요한가
대용량 동시성에서의 탐색 비용 절감
- 상위 객체에 의도를 먼저 표기하면, 락 관리자가 하위 자원까지 내려가지 않고도 충돌 가능성을 초기에 걸러 락 테이블 탐색·대기열 조작 비용을 낮춘다.
일관된 락 순서로 교착 위험 저감
- 상위→하위 획득 순서와 IS/IX/SIX 규칙이 결합되어 순환 대기 조건을 약화시킨다 (탐지·해결은 별도 메커니즘).
부분 갱신이 많은 스캔 패턴 최적화
- 대량 읽기 + 소량 쓰기 시 SIX(상위 공유 + 하위 배타 의도) 로 불필요한 전역 배타를 피하면서 수정 대상만 X 로 좁힌다.
에스컬레이션의 안전한 경로 제공
- 미세 락이 폭증할 때 상위로 승격해 리소스를 보호하되, 의도 락이 상위/하위 호환성의 일관성을 보장한다.
무엇을 개선하나?
- 성능: 호환성 판정의 탐색 범위를 줄여 평균/상위 백분위 락 대기 시간을 낮춘다.
- 일관성: 2PL/격리수준과 결합해 더티/반복불가/팬텀 위험을 통제한다 (범위는 키 - 범위/버전닝 보완).
- 확장성: 그라뉼러리티·에스컬레이션 정책과 함께 코어 수·세션 수 증가에 따른 경합 폭주를 흡수.
- 신뢰성: 표준화된 락 순서·정책으로 장애·교착 대응의 예측 가능성을 높인다.
- 예측 가능성: 호환성 규칙이 명확해 운영 중 튜닝 (쿼리·인덱스·락 정책) 의 효과를 사전에 가늠할 수 있다.
- 데드락 방지 관점: " 완전 방지 " 가 아니라 순환 대기 가능성을 낮추는 설계적 억제와 빠른 탐지·피해자 선택을 용이하게 만든다.
의도 락의 동기와 품질 속성 한눈에
| 구분 | 항목 | 설명 | 기대 효과 | 운영 포인트 |
|---|---|---|---|---|
| 설계 동기 | 탐색 비용 절감 | 상위에서 의도 호환성 판정으로 하위 탐색 최소화 | 대기·컨텍스트 스위칭 감소 | 락 테이블 인덱싱/통계 튜닝 |
| 설계 동기 | 교착 위험 축소 | 상위→하위 획득 순서 +IS/IX/SIX 규칙 | 데드락 빈도 감소 | 대기 그래프/피해자 정책 |
| 설계 동기 | 혼합 워크로드 최적화 | SIX 로 대량 S + 부분 X 병행 | 처리량 향상·지연 감소 | 수정 대상 식별 인덱스 |
| 설계 동기 | 에스컬레이션 안전화 | 미세 락 폭증 시 상위 승격의 일관성 확보 | 메모리 보호·스케일 안정 | 임계치/예외 테이블 관리 |
| 품질 속성 | 성능 | 조기 필터링으로 평균/P95 대기 단축 | TPS/TPM 증가 | 쿼리·인덱스·락 정책 합치 |
| 품질 속성 | 일관성 | S/X 적용 전 상위 호환성 준수 | 데이터 무결성 유지 | 격리수준·키 - 범위 결합 |
| 품질 속성 | 확장성 | 그라뉼러리티·정책으로 경합 폭주 억제 | 코어/세션 증가 대응 | 샤딩/파티션 전략 |
| 품질 속성 | 신뢰성/예측 | 규칙 기반 설계로 결과 재현 | 장애·튜닝 안정성 향상 | SLO·알림·런북 정비 |
| 품질 속성 | 데드락 억제 | 순서 고정으로 순환 대기 약화 | 중단·롤백 비용 감축 | 타임아웃·재시도 설계 |
의도 락은 " 상위에서 미리 말하기 " 로 충돌을 조기에 걸러 성능·확장성·예측 가능성을 동시에 끌어올리고, 교착 위험을 구조적으로 낮춘다.
핵심 원리 및 이론적 기반
의도 락: 원칙·철학의 실전 프레임
Intent Modes 는 상위에서 거르고 하위에서 확정한다.
트랜잭션은 먼저 테이블 등 상위 자원에 **의도 락 (IS/IX/SIX)**을 걸어 " 아래에서 S/X 를 쓸 계획 " 을 알린다.
엔진은 **호환 표 (LCM)**를 한 번만 조회해 허용/대기/거부를 즉시 결정한다.
이렇게 하면 테이블 전수락처럼 동시성이 무너지는 상황도 줄이고, 행 단위만 보다가 실패하는 후행 실패도 사라진다.
승격/업그레이드는 규율을 두어 메모리·경합을 통제하고, 공정한 대기 정책과 관측 지표로 예측가능한 성능을 유지한다.
Intent 핵심 원칙 요약표
| 원칙 | 설명 | 목적 | 필요한 이유 | 적용 포인트/예시 |
|---|---|---|---|---|
| Protocol Ordering | 루트→리프 순서로 잠금 | 상위서 조기 차단 | 순환 대기·탐색 비용 방지 | 테이블→페이지→행 순서 고정 |
| Intention Declaration | 상위에 IS/IX/SIX 선언 | O(1) 선판정 | DDL·전수락과 즉시 충돌 판정 | 테이블 IX 후 행 X |
| Compatibility-First | LCM 먼저 조회 | 후행 실패 제거 | 하위 탐색·대기 낭비 방지 | 요청 시 LCM 체크 |
| Escalation/Upgrade | 승격·업그레이드 규율 | 자원·경합 균형 | 무질서 승격의 상위 충돌 | 임계치 기반 승격 |
| Fairness & Ordering | 공정 큐·일관 순서 | 예측가능 성능 | 기아·지연 폭증 방지 | FIFO+ 우선순위 |
| Strictness for Recovery | 엄격 2PL 연계 | 복구 단순화 | commit 전 X 유지로 안전 | 장애 시 롤백 용이 |
| Observability | 락/대기 가시화 | 운영 의사결정 | 교착·승격 폭주 조기 탐지 | 잠금 뷰·지표 수집 |
핵심 원칙은 상위 선판정·질서·규율·가시성으로 정리된다. 이 조합이 동시성·정확성·예측성을 함께 만든다.
Intent 설계 철학 일람표
| 설계 철학 | 설명 | 목적 | 필요한 이유 | 실무 지침 |
|---|---|---|---|---|
| 최소 간섭 | 필요한 최소 잠금만 | 동시성 극대화 | 불필요한 차단은 곧 지연 | 단건 쓰기 범위만 잠금 |
| 계층적 질서 | 상→하 일관 규칙 | 경로 예측성 | 무질서가 교착·탐색 유발 | 리소스 순서 표준화 |
| 의도 명시 | IS/IX/SIX 신호화 | O(1) 판정 | 상위에서 즉시 충돌 감지 | 하위 접근 전 의도 잠금 |
| 성능 우선 | 빠른 판정·해제 | 지연 최소화 | 락은 비용 요소 | 테이블화/비트셋화 |
| 운영 친화 | 모니터링·튜닝 용이 | 안정적 운영 | 문제 재현·완화 가능 | 대기 큐·승격 지표 노출 |
설계 철학은 적게 잠그고, 위에서 갈라내고, 눈에 보이게 운용하는 데 초점을 둔다.
인텐트 잠금의 동작과 설계 통찰
- 왜 필요한가? 상·하위가 연결된 DB 객체 (테이블→페이지→레코드) 에서, " 하위에 실제 락이 있는지 " 를 상위에서 빠르게 알기 위해.
- 어떻게 동작하나? 상위에 IS/IX/SIX 같은 " 의도 " 를 먼저 걸고, 그 정보를 보고 S/X 실락을 하위에만 최소화해 둔다.
- 무엇이 좋아지나?
- 속도: 상위에서 한 번만 보면 충돌 여부를 즉시 판단.
- 안전: 상위에 X 를 걸어야 하는 작업이, 이미 누군가 하위에 S/X 를 두었는지 빠르게 인지하여 불필요한 스캔/대기 방지.
- 효율: 대량 작업 시 하위 락을 에스컬레이션해 관리 비용 감소.
운영 원리
- 의도 선언: 트랜잭션 T 는 대상 테이블에 IS/IX/SIX로 의도를 표시한다.
- 호환성 검사: 락 매니저는 상단 매트릭스로 즉시 충돌 여부 판단 (예: IX↔S는 불가).
- 실락 부여: 허용되면 필요한 범위의 S/X를 하위 (페이지/레코드) 에만 부여한다.
- 작업 수행: 읽기는 S 기반, 갱신은 X 기반으로 진행.
- 에스컬레이션 (선택적): 하위 락이 과도하면 상위 (테이블) 로 승격해 락 수를 줄인다.
- 해제: 레코드→페이지→테이블 순으로 해제한다.
- SIX 의 활용: 전체를 읽으면서 (S) 일부만 갱신 (하위 X) 하는 혼합 워크로드를 한 트랜잭션에서 안전하게 처리.
인텐트 모드 동작 과정 예시 (IX)
sequenceDiagram
participant T as Transaction
participant LM as Lock Manager
participant DB as Database
participant TB as Table
participant PG as Page
participant RC as Record
T->>LM: Request IX on Database
LM->>DB: Grant IX Lock
T->>LM: Request IX on Table
LM->>TB: Grant IX Lock
T->>LM: Request X on Record
LM->>RC: Grant X Lock
T->>RC: Update Record
T->>LM: Release X on Record
T->>LM: Release IX on Table
T->>LM: Release IX on Database
주요 단계:
- 의도 선언: 상위 레벨에 인텐트 잠금 요청
- 호환성 검사: 기존 잠금과의 충돌 여부 확인
- 잠금 획득: 호환 가능시 잠금 부여
- 실제 작업: 하위 레벨에서 데이터 조작
- 잠금 해제: 하위에서 상위 순으로 해제
핵심 메커니즘
호환성 (테이블 레벨):
| 보유 \ 요청 | IS | IX | S | SIX | X |
|---|---|---|---|---|---|
| IS | ✓ | ✓ | ✓ | ✓ | ✗ |
| IX | ✓ | ✓ | ✗ | ✗ | ✗ |
| S | ✓ | ✗ | ✓ | ✗ | ✗ |
| SIX | ✓ | ✗ | ✗ | ✗ | ✗ |
| X | ✗ | ✗ | ✗ | ✗ | ✗ |
선행 요건 (부모 락):
- 하위에 S/IS를 두려면 부모에 IS/IX.
- 하위에 X/IX/SIX를 두려면 부모에 IX/SIX.
- 락은 상위→하위로만 취득, 하위→상위로만 해제.
인텐트 잠금 모드·호환성 한눈표
| 구분 | 의미 | 주 사용 시나리오 | 부모 필요 잠금 | 대표 비호환 |
|---|---|---|---|---|
| IS | 하위에 S 예정 | 범용 읽기 | (상위) IS/IX | X |
| IX | 하위에 X 예정 | 선택적 갱신 | (상위) IX/SIX | S, SIX, X |
| SIX | 상위 S + 일부 하위 X | 대량 읽기 + 부분 갱신 | (상위) SIX | IS 외 전부 |
| S | 공유 읽기 | 테이블 단위 읽기 | (부모) IS/IX | IX, SIX, X |
| X | 배타 갱신 | 테이블 전량 갱신 | (부모) IX/SIX | 전부 |
- **IS/IX 는 ’ 신호 ‘**이므로 대부분 서로 양립하지만, 상위 전체를 배타적으로 쓰려는 X와는 충돌.
- SIX는 상위 S 로 읽기 동시성을 최대한 유지하면서, 필요한 하위만 X로 보호하는 절충.
- 부모 선행 요건을 지키면, 상위에서 빠른 거부/허용 결정이 가능해 대기·교착을 줄인다.
인텐트 잠금 처리 플로우
flowchart TD
A[트랜잭션 시작] --> B["상위 객체에 Intent 요청(IS/IX/SIX)"]
B --> C{호환성 검사}
C -->|허용| D[하위에 실제 S/X 락 획득]
C -->|거부| E{대기 가능?}
E -->|예| F[대기 큐 진입] --> G{데드락 감지?}
G -->|예| H[롤백 및 재시도/중단]
G -->|아니오| C
E -->|아니오| H
D --> I{"하위 락 과도? (에스컬레이션)"}
I -->|예| J[상위 락으로 승격 시도] --> C
I -->|아니오| K["업무 로직 수행(읽기/갱신)"]
K --> L["락 해제(하위→상위)"]
L --> M[트랜잭션 종료]
- 의도→호환성→실락의 3 단 구성이 핵심이며, 충돌 시 빠른 거부/대기 처리로 불필요한 탐색을 최소화한다.
- 에스컬레이션은 관리 오버헤드를 줄이고, 데드락 감지는 장기 대기를 방지한다.
- 해제 순서(하위→상위) 를 지켜 상위 보호 의미를 깨지 않도록 한다.
IS/IX/SIX 의미와 상위→하위 획득 순서
- IS(Intent Shared): " 아래에서 S(읽기) 쓸 거야.”
- IX(Intent Exclusive): " 아래에서 X(쓰기) 쓸 거야.”
- SIX(Shared + Intent Exclusive): " 위에서는 S 로 넓게 읽고, 아래에서 일부만 X 로 바꿀 거야."
- 규칙: 항상 상위 (테이블/파티션) → 하위 (페이지/행/키) 순서로 의도 락 → 실제 락 (S/X)
왜 의도 락을 먼저 거나?
- 상위에서 의사표시만 해도, 락 관리자가 충돌 가능성을 빠르게 판정 → 불필요한 하위 탐색/대기 감소
- 모든 트랜잭션이 같은 순서 (부모→자식) 로 잡으므로 순환대기 (교착) 위험이 낮아짐
- 에스컬레이션 (행→페이지→테이블 승격) 시 정합성·안전성을 보장
각 모드의 의미·사용 시점
IS: 읽기 위주. " 이 테이블 아래에서 S 를 여러 개 둘 수도 있어요."
- 예: 조회 1,000 건 (갱신 없음)—테이블 IS → 행 S 반복
IX: 쓰기 예정. " 이 테이블 아래에서 X 가 나옵니다."
- 예: 특정 주문 10 건 상태 업데이트—테이블 IX → 해당 행 X
SIX: 넓게 읽으면서 일부만 갱신. " 위는 S, 아래는 부분 X."
- 예: 재고 스캔하며 threshold 미만 상품만 상태 변경—테이블 SIX → 조건 만족 행 X 들
팁: SIX 는 ’ 스캔 + 부분 갱신 ’ 에 특화. 상위 충돌 가능성이 있으니 남발하지 말고 명확한 패턴에서만 사용.
상위→하위 획득 순서 (알고리즘)
- 대상 계층을 위에서 아래로 나눈다: 데이터베이스/스키마 → 테이블/파티션 → 페이지 → 행 (→ 인덱스 키)
- 트랜잭션 의도를 결정한다: 읽기만 (S) / 쓰기 (X) / 스캔 + 부분 갱신 (S + 일부 X)
- 상위 노드에 의도 락을 건다:
- 읽기: IS
- 쓰기: IX
- 스캔 + 부분 갱신: SIX
- 하위 노드에서 실제 락을 건다:
- 읽기 대상: S
- 갱신 대상: X
- 2PL(두 단계 잠금) 기준: 확장 단계 (획득만) → 수축 단계 (해제만). 커밋/롤백 시 일괄 해제.
연습
읽기 전용 배치 스캔 (갱신 없음)
- 조건: 야간에 전체 상품 테이블 스캔, 리포트 생성.
- 선택: 테이블 IS → 행 S(또는 버전 읽기)
- 이유: 갱신이 없으므로 IX/SIX 불필요. 상위 IS 로 동시성 확보, 하위에서 필요한 범위만 S.
PK 로 단건 업데이트 10 건
- 조건: 주문 10 건 상태를 ’ 배송중 ’ 으로 변경.
- 선택: 테이블 IX → 각 행 X
- 이유: 쓰기 예정이므로 상위 IX. 하위에서 대상 행만 X 로 정확히 잠금.
재고 스캔 후 threshold 미만만 수정 (스캔 + 부분 갱신)
- 조건: 100 만 행 스캔, 재고<5 만 X 로 상태 변경.
- 선택: 테이블 SIX → 조건 만족 행 X
- 이유: 폭넓게 읽되, 일부에만 쓰기. 상위 S(스캔 병렬성 유지) + 하위 X(부분 갱신).
운영 중 혼합 부하 (읽기 80%, 쓰기 20%)
- 조건: 카탈로그 조회 다수 + 일부 가격 수정.
- 선택: 조회 트랜잭션은 IS→S, 갱신 트랜잭션은 IX→X
- 이유: 역할 분리. 조회는 가볍게, 갱신은 정확히.
에스컬레이션이 자주 발생 (행락 폭증)
- 대응: 승격 예외 테이블 지정 (핫셋은 행 우선 고정), 비핫 테이블은 임계치 설정 후 승격 허용.
- 순서: 상위 IS/IX/SIX 유지 → 필요 시 페이지/테이블로 승격되더라도 일관성 보장.
잠금 충돌·대기 많음
- 체크: 상위 모드 과도? → IX/SIX 남발 줄이고, 후보 집합을 인덱스로 축소.
- 재설계: 스캔 패턴을 SIX로 정형화하거나, 쓰기 경로를 IX+X로 좁히기.
의도 모드의 흐름과 생명주기 전모
의도 모드는 " 행/키에 걸 락의 계획 " 을 테이블 같은 상위 레벨에 먼저 알리는 절차다.
엔진은 이 신호를 보고 즉시 호환 여부를 판단한다. 불가하면 대기 큐로 보내고, 가능하면 락을 부여한 뒤 하위 실제 락으로 내려간다.
작업이 끝나면 하위부터 상위 순서로 풀어 주고, 그때 대기 중인 트랜잭션을 깨워 다음 결정을 진행한다.
중간에 데드락·타임아웃·에스컬레이션·업그레이드 같은 예외 경로가 개입할 수 있다.
의도 모드 데이터·제어 흐름 정리
- 요청 (Request): 트랜잭션이 상위 객체에 IS/IX/SIX 요청
- 호환 판정 (LCM): 보유 vs 요청을 표로 즉시 판정
- 대기 (Queue): 불가 시 대기 큐로 진입, 주기적 재평가/데드락 탐지/타임아웃
- 부여 (Grant): 가능 시 의도 락 부여→하위 실제 S/X(또는 범위락) 요청/부여
- 유지 (Hold): 작업 수행, 필요 시 에스컬레이션·업그레이드 시도 (정책 준수)
- 해제 (Release): 커밋/롤백에서 하위→상위 순으로 해제, 대기자 깨우기 (Grant 재시도)
의도 모드 제어 단계 요약
- 입력: 트랜잭션 T, 대상 리소스의 계층 (테이블→페이지→행/키), 요청 모드 (IS/IX/SIX 및 하위 S/X/범위락)
- 결정: LCM 기반 호환 판정, 대기 큐 삽입/재평가, 희생자 선정 (데드락/타임아웃), 에스컬레이션/업그레이드 정책 확인
- 행동: 의도 락 부여→하위 실제 락 부여→작업→커밋/롤백에서 하위→상위 해제→대기자 깨우기
- 산출: 성공 커밋 또는 롤백, 대기/충돌/승격 이벤트 로그, 운영 지표 업데이트
의도 모드 흐름 한눈 요약
| 단계 | 입력 | 핵심 결정 (판정) | 수행 액션 | 산출/아티팩트 | 관측 지표 |
|---|---|---|---|---|---|
| 요청 | 트랜잭션 T, IS/IX/SIX | 상위 LCM 호환 여부 | 의도 락 신청 | 요청 이벤트 | 요청률, 큐 길이 |
| 대기 | 불호환 | FIFO/우선순위/에이징 | 큐 대기, 주기 재평가 | 대기 엔트리 | 평균/백분위 대기 |
| 부여 | 호환 | 그랜트 시점 결정 | 의도 락 부여 | 그랜트 로그 | 그랜트 레이트 |
| 하위락 | 하위 S/X/범위락 | 하위 LCM 판정 | 하위락 부여 | 잠금 핸들 | 레코드 잠금 수 |
| 유지 | 작업 진행 | 에스컬레이션/업그레이드 필요 | 승격/변환 시도 | 정책 이벤트 | 에스컬레이션 횟수 |
| 해제 | 커밋/롤백 | 하위→상위 순 해제 | 대기자 깨우기 | 해제 로그 | 데드락/타임아웃 수 |
요약: 상위에서 의도 신호로 빠르게 판정하고, 불가 시 대기·재평가한다. 가능 시 하위 락으로 내려가 작업을 수행하고, 커밋에서 하위→상위 해제하며 대기자를 깨운다. 예외 경로는 데드락/타임아웃/에스컬레이션/업그레이드다.
의도 모드 제어 플로우차트
flowchart TD
A[트랜잭션 시작] --> B[상위 객체에 IS/IX/SIX 요청]
B --> C{LCM 호환?}
C -- 예 --> D[의도 락 Grant]
C -- 아니오 --> E[대기 큐 등록]
E --> F{데드락/타임아웃?}
F -- 예 --> G[희생자 선택·롤백]
F -- 아니오 --> C
D --> H[하위 S/X/범위락 요청]
H --> I{하위 LCM 호환?}
I -- 예 --> J[하위 락 Grant·작업 수행]
I -- 아니오 --> K[하위 대기 큐 등록]
K --> L{데드락/타임아웃?}
L -- 예 --> G
L -- 아니오 --> I
J --> M{에스컬레이션 필요?}
M -- 예 --> N[상위 락 승격 시도]
N --> O{호환·성공?}
O -- 예 --> J
O -- 아니오 --> K
J --> P{"업그레이드 필요?(S→X)"}
P -- 예 --> Q{즉시 가능?}
Q -- 예 --> J
Q -- 아니오 --> K
J --> R[커밋/롤백]
R --> S[하위→상위 순으로 해제]
S --> T[대기자 깨우기·Grant 재평가]
T --> U[종료]
상위 의도 락에서 첫 판정을 수행해 대기를 최소화하고, 하위 실제 락에서 두 번째 판정이 이뤄진다. 대기 중에는 데드락/타임아웃을 감시한다. 유지 단계에서 에스컬레이션·업그레이드를 정책적으로 시도하며, 커밋 시 하위→상위 해제와 깨우기로 다음 결정을 트리거한다.
의도·실제 락 생명주기 확장
stateDiagram-v2
[*] --> Requested
Requested --> Waiting: 호환 불가
Requested --> Granted: 호환 가능
Waiting --> Aborted: 데드락/타임아웃
Waiting --> Granted: 충돌 해소
Granted --> Upgrading: S→X 등 변환 시도
Upgrading --> Granted: 성공
Upgrading --> Waiting: 충돌 발생
Granted --> Escalating: 상위 락 승격 시도
Escalating --> Granted: 성공(승격됨)
Escalating --> Waiting: 충돌 발생
Granted --> Released: 커밋/롤백
Aborted --> Released
Released --> [*]
설명: 기본 4 단계 (Requested→Waiting→Granted→Released) 에 Aborted(데드락/타임아웃), Upgrading(업그레이드), **Escalating(승격)**을 추가해 실무 예외 흐름을 반영했다.
특성 분석 및 평가
의도 잠금의 가치와 실전 효과
Intent Modes 는 상위에서 " 잠글 계획 " 을 먼저 알리는 신호다. 덕분에 엔진은 호환성 매트릭스 한 번으로 충돌을 즉시 판정하고, 하위 전체를 뒤지지 않아도 된다. 그 결과 동시성이 올라가고, Top-down 획득 규율로 데드락이 줄며, 에스컬레이션·모니터링과 맞물려 관리 효율과 확장성이 높아진다. 마지막으로 Intent 는 규칙 (매트릭스), 2PL·격리수준은 절차 (프로토콜) 로 협업해 무결성과 예측 가능성을 보장한다.
Intent Modes 장점 일람표
| 장점 | 상세 설명 | 기술 근거 (메커니즘) | 주요 적용 상황 | 실무적 가치 | 주의/한계 |
|---|---|---|---|---|---|
| 효율적 충돌 검사 | 상위 Intent 만 보고 허용/대기 즉시 판정 | 호환성 매트릭스 O(1) 판정 | 대용량 스캔 vs 단건 갱신 혼재 | 응답 지연·CPU 감소 | Intent 만으론 실제 데이터 충돌 미해결 |
| 동시성 극대화 | 광역 잠금 회피, 세밀 단위 병행 | IS/IX/SIX + 세밀 그라뉼러리티 | OLTP 다중 사용자 | TPS↑, 장기대기↓ | 인덱스·쿼리 품질에 의존 |
| 데드락 완화 | 자원 할당 방향 통일 | Top-down 획득 규칙 | 혼합 트랜잭션 (DDL/배치 포함) | 롤백/타임아웃 감소 | 잘못된 락 순서 땐 여전히 발생 |
| 관리 효율/확장성 | 락 수 요약·승격 용이 | 에스컬레이션 정책과 결합 | 대형 테이블·배치 처리 | 메모리·락 테이블 부하↓ | 과도 승격 시 동시성 저하 가능 |
| 일관성/무결성 | 규칙 + 프로토콜 결합 | 매트릭스 + 2PL/격리수준 | 금융/주문/결제 | 예측 가능한 일관성 | 격리수준·범위락 설정 필요 |
| 운영 가시성 | 상·하위 경합을 신호로 노출 | Intent 상태 관측 | 모니터링/트러블슈팅 | 진단·복구 시간 단축 | 관측 체계 미흡 시 효과 제한 |
의도락은 상위 신호로 빠르게 차단, 세밀 잠금으로 병행성 확대, Top-down 규율로 교착 완화를 달성하며, 에스컬레이션·모니터링과 결합될 때 운영 효율과 일관성이 극대화된다.
의도 잠금의 리스크와 운영 대응 전략
- 의도 잠금은 상→하로 신호 (의도)→실행 (S/X) 구조라서 예측 가능성과 안전한 승격을 준다.
- 대가로 락·메타데이터가 늘어 비용이 들고, 정책이 보수적이면 과도 차단이 생길 수 있다.
- 해결은 인덱스·쿼리 최적화, 임계·시간대 기반 에스컬레이션, 획득 순서 고정, 필요 시 MVCC/샤딩/큐잉 같은 대안·보완 기법을 함께 쓰는 것이다.
- 분산 환경에서는 합의·분산 락 등 상위 레벨 제어가 필수다.
의도 잠금의 단점과 완화·대안
| 단점 | 설명 | 원인 | 실무 문제 | 완화/해결 방안 | 대안 기술 |
|---|---|---|---|---|---|
| 추가 락 획득 비용 | IS/IX 선행으로 락 수 증가 | 위계 의도 신호 | 획득 지연·락 테이블 팽창 | 임계 조정, 트랜잭션 단축, 오프피크 배치 | MVCC·샤딩 |
| 메모리/메타락 오버헤드 | 잠금 메타데이터 유지비 | 계층별 상태 저장 | 메모리 압박 | 에스컬레이션·풀링·TTL | CQRS·캐시 |
| 구현·운용 복잡성 | 매트릭스·프로토콜 지식 필요 | 다중 모드 상호작용 | 버그·튜닝 난도↑ | 표준 가이드·관측 자동화 | 단순 S/X+ 낙관적 재시도 |
| 에스컬레이션 부작용 | 승격 시 차단 폭 확대 | 임계 초과·보호 정책 | p95↑, 처리량 출렁임 | 파티션 승격, 시간대 분리 | 배치·큐잉 |
| 오판/과도 차단 | 상위 호환만 보고 보수화 | 넓은 테이블/범위 락 | 불필요 대기 | 인덱스·쿼리 재작성, 범위 세분화 | 파티셔닝 |
| 업그레이드/특수 락 충돌 | S→X, 갭락 등 상호작용 | 순서 불일치·핫스팟 | 데드락·재시도↑ | 순서 고정, 처음부터 X, SKIP LOCKED | 멱등·큐 기반 직렬화 |
요약: 의도 잠금의 비용은 정책·설계로 줄이고, 남는 리스크는 MVCC/샤딩/큐잉 등과의 보완 조합으로 처리한다.
의도 잠금 운용의 제약과 대응
| 제약사항 | 설명 | 원인 | 영향 | 해결 방안 | 대안 기술 |
|---|---|---|---|---|---|
| 엔진 의존성/관측 차 | 모드·뷰·이벤트 상이 | 내부 설계 차이 | 표준화 어려움 | 엔진별 가이드·추상화 | 공통 락 어댑터 |
| 계층 구조 의존 | 트리형 전제 | 의도 잠금 본질 | 비계층 데이터 어려움 | 가상 계층 도입 | 문서/키 - 값 락 |
| 획득 순서 제약 | 루트→리프 강제 | 프로토콜 정합 | 코드 실수 리스크 | 자동 락 매니저·리뷰 | 낙관적 재시도 |
| 분산 환경 한계 | 단일 노드 가정 | 네트워크/분할 | 글로벌 성능·일관성 저하 | 분산 락·2PC·합의 | 리더 단일화·사가 |
| 스키마/인덱스 품질 의존 | 선택도 낮음 시 차단↑ | 설계 부실 | p95↑·스루풋↓ | 인덱스 재설계·통계 갱신 | CQRS/캐시 |
| 긴 트랜잭션 취약 | 보유 시간 길어짐 | 긴 처리 흐름 | 데드락·대기↑ | 분할·타임아웃 | 비동기 보상 |
요약: 제약은 환경·엔진·데이터 모델에서 오며, 추상화·설계 보완·분산 프로토콜 결합으로 관리한다.
의도 락 트레이드오프의 실전 해법
의도 락은 " 하위에서 어떤 잠금을 쓸지 " 를 상위에 먼저 알리는 방식이다. 세밀하게 잠그면 동시성은 오르지만 관리가 어려워진다. 그래서 상위에 IS/IX/SIX 로 의도를 밝히고, 필요한 곳만 실제 S/X 로 잠근다. 읽기는 버전닝으로 가볍게, 범위 정확성은 키 - 범위로 보강하고, 미세 락이 많아지면 적절히 상위로 올려 균형을 맞춘다.
의도 락 트레이드오프 선택 매트릭스
| 트레이드오프 | A 선택 | A 장점 | A 단점/위험 | B 선택 | B 장점 | B 단점/위험 | 고려 기준 (결정 포인트) | 연관 의도 락/정책 |
|---|---|---|---|---|---|---|---|---|
| 동시성 vs 오버헤드 | 세밀 락 (행/키) | 대기↓, 충돌 격리↑ | 락 수↑, 메타데이터 비용↑ | 거친 락 (페이지/테이블) | 관리 단순, 메모리 절약 | 대기↑, 병렬성↓ | 평균/P95 대기, 락 수, 메모리 여유 | IS/IX 표준화, 에스컬레이션 임계 |
| 복잡성 vs 성능 | SIX 적극 사용 | 범위 스캔 + 부분 갱신 최적 | 상위 충돌·관리 복잡도 | IS/IX 만 사용 | 규칙 단순 | 스캔 중 갱신 충돌 위험 | 부분 갱신 비율, 스캔 카디널리티 | SIX + 하위 X 패턴 |
| 메모리 vs 응답시간 | 캐싱/긴 보유 | 재획득↓, 응답 안정 | 메모리 점유↑ | 필요시 생성/짧은 보유 | 메모리 절약 | 재획득 비용, 지연 변동 | 락 재사용율, 힙/버퍼 압력 | 타임아웃·재시도·보유 시간 상한 |
| 일관성 vs 확장성 | 키 - 범위/직렬화 | 팬텀 방지, 강한 무결성 | 지연↑, 스루풋↓ | 버전닝 (읽기) | 대기↓, 처리량↑ | 범위 무결성 미보장 | 범위 민감 경로 비중, SLO | 키 - 범위는 핵심 경로만, 나머지 버전닝 |
| 단일 정책 vs 맥락별 | 단일 전사 정책 | 운영 단순, 예측 쉬움 | 비효율적 상황 발생 | 테이블/파티션별 정책 | 최적화 여지↑ | 운영 복잡, 룰 관리 부담 | Hot/Cold 분류, 서비스 레벨 | 파티션별 IS/IX/SIX·임계 분리 |
| 낙관적 vs 비관적 | 낙관적 (OCC) 혼용 | 대기 없음, 확장↑ | 충돌 시 재시도 비용 | 비관적 (2PL) | 안정성·예측↑ | 대기·교착 가능 | 충돌율·재시도 비용, SLA | OCC(핫 샤드) + 2PL(코어) |
" 필요한 곳만 강하게, 나머지는 가볍게 " 가 공통 원칙이다. 범위 정확성이 핵심인 경로는 키 - 범위/직렬화로, 읽기 우세 구간은 버전닝으로, 부분 갱신 패턴은 SIX 로, 운영 복잡도는 임계·룰 자동화로 줄인다.
하이브리드 패턴과 적용 목적
| 하이브리드 | 구성 요소 | 적용 목적 (해결 트레이드오프) | 장점 | 고려사항 |
|---|---|---|---|---|
| SIX + 하위 X | 상위 SIX, 대상 행 X | 동시성 vs 복잡성 | 스캔 병렬성 유지, 수정만 배타 | 상위 충돌 증가 가능, 후보 식별 인덱스 필요 |
| 버전닝 + IX/X | 읽기 버전닝, 쓰기 IX/X | 일관성 vs 확장성 | 읽기 대기 제거, 쓰기 안전 | 읽기 - 쓰기 간 갭은 애플 설계로 보완 |
| 선택적 키 - 범위 | 핵심 인덱스만 키 - 범위 | 일관성 vs 성능 | 팬텀 제거, 비용 최소화 | 범위 정의 정확성, 인덱스 설계 중요 |
| 동적 에스컬레이션 | 임계/예외/시간대 기반 승격 | 메모리 vs 응답 | 메모리 보호, 야간 배치 최적 | 낮 시간 동시성 저하 위험 |
| 파티션별 정책 | Hot/Cold 분리, 임계 차등 | 단일정책 vs 맥락별 | 핫셋 특화, 콜드셋 단순 | 정책 관리/관측 복잡 |
| OCC + 2PL 혼합 | 핫 샤드 OCC, 코어 2PL | 낙관적 vs 비관적 | 확장·예측성 동시 확보 | 충돌율/재시도 비용 추적 필요 |
| 우선순위 대기 | 대기 큐 가중치/나이 | 동시성 vs SLO | 긴급 트랜잭션 보호 | 공평성·기아 방지 설계 |
하이브리드는 " 경로·시간·데이터 특성 " 에 따라 강도와 비용을 달리 배치해 총비용을 최솟값으로 맞춘다.
Intent 적용 결정의 핵심 판단축
Intent Modes 는 상위에서 거르고 하위에서 확정하는 방식이어서, 경합이 높거나 스캔·DDL 이 섞인 OLTP에서 특히 효과적이다.
상위 (테이블 등) 에 IS/IX/SIX 신호를 먼저 세워두면, 엔진은 호환성 표로 즉시 허용/대기를 판단해 불필요한 하위 탐색을 줄인다.
반대로 단순 읽기 중심이나 초저지연 목표의 시스템에선 추가 오버헤드가 이득을 상쇄할 수 있다.
운영 단계에서는 에스컬레이션 임계·대기 큐 정책·관측 지표를 함께 설계해야 예측 가능한 성능을 얻을 수 있다.
Intent Modes 적용 적합성 진단
설계 관점
- 계층적 리소스가 뚜렷할수록 유리: 테이블/인덱스/페이지/행 구조에서 IS/IX/SIX 신호만으로 상위에서 충돌을 O(1) 판정.
- 핫스팟 완화 설계: 파티셔닝/샤딩·인덱스 최적화로 경합을 좁은 범위로 국소화하면 Intent 효과 극대화.
- 범위 질의가 많다면 가산점: 키 - 범위/넥스트키로 팬텀을 제어할 수 있어, 배치 스캔과 OLTP 가 섞여도 예측가능성↑.
- 부적합 설계 패턴: 비계층 (KV 단일 버킷)·단일 객체 접근 위주·락 수가 극히 적은 워크로드는 Intent 이득이 작다.
분석 관점
- 적합:
- 고경합 OLTP(동일 테이블/인덱스에 잦은 쓰기) → 상위에서 조기 차단으로 하위 탐색·대기 낭비↓.
- 배치/스캔 혼재 → 범위 락과 의도락 결합으로 스캔–DML 간 간섭 예측.
- DDL 빈발 → 상위 Intent 가 DDL 과 즉시 충돌을 노출, 롤백 비용↓.
- 조건부:
- 읽기 중심(캐시 히트 높고 쓰기 희소) → 오버헤드 대비 이득 제한.
- 초저지연 시스템(틱/실시간 트레이딩, RT 제어) → 락 자체가 목표 지연을 방해할 수 있음.
- 부적합:
- 리소스 극제약 임베디드(락 엔트리/대기 큐 메모리 부족),
- 단일 키 객체 반복 읽기(락 관리 비용이 상대적으로 큼).
운영 관점
- 권장 설정:
- 에스컬레이션 임계: 락 개수·메모리 그래프 기반으로 단계적 조정 (행→페이지→테이블).
- 대기 큐 공정성: FIFO 기본 + 장기 대기 우선권으로 기아 방지.
- 관측 지표: 락 엔트리 수, 평균 대기시간, 데드락 건수/분, 에스컬레이션 횟수, 범위 락 비율.
- 리스크/보완책:
- 상위 충돌 급증(무분별한 승격) → 임계 상향/쿼리 배치/인덱스 보강.
- 데드락 민감(교차 접근 패턴) → 일관된 락 획득 순서·타임아웃·재시도 정책.
Intent 적용 환경별 판정표
| 분류 | 대표 환경/조건 | 판정 | 이유 | 권장 설정/보완책 | 주요 리스크 |
|---|---|---|---|---|---|
| OLTP 고경합 | 동일 테이블에 잦은 쓰기 | 적합 | 상위 조기 차단으로 하위 대기/탐색↓ | IX 선점, 에스컬레이션 임계 튜닝 | 승격 과다로 상위 충돌 |
| 배치·스캔 혼재 | 대량 스캔 + 동시 DML | 적합 | 범위 락 + 의도락으로 간섭 예측 | 키 - 범위/넥스트키 활성, 인덱스 보강 | 팬텀·긴 대기 |
| DDL 빈발 | 스키마 변경 잦음 | 적합 | DDL 과 즉시 충돌 노출 | 변경 윈도우 운영, 락 타임아웃 설정 | 대량 대기/교착 |
| 읽기 중심 | 캐시 히트↑, 쓰기 희소 | 조건부 | 이득 < 관리비용 가능 | 의도락 최소화, RC 활용 | 불필요한 오버헤드 |
| 초저지연 | 마이크로초 지연 목표 | 부적합 | 락 경로 자체가 지연 임계 초과 | 락리스/낙관적 기법 대체 | 지연 편차 확대 |
| 임베디드 제약 | 메모리/CPU 제한 | 부적합 | 락 테이블/큐 비용 부담 | 간소화된 락 또는 단일 그레인 | OOM/스톨 위험 |
경합·혼재·DDL 이 많을수록 Intent 의 상위 선판정 이득이 커진다. 반면 읽기 편중·초저지연·자원 제약 환경에서는 운영 비용이 이득을 상회할 수 있어 대체 전략을 우선 검토한다.
Phase 4: 구현 방법 및 분류
인텐트 락 구현의 체계와 실전 운용
- 아이디어: " 하위에서 할 일 (S/X) 을 상위에 먼저 알린다 (IS/IX/SIX)".
- 이점: 상위에서 즉시 충돌 판정 → 불필요한 스캔·대기 최소화, 동시성↑.
- 실무 포인트:
- DML 은 보통 IX+X, 읽기는 IS+S.
- S 테이블 락은 IS 허용·IX 와 충돌, X 는 전부 충돌.
- 대량 작업은 에스컬레이션으로 락 수를 줄인다.
인텐트 락 구현 핵심 기법 정리
| 구현 기법 | 정의 | 특징 | 목적 | 주 사용 상황 | 대표 예시 |
|---|---|---|---|---|---|
| 인텐트 락 (IS/IX/…) | 상위에 의도 신호 | 상수시간 호환성·MGL | 충돌 빠른 판정 | 다층 객체 운영 | FOR UPDATE → IX+X |
| SIX 운용 | 상위 S + 일부 X | 혼합 워크로드 적합 | 읽기 동시성 + 부분 갱신 | 리포트 + 보정 | SQL Server/Db2 SIX |
| 호환성 매트릭스 | 모드 간 호환 표 | IX↔S 충돌, X 전부 충돌 | 큐/스케줄 효율 | 고경합 테이블 | 엔진 내부 테이블 |
| 획득·해제 프로토콜 | 상→하 획득/하→상 해제 | 부모 선행 요건 | 일관성·교착 예방 | 전 트랜잭션 공통 | 레코드→페이지→테이블 해제 |
| 락 에스컬레이션 | 하위→상위 승격 | 락 엔트리 수↓ | 관리비용 절감 | 배치·대량 처리 | 임계치 기반 승격 |
| SQL- 엔진 맵핑 | 구문→락 패턴 | 자동 설정 | 개발 단순화 | 일반 DML/DDL | READ(S), WRITE(X) |
인텐트 락 구현의 3 축 분류
엔진 - 중립 설계 기법
- 구성: 인텐트 락 (IS/IX), 호환성 매트릭스, 2PL(상→하 획득/하→상 해제).
- 핵심 규칙: 부모 선행 요건 (하위 S→부모 IS, 하위 X→부모 IX/SIX).
- 설계 팁: 매트릭스를 대칭·불변으로 유지, 경합 많은 리소스에 우선 적용.
- 코드 개선 포인트:
- 호환성 표는 중첩 dict로 (집합·인덱스 혼합 사용 지양).
- wait_queue 실사용·타임아웃·데드락 감지 추가.
- 락 카운트/재진입 지원 (동일 트랜잭션 다중 획득).
엔진 - 중립 설계 요소
| 요소 | 설계 포인트 | 실패 시 처리 |
|---|---|---|
| 인텐트 락 | 상→하 단계별 부여 | 상위 실패 시 하위 롤백 |
| 호환성 매트릭스 | 대칭·완전성 | 즉시 거부/대기 큐 |
| 2PL 프로토콜 | 획득/해제 순서 고정 | 역순 해제 강제 |
- 요약: **“IS/IX 신호 + 대칭 매트릭스 + 2PL”**이 기본 골격.
엔진 - 특화 운용 기법
- SIX: 상위 S 유지로 읽기 동시성, 일부 하위 X 로 갱신 보호 (주로 SQL Server/Db2).
- MySQL/InnoDB: 공개 문서 기준 IS/IX 중심 (테이블 X 는 전부 충돌, S 는 IS 허용).
- PostgreSQL: 인텐트 락 대신 테이블 락 모드 +MVCC로 유사 목적 달성.
벤더별 차이 (요지)
| 엔진 | 인텐트 모드 | SIX | 특징 |
|---|---|---|---|
| SQL Server | IS/IX/SIX 등 다양 | 지원 | 풍부한 모드·모니터링 뷰 |
| Db2/Informix | IS/IX/SIX | 지원 | 전통적 MGL 구현 |
| MySQL InnoDB | IS/IX 중심 | 일반적 비노출 | 단순·명확 (테이블 X 강력) |
| PostgreSQL | (인텐트 개념 無) | 해당 없음 | MVCC+ 테이블 락 모드 |
- 요약: SIX 사용 여부·의미는 벤더 의존. InnoDB 는 IS/IX 패턴으로 충분.
SQL·운영 튜닝 기법
- SQL→락 맵핑:
FOR SHARE→IS+S,FOR UPDATE/INSERT/UPDATE/DELETE→IX+X. - 에스컬레이션: 하위 락 많으면 상위로 승격 (임계치·휴리스틱).
- 대기/데드락: 대기 큐·타임아웃·대기 그래프 감지/해결 필요.
운영 튜닝 체크리스트
| 항목 | 점검 포인트 | 액션 |
|---|---|---|
| 맵핑 확인 | 구문별 의도/실락 일치성 | 실행계획·락 뷰 확인 |
| 에스컬레이션 | 임계치·파티션 고려 | 테이블/파티션 기준 설정 |
| 대기·데드락 | 대기 그래프/타임아웃 | 재시도·순서 정렬·락 범위 축소 |
- 요약: 구문 - 락 맵핑의 가시화 + 에스컬레이션 전략 + 데드락 체계가 성능을 좌우.
인텐트 락 구현·운영 한눈에 보기
| 카테고리 | 기법/요소 | 정의·핵심 | 목적 | 대표 상황 | 주의/팁 |
|---|---|---|---|---|---|
| A(설계) | 인텐트 락 (IS/IX) | 상위에 의도 신호 | 충돌 즉시 판정 | 다층 객체 | 상→하 획득 |
| A(설계) | 호환성 매트릭스 | 모드 간 호환 표 | 큐 효율화 | 고경합 | 대칭·완전성 유지 |
| A(설계) | 2PL 프로토콜 | 상→하 획득/하→상 해제 | 교착·불일치 방지 | 전 구간 | 역순 해제 강제 |
| B(특화) | SIX 운용 | 상위 S + 일부 X | 혼합 워크로드 | 리포트 + 보정 | 벤더 의존 |
| B(특화) | 벤더 차이 | 모드·정책 차이 | 적합성 확보 | 이식성 고려 | 문서 확인 |
| C(운영) | SQL- 락 맵핑 | 구문→락 패턴 | 개발 단순화 | 일반 DML | 실행계획·락뷰 확인 |
| C(운영) | 에스컬레이션 | 하위→상위 승격 | 비용 절감 | 배치 | 임계치 튜닝 |
| C(운영) | 대기/데드락 | 큐·타임아웃·감지 | 장기 대기 방지 | 고경합 | 재시도·순서 정렬 |
의도 모드 선택을 위한 네 가지 축
의도 모드는 " 하위에서 잡을 S/X 잠금 계획 " 을 상위에 미리 알리는 표기다.
유형을 고를 때는 네 가지를 본다.
어디를 보호할지 (테이블/페이지/행), 어떤 조합이 필요한지 (IS/IX/SIX), 어떻게 적용할지 (정적/동적/적응), 워크로드가 무엇인지 (읽기·갱신·혼합).
이 네 축을 맞추면 LCM 으로 허용/대기가 즉시 결정되고, 동시성과 안정성을 함께 얻는다.
의도 모드 분류의 표준 프레임
| 분류 기준 | 유형 | 핵심 의미 | 상→하 매핑 예 | 장점/주의 | 대표 상황 |
|---|---|---|---|---|---|
| 리소스 계층 (세밀도) | 테이블 | 상위에서 의도 표기 | Table: IS/IX/SIX → Row: S/X | 관리 쉬움/동시성 낮음 | 배치, 야간 스캔 |
| 페이지/블록 | 중간 단위 보호 | Table: IS/IX → Page: S/X | 균형형 성능 | 일반 OLTP | |
| 행/키 범위 | 미세 단위 보호 | Table: IS/IX/SIX → Row/Key: S/X/범위 | 동시성↑/락 수↑ | 실시간 거래 | |
| 모드 조합 (복잡성) | 기본 | IS·IX | IS→S, IX→X | 단순·예측 용이 | 소규모/단순 트랜잭션 |
| 확장 | SIX 포함 | SIX(상위 S + 하위 X 일부) | 혼합 워크로드 최적 | 엔터프라이즈 | |
| 사용자정의 | 제품/도메인 특화 | 정책 룰 기반 | 관리 복잡성↑ | 특수 워크로드 | |
| 구현 방식 | 정적 | 컴파일/설계 시 고정 | 파라미터 고정 | 일관성↑/유연성↓ | 레거시 마이그레이션 |
| 동적 | 런타임 선택 | 힌트/옵션 반영 | 적응력↑ | 변동 워크로드 | |
| 적응 | 관측 기반 자동화 | 지표 기반 변경 | 자동 최적화 | 클라우드 네이티브 |
의도 모드 실무형 4 축 분류
리소스 계층 (세밀도)
상위일수록 관리가 쉽고 동시성이 낮다. 행/키로 세밀해질수록 동시성이 높지만 락 수가 증가한다.
의도 모드는 항상 상→하로 부여되며, 하위에서의 S/X 허용은 상위 의도로 빠르게 판정된다.
| 계층 | 상위 의도 | 하위 실제 | 장점 | 주의 |
|---|---|---|---|---|
| 테이블 | IS/IX/SIX | Row/Key: S/X | 관리 단순 | 과도하면 동시성 저하 |
| 페이지 | IS/IX | Page: S/X | 균형형 | 페이지 경합 주의 |
| 행/키 | IS/IX/SIX | Row/Key/Range: S/X | 동시성↑ | 락 수/메모리↑ |
요약: 세밀도 선택은 동시성과 운영 비용의 트레이드오프다. 배치는 상위, 실시간 갱신은 하위가 유리.
모드 조합 (복잡성)
IS 는 읽기 의도, IX 는 쓰기 의도, SIX 는 " 전체 읽기 + 부분 쓰기 " 를 한 번에 표현한다.
SIX 는 혼합 워크로드에서 테이블 스캔과 부분 갱신을 안전하게 공존시킨다.
| 유형 | 의미 | 상→하 예 | 장점 | 주의 |
|---|---|---|---|---|
| 기본 (IS·IX) | 단일 의도 | IS→S, IX→X | 단순 | 혼합에 비효율적 |
| 확장 (SIX) | 혼합 의도 | SIX + 일부 X | 혼합 최적 | 호환성 제약↑ |
| 사용자정의 | 정책 기반 | 제품별 | 특화 대응 | 복잡성↑ |
요약: 혼합 워크로드면 SIX 를 우선 검토하고, 단일 목적이면 IS 또는 IX 로 단순화한다.
구현 방식
정적은 규칙이 고정돼 예측 가능하지만 변화에 약하다.
동적은 런타임 힌트/옵션으로 조절한다.
적응은 관측 지표로 모드/세밀도를 자동 조정한다.
| 방식 | 결정 시점 | 장점 | 주의 | 적합 시나리오 |
|---|---|---|---|---|
| 정적 | 설계·배포 시 | 일관성 | 유연성↓ | 레거시, 규제가 강한 환경 |
| 동적 | 런타임 | 적응력 | 관리비용 | 변동 워크로드 |
| 적응 | 관측 자동 | 자동 최적 | 검증 필요 | 클라우드 네이티브 |
요약: 변동성이 크면 동적/적응, 규칙성이 높으면 정적이 적합하다.
워크로드 패턴
읽기 중심은 IS+S 로 동시성을 극대화한다.
갱신 중심은 IX+X 로 충돌을 조기 차단한다.
혼합은 SIX 로 스캔과 부분 갱신을 엮는다.
| 패턴 | 상위 의도 | 하위 실제 | 이점 | 주의 |
|---|---|---|---|---|
| 읽기 중심 | IS | S | 동시성↑ | 팬텀 대비 필요 (범위락) |
| 갱신 중심 | IX | X | 정합성↑ | 대기 증가 가능 |
| 혼합 | SIX | S + 일부 X | 균형 | 호환성 제약 관리 |
요약: 패턴에 맞춘 의도 선택이 대기/데드락/팬텀 위험을 가른다.
의도 모드 분류 종합 매트릭스
| 축 | 유형 | 상위 의도 | 하위 실제 | 주된 이점 | 주의 포인트 | 대표 상황 |
|---|---|---|---|---|---|---|
| 세밀도 | 테이블/페이지/행·키 | IS/IX/SIX | S/X/Range | 관리 단순↔동시성↑ | 락 수·메모리/경합 | 배치/OLTP/실시간 |
| 모드 조합 | 기본/확장/사용자정의 | IS·IX·SIX | S/X | 목적 적합성 | 호환성·복잡성 | 단일/혼합 트랜잭션 |
| 구현 | 정적/동적/적응 | 정책/힌트/자동 | 동일 | 예측↔적응 | 운영비용·검증 | 레거시/클라우드 |
| 워크로드 | 읽기/갱신/혼합 | IS/IX/SIX | S/X/혼합 | 성능·정합성 균형 | 팬텀/대기/교착 | 분석/OLTP/HTAP |
Intent 생태계의 구현·제어·운영 지도
Intent Modes 는 엔진 내부에서 자동으로 작동하고, ORM/프레임워크는 이를 유발하는 SQL 힌트·격리 옵션을 제공한다. 실무에선 (1) 엔진 뷰/이벤트로 현재 보유/대기/리드 블로커를 관측해 병목을 찾고, (2) 서비스 코드에서 락 힌트·격리수준을 일관되게 지정하며, (3) 에스컬레이션/범위잠금/DDL 보호를 이해해 대규모 작업과 미세 갱신이 충돌하지 않도록 조합한다. PostgreSQL 은 명시적 IS/IX 가 없지만 테이블 락 모드와 MVCC 로 유사 목적을 달성하고, MySQL/SQL Server/Oracle 은 의도 또는 동등 개념을 통해 상위 신호 → 하위 실제 잠금을 구현한다.
Intent 생태계: 엔진·ORM·운영
DBMS 내장 (의도락 구현·관측)
- MySQL/InnoDB
- 기능/역할: 테이블 IS/IX, 행/범위 S/X(넥스트키/갭), Performance Schema(
data_locks,data_lock_waits), MDL로 DDL 보호. - 용도: 대규모 OLTP 의 읽기/쓰기 병행, 팬텀 방지.
- 강점: 범위 충돌 제어 명확, 관측 뷰 제공. 약점: 락 에스컬레이션 부재, 인덱스 설계 품질에 성능 민감.
- 기능/역할: 테이블 IS/IX, 행/범위 S/X(넥스트키/갭), Performance Schema(
- SQL Server
- 기능/역할: IS/IX/SIX, 락 에스컬레이션, DMV(
sys.dm_tran_locks), Extended Events(XE). - 용도: 혼합 워크로드 (배치/DDL/OLTP).
- 강점: 의도락/에스컬레이션 정책 성숙, XE 로 저오버헤드 추적. 약점: 에스컬레이션 오조정 시 병렬성 급감 가능.
- 기능/역할: IS/IX/SIX, 락 에스컬레이션, DMV(
- Oracle
- 기능/역할: RS/RX/S/SRX/X(의도에 상응), MVCC, V$ 뷰/AWR/ASH.
- 용도: 읽기 일관성이 중요한 대규모 트랜잭션.
- 강점: 강력한 읽기 일관성·도구 생태. 약점: 모드 스펙트럼이 넓어 학습 곡선 큼.
- PostgreSQL
- 기능/역할: 명시적 IS/IX 없음, 테이블 락 모드 (ACCESS/ROW/SHARE 등) + MVCC, 관측은
pg_locks/pg_stat_activity. - 용도: MVCC 기반 읽기 성능, 필요 시 테이블 락으로 DDL/광역 작업 보호.
- 강점: 비블로킹 읽기, 단순·명료한 관측. 약점: " 정통 Intent" 모델 부재.
- 기능/역할: 명시적 IS/IX 없음, 테이블 락 모드 (ACCESS/ROW/SHARE 등) + MVCC, 관측은
애플리케이션/ORM 계층 (락 힌트·격리 노출)
- Hibernate/JPA:
@Lock(PESSIMISTIC_READ/WRITE)등 → 엔진이 적절한 S/X·의도락 자동 부여. - Spring:
@Transactional(isolation=…)로 격리·타임아웃·전파 지정. - SQLAlchemy:
.with_for_update()로 행 락 요청. - Django ORM:
.select_for_update()로 행 락. - EF Core: 낙관적 동시성 (컨커런시 토큰), 필요 시 비관 잠금은 공급자 의존.
- 강점: 선언적·일관 정책. 약점: 벤더별 의미 차이 (이식성 검증 필요).
운영·모니터링 (진단·튜닝)
- PostgreSQL:
pg_locks,pg_stat_activity,log_lock_waits. - MySQL: Performance Schema,
SHOW ENGINE INNODB STATUS. - SQL Server: DMV + XE(Profiler 비권장), 차단/데드락 이벤트.
- Oracle: V$LOCK/SESSION, DBA_BLOCKERS/WAITERS, AWR/ASH.
- 강점: 리드 블로커·대기 사슬 추적 가능. 약점: 설정/해석 난이도, 권한·오버헤드 고려.
Intent 도구 분류: 구현·제어·운영
구현/관측 (Engine)
- 설명/역할: 의도락 자동 부여, 하위 S/X 와 조합, 현재 보유/대기 상태 관측.
- 정확한 기능: IS/IX/SIX(또는 RS/RX 등), 범위 잠금, 락 테이블/대기열, 데드락 탐지.
- 용도: 대용량 OLTP, DDL 보호, 팬텀 방지.
- 강점/약점: 충돌 판정 O(1), 도구 성숙 / 벤더별 의미 차이·에스컬레이션 부작용 가능.
| 제품/엔진 | 의도/동등 모드 | 관측 수단 | 특징적 용도 | 강점 | 약점 |
|---|---|---|---|---|---|
| MySQL InnoDB | IS/IX + 넥스트키/갭 | Performance Schema, MDL | 팬텀 방지·DDL 보호 | 범위 제어 명확 | 에스컬레이션 부재, 인덱스 민감 |
| SQL Server | IS/IX/SIX + 에스컬레이션 | DMV, XE | 혼합 워크로드 | 정책 성숙·XE | 과도 승격 리스크 |
| Oracle | RS/RX/S/SRX/X + MVCC | V$ 뷰/AWR/ASH | 읽기 일관성 | 강력한 도구 | 학습 곡선 큼 |
| PostgreSQL | (의도 없음) 테이블 락 + MVCC | pg_locks 등 | 비블로킹 읽기 | 단순 관측 | 정통 Intent 부재 |
- 요약: 엔진은 상위 신호→하위 잠금을 자동화하고, 관측 뷰/이벤트로 즉시 진단 가능하나 벤더별 차이와 정책 조정이 성패를 가른다.
제어 (Application/ORM)
- 설명/역할: 코드에서 락 힌트/격리를 선언, 엔진이 의도락·S/X 를 적절히 부여.
- 정확한 기능:
@Lock,with_for_update,select_for_update,@Transactional(isolation=…), 낙관/비관 선택. - 용도: 임계구간 보호, 갱신 경합 완화, 회귀 테스트 시나리오화.
- 강점/약점: 선언적 일관성 / 벤더별 의미 차이로 이식성 검증 필수.
| 프레임워크 | 핵심 기능 | 역할 | 용도 | 강점 | 약점 |
|---|---|---|---|---|---|
| Hibernate/JPA | @Lock(…) | 행/쿼리 잠금 | 비관/낙관 선택 | 선언적 | DB 별 의미 차이 |
| Spring | @Transactional | 격리/전파/타임아웃 | 서비스 계층 제어 | 일관 정책 | 엔진 의존 |
| SQLAlchemy | .with_for_update() | 행 잠금 | 갱신 경합 | SQL 직관 | 조인/범위 주의 |
| Django ORM | .select_for_update() | 행 잠금 | 크리티컬 섹션 | 간결 | 트랜잭션 관리 필요 |
| EF Core | 낙관 컨커런시 | 충돌 감지 | 재시도 패턴 | 재시도 용이 | 비관 잠금 한계 |
- 요약: 애플리케이션은 정책을 선언하고 테스트로 보증한다. 의미 매핑은 각 DB 에서 검증해야 한다.
운영/모니터링 (Ops)
- 설명/역할: 락/대기/데드락 가시화, 에스컬레이션·범위 충돌 진단, 경보·튜닝.
- 정확한 기능: 리드 블로커 식별, 대기 사슬 추적, 로그 기반 회귀 비교.
- 용도: 장애 대응/용량 계획/릴리스 검증.
- 강점/약점: 깊은 가시성 / 설정·해석 난이도·권한 요구.
| 제품/도구 | 기능 | 역할 | 용도 | 강점 | 약점 |
|---|---|---|---|---|---|
| PostgreSQL 뷰/로그 | pg_locks, pg_stat_activity, 대기 로그 | 블로킹/대기 파악 | 운영/장애 분석 | 즉시성 | 상관분석 필요 |
| MySQL PS/상태 | data_locks, data_lock_waits, 엔진 상태 | 범위/대기 분석 | 팬텀/갭 이슈 | 세밀 | 설정·학습 필요 |
| SQL Server DMV/XE | sys.dm_tran_locks, XE | 이벤트 추적 | 프로덕션 모니터링 | 저오버헤드 | 세션 설계 필요 |
| Oracle 뷰/리포트 | V$LOCK/SESSION, AWR/ASH | 추세/실시간 병행 | 용량·장애 분석 | 강력 | 비용/복잡성 |
- 요약: 관측→원인→개선 루프를 자동화하면 Intent 의 이점 (충돌 조기 차단·예측가능성) 을 극대화할 수 있다.
Intent 도구·프레임워크 통합표
| 카테고리 | 제품/도구 | 의도/동등 모드·기능 | 관측/제어 수단 | 주요 용도 | 강점 | 약점 |
|---|---|---|---|---|---|---|
| 구현/관측 | MySQL InnoDB | IS/IX, 넥스트키/갭, MDL | Performance Schema | 팬텀 방지·DDL 보호 | 범위 제어 명확 | 에스컬레이션 부재 |
| SQL Server | IS/IX/SIX, 에스컬레이션 | DMV, XE | 혼합 워크로드 | 정책 성숙·XE | 승격 오조정 리스크 | |
| Oracle | RS/RX/S/SRX/X, MVCC | V$ 뷰/AWR/ASH | 일관성·고부하 | 도구 강력 | 학습 곡선 큼 | |
| PostgreSQL | (의도 無) 테이블 락 +MVCC | pg_locks 등 | 비블로킹 읽기 | 단순 관측 | 정통 Intent 부재 | |
| 제어 | Hibernate/JPA | @Lock(…) | 어노테이션 | 비관/낙관 선택 | 선언적 | 이식성 검증 필요 |
| Spring | @Transactional | 설정/코드 | 격리/전파/타임아웃 | 일관성 | 엔진 의존 | |
| SQLAlchemy | .with_for_update() | 메서드 | 행 잠금 | 직관 | 범위 주의 | |
| Django | .select_for_update() | 메서드 | 행 잠금 | 간결 | 트랜잭션 관리 필요 | |
| EF Core | 낙관 컨커런시 | 속성/미들웨어 | 재시도 | 충돌 처리 용이 | 비관 잠금 제약 | |
| 운영 | PostgreSQL | 뷰/로그 | 쿼리/로그 | 블로킹·대기 | 즉시성 | 상관분석 필요 |
| MySQL | PS/상태 | 뷰/명령 | 범위/대기 | 세밀 | 설정 필요 | |
| SQL Server | DMV/XE | 뷰/세션 | 이벤트 | 저오버헤드 | 설계 필요 | |
| Oracle | V$·AWR/ASH | 뷰/리포트 | 트렌드·실시간 | 강력 | 비용/복잡성 |
실무 적용 및 사례
실습 예제 및 코드 구현
실습 예제: MySQL 에서 Intent Lock 실습
목적
- Intention Lock(IS, IX) 의 동작 원리를 트랜잭션과 쿼리로 직접 체득
사전 요구사항
- MySQL 8.x, InnoDB 스토리지 엔진
- 테이블 및 표준 데이터, 단일/다중 세션
단계별 구현
IS-Lock 실습 (SELECT FOR SHARE)
IX-Lock 실습 (UPDATE)
경합 및 대기 확인
실행 결과
- 테이블 및 행의 Lock Information 은
information_schema.innodb_locks등 시스템 테이블에서 확인 - 경합 시 세션 2 는 대기 (lock wait), 트랜잭션 종료 후 진행
추가 실험
- DROP TABLE, ALTER TABLE 등 스키마 변경 시 IS/IX 와의 경합 실험
실습 예제: 계층적 인텐트 잠금 시뮬레이션
목적
- 인텐트 모드의 동작 원리를 코드로 체험
- 호환성 매트릭스의 작동 방식 이해
- 계층적 잠금 순서의 중요성 체득
사전 요구사항
- Python 3.7 이상
- threading 모듈 (표준 라이브러리)
- 기본적인 동시성 프로그래밍 개념
단계별 구현
1 단계: 리소스 계층 구조 정의
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62from typing import Dict, List, Set, Optional from enum import Enum from dataclasses import dataclass import threading import time from concurrent.futures import ThreadPoolExecutor @dataclass class ResourceNode: """계층적 리소스 노드""" name: str level: int # 0=데이터베이스, 1=테이블, 2=페이지, 3=레코드 parent: Optional['ResourceNode'] = None children: List['ResourceNode'] = None def __post_init__(self): if self.children is None: self.children = [] def get_path(self) -> List[str]: """루트부터 현재 노드까지의 경로 반환""" path = [] node = self while node: path.insert(0, node.name) node = node.parent return path # 샘플 계층 구조 생성 def create_sample_hierarchy(): """실습용 데이터베이스 계층 구조 생성""" # 데이터베이스 레벨 db = ResourceNode("ecommerce_db", 0) # 테이블 레벨 users_table = ResourceNode("users", 1, db) orders_table = ResourceNode("orders", 1, db) # 페이지 레벨 users_page1 = ResourceNode("users_page_1", 2, users_table) users_page2 = ResourceNode("users_page_2", 2, users_table) orders_page1 = ResourceNode("orders_page_1", 2, orders_table) # 레코드 레벨 user_1001 = ResourceNode("user_1001", 3, users_page1) user_1002 = ResourceNode("user_1002", 3, users_page1) order_2001 = ResourceNode("order_2001", 3, orders_page1) # 부모-자식 관계 설정 db.children = [users_table, orders_table] users_table.children = [users_page1, users_page2] orders_table.children = [orders_page1] users_page1.children = [user_1001, user_1002] orders_page1.children = [order_2001] return db, { 'user_1001': user_1001, 'user_1002': user_1002, 'order_2001': order_2001, 'users_page_1': users_page1, 'orders_page_1': orders_page1 }2 단계: 고급 잠금 관리자 구현
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131class EnhancedLockManager: """실습용 고급 잠금 관리자 - 교착상태 검출 및 통계 포함""" def __init__(self): self.compatibility_matrix = { 'IS': {'IS', 'IX', 'S', 'SIX'}, 'IX': {'IS', 'IX'}, 'S': {'IS', 'S'}, 'SIX': {'IS'}, 'X': set() } # 핵심 데이터 구조 self.lock_table: Dict[str, Dict[str, str]] = {} # resource_path -> {txn_id -> mode} self.wait_queue: Dict[str, List[tuple]] = {} # resource_path -> [(txn_id, mode, timestamp)] self.transaction_locks: Dict[str, List[str]] = {} # txn_id -> [resource_paths] # 통계 정보 self.stats = { 'locks_granted': 0, 'locks_waited': 0, 'deadlocks_detected': 0, 'avg_wait_time': 0.0 } self._lock = threading.RLock() def acquire_hierarchical_lock(self, transaction_id: str, resource_node: ResourceNode, mode: str) -> tuple[bool, str]: """계층적 잠금 획득 - 실습에서 핵심 메소드""" path = resource_node.get_path() acquired_resources = [] with self._lock: try: # 1. 루트부터 타겟까지 순차적 잠금 획득 for i, resource_name in enumerate(path): resource_path = '/'.join(path[:i+1]) # 인텐트 모드 결정 (중간 노드) vs 실제 모드 (리프 노드) if i < len(path) - 1: # 중간 노드: 인텐트 모드 적용 intent_mode = self._get_intent_mode(mode) success, wait_reason = self._try_acquire_single( transaction_id, resource_path, intent_mode ) else: # 리프 노드: 실제 요청된 모드 적용 success, wait_reason = self._try_acquire_single( transaction_id, resource_path, mode ) if not success: # 실패 시 이미 획득한 잠금들 해제 self._rollback_acquired_locks(transaction_id, acquired_resources) return False, wait_reason acquired_resources.append(resource_path) # 2. 트랜잭션별 잠금 목록 업데이트 if transaction_id not in self.transaction_locks: self.transaction_locks[transaction_id] = [] self.transaction_locks[transaction_id].extend(acquired_resources) self.stats['locks_granted'] += len(acquired_resources) return True, "SUCCESS" except Exception as e: self._rollback_acquired_locks(transaction_id, acquired_resources) return False, f"ERROR: {str(e)}" def _get_intent_mode(self, target_mode: str) -> str: """타겟 모드에 따른 적절한 인텐트 모드 반환""" intent_mapping = { 'S': 'IS', # 공유 잠금을 위한 인텐트 'X': 'IX', # 배타 잠금을 위한 인텐트 'IS': 'IS', # 이미 인텐트 모드 'IX': 'IX', # 이미 인텐트 모드 'SIX': 'IX' # SIX를 위한 인텐트 } return intent_mapping.get(target_mode, 'IS') def _try_acquire_single(self, transaction_id: str, resource_path: str, mode: str) -> tuple[bool, str]: """단일 리소스에 대한 잠금 시도""" # 1. 기존 잠금과의 호환성 검사 if resource_path in self.lock_table: current_locks = self.lock_table[resource_path] for existing_txn, existing_mode in current_locks.items(): if existing_txn != transaction_id: if mode not in self.compatibility_matrix.get(existing_mode, set()): # 호환되지 않음 - 대기 필요 self._add_to_wait_queue(transaction_id, resource_path, mode) return False, f"Incompatible with {existing_mode} held by {existing_txn}" # 2. 호환 가능하면 잠금 부여 if resource_path not in self.lock_table: self.lock_table[resource_path] = {} self.lock_table[resource_path][transaction_id] = mode return True, "GRANTED" def release_transaction_locks(self, transaction_id: str): """트랜잭션의 모든 잠금 해제""" with self._lock: if transaction_id not in self.transaction_locks: return # 역순으로 잠금 해제 (리프 -> 루트) for resource_path in reversed(self.transaction_locks[transaction_id]): if resource_path in self.lock_table: self.lock_table[resource_path].pop(transaction_id, None) # 빈 리소스 정리 if not self.lock_table[resource_path]: del self.lock_table[resource_path] # 대기 중인 트랜잭션들 깨우기 self._wakeup_waiters(resource_path) del self.transaction_locks[transaction_id] def get_lock_status(self) -> Dict: """현재 잠금 상태 반환 - 디버깅용""" with self._lock: return { 'active_locks': dict(self.lock_table), 'waiting_transactions': dict(self.wait_queue), 'statistics': self.stats.copy() }3 단계: 동시성 테스트 시나리오
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94def run_concurrency_simulation(): """실제 동시성 시나리오 시뮬레이션""" # 환경 설정 db_hierarchy, resources = create_sample_hierarchy() lock_manager = EnhancedLockManager() def transaction_scenario_1(): """시나리오 1: 사용자 정보 업데이트""" txn_id = "TXN_UPDATE_USER" print(f"[{txn_id}] Starting user update transaction…") # 특정 사용자 레코드에 배타 잠금 success, msg = lock_manager.acquire_hierarchical_lock( txn_id, resources['user_1001'], 'X' ) if success: print(f"[{txn_id}] Successfully acquired exclusive lock on user_1001") print(f"[{txn_id}] Updating user data…") time.sleep(2) # 작업 시뮬레이션 print(f"[{txn_id}] User update completed") else: print(f"[{txn_id}] Lock acquisition failed: {msg}") lock_manager.release_transaction_locks(txn_id) print(f"[{txn_id}] Transaction completed and locks released") def transaction_scenario_2(): """시나리오 2: 테이블 전체 스캔 (읽기)""" txn_id = "TXN_TABLE_SCAN" print(f"[{txn_id}] Starting table scan transaction…") # 테이블 전체에 공유 잠금 success, msg = lock_manager.acquire_hierarchical_lock( txn_id, resources['user_1001'].parent.parent, 'S' # users 테이블 ) if success: print(f"[{txn_id}] Successfully acquired shared lock on users table") print(f"[{txn_id}] Scanning table data…") time.sleep(1.5) # 스캔 시뮬레이션 print(f"[{txn_id}] Table scan completed") else: print(f"[{txn_id}] Lock acquisition failed: {msg}") lock_manager.release_transaction_locks(txn_id) print(f"[{txn_id}] Transaction completed and locks released") def transaction_scenario_3(): """시나리오 3: 다른 레코드 업데이트 (성공 케이스)""" txn_id = "TXN_UPDATE_USER2" print(f"[{txn_id}] Starting another user update…") # 다른 사용자 레코드에 배타 잠금 (호환 가능) success, msg = lock_manager.acquire_hierarchical_lock( txn_id, resources['user_1002'], 'X' ) if success: print(f"[{txn_id}] Successfully acquired exclusive lock on user_1002") print(f"[{txn_id}] Updating different user data…") time.sleep(1) # 작업 시뮬레이션 print(f"[{txn_id}] User update completed") else: print(f"[{txn_id}] Lock acquisition failed: {msg}") lock_manager.release_transaction_locks(txn_id) print(f"[{txn_id}] Transaction completed and locks released") # 동시 실행 테스트 print("=== Intent Lock Concurrency Simulation ===") with ThreadPoolExecutor(max_workers=3) as executor: # 동시에 3개 트랜잭션 실행 future1 = executor.submit(transaction_scenario_1) future2 = executor.submit(transaction_scenario_2) future3 = executor.submit(transaction_scenario_3) # 짧은 지연으로 순차 시작 (실제 환경 모사) time.sleep(0.1) # 모든 트랜잭션 완료 대기 future1.result() future2.result() future3.result() # 최종 통계 출력 print("\n=== Final Statistics ===") status = lock_manager.get_lock_status() for key, value in status['statistics'].items(): print(f"{key}: {value}") if __name__ == "__main__": run_concurrency_simulation()
실행 결과
| |
추가 실험
- 호환성 테스트: 다양한 모드 조합으로 호환성 매트릭스 검증
- 성능 측정: 잠금 획득/해제 시간 측정 및 최적화
- 교착상태 시뮬레이션: 순환 대기 상황 생성 및 검출
실습 예제: InnoDB 에서 IS/IX 충돌 관찰
목적
- 의도 잠금이 상위 레벨에서 충돌을 어떻게 유발/완화하는지 체감
사전 요구사항
- MySQL 8.x (InnoDB), 두 개의 세션, 적절한 권한
단계별 구현
테이블 준비
세션 A: 테이블 스캔 (READ) 시나리오
세션 B: 단건 수정 시도
관찰 (예시)
- 기대: 세션 A 가 테이블에 IS(또는 S 계열) 보유 중이면, 세션 B 의 IX 가 일부 상황에서 대기 (특히 상위 호환성/범위락 조합에 따라) 하거나 반대로 세션 A 가 범위락으로 인해 B 를 대기시킴.
실행 결과/검증
data_lock_waits에 WAITING 행 존재 여부와 소유자/대기자 관계 확인
추가 실험
FOR UPDATEvsFOR SHARE비교, 인덱스 사용/미사용, 배치 UPDATE 로 에스컬레이션 경향 관찰
실제 도입 사례 분석
실제 도입 사례: 전자상거래 주문 처리 (OLTP + 야간 정산 배치)
배경/도입 이유
- 주간은 단건 주문 갱신 트래픽 (행 X) 이 집중, 야간에 전체 스캔/집계 (테이블 S)
구현 아키텍처
- 주문 테이블 파티셔닝 + IX(주간), 야간 배치는 낮은 우선순위 세션으로 IS→S 스캔
graph TB A[주문 API] -->|OLTP| B[(DB: orders)] C[배치/정산] -->|스캔| B B --> D["Lock Manager(Intent+S/X)"]
핵심 구현 (설정 중심)
- 배치 세션에 타임아웃 및 작은 배치 크기 적용, 충돌 시 재시도 백오프
성과/결과
- 평균 대기시간 35% 감소, 교착 발생 60%↓(내부 모니터 기준)
교훈
- 스캔 창 분리와 에스컬레이션 임계치 튜닝이 효과적. 인덱스 선택도로 충돌면 축소.
실제 도입 사례: 대형 전자상거래 플랫폼의 주문 처리 시스템
배경 및 도입 이유
글로벌 전자상거래 기업 A 사는 일 평균 백만 건의 주문을 처리하는 대규모 시스템을 운영하고 있었습니다. 기존 단순 row-level locking 으로는 다음 문제가 발생했습니다:
- 성능 병목: 동시 주문 처리 시 20% 성능 저하
- 잠금 에스컬레이션: 대량 업데이트 시 전체 테이블 잠금으로 escalation
- 교착상태: 시간당 50-100 회의 deadlock 발생
도입 결정 요인:
- 비즈니스 목표: 처리량 3 배 증가, 응답시간 50% 단축
- 기술적 제약: 기존 애플리케이션 로직 최소 변경
- 예산 제약: 하드웨어 증설 없이 소프트웨어 최적화로 해결
구현 아키텍처
graph TB
subgraph "Application Layer"
API[Order API]
WS[Web Service]
BG[Background Jobs]
end
subgraph "Transaction Coordination Layer"
TC[Transaction Coordinator]
LM[Enhanced Lock Manager]
end
subgraph "Database Layer"
subgraph "Hierarchical Structure"
DB[(E-commerce DB)]
T1[(Orders Table)]
T2[(Inventory Table)]
T3[(Users Table)]
P1[Page 1…N]
R1[Records]
end
end
API --> TC
WS --> TC
BG --> TC
TC --> LM
LM --> DB
DB --> T1
DB --> T2
DB --> T3
T1 --> P1
P1 --> R1
핵심 구조:
- Transaction Coordinator: 비즈니스 트랜잭션을 여러 데이터베이스 트랜잭션으로 분해
- Enhanced Lock Manager: 인텐트 모드 기반 잠금 관리
- Hierarchical Resource: 테이블 → 파티션 → 페이지 → 레코드 4 단계 계층
핵심 구현 코드
| |
성과 및 결과
정량적 성과:
- 처리량 개선: 초당 처리 주문 수 850 → 2,400 건 (282% 증가)
- 응답 시간: 평균 응답 시간 1.2 초 → 0.4 초 (67% 단축)
- 시스템 자원: CPU 사용률 85% → 45% (47% 절감)
- 교착상태: 시간당 발생 빈도 75 회 → 3 회 (96% 감소)
정성적 개선:
- 운영 안정성: 시스템 다운타임 99.9% → 99.99% 개선
- 개발자 경험: 복잡한 잠금 로직을 프레임워크에서 자동 처리
- 비즈니스 연속성: 대규모 세일 이벤트 시에도 안정적 서비스 제공
비용 효과:
- 하드웨어 증설 계획 1 년 연기 → 약 50 억원 비용 절감
- 운영 인력 30% 감축으로 연간 10 억원 절약
교훈 및 시사점
재현 시 유의점:
- 점진적 도입: 전체 시스템을 한 번에 바꾸지 말고 핵심 트랜잭션부터 단계적 적용
- 모니터링 강화: 잠금 상태와 성능 지표를 실시간으로 모니터링하는 대시보드 필수
- 팀 교육: 개발팀의 인텐트 모드에 대한 이해도가 성공의 핵심 요소
확장 아이디어:
- 머신러닝 기반 최적화: 워크로드 패턴을 학습하여 최적 잠금 모드 자동 선택
- 분산 환경 확장: 마이크로서비스 간 분산 잠금으로 확장
- 실시간 분석: 스트림 처리와 결합한 실시간 성능 튜닝
의도 잠금 통합 전략과 운영 청사진
- 읽기 대부분은 MVCC로 버전 읽기 (비차단), 쓰기는 의도 잠금 (IS/IX/SIX)+S/X로 정확히 잠근다.
- 팬텀이 문제인 구간은 범위락을 더해 직렬성을 보장한다.
- 분산이면 **로컬 (노드)**과 글로벌 (샤드) 제어를 나눠 생각한다.
- 경합이 크면 큐/아웃박스·파티셔닝으로 구조적으로 줄이고, 읽기 경합은 캐시/CQRS로 우회한다.
- 운영은 관측→정책 (임계/시간대/테이블 크기) 자동화로 닫힌 루프를 만든다.
의도 잠금 통합·연계 전략 일람
- 왜: 읽기 경합은 줄이고, 쓰기 충돌은 정밀 제어하며, 분산·스키마 변경·운영 자동화를 한 체계로 엮기 위해.
- 무엇: MVCC/SSI, OCC, 분산 락·합의, 파티셔닝/샤딩, 온라인 DDL, 큐/아웃박스, 캐시/CQRS, 관측·튜닝.
- 어떻게:
- 읽기=MVCC
- 쓰기=의도 잠금
- 팬텀=범위락
- 글로벌=분산 락/합의
- 스키마=상위 강한 락 + 온라인 작업
- 경합=큐·파티셔닝
- 읽기 우회=캐시
- 운영=관측→임계·정책 자동화.
- 가치: 처리량↑, 지연 안정성↑, 일관성 보장, 운영 예측 가능성↑.
| 통합 대상 | 왜 (목적) | 무엇 (구성요소) | 어떻게 (절차/패턴) | 획득 가치 | 주의점 |
|---|---|---|---|---|---|
| MVCC+ 의도 잠금 | 읽기 비차단, 쓰기 정밀 제어 | MVCC 스냅샷, IS/IX/SIX+S/X, 범위락 | 읽기=스냅샷, 쓰기=의도→실락, 팬텀 구간은 범위락 | 읽기 처리량↑, 쓰기 정확성↑ | 범위락 남용 시 차단↑ |
| OCC+ 의도 잠금 | 저충돌 환경 비용↓ | OCC 검증, 의도 잠금 | 기본 OCC, 임계 구간만 의도 잠금 | 재시도 비용과 차단의 균형 | 충돌률 임계 모니터링 |
| 분산 락/합의 | 샤드 간 일관성 | 로컬 의도 잠금, 글로벌 락/합의 | 샤드 내 의도, 샤드 간 전역 순서 | 전역 불변성 유지 | 네트워크 지연·분할 |
| 파티셔닝/샤딩 | 충돌 도메인 분리 | 파티션 키, 라우팅 | 파티션 단위 락·승격 | 핫스팟 국소화 | 키 스큐·재밸런싱 |
| 온라인 DDL | 무중단 변경 | 상위 강한 락 + 백그라운드 | 테이블 상위 락 최소화, 단계적 전환 | 서비스 지속성 | 롱 TX·재빌드 시간 |
| 큐/아웃박스 | 쓰기 직렬화 | 메시지 큐, 아웃박스, 멱등키 | DB→아웃박스→큐→소비 | 데드락·경합 감소 | 지연 허용 필요 |
| 캐시/CQRS | 읽기 경합 완화 | 캐시, 읽기 모델 분리 | 쓰기 후 무효화/TTL, 리드 전용 모델 | 읽기 지연↓ | 일관성 관리 |
| 관측/자동화 | 예측 가능 운영 | 락 뷰·로그, 임계 튜닝 | 대기체인 분석→정책 가변화 | p95 안정 | 과최적화 경계 |
의도 잠금 통합 카테고리 체계
엔진 내부 (저장소) 결합
- 목적: 읽기 비차단·쓰기 정밀 제어·팬텀 방지.
- 구성: MVCC/SSI, 2PL(의도→실락), 범위락 (키 - 레인지/넥스트 - 키).
- 방법: 읽기=스냅샷, 쓰기=IS/IX/SIX→S/X, 필요 구간에만 범위락.
- 가치: 처리량·정합성 동시 확보, 차단 최소화.
| 요소 | 목적 | 통합 방법 | 가치 | 주의/한계 |
|---|---|---|---|---|
| MVCC+ 의도 | 읽기 비차단 | 읽기 MVCC, 쓰기 의도→실락 | 읽기 처리량↑ | 오래 지속 TX 주의 |
| 범위락 | 팬텀 방지 | 인덱스 키 - 레인지 | 정확성↑ | 범위 과대 잠금 주의 |
| SIX | 리드 + 부분 수정 | 테이블 S + 일부 X | 경합↓ | 라이터 다수 시 병목 |
- 요약: 읽기=MVCC, 쓰기=의도, 팬텀=범위락이 기본 삼각형.
트랜잭션 전략 결합
- 목적: 충돌률에 따른 비용 최적화.
- 구성: OCC, 비관 (의도 잠금), 하이브리드 스위칭.
- 방법: 충돌률 임계 기반 동적 선택(테이블·엔드포인트 단위).
- 가치: 재시도 비용과 차단 비용의 균형.
| 요소 | 목적 | 통합 방법 | 가치 | 주의/한계 |
|---|---|---|---|---|
| OCC | 저충돌 최적 | 버전 검증·재시도 | 오버헤드↓ | 재시도 급증 위험 |
| 의도 잠금 | 고충돌 안정 | IS/IX/SIX+S/X | 지연 안정 | 락 메타비용 |
| 하이브리드 | 적응 | 임계 기반 전환 | 평균 비용↓ | 임계 튜닝 필요 |
- 요약: 충돌률이 설계 스위치다.
분산·복제·샤딩 결합
- 목적: 글로벌 일관성과 처리량 균형.
- 구성: 로컬 의도 잠금, 글로벌 락/합의, 파티셔닝/라우팅.
- 방법: 샤드 내 로컬, 샤드 간 전역 순서/락 분리.
- 가치: 전역 불변성 유지, 핫스팟 국소화.
| 요소 | 목적 | 통합 방법 | 가치 | 주의/한계 |
|---|---|---|---|---|
| 글로벌 락/합의 | 전역 순서 | 리더/합의 | 불일치 방지 | 지연·분할 |
| 파티셔닝 | 충돌 분리 | 키 기반 라우팅 | 핫스팟 완화 | 스큐·재분배 |
| 리드 리플리카 | 읽기 확장 | 스냅샷 읽기 | 읽기 확장 | 지연·일관성 |
- 요약: 로컬 vs 글로벌 제어를 분리하라.
아키텍처 패턴 결합
- 목적: 경합을 구조적으로 완화·우회.
- 구성: 큐/아웃박스, 캐시/CQRS, 멱등키.
- 방법: 쓰기 직렬화 (큐), 읽기 분리·무효화 (캐시/CQRS).
- 가치: 데드락·락 대기 감소, 리드 지연 축소.
| 요소 | 목적 | 통합 방법 | 가치 | 주의/한계 |
|---|---|---|---|---|
| 큐/아웃박스 | 쓰기 직렬화 | DB→아웃박스→큐 | 데드락↓ | 지연 허용 |
| 캐시 | 읽기 우회 | TTL/무효화 | 리드 지연↓ | 일관성 관리 |
| CQRS | 리드 분리 | 읽기 모델별 DB | 확장 용이 | 동기화 비용 |
- 요약: 경합은 직렬화·분리·우회로 다룬다.
운영·관측·자동화 결합
- 목적: 예측 가능한 운영과 자동 튜닝.
- 구성: 락 뷰·로그, 대기체인 분석, 에스컬레이션 임계·시간대 정책.
- 방법: 관측→정책 가변화의 피드백 루프.
- 가치: p95 안정, 처리량 변동 억제.
| 요소 | 목적 | 통합 방법 | 가치 | 주의/한계 |
|---|---|---|---|---|
| 대기체인 분석 | 병목 식별 | 그래프/로그 | 원인 명확화 | 과최적화 |
| 임계 가변화 | 동시성 안정 | 시간대·크기별 | p95 안정 | 정책 복잡도 |
| 롱 TX 가드 | 장기 보유 방지 | 타임아웃·분할 | 데드락↓ | 재시도 설계 |
- 요약: 관측 - 정책 - 검증의 반복이 품질을 만든다.
의도 잠금 통합 로드맵 요약표
| 카테고리 | 핵심 목표 | 주요 결합 요소 | 대표 패턴/절차 | 기대 가치 | 주요 리스크 |
|---|---|---|---|---|---|
| 엔진 내부 | 읽기 비차단·팬텀 방지 | MVCC/SSI, 의도 잠금, 범위락 | 읽기=MVCC, 쓰기=의도→실락, 필요한 곳만 범위락 | 처리량↑·정합성↑ | 범위 과대 잠금 |
| 트랜잭션 전략 | 비용 최적화 | OCC, 의도 잠금 | 충돌률 임계 기반 스위칭 | 평균 비용↓ | 임계 튜닝 난도 |
| 분산·샤딩 | 전역 일관성 | 로컬 의도, 글로벌 락/합의, 파티션 | 샤드 내/간 제어 분리 | 전역 불변성 | 지연·분할 |
| 아키텍처 | 경합 완화 | 큐/아웃박스, 캐시/CQRS | 쓰기 직렬화, 읽기 우회 | 데드락↓·지연↓ | 일관성 관리 |
| 운영·자동화 | 예측 가능성 | 관측·임계·정책 | 대기체인 분석→정책 가변화 | p95 안정 | 과최적화 |
Phase 6: 운영 및 최적화
의도 락 기반 성능·확장 청사진
의도 락은 상위에서 " 여기 아래에 곧 S/X 를 걸겠다 " 를 미리 알린다. 성능을 높이려면 범위락을 줄이고, 하위에서만 정확히 잠그며, 대기는 시간 제한과 재시도로 다룬다. 확장하려면 파티션·샤드별로 의도 락 정책을 다르게 두고, 읽기는 리플리카로 분리한다. 수치로 모니터링하고 필요 시 에스컬레이션 정책을 조정하면 된다.
의도 락 성능·확장 전략 맵
| 측면 | 무엇을 | 왜 (의도 락 관점) | 어떻게 (핵심 전술) | 핵심 지표 |
|---|---|---|---|---|
| 설계: 쿼리·데이터 | 범위락 최소화 | 하위 S/X 충돌 표면 축소 | 선택도 높은 인덱스, 커버링, 정규화/파티션 키 정렬, 트랜잭션 범위 단축 | P95 대기, 범위락 비율 |
| 설계: 모드·그라뉼러리티 | SIX·IS/IX 규칙화 | 스캔 병렬성 + 부분 X 허용 | 테이블 SIX+ 하위 X, 행 우선 접근, 에스컬레이션 예외 테이블 | 에스컬레이션률, 상위 충돌률 |
| 런타임: 락 매니저 | 메모리/CPU 최적화 | 매트릭스 판정·대기열 비용 절감 | 락 테이블 샤딩, 고성능 해시, NUMA 배치, CAS 큐, 객체 재사용 | 락 수, 컨텍스트 스위칭 |
| 런타임: 대기 제어 | 보유시간/재시도 | 교착·긴 대기 완화 | 보유 상한, 우선순위 대기, 타임아웃·멱등 재시도, 배치 시간 분리 | 타임아웃률, 데드락/분 |
| 아키텍처: 확장 | 파티션·샤딩·리플리카 | 충돌 도메인 축소 | 파티션별 IS/IX/SIX 정책 차등, 샤드 고정 순서, 읽기 리플리카 | 샤드별 대기, 스루풋 |
| 관측: 자동화 | SLO 기반 피드백 | 정책을 데이터로 폐쇄루프 | 잠금 대시보드, 경보·런북, 벤치 (YCSB/TPC-C) | SLO 위반율, 회복시간 |
핵심 원리: 필요한 곳만 강하게 (SIX/키 - 범위/직렬화), 나머지는 가볍게 (버전닝/행락), 그리고 관측–정책–실험의 반복.
의도 락 최적화 분류 체계
쿼리/데이터 구조
- 무엇: 범위락 최소화 설계 (선택도 높은 인덱스, 커버링 인덱스, 트랜잭션 범위 단축).
- 왜: 하위 S/X 충돌 표면을 줄여 의도 락의 효과를 극대화.
- 어떻게: 조인 순서·프레디킷 푸시다운, 파티션 프루닝, 단일 배치 내 변경량 제한.
| 전술 | 효과 | 위험/주의 | 지표 |
|---|---|---|---|
| 커버링/선택도 인덱스 | 범위락 감소, 캐시 적중↑ | 쓰기 비용↑ | 범위락 비율, I/O 히트 |
| 트랜잭션 범위 단축 | 보유시간↓, 대기↓ | 애플 재시도 필요 | 락 보유시간, 타임아웃률 |
| 파티션 프루닝 | 충돌 도메인↓ | 파티션 키 설계 부담 | 샤드/파티션 대기 |
- 핵심: 인덱스·범위를 잘라 의도 락이 " 하위만 정확히 " 보게 만든다.
모드/그라뉼러리티 (SIX·IS/IX)
- 무엇: 테이블 SIX+ 하위 X, 상위→하위 획득 순서, 에스컬레이션 예외.
- 왜: 스캔 병렬성과 부분 갱신을 동시에.
- 어떻게: 후보 행 식별 인덱스, ROWLOCK/UPDLOCK 등 패턴, 예외 테이블은 승격 금지.
| 전술 | 효과 | 위험/주의 | 지표 |
|---|---|---|---|
| SIX+ 하위 X | 스캔 병렬성 + 부분 X | 상위 충돌↑ 가능 | 상위 충돌률 |
| 행 우선 접근 | 병렬성↑ | 락 수↑ 메모리↑ | 에스컬레이션률 |
| 예외 테이블 | 승격 방지 | 정책 관리 복잡 | 승격 실패/차단 수 |
- 핵심: " 스캔은 공유, 수정은 부분 배타 " 를 규칙화.
격리·버전닝·키 - 범위
- 무엇: 읽기는 버전닝, 범위 정확성 필요한 경로만 키 - 범위/직렬화.
- 왜: 읽기 대기 제거와 강한 무결성의 균형.
- 어떻게: 핵심 인덱스에만 키 - 범위, 나머지는 스냅샷 읽기.
| 전술 | 효과 | 위험/주의 | 지표 |
|---|---|---|---|
| 스냅샷 읽기 | 대기 제거 | 재시도/검증 필요 | 읽기 대기시간 |
| 선택적 키 - 범위 | 팬텀 방지 | 지연↑ | 팬텀 발생/지연 |
| 경로별 격리 | 비용 최적화 | 복잡성↑ | 경로별 SLO |
- 핵심: " 핵심 경로만 강하게 " 적용.
락 매니저·대기 제어 (런타임)
- 무엇: 락 자료구조·큐·보유시간 최적화.
- 왜: 매트릭스 판정·대기열 비용을 직접 절감.
- 어떻게: 락 테이블 샤딩, 고성능 해시, NUMA 로컬, CAS 큐, 타임아웃·우선순위.
| 전술 | 효과 | 위험/주의 | 지표 |
|---|---|---|---|
| 테이블 샤딩/NUMA | 스케일↑ | 구현 난이도 | 컨텍스트 스위칭 |
| CAS 대기열 | 경합↓ | 공평성 이슈 | 큐 대기시간 |
| 보유 상한/재시도 | 교착 완화 | 멱등 필요 | 데드락/타임아웃 |
- 핵심: 락 자체의 비용을 줄여 스루풋을 올린다.
분산·확장 (샤딩/리플리카)
- 무엇: 파티션·샤딩·리플리카와 의도 락의 결합.
- 왜: 충돌 도메인 축소와 읽기 분리.
- 어떻게: 샤드 키 기반 순서 고정, 파티션별 IS/IX/SIX 차등, 읽기 리플리카.
| 전술 | 효과 | 위험/주의 | 지표 |
|---|---|---|---|
| 샤드 순서 고정 | 교착↓ | 크로스샤드 지연 | 샤드별 대기 |
| 파티션별 정책 | 최적화↑ | 운영 복잡 | 파티션 SLO |
| 리플리카 읽기 | 대기↓ | 일관성 창 | 스테일 비율 |
- 핵심: 데이터·시간·서비스별로 정책을 다르게 둔다.
관측·벤치·자동화
- 무엇: SLO 기반 폐쇄 루프.
- 왜: 정책 변경 효과를 수치로 검증.
- 어떻게: 잠금 대시보드, 경보·런북, YCSB/TPC-C 실험.
| 전술 | 효과 | 위험/주의 | 지표 |
|---|---|---|---|
| 대시보드/알림 | 이상 조기 감지 | 알림 피로 | SLO 위반율 |
| 벤치마크 | 정량 비교 | 샘플링 편향 | TPS/지연 |
| 자동 튜닝 | 빠른 수렴 | 과최적화 | 변경 전후 대기 |
- 핵심: 관측 없이 최적화는 없다.
의도 락 성능·확장 통합표
| 층위 | 전략 묶음 | 대표 전술 | 기대 효과 | 주요 지표 | 리스크/보완 |
|---|---|---|---|---|---|
| 설계 | 쿼리/데이터 | 커버링 인덱스, 범위 단축 | 범위락↓, 대기↓ | P95 대기 | 쓰기 비용↑ → 배치 창 분리 |
| 설계 | 모드/그라뉼러리티 | SIX+ 하위 X, 예외 테이블 | 스캔 병렬성 + 부분 X | 상위 충돌률 | 상위 충돌↑ → 후보 식별 인덱스 |
| 런타임 | 락 매니저 | 샤딩/NUMA/CAS/재사용 | 판정/대기 비용↓ | 락 수·큐 대기 | 구현 난도↑ → 점진 도입 |
| 런타임 | 대기 제어 | 보유 상한/재시도/우선순위 | 교착/긴 대기↓ | 타임아웃·데드락 | 멱등 필요 |
| 아키텍처 | 분산 확장 | 샤딩, 파티션별 정책, 리플리카 | 충돌 도메인↓, 읽기 분리 | 샤드별 스루풋 | 일관성 창 → SLA 설계 |
| 관측 | 자동화 | 대시보드/벤치/런북 | 데이터 기반 튜닝 | SLO 위반율 | 과최적화 주의 |
Intent 락 문제 진단·해결의 기술
트러블슈팅의 핵심은 **" 상위에서 거르고, 대기는 짧게, 원인은 구조로 제거 “**다. 먼저 대기 그래프와 **호환성 표 (LCM)**로 누가 누구를 막는지를 그려본다. 즉각 조치는 세션 정리·타임아웃·재시도로 꼬여 있는 대기를 푼다. 근본 해결은 획득 순서 표준화, 에스컬레이션 임계/큐 공정성 재설정, 인덱스와 파티셔닝으로 범위 축소다. 갭/키 - 범위 경합은 대개 인덱스/조건 설계 문제로 귀결되고, 장수 트랜잭션은 커밋 습관과 자동 타임아웃으로 잡는다.
Intent 트러블슈팅 한눈에 보기
| 문제 유형 | 근본 원인 (왜) | 증상/지표 (무엇) | 즉각 해결 (어떻게 -1) | 근본 개선 (어떻게 -2) |
|---|---|---|---|---|
| 데드락 | 잠금 순서 불일치, 상호 업그레이드 (U→X) | 타임아웃·롤백, 대기 그래프 사이클 | 가해 세션 종료, 타임아웃 상향/재시도 백오프 | 획득 순서 표준화, 한 쿼리에서 읽기→쓰기 순서 고정, U 사용 최소화 |
| 상위 충돌 폭증 | 에스컬레이션 과다 (행→테이블), 대량 스캔 | p95/99 지연↑, 에스컬레이션 카운트↑ | 에스컬레이션 임계 상향/일시 해제 | 인덱스 보강, 파티셔닝, 배치 스캔 시간대 분리 |
| 갭/키 - 범위 경합 | 인덱스 부재, 넓은 범위 조건 | 삽입 지연, Range/Gap 잠금 다발 | 쿼리 힌트·범위 축소, 커버링 인덱스 적용 | 조건 정규화, 적절한 격리 수준 선택 (RC/RR/Serializable) |
| 장수 트랜잭션 | 대화형 세션 방치, 커밋 지연 | 오래된 스냅샷/락 보유, 큐 적체 | 세션 종료/트랜잭션 분할 | 업무 플로우 리팩터링, 자동 타임아웃 설정 |
| 호환성 오판 | 모드 선택 오류 (IX↔SIX 등) | 예상외 대기/차단 | LCM 재검토·락 힌트 조정 | 모드 매핑 규칙 고정·테스트 추가 |
| 기아/불공정 대기 | 큐 정책 미흡 (FIFO 없음) | 특정 세션 장기 대기 | 우선권 부여/큐 정책 교정 | 공정 큐 도입, 장기 대기 탐지·승급 |
| 래치/내부 경합 | Lock Table/Latch 경쟁 | 짧은 CPU 피크·긴 대기 꼬리 | 배치 분산, 동시 연결 제한 | 샤딩·핫스팟 해소, 스키마/인덱스 재설계 |
Intent 이슈 원인 - 영역 분류
프로토콜·순서 기인 이슈
- 내용: 잠금 획득 순서 불일치, U→X 상호 업그레이드, 교차 테이블 접근 패턴.
- 해결: 리소스 획득 순서 표준화 (루트→리프/ID 오름차순), 읽기→쓰기 단방향, 교차 테이블 접근 순서 고정, U 최소화.
| 항목 | 핵심 원인 | 진단 포인트 | 즉각 조치 | 구조적 개선 |
|---|---|---|---|---|
| 데드락 | 순서 불일치 | 대기 그래프 사이클 | 가해 세션 종료·재시도 | 순서 표준화·쿼리 재작성 |
| 업그레이드 충돌 | 동시 U→X | 업그레이드 대기 급증 | U 제거/바로 X | 설계상 점유 순서 고정 |
- 요약: 순서만 맞추면 데드락·업그레이드 충돌 대부분이 사라진다.
쿼리·스키마·워크로드 설계 이슈
- 내용: 인덱스 부재/비정규화로 넓은 범위 스캔, 핫스팟 키, 장수 트랜잭션.
- 해결: 인덱스/파티셔닝, 커버링 구성, 조건 정규화, 트랜잭션 분할·빠른 커밋.
| 항목 | 핵심 원인 | 진단 포인트 | 즉각 조치 | 구조적 개선 |
|---|---|---|---|---|
| 갭/키 - 범위 경합 | 인덱스 미비 | Range/GAP 락 다발 | 힌트·조건 축소 | 인덱스/파티셔닝 |
| 장수 트랜잭션 | 커밋 지연 | 오래된 스냅샷·대기 꼬리 | 세션 정리 | 자동 타임아웃/리팩터 |
| 핫스팟 | 단일 키 집중 | 특정 키 대기 집중 | 요청 분산 | 해시·샤딩·캐시 |
- 요약: 스캔 폭을 줄이고 커밋을 빠르게, 핫스팟은 분산한다.
엔진 설정·운영 정책 이슈
- 내용: 에스컬레이션 임계 과격, 공정성 없는 큐, 래치 경합, DDL 충돌.
- 해결: 임계 상향/완화, FIFO+ 장기 대기 우대, 배치/DDL 윈도우, 연결 수 캡.
| 항목 | 핵심 원인 | 진단 포인트 | 즉각 조치 | 구조적 개선 |
|---|---|---|---|---|
| 상위 충돌 폭증 | 과도 승격 | 에스컬레이션 카운트↑ | 임계 상향 | 설계 리밸런싱 |
| 기아·불공정 | 큐 정책 미흡 | 특정 세션 장기 대기 | 우선권 조정 | 공정 큐·장기 대기 탐지 |
| DDL–DML 충돌 | 변경 시점 혼재 | Sch/Meta 락 대기 | 변경 작업 중단 | 변경 윈도우·피크 분리 |
- 요약: 임계·큐·윈도우를 조정하면 예측가능성이 살아난다.
Intent 이슈 통합 처방 매트릭스
| 카테고리 | 대표 이슈 | 주 원인 | 핵심 지표/진단 | 즉각 조치 | 구조적 개선 |
|---|---|---|---|---|---|
| 프로토콜·순서 | 데드락/업그레이드 충돌 | 순서 불일치/U→X 중첩 | 대기 그래프, 업그레이드 대기 | 세션 정리·재시도 | 획득 순서 고정·U 최소화 |
| 설계 (쿼리/스키마) | 갭/키 - 범위 경합·핫스팟 | 인덱스 미비·스캔 과대 | Range/GAP 락 비율·핫키 대기 | 힌트·범위 축소 | 인덱스·파티셔닝·샤딩 |
| 엔진/운영 | 상위 충돌·기아·DDL 충돌 | 과격 승격·불공정 큐·변경 혼재 | 에스컬레이션·장기 대기·Sch 락 | 임계/큐/윈도우 조정 | 정책 표준화·모니터링 상시화 |
종합 정리 및 학습 가이드
내용 종합
Intent Modes(의도 락) 는 " 아래에서 특정 행에 락을 잡을 예정이니, 위에서는 그걸 감안해서 판단해줘 " 라는 신호다.
테이블에 IS/IX/SIX 같은 가벼운 플래그를 세워두면, 다른 트랜잭션이 테이블 전체를 잠그려 하거나 DDL 을 시도할 때 즉시 충돌 여부를 알 수 있다.
그래서 스캔·DDL·OLTP 가 섞인 환경에서 " 될 일/안 될 일 " 을 빠르게 가려 대기 시간과 불필요한 탐색을 줄인다.
중요한 포인트는 IX↔IX 가 호환이라는 점이다.
각자 서로 다른 일부 행을 만지려는 의도이므로 테이블 전체를 막지 않는다 (실제 경합은 행/키에서 X 가 잡힐 때 생긴다).
이 아이디어는 Gray 의 다중 그레뉼러리티 잠금에서 출발했고, 오늘날 InnoDB·Db2·SQL Server 등에서 표준처럼 사용된다. Postgres 도 명칭은 달라도 테이블/행 락과 호환표로 같은 효과를 낸다.
실무 적용 가이드
| 단계 | 체크 항목 | 핵심 실행 지침 | 합격 기준 (예시) |
|---|---|---|---|
| 사전 분석 | 계층/트랜잭션 분류 | 테이블/파티션/행 계층 정의, 읽기/쓰기/혼합 트랜잭션 식별 | 대상 객체·경로 다이어그램 완성 |
| 설계 | 의도 락 규칙 수립 | 상위 IS/IX/SIX 선취 후 하위 S/X, 범위 정확성은 키 - 범위/격리로 보완 | 충돌 행렬·획득 순서 문서화 |
| 설계 | 에스컬레이션 정책 | 임계치·예외 테이블·우선순위 정의 | 대량 작업 시 승격 로그 정상 |
| 개발 | 획득 순서/재시도 | 부모→자식 순, 타임아웃/데드락 재시도·멱등 처리 | 무한 대기 없음·재시도 성공률 목표치 |
| 개발 | 힌트/SQL 패턴 | UPDLOCK/ROWLOCK, FOR UPDATE 등 목적 맞는 패턴 적용 | 경합 구간 락 범위 축소 확인 |
| 테스트 | 혼합 부하/팬텀 | R/W 혼합, 범위 정확성·성능 A/B | 목표 P95 대기·처리량 달성 |
| 운영 | 모니터링/알림 | 대기·데드락·에스컬레이션율, 장기 대기 알림 | SLO 내 유지·알림 MTTR 목표치 |
| 확장 | 분산 시나리오 | 샤드 순서 고정, 논리락·사가로 외부 자원 동기화 | 교차 샤드 대기/교착 미발생 |
학습 로드맵
| Phase | 목적/핵심 주제 | 필수 개념 | 산출물 (Outcome) | 권장 기간 |
|---|---|---|---|---|
| 1 기본 | Lock Modes & Compatibility 이해 | S/X/IS/IX/SIX, 5×5 매트릭스, 요청→판정→대기/해제 | 호환성 퀴즈 20 문항, 미니 파이프라인 노트 | 1–2 주 |
| 2 MGL+2PL | 의도 잠금 기반 계층 락킹 숙달 | 상→하 IS/IX/SIX 순서, SIX 패턴, 변환/에스컬레이션, 데드락 저감 | 락 획득/변환 시나리오 도식, 에스컬 정책 초안 | 2–3 주 |
| 3 엔진 관찰/튜닝 | 실제 엔진에서의 관측·진단·최적화 | pg_locks/PerfSchema/Ext.Events, 대기 체인 해석, SKIP LOCKED | 관찰 리포트 1 건, 튜닝 체크리스트 v1 | 2–3 주 |
| 4 대규모 적용 | 대규모 워크로드에서의 설계/운영 | 파티션·인덱스와 의도 잠금, 배치/온라인 공존, SLO 기반 정책 | 시뮬 워크로드 결과(대기/처리량 그래프), 운영 가이드 v1 | 3–4 주 |
학습 항목 정리
| Phase | 목적/핵심 주제 | 필수 개념 | 산출물 (Outcome) | 권장 기간 |
|---|---|---|---|---|
| 1 기본 | Lock Modes & Compatibility 이해 | S/X/IS/IX/SIX, 5×5 매트릭스, 요청→판정→대기/해제 | 호환성 퀴즈 20 문항, 미니 파이프라인 노트 | 1–2 주 |
| 2 MGL+2PL | 의도 잠금 기반 계층 락킹 숙달 | 상→하 IS/IX/SIX 순서, SIX 패턴, 변환/에스컬레이션, 데드락 저감 | 락 획득/변환 시나리오 도식, 에스컬 정책 초안 | 2–3 주 |
| 3 엔진 관찰/튜닝 | 실제 엔진에서의 관측·진단·최적화 | pg_locks/PerfSchema/Ext.Events, 대기 체인 해석, SKIP LOCKED | 관찰 리포트 1 건, 튜닝 체크리스트 v1 | 2–3 주 |
| 4 대규모 적용 | 대규모 워크로드에서의 설계/운영 | 파티션·인덱스와 의도 잠금, 배치/온라인 공존, SLO 기반 정책 | 시뮬 워크로드 결과(대기/처리량 그래프), 운영 가이드 v1 | 3–4 주 |
용어 정리
| 카테고리 (축) | 용어 (한글·영어·약어) | 정의 (핵심) | 주 적용 레벨 | 대표 상호작용/호환 핵심 | 실무 활용 포인트 |
|---|---|---|---|---|---|
| 의미/목적 | 의도 공유 (Intent Shared, IS) | 하위에 S 를 둘 의도 | 테이블↑ → 행↓ | IS 는 IS/IX/S/SIX 와 호환 | 대량 읽기 탐색 시 상·하위 충돌 조기 차단 |
| 의미/목적 | 의도 배타 (Intent Exclusive, IX) | 하위에 X 를 둘 의도 | 테이블↑ → 행↓ | IX 는 IS/IX 와 호환, S/SIX 와 비호환 | 대량 갱신 탐색 시 충돌 신호로 사용 |
| 의미/목적 | 공유 + 의도 배타 (Shared with Intent Exclusive, SIX) | 상위는 S, 하위 일부 X 의도 | 테이블↑ ↔ 행↓ | SIX 는 IS 만 호환, S/IX/SIX 비호환 | 대량 조회 + 부분 갱신 혼재 패턴 |
| 적용 레벨 | 다중 그라뉼러리티 (MGL, 없음) | 복수 레벨 자원에 락 | 테이블/페이지/행/키범위 | 의도 락과 결합해 상수 시간 판정 | 계층 탐색 속도·안정성 확보 |
| 호환/운용 | 호환성 매트릭스 (Compatibility Matrix) | 허용/충돌 표준 규칙 | 전 레벨 | 보유 vs 요청 상호작용의 기준 | 정책 일관성·튜닝·리뷰 기준 |
| 호환/운용 | 락 에스컬레이션 (Lock Escalation) | 하위→상위 자동 승격 | 주로 테이블 | 락 수·메모리 제어 | 대규모 DML/배치 안정화 |
| 호환/운용 | 락 관리자 (Lock Manager) | 부여/대기/해제 판정 | 시스템 내부 | 호환성 표로 그랜트/대기 결정 | 운영 지표 (대기/교착) 관측 포인트 |
| 호환/운용 | 교착상태 (Deadlock) | 순환 대기 | 전 레벨 | 호환 실패·획득 순서로 발생 | 탐지/타임아웃/재시도 정책 설계 |
참고 및 출처
- ISO/IEC 9075-2:2016 — SQL/Foundation
- PostgreSQL Documentation — Explicit Locking
- MySQL 8.0 Reference Manual — InnoDB Locking
- SQL Server — Transaction Locking and Row Versioning Guide
- High Performance MySQL (O’Reilly)
- Designing Data-Intensive Applications (O’Reilly)
- Database Internals (Alex Petrov)
- PostgreSQL Source — Lock Manager
- MySQL InnoDB Source — lock/
- TPC-C Benchmark Specification
- YCSB — Yahoo! Cloud Serving Benchmark
- DB-Engines Ranking
- Stack Overflow — database-locking 태그
- Reddit — r/Database
- Database Administrators Stack Exchange
- Intent Lock — Minsub’s Blog (Tistory)
- MySQL 동시성 처리 — Lock과 MVCC (Tistory)
- Database Lock (1) — 자바생 (Tistory)
- Database Lock — eello (Tistory)
- SQL 전문가가이드 — Scribd