Lock Modes
락 모드는 트랜잭션의 동시 접근을 제어해 일관성을 보장하는 핵심 수단이다.
기본적으로 S(공유) 와 X(배타) 를 시작으로 U(업데이트), Intent(IS/IX/SIX) 와 범위 락 (Range/Gap/Predicate), Schema 락 등으로 세분화된다. 범위 락은 인덱스의 빈 공간이나 조건 (프레디케이트) 에 대해 팬텀을 방지한다.
데이터베이스마다 구현이 다르다:
- PostgreSQL 은 논리적 predicate lock 으로 범위를 표현하고, MySQL InnoDB 는 레코드 락과 gap 락을 결합한 next-key 로 phantom 을 제어하며, SQL Server 는 Range 락을 통해 유사한 목적을 달성한다.
락의 호환성 매트릭스 (예: S 끼리는 허용, S 와 X 는 충돌) 는 데드락과 성능에 직접 영향주며, 이를 완화하려면 적절한 인덱스 설계·짧은 트랜잭션·작업 분리·격리 수준 조정이 필요하다.
현대 시스템은 MVCC 나 SSI 같은 버전 기반 기법과 결합해 읽기 성능과 일관성 사이에서 균형을 맞춘다.
모니터링은 대기 그래프·블로킹 세션·데드락 로그를 확인해 병목과 정책을 개선하는 방향으로 진행한다.
트랜잭션 락 모드와 실무 적용 구조
데이터베이스의 동시성은 여러 트랜잭션이 같은 데이터를 동시에 다룰 때도 일관성을 보장해야 하는 문제다.
락 모드는 그 도구로, 읽기 전용엔 S(공유), 쓰기 필요시엔 **X(배타)**를 사용하며, **U(업데이트)**는 읽은 후 갱신할 가능성이 있는 경우 데드락을 줄이기 위해 중간 역할을 한다.
상위 객체 (테이블) 에는 IS/IX 같은 의도 락을 두어 하위 (행) 락 존재를 빠르게 알 수 있다.
범위 검색이나 인덱스 스캔에는 단순 행 락만으로는 부족해 gap/next-key/predicate 같은 범위 락을 써서 새로운 행 (팬텀) 이 들어오는 걸 막고, 필요한 격리 수준 (Repeatable/Serializable) 을 만족시킨다.
실무에서는 락의 세분성 (행/페이지/테이블), 보유 기간 (문장/트랜잭션), 그리고 DBMS 별 정책을 함께 고려해 설계해야 안정성과 성능을 모두 얻을 수 있다.
락 모드 핵심 개념 표
| 번호 | 핵심 개념 (한글 · 약어) | 한 줄 정의 | 실무 핵심 포인트 |
|---|---|---|---|
| 1 | 공유 락 · S (Shared) | 읽기 허용, 다중 보유 가능 | 다중 동시 조회 허용 |
| 2 | 배타 락 · X (Exclusive) | 읽기/쓰기 모두 배타적 점유 | 수정 시 반드시 필요 |
| 3 | 업데이트 락 · U (Update) | S 와 호환되나 단일 보유, X 로 승격 가능 | Deadlock 예방용 중간 모드 |
| 4 | 의도 락 · IS/IX/SIX | 상위 객체에 하위 락 의도 표시 | 계층적 충돌 검사 효율화 |
| 5 | 행/페이지/테이블 락 · (Row/Page/Table) | 락의 세분성 단위 | 세분성 - 동시성 트레이드오프 |
| 6 | 키 - 레인지 (갭) 락 · Gap/Next-Key | 인덱스 레코드 + 갭 잠금 (Next-Key) | 팬텀 방지에 핵심 역할 |
| 7 | 프레디케이트 락 · Predicate | 조건식 단위의 범위 락 | Serializable 구현 수단 |
| 8 | 보유 기간 · Stmt/Txn/Session | 락 해제 시점 분류 | 장기 락은 블로킹 유발 |
| 9 | 락 호환성 · Compatibility | 모드 간 동시 보유 가능성 행렬 | 블로킹/교착 분석의 근거 |
| 10 | 락 확대 · Escalation | 세밀 → 큰 단위로 자동 전환 | 메모리/관리 오버헤드 절감 |
- S 는 읽기 동시성을, X 는 쓰기 무결성을 보장한다. U 는 두 모드 사이에서 데드락을 줄이는 역할을 한다.
- Intent 락은 계층적 리소스 검사 비용을 줄이는 장치이며, gap/next-key/predicate 는 팬텀을 막아 격리 수준을 보장한다.
- 보유 기간과 락 확대 정책은 운영 (성능/자원) 과 직결되므로 트랜잭션 설계 시 신중히 고려해야 한다.
락 개념 상호관계
트랜잭션은 특정 리소스에 대해 모드와 전략을 선택하고 (예: 인덱스 스캔 → next-key S locks), DBMS 의 호환성 매트릭스를 통해 허용 여부를 결정한다. Intent Locks 는 상위 레벨에서 빠른 충돌 판단을 도와준다.
| 출발 개념 → 도착 개념 | 방향성 (무엇을 위해) | 요약 설명 |
|---|---|---|
| Transaction → Lock Mode | 트랜잭션의 동작을 보호하기 위해 | 트랜잭션이 읽기/갱신 정책에 따라 S/U/X 선택 |
| Lock Mode → Compatibility Matrix | 블로킹 여부 판단을 위해 | 요청한 모드가 기존 락과 충돌하는지 검사 |
| Resource Granularity → Intent Locks | 상위 수준 빠른 충돌 검사 위해 | 테이블에 IS/IX 두어 행 락 존재를 표시 |
| Index Scan → Next-Key / Gap Lock | 팬텀 방지를 위해 | 인덱스 범위를 잠궈 삽입을 제어 |
| Isolation Level → Lock Strategy | 격리 보장 위해 적절한 락 선택 | Serializable → predicate/next-key 필요 |
| Lock Acquisition → Lock Escalation | 자원 최적화 위해 | 많은 행 락 시 페이지/테이블로 승격 |
- 방향성은 항상 " 무엇을 보장하려는가 (무결성·동시성·성능)" 로 판단된다.
예: 팬텀 방지 (무결성) → next-key/predicate 적용, 대량 락 (성능) → escalation.
락 모드의 실무 연관성
성능 (무엇): 불필요한 X/U 를 줄이고 인덱싱을 개선해 키 - 레인지 (범위) 잠금 폭 감소
어떻게: 적절한 인덱스 설계, 작은 트랜잭션, 필요한 곳만 UPDLOCK/ROWLOCK 등 힌트 적용 (신중히).
왜: 대기·교착 감소, 처리량 향상.정확성 (무엇): 팬텀 방지 (Serializable 필요 시 predicate/next-key)
어떻게: 인덱스 기반 range locking / predicate lock(또는 SSI) 사용
왜: 비즈니스 무결성 (예: 은행 계좌 집계) 의 보장.운영 (무엇): 교착 탐지·타임아웃·로그/모니터링
어떻게: 락 타임아웃 설정, 교착탐지 주기·알림, 블로킹 체인 분석 (프로파일링)
왜: 시스템 가용성 및 SLA 유지.
| 핵심 개념 | 실무에서 무엇 (사례) | 어떻게 (설계·운영) | 왜 (비즈니스 영향) |
|---|---|---|---|
| S/X/U | 은행 잔액조회/송금 | 조회는 S, 업데이트는 U→X 로 설계 (UPDLOCK 힌트 신중 사용) | 무결성 (정확한 잔액) 과 동시성 균형 |
| Intent Locks | 대형 테이블 DML 동시성 | 테이블 단위 IS/IX 사용해 충돌 검사 빠르게 | 잠금 검사 비용 절감으로 처리량 향상 |
| Next-Key / Gap | 인덱스 범위 쿼리 (예: date BETWEEN) | 인덱스 설계 + 트랜잭션 짧게 유지, 필요 시 gap lock 허용 | 삽입 (팬텀) 으로 인한 잘못된 집계 방지 |
| Lock Duration | 배치 vs 실시간 트랜잭션 | 배치는 더 작은 배치로 쪼개고, 트랜잭션 짧게 | 장기 락은 전체 서비스 지연 초래 |
| Escalation | 대량 업데이트 (대량 로깅) | 임계치 조정/모니터링으로 불필요한 승격 방지 | 메모리·락 테이블 폭증 방지 |
| Monitoring | 블로킹/Deadlock | DB 모니터링 + 타임아웃/교착테이블 확인 | SLA 위반 방지, 원인 추적 |
- 실무 설계는 (1) 적절한 인덱스, (2) 트랜잭션 최소화, (3) DBMS 별 락 특성 숙지, (4) 모니터링·타임아웃 정책으로 요약된다. 이 네 가지가 성능·정확성·운영성의 핵심 축이다.
기초 조사 및 개념 정립
데이터베이스 잠금 모드와 본질
왜 잠금이 필요한가?
- 여러 작업이 동시에 같은 데이터를 읽고 쓰면 결과가 엉킬 수 있음 → 잠금으로 충돌을 조절.
잠금의 기본 아이디어
- 읽기엔 공유 (S), 쓰기엔 배타 (X). 어떤 조합이 동시에 가능한지 (호환성) 를 정의하는 것이 잠금 모드.
잠금의 단위
- 테이블/페이지/행/키/갭 등. 단위가 작을수록 동시성은 좋아지지만 관리비용은 커짐.
특수 모드와 문제
- Intent: 상위 레벨에서 " 내가 곧 행을 잠금 " 이라고 표시.
- Update: 읽고 나서 쓰려는 의도 표시 (데드락 완화).
- Range/Gap: 팬텀 방지용 (범위 삽입 차단).
현대적 대안
- MVCC(버전 기반)—읽기와 쓰기를 분리해 읽기 성능 향상, 단 쓰기 충돌 처리 필요.
잠금 모드 (Lock Mode) 는 데이터베이스 트랜잭션이 특정 자원 (테이블/행/키/범위 등) 에 대해 어떤 종류의 접근을 허용받는지를 규정하는 상태다.
각 모드는 **허용되는 연산 (읽기/쓰기/수정)**과 다른 잠금과의 호환성을 정의하며, 이 규칙을 통해 동시성 환경에서 데이터 일관성과 무결성을 확보한다.
일반적으로 읽기는 공유 (Shared) 잠금으로, 쓰기는 배타 (Exclusive) 잠금으로 보호된다. 그러나 현실적 운영에서는 성능과 동시성 확보를 위해 의도 (Intent) 잠금, 업데이트 (Update) 잠금, 범위/갭/술어 (Predicate) 잠금 등 다양한 보조 모드가 도입된다.
범위 잠금은 특히 팬텀 현상 (트랜잭션 A 가 보았던 검색 결과에 트랜잭션 B 가 새 레코드를 삽입해 결과가 달라지는 현상) 을 막기 위해 사용되며, 반면 MVCC 같은 버전 기반 기법은 읽기 성능을 높이는 다른 접근법을 제공한다.
잠금 설계는 ’ 무결성 보장 ’ 과 ’ 동시성 (성능) 최적화 ’ 사이의 균형을 찾는 작업이다.
데이터베이스 락 모드의 역사와 진화
데이터베이스에서 동시에 여러 사람이 같은 데이터를 쓰거나 읽을 때 문제가 생긴다 (예: 두 사람이 동시에 잔액을 수정하면 하나의 수정이 사라지는 Lost Update). 이를 방지하려고 락 (lock) 이라는 ’ 사용·수정 권한표 ’ 를 씌운다.
초기에는 단순히 공유 (S) 와 독점 (X) 만 있었지만, 성능과 동시성을 더 높이기 위해 잠금의 크기 (테이블/페이지/레코드), 의도 락 (상위에서 하위 락 존재를 알려주는 방법), 범위/프레디킷 락 (검색 조건에 따른 삽입 방지), MVCC(읽기용 스냅샷을 만들어 읽기와 쓰기를 분리) 같은 여러 기법이 추가되었다.
최근에는 분산 시스템 환경에 맞춰 이들 기법을 조합·최적화하는 방향으로 발전 중이다.
등장 배경
다중 사용자가 동시에 같은 데이터에 접근하는 시스템에서는 읽기·쓰기 충돌로 인해 데이터 일관성이 깨질 수 있다.
데이터베이스는 이러한 충돌을 막아 직렬가능성 (Serializability) 과 Isolation 을 보장해야 한다.
초기에는 단순히 읽기/쓰기 충돌을 막는 공유 (S)·독점 (X) 락으로 대응했으나, 실무에서의 성능·동시성 요구로 인해 락의 그레인 (테이블→페이지→레코드), 의도 락, 범위/프레디킷 락, 그리고 MVCC와 같은 더 정교한 메커니즘이 도입되어 왔다.
발전 과정
| 시기 | 기술/개념 | 등장 배경 (무엇을 해결하려고) | 개선 포인트 (무엇이 좋아졌나) | 대표 문헌/시스템 |
|---|---|---|---|---|
| 1970 년대 | S/X 락, 2PL(두 단계 잠금) | 동시 읽기/쓰기 충돌로부터 직렬성 보장 | 단순한 충돌 규칙으로 직렬성 보장 | System R; 2PL 이론 |
| 1976 | Predicate locks (프레디킷 락) | 팬텀 (조건에 맞는 레코드 삽입) 문제 해결 | 논리적 집합 단위 잠금으로 팬텀 방지 (이론적) | Eswaran et al. 1976 |
| 1970s~1980s | 락 그레인·의도 락 | 다양한 그레인에서 효율적 충돌 판별 필요 | 상위 - 하위 락 통합 검사로 불필요 대기 회피 | Gray 등 연구, 상용 DB 구현 (예: SQL Server) |
| 1990 년대 | 정밀 락 / 키 - 레인지·범위 락, ARIES/KVL | 인덱스·트리 탐색·구조변경시 동시성 보장 | B-tree 등에서 높은 동시성·안정성 확보 | Lomet, Mohan 등 논문 (ARIES/KVL) |
| 1980s~2000s | MVCC 상용화·발전 | 읽기 - 쓰기 충돌 최소화, 읽기 성능 향상 | 읽기 작업 블로킹 감소, 높은 동시성 제공 | VAX Rdb/ELN(1984), PostgreSQL 등; MVCC 역사 정리 |
| 2000 년대~현재 | 하이브리드·분산 최적화 | 분산·파티셔닝·대규모 처리 환경 대응 | 락 +MVCC 결합, 분산 트랜잭션 최적화, 일관성 조정 | 현대 RDB/NOSQL 의 혼합 설계 |
timeline
title 락 모드 발전 타임라인
1976 : System R / 2PL 및 S/X 모델 정립.
1976 : Eswaran et al. - Predicate locks 제안(팬텀 이슈).
1970s-1980s : 락 그레인·의도 락(계층적 잠금) 연구 및 도입.
1984 : MVCC 상용 제품(VAX Rdb/ELN) 등장(초기 상용화).
1990s : 키-레인지/정밀 락, ARIES/KVL 등 인덱스 기반 동시성 향상 기법 등장.
2000s~ : MVCC+락 하이브리드, 분산·클라우드 네이티브 최적화 진행.
1970 년대에 S/X 와 2PL 이 등장해 직렬성의 이론적 토대를 닦았고 (실무: System R), 같은 시기 Eswaran 등은 프레디킷 락으로 팬텀 문제를 이론적으로 해결하려 했다.
이후 그레인 문제를 해결하기 위한 의도 락/계층적 락이 도입되었고, 1990 년대에는 인덱스·키 - 레인지 기반의 정밀 락과 ARIES/KVL 같은 트리 최적화 기법으로 동시성이 많이 개선되었다.
1980 년대 중반부터는 MVCC가 상용화되어 읽기 성능을 크게 개선했고, 2000 년대 이후 분산·클라우드 환경을 반영해 락과 MVCC 를 상황에 맞게 혼합·확장하는 설계가 주류가 되었다.
잠금 모드 기반 동시성 설계 정석
트랜잭션이 동시에 데이터베이스를 읽고 쓸 때 무엇이 문제인가?
- 두 트랜잭션이 같은 데이터를 동시에 다루면 한쪽 변경이 다른 쪽에 이상한 결과를 만들거나, 변경이 사라지거나, 같은 쿼리가 다른 결과를 줄 수 있다. 이게 바로 Lost/Dirty/Non-repeatable/Phantom 문제들이다.
어떻게 방지하나?—직관적 비유
- X(배타) 잠금 = 화장실 문을 잠그는 것. 한 사람이 들어가서 쓰는 동안 다른 사람은 못 들어온다 → 동시 쓰기 충돌 방지.
- S(공유) 잠금 = 도서관의 참고자료. 여러 명이 동시에 읽을 수는 있지만, 수정 (책갈피 추가 등) 은 못 하게 한다 → 미완료 쓰기를 읽지 않게 함.
- 범위잠금 (gap) = 공용 전시대 구역을 막아 새 전시물을 끼워 넣지 못하게 하는 것 → 범위 기반 삽입 (phantom) 방지.
- 트레이드오프: 잠그면 안전하지만 동시성 (성능) 이 줄어든다. 그래서 필요한 최소한만 잠그는 전략 (짧게·작게) 이 중요하다.
동시성 이상 (이슈) 및 설명 표
| 문제 유형 | 증상 (무엇이 일어남) | 잠금/기법으로의 해결 방식 |
|---|---|---|
| Lost Update | 두 트랜잭션이 같은 행을 동시에 갱신 → 한 쪽 변경이 덮어짐 | X 잠금으로 동시에 쓰기 차단 |
| Dirty Read | 커밋 전 다른 트랜잭션의 변경을 읽음 → 잘못된 판단 가능 | S 잠금 (또는 커밋된 스냅샷) 으로 미커밋 읽기 차단 |
| Non-repeatable Read | 트랜잭션 내 동일 쿼리 결과가 변경됨 | 트랜잭션 동안 S 잠금 유지 또는 스냅샷 격리 사용 |
| Phantom Read | 범위 조건의 결과셋에 새 행이 생김/사라짐 | Range/Gap/Next-key 잠금으로 범위 보호 |
이 표는 각 동시성 이상 현상에 대해 무슨 일이 발생하는지와 잠금 관점에서 어떻게 대응하는지를 직접 연결한다. 실제 DB 에서는 MVCC 나 스냅샷 격리 같은 기법이 같은 문제를 다른 방식으로 해결할 수 있으므로 (예: 스냅샷은 반복 읽기 일관성을 제공) 설계 시 DB 특성을 고려해야 한다.
잠금 도입의 핵심 목적 표
| 핵심 목적 | 목표 (구체적 의미) | 실행 수단 (잠금/정책) |
|---|---|---|
| 데이터 일관성 보장 | 트랜잭션 격리로 잘못된 데이터 흐름 차단 | 적절한 S/X, Range 잠금 / 격리 수준 설정 |
| 동시성 (throughput) 극대화 | 불필요한 차단을 줄여 처리량 유지 | 최소 범위·짧은 유지, MVCC 활용 |
| 데드락·무결성 완화 | 교착·무결성 위협을 설계로 흡수 | 잠금 순서, 타임아웃, 낙관적 동시성 제어 |
| 예측 가능한 동작 | 비즈니스 로직이 동시 실행 시에도 예측됨 | 격리 수준·스냅샷·원자적 트랜잭션 설계 |
핵심 목적은 단순히 ’ 잠금 ’ 을 많이 거는 것이 아니라 어떤 문제를 막고 어떤 수준의 동시성을 허용할지 균형을 잡는 것이다. 즉, 일관성과 성능 사이의 트레이드오프를 운영 목표에 맞게 조정하는 것이 관건이다.
문제와 목적 간 연관성 매핑
| 문제 유형 | 주요 관련 핵심 목적 | 연관 설명 |
|---|---|---|
| Lost Update | 데이터 일관성 보장 | 덮어쓰기 방지로 무결성 확보 |
| Dirty Read | 데이터 일관성 보장, 예측성 | 미완료 데이터 노출 제거 → 신뢰성 확보 |
| Non-repeatable Read | 예측 가능한 동작, 데이터 일관성 | 같은 트랜잭션 내 반복 일관성 제공 |
| Phantom Read | 데이터 일관성 보장, 예측성 | 범위 안정성 확보로 쿼리 예측성 향상 |
각 문제는 대부분 데이터 일관성 보장과 직결되며, 일부 (특히 Non-repeatable/Phantom) 는 트랜잭션의 예측성과도 깊게 연결된다. 따라서 목적을 우선순위로 두고 (예: 금융권은 강한 일관성 우선) 잠금·격리 전략을 선택해야 한다.
락 모드 전제와 성능 요구사항
핵심 전제
- 트랜잭션 경계의 존재: 트랜잭션 시작·커밋·롤백을 기준으로 락 획득·해제가 정의되어야 함. (근거: ACID 모델)
- 정의된 격리 수준: 어떤 격리 (Serializable, Repeatable Read 등) 를 지원할지 명확히 해야 락 모드와 범위가 결정됨. (근거: 팬텀/갭 락 의존)
- 일관된 락 관리 엔티티: Lock Manager 와 Deadlock Detector 는 일관된 정책으로 동작해야 함. (근거: 충돌 판단·희생자 선정 필요)
성능 요구사항 및 특징 (근거 포함)
- 낮은 락 오버헤드: 락 획득/해제는 경합 없는 경로가 빠르고, 락 구조체 크기를 작게 유지해야 함. (근거: 소형 락이 많을수록 메모리·캐시 오버헤드 증가)
- 메모리 관리: 락 테이블의 해시·버킷 수와 정리 (garbage collection) 정책을 정해 메모리 상한을 보장해야 함. (근거: 무제한 증가 시 OOM 유발)
- 빠른 데드락 탐지/해결: 탐지 주기와 탐지 알고리즘 (Wait-For 그래프 등) 을 정의해 평균 복구 시간을 제한해야 함. (근거: 긴 데드락 회복은 트랜잭션 지연과 자원 낭비 증가)
- 에스컬레이션 제어: 에스컬레이션 임계값·예외 규칙으로 과도한 테이블 락 전이를 방지해야 함. (근거: 에스컬레이션은 동시성 저하 주원인)
- 분산 고려: 네트워크 지연·부분 장애를 반영한 분산 락 (혹은 분산 트랜잭션) 전략을 마련해야 함. (근거: 분산 환경에서는 단일 노드 가정 불가)
등장 이전 관련 기술 및 차별점
- MVCC(다중 버전 동시성 제어): 읽기 - 쓰기 충돌을 버전으로 해결하여 읽기 락을 피함.
차별점: 락 기반보다 읽기 성능 우수하지만 쓰기 충돌 처리·갱신 비용을 갖음. - 낙관적 동시성 제어 (OCC): 트랜잭션을 검증 시점에만 충돌 체크.
차별점: 충돌이 적은 워크로드에 유리, 충돌 많으면 재시도 비용 큼. - 타임스탬프 순서화: 타임스탬프 기반으로 직렬화 순서를 강제.
차별점: 락 의존성 제거 가능, 구현 복잡성 및 롤백/충돌 처리 필요.
- MVCC(다중 버전 동시성 제어): 읽기 - 쓰기 충돌을 버전으로 해결하여 읽기 락을 피함.
설계 체크포인트 (실무)
- 목표 격리 수준 선정 → 락 모드·범위 정의 → Lock Manager 자료구조 설계 → 데드락 정책 수립 → 에스컬레이션·모니터링 지표 정의 → 성능 목표 (숫자) 설정 → 테스트 (부하·장기 운전) 및 운영계 모니터링.
락 모드 전제·요구사항 표
| 구분 | 항목 | 설명 | 설계/운영 영향 (근거) |
|---|---|---|---|
| 전제 | 트랜잭션 경계 | 시작/커밋/롤백 정의 필요 | 락의 범위·유효기간이 트랜잭션 경계에 의존 |
| 전제 | 격리 수준 정의 | Serializable, Repeatable Read 등 선택 | 팬텀·갭 락 필요성 결정 |
| 전제 | Lock Manager 구현 | 해시·대기 큐·소유자 관리 | 메모리·성능 핵심 요소 |
| 전제 | Deadlock Detector | 탐지 방식·희생자 정책 명시 | 복구 시간과 트랜잭션 손실 영향 |
| 성능 | 획득/해제 오버헤드 최소화 | 락 구조 최적화, 경합 회피 | 응답성·처리량 개선 |
| 성능 | 메모리 관리 | 락 테이블 한도·GC 정책 | OOM·성능 저하 방지 |
| 성능 | 데드락 탐지 지연 최소화 | 탐지 주기·정책 설정 | SLA 준수, 지연 감소 |
| 성능 | 에스컬레이션 제어 | 임계치와 예외 규칙 정의 | 동시성 급락 예방 |
| 운영 | 호환성 매트릭스 | 락 충돌 규칙 구현·테스트 | 논리적 정합성 확보 |
| 운영 | 모니터링 지표 | 대기수·평균대기·에스컬레이션 등 | 운영·튜닝 빠른 대응 가능 |
| 운영 | 분산 고려 | 분산 락/네트워크 불확실성 대응 | 분산 시스템 안정성 확보 |
| 검증 | 성능 목표 수치화 | 지연/메모리/탐지시간 목표 설정 | 검증·테스트 기준 제공 |
위 표는 락 모드 설계에서 반드시 점검해야 할 전제와 요구사항을 카테고리별로 묶은 것이다. 설계는 먼저 전제 (트랜잭션 경계·격리 수준·락·데드락 매니저) 를 명확히 하고, 성능 목표 (오버헤드·메모리·에스컬레이션) 를 수치화한 뒤 운영·모니터링 요소로 검증·튜닝하는 순서로 진행해야 한다. 분산 환경이라면 추가적으로 네트워크 불확실성과 분산 조정 비용을 반영해 정책을 조정해야 한다.
동시성 제어를 위한 락 모드의 설계 특성
락 모드는 데이터에 대한 접근 권한을 규정해 여러 트랜잭션이 동시에 일할 때 일관성을 지키도록 한다.
의도 (상위) 잠금은 테이블·페이지 같은 상위 단위에서 하위 충돌을 미리 검출해 비용을 줄이고, 세분화된 행/키 단위 잠금은 서로 다른 레코드를 동시에 건드릴 수 있게 해 동시성을 높인다.
필요에 따라 잠금 강도를 올리거나 (업그레이드) 낮추는 기능은 초기 과도한 배타를 피하고 효율을 높인다.
다만 세밀한 잠금은 메타데이터 관리 오버헤드와 업그레이드 경쟁으로 인한 데드락 가능성을 낳는다.
범위·프레디케이트 락은 삽입·팬텀 문제를 해결하며, MVCC 같은 버전 기법과 함께 쓰이면 읽기 성능과 일관성 사이에서 균형을 맞출 수 있다.
락 모드의 핵심 설계 특성
계층적 잠금 (의도 잠금)—빠른 상위 충돌 판정
- 설명: 상위 (테이블) 레벨에 Intent(IS/IX) 락을 두어 하위 (행/키) 락 충돌을 상위에서 빠르게 판별.
- 기술적 근거: 상위 노드의 의도 표시만으로도 하위 충돌 가능성 판단이 가능하므로 전체 스캔 없이 충돌 검사 비용을 절감.
- 차별점: 단순 전역 배타락과 달리 하위 단위 동시성을 보존하면서도 충돌 검사 비용을 낮춤.
세분화된 그레뉴러리티—충돌 표면 축소
- 설명: 행/키/페이지 등 세밀한 대상에 락을 걸어 동시성 향상.
- 기술적 근거: 잠금 단위가 작을수록 두 트랜잭션이 서로 다른 단위를 건드릴 확률 증가 → 충돌 감소.
- 차별점: 전체 테이블 락과 비교해 동시 처리량이 높지만 락 관리 오버헤드가 증가.
업그레이드/다운그레이드—필요시 권한 조정
- 설명: 트랜잭션 흐름에 따라 더 강한 (또는 약한) 락으로 변환해 초기 과도한 락을 회피.
- 기술적 근거: 변환 시점까지 공유를 유지하다가 쓰기 필요 시 배타로 전환 → 불필요한 배타 기간 축소.
- 차별점: 항상 처음부터 배타락을 잡는 설계보다 동시성을 더 잘 보존하나 업그레이드 경쟁에서 데드락 발생 가능.
범위/프레디케이트 락—팬텀 제어의 정밀성
- 설명: 조건 (프레디케이트) 이나 인덱스 간격 (gap) 에 대한 락으로 삽입·팬텀 방지.
- 기술적 근거: 단순 행락으로는 팬텀을 막기 어려워 범위 단위를 잠그면 팬텀 현상 방지 가능.
- 차별점: 논리적 predicate(정밀) vs 물리적 gap(효율) 의 구현 차이로 DBMS 별 장단 존재.
MVCC/버전 기법과의 보완적 관계
- 설명: MVCC 는 읽기 성능을 높이나, 직렬화 보장이 필요할 때는 predicate/range 락 같은 락 메커니즘이 병행 사용됨.
- 기술적 근거: MVCC 는 읽기 - 읽기 충돌을 제거하지만, 삽입/팬텀 관련 문제는 전통적 락으로 제어해야 함.
- 차별점: 순수 락 기반 (2PL) 대비 읽기 부하에서 이득을 얻지만, 완전 대체는 아님—하이브리드 적용이 보편적.
락 모드 핵심 특징 비교표
| 핵심 특징 | 기술적 근거 | 다른 기술과의 차별점 (요지) |
|---|---|---|
| 계층적 잠금 (Intent) | 상위 의도 표시로 하위 충돌 사전판정 → 충돌 검사 비용 절감 | 전역 배타락보다 충돌 검사 비용 적고 동시성 보존 |
| 그레뉴러리티 (세분화) | 작은 단위 잠금 → 충돌 표면 축소 → 동시성 증가 | 테이블 락 대비 처리량↑, 락 관리 오버헤드↑ |
| 업그레이드/다운그레이드 | 초기 공유 유지 후 필요시 배타 전환 → 배타 기간 최소화 | 초기부터 X 잡는 설계보다 유연, 업그레이드 경쟁으로 데드락 가능 |
| 범위/프레디케이트 락 | 범위 삽입/검색에 대한 잠금으로 팬텀 방지 | 논리적 predicate(정밀) vs 물리적 gap(효율) 선택지 |
| MVCC 보완성 | 버전으로 읽기 충돌 제거, 삽입/팬텀은 락으로 보완 | 순수 락 기반보다 읽기 성능 유리하지만 완전 대체 아님 |
- 핵심 결론: 락 모드는 ’ 권한의 계층화 ’ 와 ’ 잠금 단위의 세분화 ’ 를 통해 동시성과 일관성 사이에서 균형을 만든다.
- 트레이드오프: 세분화·유연성은 동시성 개선을 주지만 메타데이터·운영 복잡성을 증가시켜 데드락·관리 비용을 유발할 수 있다.
- 실무 시사점: 인덱스·트랜잭션 설계로 충돌 표면을 줄이고, 필요시 MVCC 나 격리 모드 선택으로 성능/정합성 균형을 맞춰야 함.
락 매니저 성능을 결정하는 HW·SW 요인
데이터베이스에서 많은 트랜잭션이 동시에 락을 요구하면, 락을 관리하는 테이블 (또는 매니저) 은 메모리에 락 상태를 유지한다.
따라서 충분한 RAM 이 필요하고, 많은 CPU 코어가 있어도 락을 둘러싼 경쟁이 심하면 성능은 오히려 떨어질 수 있다. 또한 트랜잭션의 영속성은 WAL 에 의존하므로 WAL 을 쓸 디스크 용량과 I/O 성능도 중요하다.
마지막으로, 물리적 서버의 NUMA 구조와 CPU 캐시 동작 방식 (캐시 라인 경쟁) 은 락 처리 지연과 확장성에 직접적인 영향을 준다.
시스템 요구사항
메모리—Lock Table 저장용
- 설명: 각 락 (행/레인지/인텐트 등) 마다 메타 데이터 (트랜잭션 id, 모드, 대상 등) 를 유지.
- 이유: 동시 락 수가 증가하면 메모리 사용량이 선형으로 증가. 부족 시
lock table초과 또는 성능 저하 발생. (예: InnoDB 관련 사례)
CPU—멀티코어 및 동기화 처리 능력
- 설명: 락 획득/해제, 트랜잭션 관리, 스케줄링은 CPU 연산으로 처리됨.
- 이유: 코어 수가 많아도 락 경쟁으로 캐시 라인 이동과 컨텍스트 스위칭이 늘어나면 오히려 처리량이 제한된다. 올바른 락 알고리듬 (스핀 vs 블록) 선택 필요.
스토리지—WAL 저장 및 fsync 성능
- 설명: 커밋 전 WAL 에 기록하고 fsync 로 디스크에 보장. WAL 파일 보관 공간 필요.
- 이유: WAL 쓰기·동기화가 느리면 커밋 지연→트랜잭션 체류 시간 증가→락 보유 시간 증가→블로킹 확대.
하드웨어 의존성
NUMA
- 설명: CPU 소켓마다 로컬 메모리 뱅크가 있고, 원격 노드 접근은 지연/대역폭 비용이 큼.
- 이유: 락 메타데이터나 버퍼가 원격 노드에 위치하면 락 획득 지연 증가. NUMA-unaware 설계는 성능 저하로 직결.
캐시 일관성 / 캐시 라인 경쟁
- 설명: 락 변수 (예: spinlock) 하나가 여러 코어의 캐시에 자주 반영되면 캐시 라인이 이동하며 성능이 나빠짐.
- 이유: 캐시 라인 핑퐁과 false sharing 은 락 대기 시간을 크게 늘려 전체 처리량을 낮춘다. 설계 단계에서 패딩·슬로팅·분산락 등으로 회피해야 함.
하드웨어 원자 연산
- 설명: CPU 레벨의 CAS, atomic inc/dec 등 연산은 락 없는 (혹은 경량 락) 동기화의 기반.
- 이유: 효율적 원자 연산이 없으면 락 구현이 폴백되어 스케일링이 제한된다. 소프트웨어 동기화 기법 선택에 직접 영향.
락 매니저 필수 시스템·하드웨어 항목
| 분류 | 항목 | 설명 | 영향 (무엇이 나빠지는가) | 대응/검토 포인트 |
|---|---|---|---|---|
| 시스템 요구 | 메모리 (Lock Table) | 락 메타데이터·대기 큐 저장 | 메모리 부족 → lock table 초과/오류, 성능저하 | 락 수 모니터링, 메모리 할당 증대, 트랜잭션 축소. |
| 시스템 요구 | CPU (멀티코어) | 동시 스레드 처리, 동기화 연산 | 락 경쟁 → 캐시 라인 이동·컨텍스트 스위치 증가 | 락 설계 (스핀/블록), 스레드 배치, 프로파일링. |
| 시스템 요구 | 스토리지 (WAL) | WAL 용량·fsync 처리 성능 | 느린 WAL → 커밋 지연 → 락 장기화 | 고성능 디스크, WAL 로테이션/아카이브 정책. |
| 하드웨어 의존 | NUMA | 메모리 지역성 (로컬 vs 원격) | 원격 접근 지연 → 락 획득 지연/불균형 | NUMA 바인딩, 메모리/스레드 배치, NUMA-aware 설계. |
| 하드웨어 의존 | 캐시 일관성 (캐시라인) | 캐시 라인 이동·false sharing | 핑퐁 현상 → 락 대기 시간 증가 | 패딩, 분산 락, backoff 전략. |
| 하드웨어 의존 | 원자 연산 지원 | CAS/LL-SC/메모리 배리어 | 비효율적 동기화 구현 → 확장성 저하 | HW 기능 확인, 경량 동기화 설계. |
- 핵심은 락 보유 객체 수 (메모리), 락 경쟁을 다루는 CPU/캐시 설계, WAL 에 의한 I/O 요구 그리고 NUMA 로 인한 메모리 지역성이다.
- 실무에서는 먼저 워크로드 (동시 트랜잭션 수, 트랜잭션 길이, 읽기/쓰기 비율) 를 측정한 뒤 위 항목들을 용량/배치·설계 관점에서 맞추는 것이 효과적이다.
핵심 원리 및 이론적 기반
잠금 모드의 원칙·철학·개요
- 문제 (왜 필요한가?)—여러 트랜잭션이 동시에 같은 데이터에 접근하면 결과가 꼬일 수 있다.
- 해결 아이디어 (무엇을 하는가?)—잠금을 이용해 어떤 트랜잭션이 언제 어떤 연산을 할지 제어 (읽기/쓰기 충돌 방지).
- 핵심 규칙 (어떤 원칙이 있나?)
- 2PL 로 직렬화 보장,
- 호환성 매트릭스로 허용 조합 판정,
- 최소한의 잠금 원칙으로 성능 유지,
- 계층적 잠금으로 상하위 충돌 효율화.
- 실무 팁—읽기가 많으면 공유 읽기/또는 MVCC 고려, 잦은 작은 업데이트면 락 경합·에스컬레이션 모니터링 필요.
락 모드 핵심 원칙 표
Two-Phase Locking (2PL)
- 설명: 잠금 획득 (확장) 단계와 잠금 해제 (축소) 단계로 동작.
- 목적: 트랜잭션 스케줄의 직렬화 가능성 보장.
- 왜 필요한가: 동시 실행이지만 결과가 마치 순차 실행인 것처럼 보장하여 데이터 무결성 확보.
호환성 기반 제어 (Compatibility Matrix)
- 설명: 각 잠금 모드 간 허용·비허용 조합을 표로 정의해 충돌을 판정.
- 목적: 충돌 여부를 빠르게 결정해 올바른 동작을 허용/차단.
- 왜 필요한가: 불필요한 차단을 줄이고, 동시에 허용 가능한 작업은 병렬로 실행시켜 성능 확보.
최소 제한의 원칙 (Minimize Locks)
- 설명: 잠금의 범위 (단위) 와 지속시간을 최소화.
- 목적: 동시성 (throughput) 극대화 및 대기 시간 최소화.
- 왜 필요한가: 불필요한 동시성 제약은 처리량 감소와 응답성 악화를 야기하므로 최소화 필요.
계층적 (다중 그레인) 잠금 (Multiple Granularity)
- 설명: 데이터 계층에 맞춰 Intent(IS/IX/SIX) 등으로 상하위 잠금을 조정.
- 목적: 상위 - 하위 충돌을 효율적으로 판정하고, 대규모 연산에 유연성 제공.
- 왜 필요한가: 전체 테이블을 무조건 잠그는 단순 방식은 병목이므로 계층적 제어가 실무에서 효과적.
| 원칙명 | 간단 설명 | 목적 (무엇을 위한가) | 필요한 이유 (왜 필요한가) |
|---|---|---|---|
| Two-Phase Locking (2PL) | 획득 단계 / 해제 단계로 잠금 관리 | 직렬화 (Serializability) 보장 | 동시 실행의 결과를 순차 실행 결과와 동일하게 만들어 무결성 확보. |
| 호환성 기반 제어 | 잠금 모드 간 허용/차단 매트릭스 사용 | 충돌 판정의 표준화 | 불필요한 차단 최소화·허용 가능한 병렬성 확보. |
| 최소 제한 원칙 | 잠금 범위·기간 최소화 | 처리량 (throughput) 극대화 | 과도한 잠금은 응답성·처리량 저하 초래. |
| 다중 그레인 잠금 | 계층적 (Intent) 잠금 사용 | 상하위 잠금 충돌 효율적 관리 | 대형 연산에서 전체 잠금 대신 부분 잠금으로 유연성 제공. |
2PL 은 일관성 (직렬화) 을 보장하는 구조적 규약이고, 호환성 매트릭스와 다중 그레인 설계는 그 규약을 현실의 트리 구조 데이터에 적용해 성능과 안전성을 조정한다. 최소 제한 원칙은 실무에서의 성능 판단 기준으로 항상 고려되어야 하는 트레이드오프다.
잠금 설계 철학 개요
가능한 한 공유 읽기 허용
- 설명: 읽기에는 공유 잠금을 넓게 허용해 동시 읽기를 살린다.
- 목적: 읽기 중심 워크로드에서 처리량 극대화.
- 왜 필요한가: 많은 시스템이 읽기 비중이 높아 읽기 동시성이 전체 성능에 큰 영향.
갱신 시에는 명확한 배타 확보
- 설명: 쓰기·갱신 작업은 배타 (X) 혹은 업데이트 (U) 로 보장.
- 목적: 쓰기 충돌로 인한 일관성 손상을 차단.
- 왜 필요한가: 쓰기 동작이 데이터 무결성에 직접적 영향을 주므로 확실한 보호 필요.
성능과 일관성의 명확한 트레이드오프 관리
- 설명: 락 강도·단위를 조정해 일관성 (강) vs 동시성 (높음) 사이 균형 선택.
- 목적: 애플리케이션 요구 (응답성, 일관성 수준) 에 맞춰 최적화.
- 왜 필요한가: 모든 환경에 최적인 단일 설정은 없으므로 설계 시 정책 결정이 필수.
| 철학명 | 설명 | 목적 (무엇을 위한가) | 필요한 이유 (왜 필요한가) |
|---|---|---|---|
| 공유 읽기 최우선 | 읽기 작업은 넓게 허용 | 읽기 중심 성능 최적화 | 대부분 시스템에서 읽기 비중이 높아 전체 처리량에 큰 영향. |
| 갱신은 배타 확보 | 쓰기/갱신은 강한 배타 보장 | 데이터 무결성 보장 | 쓰기는 직접적인 상태 변경이므로 충돌 방지 필수. |
| 명확한 트레이드오프 정책 | 일관성·성능 사이 정책화 | 시스템 요구에 맞춘 최적화 | 단일 설정으로 모든 상황 해결 불가, 설계 결정 필요. |
설계 철학은 운영 환경 (읽기/쓰기 비율, 응답성 요구) 에 따라 어떤 잠금 전략을 택할지 결정하는 가치판단이다. 읽기 우선은 성능, 갱신 배타는 무결성, 그 사이에서 적절한 타협을 정책으로 명확히 해야 한다.
락 기반 동시성 제어의 구조와 동작
트랜잭션이 데이터를 읽거나 쓸 때는 먼저 어떤 종류의 락을 걸 것인지 락 관리자에게 요청한다.
락 관리자는 어떤 락들이 서로 함께 존재할 수 있는지를 담은 표 (호환성 매트릭스) 를 보고 요청을 허용하거나 대기시킨다.
만약 트랜잭션들이 서로의 락을 기다리다가 원형으로 얽히면 (데드락) 시스템이 이를 탐지해 한 트랜잭션을 강제로 취소하여 풀어준다.U(update) 락처럼 특별한 모드는 데드락을 줄이기 위해 설계되어 있으며, 구체적 규칙은 사용하는 DBMS 문서를 참고해야 한다.
락 관리자와 호환성 메커니즘 핵심
트랜잭션 (클라이언트)
- 동작: 리소스 접근 전 락 요청 (모드 지정).
- 목적: 필요한 격리 수준 달성.
락 관리자 (Lock Manager)
- 동작: 요청 수신 → 현재 리소스 락 상태 확인 → 호환성 매트릭스 검사 → 즉시 허용/대기 큐 삽입 → 락 테이블 갱신.
- 비고: 락 승격/변환, 락 에스컬레이션 (예: 행→페이지→테이블) 관리.
호환성 매트릭스
- 동작: 요청 모드 × 보유 모드 조합으로 허용 여부 결정.
- 예: U 는 S 와 호환되나 U-U 는 불허 (또는 제한). 실제 규칙은 DBMS 문서 참조 필요.
대기 큐 및 데드락 탐지
- 동작: 충돌 시 대기큐에 삽입 → 주기적/이벤트 기반 데드락 검사 (Wait-for 그래프) → 사이클 감지 시 희생자 선정·롤백.
락 해제·신호
- 동작: 트랜잭션 커밋/롤백시 락 해제 → 대기 큐에 신호 → 재시도/승인.
락 관리자 구성요소와 동작 요약
| 구성 요소 | 역할 | 주요 행동 (알고리듬 관점) | 핵심 고려사항 |
|---|---|---|---|
| 트랜잭션 | 락 요청자 | 리소스 접근 전 락 (mode) 요청 | 필요한 격리 수준에 맞는 모드 선택 |
| 락 관리자 | 중앙 결제자 | 현재 락 상태 조회 → 호환성 검사 → grant/queue → 락 테이블 갱신 | 락 테이블 동기화, 승격/변환 로직 |
| 호환성 매트릭스 | 정책 (테이블) | mode×mode → 허용/거부 판단 | DBMS 별 차이 존재 (U, SIX 등) |
| 대기 큐 | 블로킹 관리 | 충돌 시 큐 삽입, 우선순위/타임아웃 정책 | 공정성·우선순위 설계 필요 |
| 데드락 탐지기 | 안전성 보장 | Wait-for 그래프 또는 주기 검사 → 희생자 선정 | 검사 주기, 성능·탐지 지연 트레이드오프 |
| 락 해제/신호 | 진행 재개 | 트랜잭션 종료시 락 해제 → 대기 후보 신호 | 락 에스컬레이션/수동 해제 이슈 |
트랜잭션은 락을 ’ 요청 ’ 하고, 락 관리자는 호환성 매트릭스로 즉시 허용 혹은 대기를 결정한다.
대기 상태가 길어지면 데드락 탐지기가 그래프 기반으로 사이클을 찾고, 희생자를 골라 트랜잭션을 롤백해 교착을 해소한다.
락 승격 (예: U→X), 에스컬레이션 (행→페이지→테이블), 우선순위/타임아웃 정책 등은 전체 동작에 성능·공정성에 큰 영향을 준다. 또한 모드별 호환성 규칙은 DBMS 문서에서 정의된 상세 규칙을 따르는 것이 안전하다.
락 처리 흐름과 데드락 대응 흐름도
flowchart TD
T[트랜잭션 요청] -->|"LOCK_REQ(mode)"| LM[Lock Manager]
LM --> CK{호환성 검사}
CK -->|허용| GRANT[락 부여 및 테이블 갱신]
CK -->|불허| QUEUE[대기 큐에 삽입]
QUEUE --> DF[데드락 탐지기]
DF -->|사이클 없음| WAIT[대기 상태 유지]
DF -->|사이클 있음| VICTIM[희생자 선정]
VICTIM --> ROLLBACK[트랜잭션 롤백]
ROLLBACK --> RELEASE[락 해제 -> 큐에 신호]
GRANT --> EXEC[트랜잭션 수행]
EXEC -->|커밋/롤백| RELEASE
RELEASE --> CK
%% 보완 항목 표시
subgraph 보완요소
ESC[락 에스컬레이션/승격]
METRICS[모니터링/메트릭 수집]
TIMEOUT[타임아웃/우선순위 정책]
end
GRANT --> ESC
QUEUE --> TIMEOUT
LM --> METRICS
트랜잭션이 락 요청을 보내면 락 관리자는 호환성 매트릭스 기반으로 즉시 부여하거나 대기 큐에 넣는다.
대기 큐에 들어간 트랜잭션들은 주기적 (또는 이벤트 기반) 으로 데드락 탐지기의 검사를 받는다.
사이클이 발견되면 희생자를 골라 롤백하고 그 결과로 락이 해제되어 대기 큐의 다음 후보가 재검사된다.
운영 관점에서는 락 승격 (예: U→X), 락 에스컬레이션 (세분화→거시화), 탐지 주기, 대기 타임아웃/우선순위 정책, 그리고 모니터링 지표가 전체 동작·성능에 큰 영향을 준다.
실제 구현 세부는 DBMS 문서를 따르는 것이 안전하다.
잠금 제어 흐름과 생명주기 핵심
트랜잭션이 락을 다루는 흐름은 요청 → 검사 → (대기 또는 부여) → 사용 → 해제 로 단순화할 수 있다.
- 요청할 때는 " 무엇을 (행/범위/테이블), 왜 (읽기/쓰기) 잠그는지 " 를 명시.
- DB 내부의 락 매니저는 호환성 표를 보고 즉시 부여할지 대기열에 넣을지 결정.
- 대기열에 들어가면 오래 기다리면 데드락 검출 알고리즘에 걸려 트랜잭션이 강제로 종료될 수 있다 (한 쪽을 죽여 문제를 풀음).
- 트랜잭션이 끝나면 보유한 락을 해제하고 대기 중인 트랜잭션을 깨운다.
이 전체 과정에서 의도 락, 락 변환, 락 승격 같은 기법들이 동시성과 안전을 균형 있게 맞추도록 돕는다.
잠금 데이터·제어 흐름 요약
- 요청: 트랜잭션이 대상 객체 (테이블/행/범위) 에 S/IS/X/IX 등 모드로 락 요청.
- 평가 (락 매니저): 현재 부여/대기된 락들과 비교해 호환성 판별 (호환 → Granted, 불호환 → Waiting).
- 대기 정책: 일반적으로 FIFO 지만 우선순위 (예: 트랜잭션 우선순위, 타임아웃) 로직을 둘 수 있음. 교착 가능성 판단을 위해 대기 그래프를 유지.
- 락 변환: S→X 같은 변환 요청 시 재검사. 변환 대기 중 교착 가능성 주의.
- 해제 & 깨움: 트랜잭션 종료 (커밋/롤백) 시 락 해제 → 큐에서 부합하는 요청을 깨워서 부여.
- 운영 팁: 의도 락 사용, 최소 범위 (행 수준), 가능한 MVCC 활용, 락 승격 모니터링 권장.
잠금 제어 흐름 단계와 핵심 처리
| 단계 | 작업 내용 | 핵심 고려 사항 / 효과 |
|---|---|---|
| 요청 (Request) | 잠금 대상/모드 지정 (S/IS/X/IX 등) | 명확한 모드 선택으로 불필요한 대기 최소화 |
| 평가 (Compatibility) | 락 매니저가 기존 락과 비교 | 의도 락·호환성 매트릭스로 빠른 판별 가능. ([MySQL Developer Zone][2]) |
| 대기 (Waiting) | 불호환 시 큐에 삽입 (FIFO/우선순위) | 데드락 가능성 → 데드락 탐지/타임아웃 필요. ([dsf.berkeley.edu][4]) |
| 변환 (Conversion) | S→X 등 모드 변환 요청 및 재평가 | 변환 대기 중 교착 유의; 구현별 정책 차이. ([MySQL Developer Zone][5]) |
| 부여/사용 (Granted) | 락 부여 후 작업 수행 | 최소 범위로 락 유지 (성능 보전) |
| 해제 (Release) | 커밋/롤백 시 락 해제 → 대기자 깨움 | 해제로 인한 깨움 순서가 전체 성능에 영향 |
이 표는 락 획득·처리의 단계적 흐름과 각 단계에서 반드시 고려해야 할 운영·성능 요소를 연결한다. 특히 호환성 평가, 대기 정책, 변환 시 교착 위험은 실무 튜닝의 핵심 포인트다.
락 제어 흐름 다이어그램
flowchart TD
A["트랜잭션 요청: 잠금(R/W, 대상, 모드)"] --> B[락 매니저: 의도락/호환성 검사]
B --> |호환 가능| C["부여(Granted)"]
B --> |충돌| D["대기열(Waiting)"]
D --> E{대기 정책}
E --> |FIFO| D
E --> |우선순위/타임아웃| F[타임아웃 검사]
F --> |타임아웃 발생| G[Abort / 트랜잭션 중단]
D --> H[데드락 탐지]
H --> |사이클 발견| G
C --> I[작업 수행]
I --> J{변환 요청?}
J --> |예| K["잠금 변환 요청(S→X 등)"]
K --> B
J --> |아니오| L[트랜잭션 완료?]
L --> |예| M[락 해제 → 대기자 깨움]
L --> |아니오| I
G --> N[롤백 & 락 해제]
N --> M
락 생명주기 상태도
stateDiagram-v2
[*] --> Requested : 잠금 요청
Requested --> Evaluating : 의도락/호환성 검사
Evaluating --> Granted : 호환성 통과 (부여)
Evaluating --> Waiting : 충돌 → 대기열 삽입
Waiting --> DeadlockCheck : 대기 중 데드락 탐지
DeadlockCheck --> Aborted : 데드락 victim 선정 (Abort)
DeadlockCheck --> Waiting : 이상 없음
Waiting --> TimeoutCheck : 타임아웃 검사
TimeoutCheck --> Aborted : 타임아웃 → Abort
TimeoutCheck --> Granted : 락 해제 후 부여
Granted --> Converting : 변환 요청(S->X 등)
Converting --> Evaluating : 변환 재평가
Converting --> Granted : 변환 부여
Granted --> Released : 트랜잭션 완료(커밋/롤백)
Released --> [*]
Aborted --> Released
운영 중심 락 시스템 아키텍처
간단히 말하면, 락 시스템은 트랜잭션이 데이터에 안전하게 접근하도록 중앙에서 조정하는 매커니즘이다.
트랜잭션이 락을 요청하면 Lock Manager 가 리소스를 빠르게 찾기 위해 Resource Hash 를 조회하고, Lock Table 에서 현재 상태를 확인한다.
충돌이 있으면 요청은 Wait Queue 에 들어가고, 여러 트랜잭션이 서로 기다리면 Deadlock Detector 가 이를 찾아서 희생자를 선정해 회복한다.
의도 락은 상위 레벨에서 하위 요청을 효율적으로 조절하도록 돕고, 모니터링은 운영 중 문제를 감지·해결할 근거를 제공한다.
안정적 락 시스템 구조 설계
- 트랜잭션 → 락 요청 → Lock Manager 가 Resource Hash 로 위치 파악 → Lock Table 에서 허용/거부 판정 → 허용이면 사용, 거부면 Wait Queue → Deadlock Detector 감시 → 트랜잭션 종료 시 락 해제 → 모니터링 기록.
락 구조별 역할·기능 요약표
| 구조 요소 | 설명 | 역할 | 기능 | 특징 | 상호관계 |
|---|---|---|---|---|---|
| Lock Manager | 중앙 제어 엔진 | 요청 수락/거부·에스컬레이션 | Lock Table·Wait Queue 제어 | 고동시성 최적화 필요 | Transaction/Resource Manager 와 연동 |
| Resource Hash | 리소스 인덱스 | 빠른 리소스 조회 | 해시 버킷·리샤이징 | 해시 충돌 관리 필요 | Lock Table 을 색인 |
| Lock Table | 락 상태 저장소 | 리소스별 상태 유지 | 레코드 CRUD, 소유자 목록 | 메모리 중심, GC 필요 | Wait Queue·Deadlock Detector 공유 |
| Wait Queue | 대기열 | 거부된 요청 보관·정렬 | 대기 항목 삽입/우선순위 | 대기 정책에 따라 성능 달라짐 | Deadlock Detector 의 입력 |
| Deadlock Detector | 데드락 탐지기 | 사이클 탐지·회복 트리거 | 그래프 생성·사이클 탐지 | 탐지 빈도에 비용 | Wait Queue·Transaction List 참조 |
| Intent Locks | 상위 의도 표시 | 계층적 충돌 빠른 판정 | IS/IX/SIX 처리 | 경량·성능 최적화용 | Lock Manager 호환성 검사에 사용 |
| Transaction Manager | 트랜잭션 상태 유지 | 락 보유 목록·복구 | 락 해제·복구 트리거 | 트랜잭션 메타데이터와 결합 | Lock Manager 와 직접 통신 |
| Monitoring API | 계측·노출 계층 | 운영·튜닝 데이터 제공 | 실시간/집계 지표 노출 | 낮은 오버헤드 필요 | 모든 모듈에서 계측데이터 제공 |
이 표는 락 시스템의 핵심 구조별로 무엇을 담당하고 어떤 기능을 수행하는지 정리했다. 설계 시 각 요소의 특징 (메모리 민감도, 동시성 부담, 비용) 을 고려해 자료구조·주기·정책을 설정해야 한다.
구조별 설계·운영 고려사항
| 구조 요소 | 설계 고려사항 | 운영 고려 지표 | 실패 시 영향 |
|---|---|---|---|
| Lock Manager | 락 - 프리 vs 버킷 락, 스케일 아웃 | 평균 응답시간, CPU 사용량 | 전체 시스템 응답 지연 |
| Resource Hash | 해시 함수·버킷수, 리사이징 정책 | 버킷 충돌률, 메모리 사용 | 검색 지연·경합 증가 |
| Lock Table | 레코드 포맷·GC 주기 | 메모리 점유, 레코드 수 | OOM, 성능 저하 |
| Wait Queue | 우선순위 정책, 스핀 vs 블록 | 대기 길이, 평균 대기시간 | 트랜잭션 병목 |
| Deadlock Detector | 탐지 주기, 희생자 정책 | 데드락 발생률, 복구 시간 | 장시간 블로킹 |
| Intent Locks | 계층 매핑 방식 | 의도 락 비율 | 과도하면 상위 충돌 유발 |
| Transaction Manager | 락 리스트 스냅샷 빈도 | 트랜잭션당 락 수 | 회복 복잡성 증가 |
| Monitoring API | 집계 레벨·노출 주기 | 알람 빈도, 데이터 신뢰성 | 운영 판단 지연 |
구조별로 설계 시 선택해야 하는 옵션들과 운영에서 모니터링해야 할 지표들, 실패 시 발생 가능한 영향을 정리했다. 초기 설계 시 이 고려사항들을 명시해두면 운영 중 문제 추적과 튜닝이 수월해진다.
락 시스템 상호작용 구조도
(점검·보완 사항 반영: 의도 락 표시, 모니터링 라인, Deadlock Detector 의 그래프 입력 포함)
flowchart TB
subgraph ClientLayer
T[Transaction Start/End]
end
subgraph TransactionManager
TM[Transaction State]
TL[Lock List per Txn]
end
subgraph LockSubsystem
RM[Resource Hash Table]
LT[Lock Table]
WQ[Wait Queue]
CM[Compatibility Matrix]
ID[Intent Locks Handler]
DD[Deadlock Detector]
LM[Lock Manager Core]
end
subgraph Monitoring
MA[Metrics API / Collector]
Dashboard[Dashboard / Alerts]
end
T -->|요청 락| LM
LM --> RM
RM --> LT
LM -->|호환성 조회| CM
LM --> ID
LT --> WQ
WQ --> DD
TL --> LT
TM --> TL
DD --> LM
LT --> MA
WQ --> MA
DD --> MA
MA --> Dashboard
- 트랜잭션은 Lock Manager 에 락 요청을 보낸다. Lock Manager 는 Resource Hash 로 리소스 레코드를 찾아 Lock Table 을 조회하고, Compatibility Matrix 와 Intent Locks 핸들러를 통해 허용 여부를 판단한다.
- 거부된 요청은 Wait Queue 에 등록되고, Deadlock Detector 는 Wait Queue 와 Transaction 의 락 리스트를 참고해 그래프를 구성하여 사이클 (데드락) 을 탐지한다.
- 모든 핵심 상태 (락 테이블, 대기열, 데드락 이벤트) 는 Metrics API 로 집계되어 대시보드와 알람으로 노출된다. 이 도식은 의도 락을 통한 계층적 판정, 모니터링의 위치, 데드락 탐지 입력 흐름을 명확히 반영한다.
락 구성 요소 및 운영 속성
구성 요소는 락 시스템을 실제로 동작시키는 모듈들이다. 간단히: Lock Table 은 현재 누가 어떤 락을 갖고 있는지 저장하고, Resource Hash 는 빠르게 그 레코드를 찾게 해준다. Wait Queue 는 대기하는 요청을 보관하고, Deadlock Detector 는 서로 기다리는 트랜잭션 간 순환을 찾아 회복을 트리거한다. Intent Locks 는 상위 레벨에서 하위 요청을 효율화하고, Transaction Manager 는 트랜잭션별 보유 락을 정리해서 커밋/롤백 시 일괄 해제한다. Monitoring 은 운영자가 시스템 상태를 볼 수 있게 조직화된 데이터를 제공한다.
락 구성요소 상세 속성 표
| 구성 요소 | 설명 | 역할 | 기능 | 특징 | 상호관계 | 필수/선택 | 속하는 구조 |
|---|---|---|---|---|---|---|---|
| Lock Table | 락 레코드 저장소 | 리소스 상태 저장 | 레코드 CRUD, 소유자 목록 | 메모리 중심, GC 필요 | Resource Hash, Wait Queue 연동 | 필수 | LockSubsystem |
| Resource Hash | 리소스 인덱스 | 빠른 레코드 검색 | 해시/버킷 관리 | 확장성 중요 | Lock Table 사용 | 필수 | LockSubsystem |
| Wait Queue | 대기열 | 대기 요청 관리 | 대기 삽입/우선순위 | 우선정책 영향 큼 | Lock Table, DD 참조 | 필수 | LockSubsystem |
| Deadlock Detector | 탐지기 | 데드락 식별·회복 | 그래프 구성, 사이클 탐지 | 비용 - 정확도 트레이드오프 | Wait Queue, Transaction List | 필수 | LockSubsystem |
| Compatibility Matrix | 충돌 규칙 | 모드간 허용 판단 | 행렬 조회 | DB 별 커스터마이징 | Lock Manager 핵심 입력 | 필수 | LockSubsystem |
| Intent Locks Handler | 의도 락 처리기 | 계층적 의도 관리 | IS/IX/SIX 관리 | 상위 - 하위 최적화 | Lock Manager, Lock Table | 필수 (계층 락 시) | LockSubsystem |
| Transaction Lock List | Tx 보유 락 목록 | 트랜잭션별 정리 | 락 해제·회복 | 복구시 중요 | Transaction Manager ↔ Lock Table | 필수 | TransactionManager |
| Monitoring API | 계측 인터페이스 | 운영 지표 제공 | 집계·쿼리·알람 | 낮은 오버헤드 필요 | 모든 모듈 데이터 수집 | 필수 (운영) | Monitoring |
| Timeouts/Backoff | 대기 정책 모듈 | 대기 제어 | 타임아웃, 재시도 정책 | 정책 튜닝 필요 | Wait Queue, Transaction Manager | 선택 (정책에 따라) | LockSubsystem |
구성 요소별로 필수성, 상호연결, 그리고 속한 구조를 명시했다. 기본적인 락 시스템을 운영하려면 Lock Table, Resource Hash, Wait Queue, Deadlock Detector, Compatibility Matrix, Transaction Lock List, Monitoring API 는 반드시 필요하다. Timeouts/Backoff 등은 정책 선택에 따라 도입한다.
구성요소 구현·운영 고려사항
| 구성 요소 | 구현 고려사항 | 운영 고려지표 | 확장성 이슈 | 보안/권한 고려 |
|---|---|---|---|---|
| Lock Table | 메모리 포맷, GC, 동시성 제어 | 레코드 수, 메모리 점유 | 리샤딩 필요 시 복잡 | 권한별 락 열람 제어 |
| Resource Hash | 해시 함수, 리사이징 | 버킷 충돌률 | 노드 간 분산 인덱스 | 정보 노출 최소화 |
| Wait Queue | 우선순위 정책 | 대기길이, 재시도율 | 큐 분할 필요성 | 공격성 요청 방지 |
| Deadlock Detector | 탐지 주기·알고리즘 | 탐지시간, 회복시간 | 대규모 그래프 비용 | 로그/증적 보호 |
| Compatibility Matrix | 버전 관리 | 매트릭스 변경 빈도 | DB 별 커스터마이징 | 변경 권한 통제 |
| Intent Locks | 계층 매핑·오버헤드 | IS/IX 비율 | 계층 깊이 증가 시 복잡 | 적절한 권한 정보 포함 |
| Monitoring API | 데이터 집계 방식 | 수집 지연, 오버헤드 | 높은 왕복시 성능 문제 | 민감 데이터 마스킹 |
| Timeouts/Backoff | 정책 파라미터 | 타임아웃 빈도 | 글로벌 정책 적용 문제 | 정책 변경 권한 관리 |
구성요소별로 구현 시 고려해야 할 기술적 사항과 운영지표, 확장성·보안 관련 주의점을 정리했다. 초기 설계 단계에서 이 표의 항목들을 검토하면 운영 이전 위험을 줄일 수 있다.
락 구성요소 상호관계도
graph LR
subgraph TransactionManager
TState[Transaction State]
TLockList[Lock List per Txn]
end
subgraph LockSubsystem
ResourceHash[Resource Hash]
LockTable[Lock Table]
CompatMatrix[Compatibility Matrix]
IntentHandler[Intent Locks Handler]
WaitQueue[Wait Queue]
Deadlock[Deadlock Detector]
Timeouts[Timeouts/Backoff]
end
MonitoringAPI[Monitoring API]
TState -->|보유/요청| TLockList
TLockList -->|요청| LockTable
TState -->|요청| LockTable
LockTable -->|색인 요청| ResourceHash
LockTable -->|호환성 조회| CompatMatrix
LockTable --> IntentHandler
LockTable -->|거부 시| WaitQueue
WaitQueue --> Deadlock
WaitQueue --> Timeouts
Deadlock -->|희생자| TransactionManager
LockTable --> MonitoringAPI
WaitQueue --> MonitoringAPI
Deadlock --> MonitoringAPI
Timeouts --> MonitoringAPI
- 트랜잭션은 자신의 락 목록을 통해 락 획득/반환을 관리하며, Lock Table 에 요청을 보낸다. Lock Table 은 Resource Hash 로 리소스 매핑을 수행하고 Compatibility Matrix 및 Intent Handler 를 참조해 결정한다.
- 거부된 요청은 Wait Queue 로 가며, Timeouts/Backoff 와 Deadlock Detector 가 이를 관리한다. Monitoring API 는 핵심 상태를 수집해 운영 대시보드에 제공한다.
특성 분석 및 평가
락 모드의 실무적 가치와 설계 원리
락은 여러 트랜잭션이 동시에 데이터에 접근할 때 발생할 수 있는 충돌과 이상현상을 막는 규칙이다.
올바른 락 모드 설계는
- 데이터의 정합성을 보장하고
- 동시에 가능한 작업 수를 늘려 성능 효율을 높이며
- 운영 중 문제를 추적·해결하기 쉽게 만든다.
핵심 기법으로는 상위 레벨에서 충돌을 미리 알게 해주는 의도잠금, 행 단위로 충돌 면적을 좁히는 세분화, 삽입·팬텀을 막는 범위락, 그리고 필요에 따른 락 강도 전환이 있다.
실무에서는 적절한 인덱스와 짧은 트랜잭션 경계가 이 장점들을 실제 성능으로 연결한다.
락 모드의 장점·근거·실무 효과 표
| 장점 | 기술적 근거 | 실무 효과 / 기대치 | 적용 상황 |
|---|---|---|---|
| 정합성 보장 | 2PL, Predicate/Key-range/gap 락 | Dirty/Non-repeatable/Phantom 방지 → 결과 예측 가능성↑ | 금융·회계·주문 처리 |
| 세밀한 동시성 제어 | 행/키 그레뉼러리티, 호환성 매트릭스 | 동시 처리량 증가, 응답시간 개선 | OLTP, 다중 사용자 시스템 |
| 계층적 효율성 | Intent(IS/IX/SIX) 으로 상위 충돌 판정 | 충돌 검사 비용·CPU 사용량 감소 | 대용량 테이블 수정 |
| 문제 진단 용이성 | Lock Manager·대기 그래프 구조 | 블로킹 원인 추적·MTTR 단축 | 운영 장애 대응 |
| 범위 보호 (팬텀 차단) | Key-range / Predicate 락 | SERIALIZABLE 수준 보장 → 집계·정산 신뢰성 확보 | 리포팅·정산·통계 연산 |
| 적응형 세분성 (에스컬레이션) | 락 승격/강등, Escalation 정책 | 메모리·성능 균형 최적화 (단, 정책 오류 위험) | 혼합 워크로드 환경 |
- 락 모드는 정합성 확보와 동시성 개선이라는 상반된 목표를 균형 있게 관리한다.
- 의도 잠금과 그레뉼러리티 조절은 동시성 향상에 직접 기여하고, 락 메타데이터·에스컬레이션 정책은 운영 비용·리스크를 결정한다.
- 실무에서는 인덱스·트랜잭션 길이·격리 수준을 함께 조율해 위 장점들을 실효성 있게 활용해야 한다.
락 기반 동시성의 한계와 완화 전략
락 기반 동시성 제어는 단순하고 강력하지만, 몇 가지 피할 수 없는 비용과 한계가 있다.
락을 얻고 푸는 비용 (오버헤드), 서로를 기다리게 만드는 상황 (데드락), 락이 집중되어 시스템 전체를 느리게 만드는 병목이 대표적이다.
하드웨어 관점에선 메모리·CPU·캐시 구조 (NUMA, 캐시라인) 가 성능에 직접적인 영향을 주며, 분산 환경에서는 노드 간 락 동기화 자체가 큰 제약이 된다.
그래서 실무에서는 락을 줄이는 설계 (MVCC, 낙관적 방법), 트랜잭션 단축, 파티셔닝, 그리고 하드웨어 특성 반영을 조합해 문제를 완화한다.
락 방식의 주요 단점
| 단점 | 설명 | 원인 | 실무에서 발생되는 문제 | 완화/해결 방안 | 대안 기술 |
|---|---|---|---|---|---|
| 락 오버헤드 | 락 획득/해제·메타데이터 관리 비용 | Lock Manager·lock table | 처리량 감소, CPU/메모리 소모 | 트랜잭션 단축·그라뉼러티 조정·락 풀링 | MVCC, Optimistic Concurrency |
| 데드락 | 순환 대기로 진행 불가 상태 | 리소스 접근 순서 불일치 | 트랜잭션 롤백·지연 | 자원 순서 규칙·탐지 (Wait-For Graph)·타임아웃 | Timestamp/OCC, Snapshot |
| 병목/확장성 저하 | 특정 리소스에 락 집중 | 과도한 X/Range 락·긴 TX | Throughput 저하·응답 지연 | 인덱스 개선·파티셔닝·샤딩 | MVCC, Sharding |
| 복잡성 증가 | 락 모드·계층·정책 복잡 | 다양한 모드·의도락 등 | 운영·유지보수 비용 증가 | 정책 표준화·자동화 툴 | MVCC 기반 단순화 |
| 락 확대 문제 | 세부 락 → 상위 락 승격으로 동시성 하락 | DBMS 임계치·메모리 부족 | 갑작스런 블로킹·데드락 | 임계치 조정·쿼리 리팩토링 | 샤딩, Lock-free 구조 |
- 단점은 락 방식 자체의 비용과 상호작용에서 비롯된다.
- 실무에서는 우선적으로 트랜잭션 설계 (짧게), 적절한 인덱스·파티셔닝, 그리고 MVCC/낙관적 접근을 고려해 완화한다. 또한 모니터링으로 이상 징후 (데드락 빈도·락 확대 발생) 를 조기 포착해야 한다.
락 시스템의 환경·하드웨어 제약
| 제약사항 | 설명 | 원인 | 영향 | 해결 방안 | 대안 기술 |
|---|---|---|---|---|---|
| 자원 제한 | 락 테이블·대기큐가 메모리·CPU 를 사용 | 동시 트랜잭션 폭증 | lock table overflow·성능저하 | 메모리 증설·거버닝·트랜잭션 규모 축소 | 분산 DB·샤딩 |
| 대용량·분산 한계 | 노드 간 락 동기화의 비용·복잡성 | 네트워크 지연·분산 일관성 요구 | 응답지연·복잡한 운영 | 지역성 설계·분산 락 서비스 사용 | 분산 MVCC·이벤트 기반 아키텍처 |
| NUMA·캐시 제약 | 메모리 지역성·캐시라인 경쟁 | 하드웨어 아키텍처 | 락 획득 지연, 스케일링 실패 | NUMA 바인딩·패딩·분산 락 설계 | lock-free 알고리즘 |
| 단일 노드 중심 | 중앙 Lock Manager 의 확장 한계 | 중앙 집중형 설계 | 확장성·가용성 제한 | 분산락 (zk/etcd), 파티셔닝 | 분산 합의 기반 시스템 |
- 제약사항은 하드웨어·아키텍처 선택과 직결된다.
- 이를 완화하려면 애초 아키텍처 (샤딩·지역성·분산락 서비스) 를 고려해 설계하거나, 하드웨어 (메모리·디스크·NUMA 배치) 를 워크로드에 맞춰 조정해야 한다.
잠금 트레이드오프와 혼합 전략 해법
- 무엇이 문제인가?—동시에 여러 트랜잭션이 같은 데이터를 다루면 충돌·불일치가 발생.
- 어떤 선택이 있나?—강한 락 (직렬성 보장) vs 약한 락 (높은 동시성) vs MVCC/낙관적 방식.
- 결정 기준은?—읽기/쓰기 비율, 응답성 요구, 데이터 일관성 중요도 (예: 금융은 강한 일관성), 배치 크기 등.
- 실무 패턴—MVCC 로 읽기 최적화 + 행 잠금으로 쓰기 통제, 필요 시 락 에스컬레이션.
잠금 선택지별 장단점 표
| A(선택지) | B(선택지) | 주요 고려 기준 | A 의 장점 | A 의 단점 | B 의 장점 | B 의 단점 | 권장 상황 |
|---|---|---|---|---|---|---|---|
| 행 단위 잠금 | 테이블 단위 잠금 | 동시성 vs 오버헤드 | 높은 동시성, 세밀 통제 | 락 수·메모리·관리 오버헤드 증가 | 단순·낮은 오버헤드, 빠른 대형 작업 처리 | 동시성 낮고 병목 유발 가능 | OLTP(행 단위) vs 배치/간단 스크립트 (테이블) |
| S/X 기본 모드 | Intent + Update 모드 | 단순성 vs 성능·안정성 | 구현·운영 단순, 예측 쉬움 | 데드락·경합 관리 한계 | 데드락 완화, 복잡한 트랜잭션에서 성능 우위 | 설계·디버깅 복잡 | 단순 앱 (S/X) vs 복잡 트랜잭션·다중레벨 데이터 (Intent) |
| Pessimistic(락) | Optimistic/MVCC | 일관성 보장 vs 처리량 | 강한 충돌 차단 (일관성 우수) | 동시성 저하·대기·데드락 | 읽기 동시성 우수, 낮은 락 오버헤드 | 쓰기 충돌·재시도/직렬화 추가 필요 | 금융/정산 (비관적) vs 읽기중심 서비스 (MVCC) |
- 행 단위는 동시성 극대화, 하지만 락 추적·메모리 비용과 관리 난이도가 올라간다. 테이블 단위는 단순·저비용이나 병목 유발.
- Intent/Update 모드는 다단계·복잡 트랜잭션에 유리하며, S/X 기본 모델은 단순 애플리케이션에서 충분할 때가 많다.
- MVCC/낙관적은 읽기가 많은 워크로드에 필수적 선택지이며, 비관적 (락) 방식은 변경이 잦고 일관성이 최우선인 시스템에서 선호된다.
하이브리드 동시성 제어 패턴
| 패턴명 | 구성 요소 | 적용 목적 | 장점 | 고려/주의사항 |
|---|---|---|---|---|
| MVCC + 행락 혼합 | MVCC(읽기 스냅샷) + 행잠금 (쓰기) | 읽기 병렬성 확보 + 쓰기 일관성 | 읽기 부하에 탁월, 읽기 지연 최소화 | 쓰기 충돌·재시도 관리 필요, 복잡도 증가. |
| 세분화 + 에스컬레이션 | 행/키 잠금 → 임계치 시 테이블/페이지로 에스컬레이션 | 평상시 동시성 유지, 대형 작업 비용 완화 | 운영 오버헤드 제어, 평상시 고성능 | 에스컬레이션 시 병목 급증 가능, 정책 튜닝 필요. |
| Intent + Range 락 혼합 | 다중 그레인 Intent + 범위 (갭) 락 | 팬텀 방지 + ancestor 충돌 판정 가속 | 트리 구조에서 효율적, 팬텀 제어 | 설계·디버깅 복잡, DBMS 별 세부 동작 차이. |
| OCC + 재시도 정책 | 낙관적 트랜잭션 + commit 시 검증/재시도 | 쓰기 충돌 적은 환경에서 높은 처리량 | 낮은 락 오버헤드, 간단한 읽기 | 재시도 비용·응답 지연, 충돌 빈도 높으면 비효율. |
- 하이브리드 전략은 워크로드 특성 (읽기/쓰기 비율, 배치 주기, 응답성 요구) 에 따라 선택된다.
- 운영환경에서는 보통 MVCC 기반 읽기 + 부분적 락 (쓰기 안전장치) 또는 세분화된 락 + 에스컬레이션 조합이 널리 쓰인다.
- 각 패턴은 **장점과 복잡성 (디버깅/튜닝 부담)**을 동시에 가져오기 때문에, 모니터링·메트릭 (락 대기시간, 재시도율 등) 을 기반으로 정책을 조정해야 한다.
워크로드 기반 락 전략과 권장
락 (또는 MVCC) 은 누가 언제 데이터를 읽고 쓰는지를 조정하는 도구다.
- 트랜잭션이 많고 변경이 잦은 OLTP에서는 전통적 락 (S/X/U 등) 으로 정확성을 우선한다.
- 데이터 읽기가 많고 긴 쿼리가 많은 OLAP은 스냅샷 (MVCC) 을 써서 읽기를 차단하지 않는 방식을 선호한다.
- 분산 환경에서는 전역 락을 남발하면 확장성이 깨지니, 분산 락·샤딩·낙관적 제어를 적절히 조합해야 한다.
락 모드 적용 적합성 평가
설계 관점 (Design)
- OLTP: 트랜잭션 짧게 설계, 가능한 한 행 단위 락 (row-level) 사용, 인덱스 설계로 범위 스캔 최소화—S/X/U/IS/IX 조합 권장.
- OLAP: 스냅샷 기반 조회 (읽기 전용 복제/머티리얼라이즈드 뷰) 우선, 필요 시 Read-only S 나 Range Lock 최소 사용.
- 분산: 글로벌 동기화는 비용이 크므로 파티셔닝·서브시스템별 일관성 경계 (최종일관성 허용 가능한 영역) 설계, 필요 시 분산 락 서비스 적용.
분석 관점 (Analysis / Trade-offs)
- 일관성 vs 성능: 락 (비관적) 은 일관성 높지만 대기·데드락 발생 가능. MVCC(비락) 는 읽기 성능 우수하지만 버전 GC·쓰기 충돌 비용 존재. 워크로드 특성 (읽기/쓰기 비율, 트랜잭션 길이) 에 따라 선택.
- 운영 복잡도: 락 에스컬레이션·승격 정책, 데드락 빈도와 탐지/해결 전략이 운영 부담을 결정.
운영 관점 (Ops / Runbook)
- OLTP 운영 지표: 락 대기 시간, 데드락 빈도, 에스컬레이션 횟수 모니터링 필요. 긴 트랜잭션은 피하고, 인덱스·쿼리 튜닝으로 락 획득 범위를 줄여야 함.
- 분산 운영: 분산 락 (예: Redis, ZK) 사용 시 TTL·재시도·희소성 (락 소유권) 정책을 명확히 해두어야 함.
시스템 유형별 락 적용 권장표
| 시스템 유형 | 적합도 (★5) | 왜 적합/부적합? (핵심 근거) | 권장 Lock Modes / 패턴 |
|---|---|---|---|
| OLTP (금융/결제) | ★★★★★ | 짧고 빈번한 업데이트, 강한 무결성 필요—전통 락이 안전. | S, X, U, IS, IX; 짧은 트랜잭션, 인덱스 최적화 |
| OLAP (분석/리포팅) | ★★★ | 대량 읽기·장시간 쿼리—읽기 블로킹 회피가 우선. | MVCC 스냅샷, Read-only S / Range Locks 최소 사용 |
| 배치 처리 (대용량) | ★★ | 동시성 낮고 순차적 작업—전체 잠금으로 단순화 가능 | X, BU (bulk update), 전용 배치 창 |
| 실시간 (예측응답) | ★★★★ | 응답 시간 예측 필요—락 지연 최소화 | 짧은 S/X, 타임아웃 엄격 적용, 낙관적 전략 병행 |
| 분산 시스템 | ★★ | 네트워크 지연·파티셔닝으로 전역 락 비효율 | 분산 락 서비스 + 샤딩/MVCC/낙관적 CC 조합. |
워크로드 성격에 따라 ’ 락 중심 (OLTP) ↔ MVCC/스냅샷 (OLAP)’ 선택이 핵심이다. 분산·대규모 환경에서는 전역 락은 피하고 분산 락·샤딩·낙관적 병행 제어를 조합해 확장성·일관성의 균형을 맞춰야 한다. 운영에서는 락 대기·데드락·에스컬레이션 지표를 지속 모니터링하고, 트랜잭션을 가능한 짧게 유지하는 것이 성능·가용성에 가장 큰 영향을 준다.
구현 방법 및 분류
락 모드 구현·운영 핵심 카탈로그
- 트랜잭션은 읽기용 (S) 과 쓰기용 (X) 잠금을 통해 서로 방해하지 않도록 한다.
- Update(U) 는 읽기 후 쓰기 가능성 있는 상황에서 데드락을 줄이기 위해 쓰인다.
- 의도 락은 " 내가 곧 행 단위 락을 잡을 거다 " 라고 테이블 수준에 알려줘 검사 비용을 줄여준다.
- 범위 (갭) 잠금은 범위 쿼리의 새로운 행 삽입 (phantom) 을 막는다.
- 락 관리는 락 매니저 (해시 테이블 + 대기 리스트) 가 하고, 승격·변환·데드락 탐지·타임아웃 같은 운영 정책이 성능/정합성에 큰 영향을 준다.
구현 기법별 정리
| 구현 방법 | 정의 | 특징 | 목적 | 사용 상황 | 예시 |
|---|---|---|---|---|---|
| Shared (S) | 읽기용 공유잠금 | 여러 트랜잭션 동시 보유 가능. 쓰기 차단 | Dirty Read 방지, 일관된 읽기 | SELECT(락을 요구하는 경우), READ_COMMITTED 이상 | SELECT … FOR SHARE / 보통 읽기 |
| Exclusive (X) | 쓰기용 배타잠금 | 단일 보유, 대부분 비호환 | Lost Update/Dirty Write 방지 | INSERT/UPDATE/DELETE | UPDATE … (행에 X) |
| Update (U) | 읽기 후 쓰기 가능성 표시 | S 와 호환, U 끼리 상호 제한 | S→X 변환 시 데드락 완화 | UPDATE 의 식별 단계 | SELECT for UPDATE 변형 |
| Intent (IS/IX/SIX) | 상위 객체에 하위 잠금 의도 표기 | 빠른 호환 검사, 계층적 | 락 검사 비용 절감 | 행 단위 락 시 테이블 레벨에 설정 | 행 업데이트 시 테이블에 IX |
| Range/Gap/Next-Key | 인덱스 키 범위 잠금 (갭) | 행 + 갭/갭만 등 DB 별 차이 | Phantom Read 방지 (범위 삽입 차단) | 범위 쿼리, SERIALIZABLE | InnoDB next-key lock |
| Schema Lock (Sch-S/Sch-M) | 스키마 변경 제어 | DDL/DML 간 충돌 방지 | DDL 안전성 보장 | ALTER TABLE, 쿼리 실행 | ALTER TABLE → Sch-M |
락 모드 카테고리별 분류
기본 모드 (데이터 접근 목적)
- S (Shared): 읽기 목적, 다중 보유, 쓰기 차단.
- X (Exclusive): 쓰기 목적, 단독 보유.
- U (Update): 읽기→쓰기 가능성 있는 경우, 데드락 완화.
| 모드 | 정의 | 특징 | 사용 예 |
|---|---|---|---|
| S | 읽기 잠금 | 다중 동시 보유, X 차단 | SELECT FOR SHARE |
| X | 쓰기 잠금 | 단일 보유, 강한 배타성 | UPDATE, DELETE |
| U | 업데이트 잠금 | S 와 일부 호환, U 끼리 제한 | UPDATE 전 조건 평가 |
- 기본 모드는 데이터 접근 (읽기/쓰기) 목적에 따라 선택되며, S 는 읽기 동시성을 높이고 X 는 무결성을 보장. U 는 S→X 승격에서 생기는 데드락을 줄이는 실무적 보완 모드다.
계층/메타 모드 (호환성 최적화)
- IS/IX/SIX: 상위 객체에 하위 락 의도를 표시해 전체 검사 비용을 낮춤.
- NL: 잠금 없음 (메타 목적).
| 모드 | 정의 | 역할 | 사용 예 |
|---|---|---|---|
| IS | 의도 공유 | 테이블에 읽기 의도 표기 | 행 단위 S 획득 시 테이블 IS |
| IX | 의도 배타 | 행에 X 를 잡을 의도 표기 | 행 업데이트 시 테이블 IX |
| SIX | 혼합 | 테이블 S + 하위 일부 X 의도 | 대량 읽기 + 일부 수정 |
- 의도 락은 계층적 잠금 검사의 핵심이며, 하위 락들을 일일이 검사하지 않고 O(1) 수준으로 충돌 여부를 판별하도록 해 퍼포먼스에 도움을 준다.
범위/팬텀 제어
- Gap / Next-Key / Range Locks: 인덱스 범위나 gap 을 잠궈 범위 삽입/삭제 (팬텀) 를 방지.
| 기법 | 정의 | 목적 | 사용 예 |
|---|---|---|---|
| Gap Lock | 키 사이의 gap 잠금 | 삽입 방지 (팬텀) | 범위 쿼리 |
| Next-Key | 레코드 + gap 잠금 | 레코드와 갭 동시 보호 | InnoDB next-key |
| Range Lock | 범위 기반 잠금 | 범위 안정성 보장 | SERIALIZABLE 범위 쿼리 |
- 범위 락류는 팬텀 현상을 방어하기 위해 사용되며, 구현 차이 (갭만/레코드 + 갭) 는 DBMS 에 따라 결과와 성능에 큰 영향을 준다.
스키마·시스템 레벨
- Schema Locks, Lock Manager 설계 (해시 테이블·파티셔닝), Lock Escalation 등.
| 항목 | 정의 | 운영 영향 | 사용 예 |
|---|---|---|---|
| Schema Locks | DDL/DML 충돌 제어 | DDL 시 서비스 영향 | ALTER TABLE |
| Lock Manager | 락 상태 추적 모듈 | 성능 병목/파티셔닝 필요 | 해시 lock table |
| Lock Escalation | 세부 락→상위 락 전환 | 동시성 감소 가능 | 대량 행 잠금 시 테이블 락 |
- 시스템 레벨 기법은 운영성·성능에 직접 영향. 락 매니저 구조와 승격 규칙을 모르면 대규모 작업에서 큰 병목·블로킹이 발생할 수 있다.
락 모드·기법 통합 요약표
| 카테고리 | 기법/모드 | 정의 (요약) | 목적 | 운영 포인트 |
|---|---|---|---|---|
| 기본 모드 | S / X / U | 읽기/쓰기/업데이트 잠금 | 일관성·동시성 균형 | 최소 범위/짧은 유지 권장 |
| 계층/메타 | IS / IX / SIX | 상위에 의도 표기 | 빠른 충돌 검사 | 자동 부착/검사 최적화 |
| 범위 제어 | Gap / Next-Key / Range | 인덱스 범위 잠금 | Phantom 방지 | DB 별 동작 차이 주의 |
| 시스템 레벨 | Schema / LockMgr / Escalation | 스키마·락관리·승격 | DDL 안전·자원관리 | 파티셔닝/모니터링 필요 |
SQL 표준과 DBMS 락 구현 실무 지침
SQL 표준은 격리 수준을 정의해 어떤 일관성 문제가 허용되는지 (더티 리드, 반복 불가 리드, 팬텀 등) 를 규정한다. 그러나 표준은 ’ 어떻게 구현할지 ‘(예: 어떤 종류의 락을 걸어서 팬텀을 막을지) 를 지정하지 않고 각 DBMS 가 최적화한 방법으로 구현한다.
결과적으로 같은 SERIALIZABLE 이라도 DBMS 마다 내부 동작 (범위 락, 버전 기반 검사, 재시도 정책 등) 이 달라서 실무에서는 표준 요구사항 + 대상 DBMS 문서를 함께 이해해야 한다.
SQL 표준과 DBMS 락 구현 비교
| 항목 | 표준 (ANSI/ISO) 내용 | DBMS 구현 (대표적 사례) | 실무 시 확인 포인트 |
|---|---|---|---|
| 격리 수준 정의 | Dirty/Non-repeatable/Phantom 등 현상 기준 (READ UNCOMMITTED → SERIALIZABLE). | MySQL(InnoDB), PostgreSQL, SQL Server 등 모두 격리 수준 제공하되 구현 방식 상이. | 애플리케이션이 요구하는 ** 무결성 (예: 팬텀 허용 여부)** 을 명확히 하고 DBMS 별 매핑 확인 |
| 팬텀 제어 방식 | 표준은 팬텀 방지를 요구 (Serializable)—구현 방법은 미지정. | InnoDB: next-key/gap locks PostgreSQL: SSI(predicate-like checks) SQL Server: range locks/locking strategies. | 특정 쿼리 (인덱스 유무, 스캔 유형) 에 따라 실제 락 범위가 달라짐—쿼리 플랜과 인덱스 확인 |
| Predicate/Range Lock | 표준은 현상 정의만, predicate lock 직접 명시 X. | 일부 DBMS 는 범위 락 적용 일부는 버전/SSI 로 대응. | DBMS 문서에서 ‘predicate lock’, ‘range/gap lock’, ‘serializable 구현 방식 ’ 검색 |
| 락 힌트·관리 | 표준은 힌트 규정하지 않음 (구현별 확장). | SQL Server 등은 힌트 (UPDLOCK, ROWLOCK 등) 제공 MySQL 은 힌트 일부 제공. | 힌트 사용 시 DBMS 버전·부작용 (교착, 확장성) 검증 |
| 상호운용성/마이그레이션 | 표준은 공통 언어 제공하지만 세부 구현 차이로 완전 호환성 보장하지 않음. | 마이그레이션 시 Lock Mode·격리 매핑·동작 차이로 애플리케이션 레벨 변경 필요. | 마이그레이션 계획에 락 동작 테스트 (테스트 케이스) 를 포함 |
4.6 (심화) 안티패턴 및 주의사항
무엇이 문제인가?: 잘못된 잠금 사용은 성능 저하·서비스 중단·데드락을 유발.
어떤 패턴이 위험한가?: 광역 락·잠금 순서 불일치·인덱스 없는 범위 스캔·장기 트랜잭션·에스컬레이션 무시는 대표적 위험.
간단한 우선순위 해결법: (1) 트랜잭션을 짧게, (2) 인덱스와 쿼리 최적화, (3) 일관된 락 순서, (4) 배치·파티셔닝·모니터링.
잠금 안티패턴: 문제·원인·해결
| 안티패턴 | 문제 (무슨 현상) | 결과 (운영에 미치는 영향) | 원인 | 해결책 (요약) | 예시 (발생) | 해결 적용 예시 |
|---|---|---|---|---|---|---|
| 광역 락 남발 | 테이블/DB 전체 잠금 발생 | 전체 서비스 블로킹, 처리량 급감 | 범위가 큰 DML(또는 잘못된 힌트) | 세분화 (행잠금), 배치 조정, 파티셔닝 | LOCK TABLE 또는 대규모 UPDATE | 배치를 작게, 파티셔닝 적용 |
| 잠금 순서 불일치 | 교착 (deadlock) | 트랜잭션 중단·재시도 발생 | 서로 다른 순서로 리소스 잠금 | 일관된 자원 잠금 순서 적용 | Tx1: UPDATE A then B / Tx2: UPDATE B then A | 모든 트랜잭션에서 ID 오름차순으로 잠금 |
| Lock Escalation 무시 | 수천개 락 → 테이블 락 전환 | 광범위 블로킹 | 많은 행락 획득 (임계치 도달) | 배치 크기 제한, ROWLOCK 힌트, 파티셔닝 | 대량 UPDATE 가 자동 에스컬레이션 | 작은 배치로 나누고 ROWLOCK 사용. |
| 인덱스 없는 범위 스캔 | 넓은 갭/범위 락 발생 | 팬텀·교착·성능 저하 | 적절한 인덱스 부재 | 적절한 인덱스 생성, 쿼리 리라이팅 | SELECT * FROM t WHERE col > X (no index) | 인덱스 추가 또는 범위 축소. |
| 장기 트랜잭션 | 락 장기 보유, 버전 누적 | GC 지연·디스크 증가·성능 저하 | 긴 트랜잭션 (대량 작업을 트랜잭션으로 진행) | 트랜잭션 분할, 타임아웃, 커밋 권장 | 대형 배치 트랜잭션이 오랫동안 열려있음 | 배치 당 여러 트랜잭션으로 분할·주기적 커밋. |
| 락 풀/메모리 부족 | 락 할당 실패/에스컬레이션 | 서비스 장애·에러 | 락 수·메모리 한계 초과 | 모니터링, 에스컬레이션 정책 조정, 쿼리 튜닝 | 대량 동시 업데이트로 락 급증 | 쿼리 개선·메모리 설정·에스컬레이션 튜닝. |
잠금 안티패턴 분류와 대응
운영·설정 (Operational)
운영·설정 문제는 DB 설정 (에스컬레이션 정책, 타임아웃, 락 메모리) 과 운영 관행 (대형 트랜잭션 배치, 모니터링 부재) 에서 기인한다.
문제 / 결과 / 원인 / 해결책
- 문제: 예기치 않은 lock escalation, 오래 걸리는 배치로 전체 서비스 정체.
- 결과: 폭넓은 블로킹, 높은 지연, 서비스 장애 가능.
- 원인: 기본 에스컬레이션 임계치 초과, 배치 크기·동시성 고려 부족.
- 해결책: 배치 분할, 파티셔닝, 에스컬레이션 정책 검토 (예: SQL Server 힌트·옵션), 모니터링·알림 구성.
예시 (발생)
- 대량 UPDATE 한 번에 실행 → 수천 행 락 → 자동 에스컬레이션 → 테이블 락 → 서비스 블록.
예시 (해결 적용)
- 동일 작업을 1000 건 단위 배치로 나누고, 각 배치 후 커밋. 필요 시 파티셔닝을 통해 단일 파티션만 잠기게 설계.
| 항목 | 핵심 조치 |
|---|---|
| 원인 | 큰 배치·임계치 초과 |
| 대응 | 배치 분할, 파티셔닝, 에스컬레이션 튜닝 |
- 요약: 운영 설정과 배치 설계가 잘못되면 자동으로 광역 락이 발생하므로 배치·설정·모니터링이 우선이다.
트랜잭션 설계 (Transactional)
트랜잭션 설계 문제는 트랜잭션 길이·순서·격리 수준 선정에서 비롯된다.
문제 / 결과 / 원인 / 해결책
- 문제: 장기 트랜잭션, 불일치한 락 순서, 과도한 격리 수준 지정.
- 결과: 데드락, 긴 락 보유, MVCC 버전 보존 증가.
- 원인: 트랜잭션 안에서 대량 처리·유저 상호작용 허용, 개발자가 리소스 획득 순서 통제 안함.
- 해결책: 트랜잭션 분할, 일관된 자원 접근 순서 (예: ID 오름차순), 가능한 한 낮은 격리 수준 사용, 타임아웃/재시도 로직 도입.
예시 (발생)
- Tx1: UPDATE A → UPDATE B; Tx2: UPDATE B → UPDATE A → 둘 다 기다림 → deadlock.
예시 (해결 적용)
- 모든 트랜잭션에서 리소스 접근을 ID 오름차순으로 고정하고, 큰 작업은 여러 트랜잭션으로 쪼갬.
| 항목 | 핵심 조치 |
|---|---|
| 원인 | 긴 트랜잭션·불일치 순서 |
| 대응 | 분할·일관된 순서·타임아웃 |
- 트랜잭션을 짧고 예측 가능하게 설계하면 데드락과 GC 부담을 크게 줄일 수 있다.
쿼리·인덱스 (Query/Index)
쿼리 패턴과 인덱스가 잠금 범위에 직접적 영향을 준다.
문제 / 결과 / 원인 / 해결책
- 문제: 인덱스 없는 범위 스캔 → 넓은 범위/갭 락 → 팬텀·교착·성능 저하.
- 결과: 불필요한 락 확장, 응답성 악화.
- 원인: WHERE 절에 적절한 인덱스 부재, 비효율 쿼리 작성.
- 해결책: 적절한 인덱스 추가, 쿼리 리라이팅 (범위 축소), 필요한 경우 명시적 잠금 (주의).
예시 (발생)
SELECT * FROM orders WHERE created_at > '2025-01-01'(created_at 에 인덱스 없음) → 전체 인덱스 스캔 → 갭락 확대.
예시 (해결 적용)
- created_at 에 인덱스 추가 또는 날짜 범위를 더 좁혀서 인덱스 스캔이 가능하도록 쿼리 조정.
| 항목 | 핵심 조치 |
|---|---|
| 원인 | 인덱스 부재·비효율 쿼리 |
| 대응 | 인덱스 설계·쿼리 개선 |
- 요약: 인덱스와 쿼리 구조는 잠금 범위를 결정하므로 쿼리 최적화가 근본적 해결책이다.
시스템·자원 (Resource)
락 메모리·락 테이블 등의 시스템 자원 한계와 모니터링 부재에서 오는 문제.
문제 / 결과 / 원인 / 해결책
- 문제: 락 테이블/메모리 한계 초과 → 서비스 에러/에스컬레이션.
- 결과: 장애·성능 악화.
- 원인: 동시 트랜잭션 급증, 비효율 쿼리.
- 해결책: 모니터링 (락 수, 대기 시간), 리소스 한계 조정, 쿼리·배치 튜닝.
예시 (발생)
- 갑작스런 동시 사용자 증가로 락 수 급증 → DB 가 락 메모리 부족 보고.
예시 (해결 적용)
- 모니터링 경보로 원인 쿼리 차단 및 재시도, DB 설정으로 메모리/에스컬레이션 정책 수정.
| 항목 | 핵심 조치 |
|---|---|
| 원인 | 자원 한계·동시성 급증 |
| 대응 | 모니터링·리소스 튜닝 |
- 요약: 시스템 레벨 모니터링과 적절한 설정 없이는 작은 문제도 곧 장애로 이어진다.
잠금 안티패턴 통합 표
| 패턴 | 근본 원인 | 대표 증상 | 즉시조치 | 장기적 대책 |
|---|---|---|---|---|
| 광역 락 남발 | 대형 트랜잭션·잘못된 힌트 | 전체 블로킹 | 배치 중단/작게 나눔 | 파티셔닝·쿼리 재설계 |
| 잠금 순서 불일치 | 랜덤한 자원 접근 순서 | 빈번한 deadlock | 트랜잭션 강제 종료 (재시도) | 접근 순서 표준화 |
| Lock Escalation | 다량 행락 → 임계치 도달 | 갑작스런 테이블 락 | 작업 일시중단·배치 재스케줄 | 배치 작게·힌트/튜닝 |
| 인덱스 없는 범위 스캔 | 인덱스 부재 | 갭 락 확대·팬텀 | 쿼리 중단·임시 인덱스 | 인덱스 설계·쿼리 최적화 |
| 장기 트랜잭션 | 오랜 트랜잭션 | GC 지연·리소스 축적 | 트랜잭션 강제 커밋 | 작업 분할·타임아웃 정책 |
| 락 풀 부족 | 동시성 폭증 | 락 실패·에러 | 일부 트랜잭션 종료 | 모니터링·리소스 증설 |
- 즉시 조치는 서비스 복구를 위한 응급처치, 장기적 대책은 설계·운영 관행 개선과 DBMS 설정 최적화로 귀결된다.
DBMS 락 모드 이전·업그레이드 전략
마이그레이션은 락의 이름이 같은지 아닌지보다 락이 실제로 무엇을 막고 보장하는지를 맞추는 작업이다.
- 먼저 현재 시스템이 어떤 락을 언제 어떻게 얻는지 (실제 트랜잭션 로그·모니터링으로) 확인한다.
- 다음으로 대상 DBMS 의 동작과 비교해 ’ 동일한 보호 수준 ’ 을 보장하도록 매핑하고, 단위·부하 테스트로 실제 동작을 확인한다.
- 문제가 발견되면 애플리케이션 (트랜잭션 길이 조정, 재시도 로직) 또는 DB 설정 (에스컬레이션 임계값, 타임아웃) 으로 보완한다.
- 최종적으로는 단계적 전환 (파일럿→확대) 과 운영 모니터를 통해 안전하게 전환한다.
마이그레이션 단계별 체크리스트
| 단계 | 주요 작업 | 산출물 (Deliverable) | 주요 리스크 | 완화책 |
|---|---|---|---|---|
| 1. 현황 수집 (Discovery) | 트랜잭션·락 로그 수집, 주요 쿼리 식별 | 사용중인 락·격리 목록, 대표 트랜잭션 집합 | 누락된 케이스로 인한 미검증 | 운영기간 로그 수집, 핵심 트랜잭션 우선순위화 |
| 2. 세멘틱 매핑 | 모드별 의미 문서화 및 대상 DBMS 매핑표 작성 | 세멘틱 매핑표 (행동 기준) | 이름 기반 오매핑 | 행동 (예: 삽입 방지 여부) 기준 매핑 |
| 3. 단위 테스트 | 데드락·승격·범위 삽입 시나리오 실행 | 단위 테스트 결과 리포트 | DB 내부 구현 차이 발견 | 테스트 케이스 보강, 애플리케이션 수정안 도출 |
| 4. 부하·호환성 테스트 | 실제 동시성으로 벤치 (스트레스) | 벤치 결과 (처리량·대기·데드락) | 성능 저하·예상외 에스컬레이션 | 임계값 튜닝·쿼리/인덱스 최적화 |
| 5. 파일럿/Canary | 일부 트래픽 전환 (부분 서비스) | 모니터링 대시보드, 문제 리포트 | 실서비스 영향 | 빠른 롤백 경로·페일오버 정책 |
| 6. 전면 전환 | 전체 트래픽 전환, 모니터링 강화 | 전환 완료 리포트 | 운영 이슈 확산 | 단계별 롤아웃, 긴급 롤백 플랜 |
| 7. 운영·튜닝 | 지속 모니터링, 지표 기반 튜닝 | 운영 SOP, 튜닝 파라미터 | 장기적 성능 저하 | 정기 리뷰, 자동 알람/대응 playbook |
- 핵심: 마이그레이션은 " 분석 → 매핑 → 검증 → 파일럿 → 전환 → 모니터링 " 의 순서로 진행해야 실패 확률이 낮다.
- 중요 포인트: 이름 (예: SIX, U) 은 참고용일 뿐이고, 실제로는 그 락이 어떤 동작 (읽기 보호, 삽입 방지, 범위 잠금 등) 을 하는지를 기준으로 대상 DBMS 에서 같은 동작을 보장하도록 매핑해야 한다.
- 운영 팁: 전환 초반엔 락 대기·데드락 빈도를 집중 감시하고, 에스컬레이션 임계값·타임아웃·VACUUM(GC) 같은 DB 고유 파라미터를 조정할 준비를 해 둬야 한다.
실무 적용 및 사례
실습 예제 및 코드 구현
실습 예제: Python 과 SQLite 를 활용한 Shared/Exclusive Lock 체험
목적
- 락 모드의 실시간 동작을 확인하고 병렬 트랜잭션 환경에서 데이터 일관성을 점검
사전 요구사항
- Python, sqlite3, threading, time 라이브러리
단계별 구현
1 단계: 데이터베이스 생성 및 샘플 데이터 삽입
2 단계: 병렬 트랜잭션 및 Lock 동작 구현
| |
실행 결과
- 배타 락 (EXCLUSIVE) 동작 시 다른 트랜잭션의 Read(공유락) 대기 발생 여부 확인
추가 실험
- 여러 Thread 에서 동시에 Update, Read 시도 (Deadlock, Dirty Read 탐지)
실습 예제: Lock Mode 호환성 매트릭스 실험
목적
- 다양한 Lock Mode 간 호환성 규칙을 실제로 확인
- SIX 락과 같은 고급 모드의 동작 이해
단계별 구현
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 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 108import pyodbc import threading import time from concurrent.futures import ThreadPoolExecutor, as_completed class LockCompatibilityTester: def __init__(self, connection_string): self.connection_string = connection_string def execute_with_lock(self, sql_command, lock_hint="", session_name=""): """특정 잠금 힌트로 SQL 실행 및 잠금 상태 반환""" try: conn = pyodbc.connect(self.connection_string) cursor = conn.cursor() # 트랜잭션 시작 cursor.execute("BEGIN TRANSACTION") # 잠금이 포함된 SQL 실행 full_sql = f"SELECT * FROM LockTestTable WITH ({lock_hint}) WHERE ID = 1" start_time = time.time() cursor.execute(full_sql) # 잠금 정보 조회 cursor.execute(""" SELECT request_mode, request_status FROM sys.dm_tran_locks WHERE request_session_id = @@SPID AND resource_type = 'KEY' """) lock_info = cursor.fetchall() execution_time = time.time() - start_time # 5초 대기 (다른 세션과의 상호작용 관찰용) time.sleep(5) cursor.execute("ROLLBACK TRANSACTION") conn.close() return { 'session': session_name, 'lock_hint': lock_hint, 'lock_mode': lock_info[0][0] if lock_info else 'NONE', 'status': lock_info[0][1] if lock_info else 'NONE', 'execution_time': execution_time, 'success': True } except Exception as e: return { 'session': session_name, 'lock_hint': lock_hint, 'error': str(e), 'success': False } def test_compatibility(self, lock_combinations): """여러 잠금 조합의 호환성 테스트""" results = [] with ThreadPoolExecutor(max_workers=len(lock_combinations)) as executor: # 동시 실행을 위한 Future 객체 생성 future_to_lock = { executor.submit( self.execute_with_lock, "SELECT", lock_combo['hint'], lock_combo['name'] ): lock_combo for lock_combo in lock_combinations } # 결과 수집 for future in as_completed(future_to_lock): result = future.result() results.append(result) return results # 호환성 테스트 실행 if __name__ == "__main__": # 연결 문자열 (실제 환경에 맞게 수정) conn_str = "Driver={SQL Server};Server=localhost;Database=TestDB;Trusted_Connection=yes;" tester = LockCompatibilityTester(conn_str) # 테스트할 잠금 조합 test_combinations = [ {'name': 'Session_S', 'hint': 'HOLDLOCK'}, # Shared {'name': 'Session_U', 'hint': 'UPDLOCK'}, # Update {'name': 'Session_X', 'hint': 'XLOCK'}, # Exclusive {'name': 'Session_IS', 'hint': 'HOLDLOCK, TABLOCK'} # Intent Shared ] # 동시 실행 및 결과 분석 results = tester.test_compatibility(test_combinations) # 결과 출력 print("=== Lock Compatibility Test Results ===") for result in sorted(results, key=lambda x: x.get('execution_time', 999)): if result['success']: print(f"Session: {result['session']}") print(f" Lock Mode: {result['lock_mode']}") print(f" Status: {result['status']}") print(f" Execution Time: {result['execution_time']:f}s") else: print(f"Session: {result['session']} - ERROR: {result['error']}") print()2 단계: 호환성 매트릭스 검증
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17-- 표준 호환성 매트릭스 검증 스크립트 WITH LockCompatibility AS ( SELECT 'S' as Mode1, 'S' as Mode2, 'Compatible' as Result UNION ALL SELECT 'S', 'X', 'Incompatible' UNION ALL SELECT 'S', 'U', 'Compatible' UNION ALL SELECT 'X', 'S', 'Incompatible' UNION ALL SELECT 'X', 'X', 'Incompatible' UNION ALL SELECT 'X', 'U', 'Incompatible' UNION ALL SELECT 'U', 'S', 'Compatible' UNION ALL SELECT 'U', 'X', 'Incompatible' UNION ALL SELECT 'U', 'U', 'Incompatible' ) SELECT Mode1 + ' vs ' + Mode2 as Lock_Combination, Result as Expected_Compatibility FROM LockCompatibility ORDER BY Mode1, Mode2;
실습 예제: 키 - 레인지 락 관찰 (PostgreSQL & MySQL)
목적
- 격리 수준에 따른 팬텀/블로킹 차이를 체감하고, 인덱스가 Range/GAP 에 미치는 영향을 확인.
사전 요구사항
- PostgreSQL 15+ 또는 MySQL 8+
단계별 구현
스키마 준비
세션 A (Serializable/Repeatable Read)
세션 B (동시 변경 시도)
관찰
실행 결과
- Serializable/Repeatable Read 에서 세션 B 가 대기 또는 충돌.
추가 실험
- 인덱스 제거 후 범위 질의 → Range/GAP 범위 확대 및 대기 증가.
실제 도입 사례 분석
실제 도입 사례: Stack Overflow 데이터베이스 최적화
배경 및 도입 이유
Stack Overflow 는 수백만 명의 사용자가 동시 접근하는 Q&A 플랫폼으로, 높은 동시성과 데이터 일관성이 핵심 요구사항이었다.
기존의 단순한 테이블 수준 잠금으로는 다음 문제가 발생했다:
- 동시성 병목: 답변 작성 시 전체 질문 테이블 잠금
- 데드락 빈발: 투표와 댓글 작성의 순환 대기
- 성능 저하: 대용량 검색 쿼리가 전체 시스템 블로킹
해결 목표: 동시 사용자 10 배 증가 대응, 응답 시간 50% 단축
구현 아키텍처
graph TB
subgraph "Before: Table-level Locking"
A1[Question Table] --> A2[Full Table Lock]
A3[Answer Insert] --> A2
A4[Vote Update] --> A2
A5[Search Query] --> A2
end
subgraph "After: Hierarchical Lock Modes"
B1[Question Table] --> B2[IS/IX Intent Locks]
B3[Row-level S/X Locks] --> B2
B4[Answer Insert] --> B5[IX → X conversion]
B6[Vote Update] --> B7[U → X conversion]
B8[Search Query] --> B9[S locks only]
end
A1 -.upgrade.-> B1
핵심 설계 결정:
- Question 테이블: SIX 락으로 대량 읽기 + 선택적 수정
- Answer 테이블: 행 단위 IX/X 락으로 최대 동시성
- Vote 테이블: Update 락으로 데드락 방지
핵심 구현 코드
| |
| |
| |
성과 및 결과
정량적 성과:
- 동시 접속 처리량: 50,000 → 500,000 동시 사용자 (10 배 증가)
- 평균 응답 시간: 850ms → 420ms (51% 단축)
- 데드락 발생률: 일 평균 150 건 → 15 건 (90% 감소)
- Lock 관련 대기 시간: 전체 쿼리 시간의 15% → 3% (80% 감소)
정성적 개선:
- 사용자 경험: 답변 작성 중 다른 사용자의 질문 조회 차단 해소
- 운영 안정성: 피크 시간대 시스템 블로킹 현상 근절
- 확장성: 트래픽 증가에 따른 선형적 성능 확장 가능
교훈 및 시사점
재현 시 유의점:
- 점진적 적용: 전체 시스템 한번에 변경하지 말고 핵심 테이블부터 단계적 적용
- 모니터링 강화:
sys.dm_tran_locks,sys.dm_os_wait_stats지속 관찰 필요 - 테스트 환경: 프로덕션과 동일한 부하 조건에서 성능 테스트 필수
대안 접근법:
- MVCC 도입: PostgreSQL 스타일의 다중 버전 동시성 제어
- 읽기 전용 복제본: 조회 트래픽 분산으로 쓰기 잠금 부담 감소
- 캐싱 계층: Redis 를 활용한 자주 조회되는 데이터의 DB 접근 최소화
확장 아이디어:
- 머신러닝 기반 Lock Mode 선택: 쿼리 패턴 분석으로 최적 잠금 모드 자동 추천
- 분산 잠금: 마이크로서비스 환경에서 서비스 간 분산 잠금 메커니즘 구현
동시성 제어 통합 기술 아키텍처
- 핵심 아이디어: 락은 ’ 누가 지금 쓰는가 ’ 를 통제한다. 하지만 락만으로 모든 문제 (성능·확장성) 를 해결하긴 어렵다. 그래서 버전 (스냅샷), 애플리케이션 레벨 낙관적 검사, 분산 코디네이션, 메시지 기반 분해 같은 기술을 조합한다.
- 결론 비유: 락은 ’ 문을 잠그는 열쇠 ‘, MVCC 는 ’ 방 안에 과거 사진을 두는 것 ‘, 낙관적 잠금은 ’ 먼저 들어가서 작업하고 퇴실 시 확인 ‘, 분산 락은 ’ 건물 전체의 출입통제 시스템 ’ 이다. 상황에 맞는 조합이 핵심이다.
왜 통합하는가
- 단일 기법만으로는 트레이드오프를 완전 해소할 수 없음: 락은 일관성에 강하나 성능·확장성에서 불리, MVCC 는 읽기 성능에 유리하나 일부 직렬화 이상은 검출·해결 필요. 따라서 서로 장단점을 보완하기 위해 통합한다.
무엇을 통합하는가
- MVCC + Lock Modes: 읽기는 버전으로, 쓰기는 필요 시 락으로 보강.
- Optimistic Locking + DB Lock: 애플리케이션 레벨 버전 체크로 대부분 케이스를 낙관 처리, 충돌 시 DB 락/재시도.
- Snapshot Isolation (row-versioning): 읽기 격리 확보 (READ_COMMITTED_SNAPSHOT), 락 경쟁 감소.
- 분산 Lock + Local Lock: 노드간 글로벌 코디네이션 (ZooKeeper/etcd/Redis) + 노드 내부의 세밀한 DB 락.
- Messaging / Saga / CQRS: 긴 단위 트랜잭션을 이벤트로 분해해 로컬 ACID + 보상으로 처리.
어떻게 통합하는가
- 계층적 결합: 애플리케이션 (optimistic/versioning) → DB(MVCC + selective locks) → 인프라 (distributed lock/fencing) → 아키텍처 (messaging/saga) 식으로 역할 분담.
얻는 가치
- 성능 극대화: 읽기 -heavy 워크로드는 MVCC/스냅샷으로 락 경합 감소.
- 일관성/무결성 유지: 필요한 지점에서만 강한 락 또는 분산 코디네이션을 사용해 데이터 무결성 확보.
- 확장성/가용성: 글로벌 락을 최소화하고 로컬 트랜잭션을 우선시하면 노드 수를 늘려도 확장성 확보.
- 운영 유연성: 워크로드 특성에 따라 동적 조합 (예: read-heavy → snapshot on; write-heavy → pessimistic where needed).
Lock Modes 연계 기술 통합 요약
| 결합 기술 | 주된 역할 | 통합 방식 (실무) | 기대 효과 |
|---|---|---|---|
| MVCC (Postgres 등) | 읽기 경합 완화 | 읽기는 스냅샷, 쓰기는 필요 시 락 보강 | 읽기 처리량 증가, 읽기→쓰기 충돌 감소. |
| Optimistic Locking | 애플리케이션 수준 충돌 감지 | 버전 필드 (CAS) + 실패 시 재시도/보정 | 락 오버헤드 감소, 낮은 충돌 워크로드에 유리. |
| Snapshot Isolation | 버전 기반 읽기 일관성 | READ_COMMITTED_SNAPSHOT 등 설정 | 읽기 락 경쟁 제거 (옵션기반). |
| Distributed Locking | 노드 간 상호배제 | ZooKeeper/etcd (강일관) or Redis(경량) + fencing | 글로벌 일관성 보장, 장애 시 안전성 확보. |
| Messaging / Saga / CQRS | 장기 트랜잭션 분해 | 이벤트·명령 기반 로컬 트랜잭션 + 보상 | 장기 락 회피, 복잡한 분산 트랜잭션 처리. |
위 표는 실무에서 흔히 쓰이는 결합 패턴과 기대 효과를 요약한다. 각 결합은 워크로드 특성(읽기/쓰기 비율, 트랜잭션 길이, 분산 정도) 에 따라 선택/조정해야 한다.
최종 정리 및 학습 가이드
내용 종합
핵심 기능
락 모드는 동시 접근을 제어해 일관성을 보장하는 기본 수단이다. S 는 읽기 공유, X 는 배타적 갱신, U 는 읽은 후 갱신할 가능성이 있는 경우 데드락을 줄이기 위한 중간 모드다. Intent 는 계층적 리소스 (테이블→페이지→행) 에서 하위 락 존재를 빠르게 알려주는 시그널 역할을 한다.범위·팬텀 제어
인덱스 스캔이나 범위 쿼리에서는 단순 행 락으로 팬텀이 제어되지 않으므로 gap/next-key/predicate 같은 범위 락 또는 SSI(직렬화 스냅샷 검사) 같은 대체 기법이 필요하다. 구현 방식에 따라 성능과 복잡성이 달라진다.대안 및 혼용
MVCC 는 읽기와 쓰기 간 충돌을 줄여 고동시성을 제공하지만 버전 관리·GC 비용이 생긴다. 낙관적 (충돌 후 재시도) 과 비관적 (락에 의한 직권) 방식은 워크로드 특성에 따라 선택하거나 혼합해서 쓴다.운영·모니터링
실무에서는 데드락 빈도, 평균 락 대기시간, 락 확대 이벤트, lock table 사용률 등을 모니터링한다. 문제 발견 시 트랜잭션 분해, 쿼리·인덱스 개선, 파티셔닝, MVCC 전환 등을 계획한다.표준 vs 구현
ANSI/ISO 는 격리 수준의 기대 동작 (예: SERIALIZABLE 은 팬텀 방지) 을 규정하지만 실제로 이를 달성하기 위한 메커니즘은 DBMS 마다 다르므로 표준 (what) + 엔진 문서 (how) + 실무 테스트가 필수다.하드웨어·아키텍처 영향
락 테이블은 메모리를 사용하고 스핀락·뮤텍스는 CPU 캐시 구조에 민감하다. NUMA 나 캐시라인 경쟁을 고려하지 않으면 락 경쟁이 성능 병목으로 확대된다.
실무 적용 가이드
| 단계 | 핵심 액션 | 예시 쿼리/도구 (템플릿) | 성공 기준 (가이드라인) | 주의사항 |
|---|---|---|---|---|
| 1. 현황 분석 | 동시 사용자·트랜잭션 패턴 파악 | SQL Server: SELECT * FROM sys.dm_exec_requests WHERE blocking_session_id<>0;Postgres: pg_locks 기반 블로커 쿼리 (아래 예시)MySQL: SHOW ENGINE INNODB STATUS\G | 블로킹 세션 비율·평균 대기시간 수치화 | 수집기간 (최소 24–72 시간) 확보 |
| 1. 데드락 진단 | 최근 데드락 트레이스 수집 | SQL Server: Extended Events / sys.dm_os_ring_buffersMySQL: SHOW ENGINE INNODB STATUS | 원인 쿼리 목록 작성 (상위 10) | 데드락 victim 패턴 분석 필요 |
| 2. 최적화 계획 | 격리 수준·인덱스·트랜잭션 설계 | 적용 전 A/B 테스트: 스테이징 재현 | 평균 락 대기 20–50% 개선 목표 | Serializable 도입은 신중 (충돌·abort 증가) |
| 2. 락 승격/파티셔닝 | 승격 임계·파티셔닝 정책 수립 | DBMS 정책 확인·테스트 | 승격으로 인한 테이블 락 빈도 감소 | 승격 방지 위해 쿼리 리팩토링 |
| 3. 모니터링 구축 | 실시간 블로킹 감지·알림 | Prometheus + Grafana, 또는 DBMS 내 Performance Schema/DMV | 알림 응답 (예: 5 분 이내) SLAs 정의 | 알림 소음 최소화 (중요도 분류) |
| 3. 자동대응 | Head blocker 탐지 스크립트 | 예: blocker → 알림 → (검증 후) KILL 스크립트 (인증·로그 남김) | 수동介入률 감소, 평균 회복시간 단축 | 자동 kill 은 권한·검증 필요 |
| 4. 고도화 | 분산락/메시징/Saga 적용 검토 | ZooKeeper/etcd/Redis, 메시지큐 (Kafka/RabbitMQ) | 긴 트랜잭션 수 감소, 확장성 개선 | 아키텍처 복잡성 증가 |
| 운영 (Timetable) | 일/주/월 점검 루틴 | 일별 블로킹 리포트, 주간 승격 분석 | 정량적 KPI 달성 여부 | 리포트 자동화 권장 |
학습 로드맵
| 단계 | 기간 (권장) | 목표 | 주요 주제 | 실무 연관성 | 권장 실습 |
|---|---|---|---|---|---|
| 기초 | 0–2 개월 | 기본 개념 숙지 | ACID, S/X/U, 호환성, 2PL | 트랜잭션 설계의 기초 | 블로킹 재현, DMV 조회 |
| 주요 원리 | 2–6 개월 | 내부 동작·트레이드오프 이해 | Intent, Upgrade/Downgrade, Range/Gap | 대규모 수정·동시성 설계 | 업그레이드 경쟁 재현, gap 예제 |
| 실무구현 | 6–12 개월 | DB 별 구현·모니터링 습득 | Postgres/InnoDB/SQLServer 뷰·동작 | 운영 진단·대응 능력 | Deadlock 캡처, Grafana 대시보드 |
| 응용/트렌드 | 12–24 개월 | MVCC/하이브리드 설계 | MVCC vs 2PL/SSI, Snapshot 문제 | 리포팅·정산 일관성 설계 | 장기 트랜잭션 실험 |
| 최적화/고급 | 2 년 + | 분산/최신 기법 적용 | 분산 락, lock-free, ML 튜닝 | 분산 시스템 일관성 전략 | etcd/Redis 레드락 실험 |
학습 항목 정리
| 단계 | 항목 | 중요도 | 학습 목표 | 실무 연관성 | 설명 |
|---|---|---|---|---|---|
| 기초 | S/X/U Lock 개념 | 필수 | 기본 잠금 모드 이해 | 높음 | 공유/배타/업데이트 락의 역할과 호환성 |
| 기초 | 호환성 매트릭스 | 필수 | 충돌 예측 능력 | 높음 | 어떤 모드가 동시에 가능한지 판정 |
| 기초 | 2PL 프로토콜 | 필수 | 직렬화 보장 원리 | 높음 | 락 획득·해제 규칙 (2 단계) 이해 |
| 주요 원리 | Intent Locks (IS/IX/SIX) | 필수 | 계층적 충돌 감지 | 높음 | 상위 - 하위 락 협력 메커니즘 |
| 주요 원리 | Lock Escalation | 필수 | 메모리 vs 동시성 트레이드오프 | 높음 | 행→테이블 승격 시 영향 이해 |
| 주요 원리 | Range/Gap Locks | 권장 | 팬텀 방지 메커니즘 | 중간 | 인덱스 기반 범위 잠금 이해 |
| 실무구현 | DBMS 별 락 구현 | 필수 | Postgres/InnoDB/SQLServer 차이 | 높음 | 각 DB 의 구현·관찰 방법 습득 |
| 실무구현 | 모니터링·대시보드 | 필수 | 문제 탐지·알림 체계 구성 | 높음 | Prometheus/Grafana 연동 실습 |
| 응용 | MVCC 통합 | 권장 | 읽기 성능 vs 정합성 균형 | 중간 | MVCC 동작과 한계 파악 |
| 응용 | 장기 트랜잭션 영향 | 권장 | 성능·버전 증가 영향 분석 | 중간 | Snapshot 오래 유지 시 문제점 분석 |
| 고급 | 분산 잠금 | 권장 | 서비스 간 조정 설계 | 중간 | ZooKeeper/etcd/Redis 사용법 실습 |
| 고급 | Lock-free 자료구조 | 선택 | 고성능 동시성 기법 이해 | 낮음 | 연구·특화시스템 적용 가능성 탐색 |
| 고급 | 적응형 튜닝 (ML) | 선택 | 자동 튜닝 기법 탐색 | 낮음 | 연구·실험 영역 |
용어 정리
| 카테고리 | 용어 (한글 (영어, 약어)) | 정의 | 관련 개념 | 실무 활용 |
|---|---|---|---|---|
| 핵심 | 잠금 모드 (Lock Mode) | 자원에 대한 접근 권한의 분류 (읽기/쓰기/업데이트 등) 으로, 다른 트랜잭션과의 호환성 규칙을 포함. | 트랜잭션, 격리 수준, 호환성 매트릭스 | 동시성 정책 설계, 쿼리 힌트 해석 |
| 핵심 | 공유 잠금 (Shared Lock, S) | 다수의 트랜잭션이 동시에 읽을 수 있게 허용하되 쓰기는 차단하는 잠금. | 읽기 - 읽기 호환성, S/S 허용 | 빈번한 읽기 워크로드 처리 |
| 핵심 | 배타 잠금 (Exclusive Lock, X) | 해당 자원에 대해 단독 접근을 허용. 다른 모든 잠금과 비호환. | 쓰기보호, Lost Update 방지 | INSERT/UPDATE/DELETE 보호 |
| 핵심 | 업데이트 잠금 (Update Lock, U) | 읽기 후 쓰기 가능성이 있는 경우 사용되는 중간형 잠금 (데드락 완화 목적). | S → X 승격, 데드락 예방 | SELECT … FOR UPDATE, 업데이트 준비 |
| 구조 | 의도 잠금 (Intent Lock, IS/IX/SIX) | 상위 (테이블 등) 자원에 하위 (행) 잠금 의도를 표시해 다중그레인 (계층) 충돌 판정 효율화. | Multiple Granularity, 호환성 매트릭스 | 테이블/행 혼합 액세스에서 성능 보장 |
| 구조 | 락 그레인 (Granularity) | 잠금 단위 (데이터베이스/테이블/페이지/행/키 등). 단위가 작을수록 동시성↑·오버헤드↑. | 락 에스컬레이션, 성능 트레이드오프 | 설계 시 단위 결정 (OLTP vs 배치) |
| 구조 | 범위 락 (Range/Gap/Next-key/Predicate Lock) | 인덱스 키 범위나 조건 범위를 잠궈 팬텀 (Phantom) 을 방지하는 잠금 계열. | Phantom Read, Serializable | 범위 쿼리 동시성 제어, 인덱스 설계 중요 |
| 구조 | 스키마 락 (Schema Lock) | DDL(스키마 변경) 시 구조 안정성을 위해 걸리는 잠금. | DDL, 스키마 버전 | 테이블 변경 시 안전 확보 |
| 응용 | 락 호환성 매트릭스 (Lock Compatibility) | 각 잠금 모드 조합의 허용/차단 여부를 표로 정리한 규칙. | S/X/U/IS/IX 규칙 | 동시성 예측·락 충돌 판단 |
| 응용 | 락 에스컬레이션 (Lock Escalation / Promotion) | 세부 단위 잠금이 많아지면 상위 단위 (행→테이블) 로 묶는 자동/수동 전환. | 메모리 절약 vs 동시성 손실 | 배치 설계·에스컬레이션 튜닝 |
| 응용 | 블로킹 (Blocking) | 자원 점유로 인해 다른 트랜잭션이 대기 상태가 되는 현상. | Head blocker, wait chain | 성능 진단 (대기 시간 감소) |
| 응용 | 데드락 (Deadlock) | 순환적 자원 대기로 인해 트랜잭션이 서로를 기다리는 상태 (자동 희생자 선정해 롤백). | Deadlock graph, victim selection | 트랜잭션 설계·로그 분석 |
| 응용 | 락 타임아웃 (Lock Timeout) | 대기 제한시간 설정으로 장기 대기 시 예외 발생·재시도 유도. | 타임아웃 정책 | 사용자 응답성 보장, 재시도 로직 |
| 최적화 | MVCC (Multi-Version Concurrency Control) | 버전 기반 동시성 제어로 읽기와 쓰기를 분리해 읽기 성능을 높이는 방식 (락 최소화). | Snapshot Isolation, SSI | 읽기 중심 시스템, PostgreSQL/MySQL InnoDB 적용 |
| 최적화 | 낙관적 동시성 (Optimistic OCC) | 실행 중 충돌 검증을 커밋 시점에 수행하고 충돌 시 재시도하는 방식. | 재시도 비용, 충돌 확률 | 충돌이 드문 쓰기 환경에서 유리 |
| 진단 | 락 풀 / 락 테이블 (Lock Pool/Table) | DBMS 가 관리하는 잠금 레코드 저장 구조; 한계 초과 시 에러/에스컬레이션 유발. | 리소스 한계, 모니터링 | 용량 계획·메트릭 경보 |
| 진단 | 대기 그래프 / 락 그래프 (Wait-for Graph) | 세션들 간의 대기 관계를 그래프로 표현해 데드락 원인 분석에 사용. | Deadlock detection | 데드락 원인 추적·디버깅 |
| 진단 | 모니터링 이벤트 (Lock Events / XE / Performance Counters) | 락 획득·해제·대기 정보를 수집하는 감사·성능 추적 기능. | Extended Events, INFORMATION_SCHEMA | 운영 모니터링·사후 분석 |
참고 및 출처
- PostgreSQL 문서 — Transaction Isolation
- MySQL 8.0 Reference — InnoDB Locking
- Microsoft Learn — SQL Server: Transaction locking and row versioning guide
- PostgreSQL 문서 — MVCC (Concurrency Control)
- Oracle — Data Concurrency and Consistency (Oracle Database 19c)
- How Stack Overflow Caches Apps for a Multi-Tenant Architecture
- CockroachDB — GitHub 저장소 (cockroach)
- TiDB — GitHub 저장소 (tidb)
- PostgreSQL — GitHub 저장소 (postgres)
- Plan Explorer — SentryOne
- SQL Server Management Studio (SSMS) — Microsoft Learn
- Extended Events — SQL Server (Microsoft Learn)
- Datadog — Database Monitoring
- IBM DB2 — Lock modes and compatibility of locks
- GeeksforGeeks — Implementation of Locking in DBMS
- Alooba — Locks (개념 정리)
- TUM — Scalable concurrency control methods (PDF)
- AWS Database Blog — Improve PostgreSQL performance: Diagnose and mitigate lock manager contention