PostgreSQL

PostgreSQL: Lock

dewstream 2025. 6. 24. 08:00
728x90

※ PostgreSQL: Lock.

 

안녕하세요. 듀스트림입니다.

 

오늘은 드디어 Lock에 관한 내용입니다.


1. PostgreSQL Lock 처리 구조

PostgreSQL에서 Lock은 내부적으로 LockManager에 의해 관리되며 동시성 제어, 무결성 보장, 데이터 경합 제어에 사용됩니다.

Lock 흐름도


주요 함수 설명

단계 함수 설명 소스 코드
1 LockAcquire() 사용자가 요청한 Lock을 획득하는 진입점 lock.c#L1024
2.1 SetupLockInTable() Lock Tag에 해당하는 LOCK과 PROCLOCK 초기화 lock.c#L1157
2.1.1 GetLockHashPartition() Lock Tag에 따라 Hash 파티션 결정 lock.c#L809
2.1.2 LockLookup() 이미 존재하는 Lock 객체가 있는지 탐색 lock.c#L1386
2.1.3 InitLock() Lock 객체가 없을 경우 초기화 lock.c#L1433
2.1.4 InitProcLock() PGPROC과 LOCK을 연결하는 PROCLOCK 초기화 lock.c#L1473
2.2 LockCheckConflicts() 기존 Lock들과의 충돌 여부 판단 lock.c#L1909
2.2.1 CheckConflicts() Conflict 매트릭스와 상태를 비교 lock.c#L1966
2.3 GrantLock() Lock 충돌이 없으면 현재 PGPROC에 Lock 부여 lock.c#L1870
2.4 WaitOnLock() 충돌 시 대기 큐 등록 및 슬립 lock.c#L1994
2.4.1 ProcSleep() 해당 PGPROC을 대기 큐에 추가 및 sleep proc.c#L1604
2.4.2 CheckDeadLock() 대기 중 deadlock 탐지 deadlock.c#L400
3 ReleaseLock() Lock을 해제하고, 다음 대기자에게 Grant lock.c#L2623
3.1 ProcWakeup() 대기 중인 프로세스에게 wakeup signal proc.c#L1821

2. Lock과 MVCC의 상호작용

MVCC는 snapshot을 통해 대부분의 SELECT를 non-blocking으로 처리하지만 다음의 경우 Lock이 반드시 필요합니다.

유형 설명
DML (UPDATE/DELETE) 튜플에 대한 row-level lock 필요
DDL (ALTER, DROP) access exclusive lock
Serializable TX predicate lock 사용
SELECT FOR UPDATE tuple-level exclusive lock 발생
Row-level Lock은 pg_locks에 표시는 되지만 식별 가능한 방식으로 자세히 나오지는 않습니다.
이유는 힙 페이지의 tuple 헤더(t_infomask)에 직접 표시되기 때문입니다.
관련 함수: heap_lock_tuple()

+ pg_locks 뷰는 PostgreSQL 내부의 Shared Memory에 존재하는 Shared Lock Table의 내용을 조회하는 시스템 뷰입니다.

3. Lock 내부 구조체

구조체 역할 위치
LOCKTAG 어떤 객체에 Lock을 거는지 정의 src/include/storage/lock.h
LOCK Lock 대상 객체에 대한 전체 Lock 상태 src/include/storage/lock.h
PROCLOCK 특정 PGPROC이 가진 LOCK 상태 src/include/storage/lock.h
PGPROC 프로세스 정보 및 대기 큐 정보 포함 src/include/storage/proc.h
PGXACT 트랜잭션 레벨 정보 (xmin 등) src/include/storage/pgxact.h

4. Lock 종류별 정리 및 예시

종류 주요 함수 설명
Table Lock LockAcquire 테이블 단위
Row Lock heap_lock_tuple 튜플 단위
Advisory Lock pg_advisory_lock 사용자 정의
Predicate Lock predicate.c Serializable용
Internal Lock LWLock, WALLock 등 시스템 보호용

Table Lock 예시: 다른 트랜잭션 SELECT 불가

 


Row Lock 예시: 다른 트랜잭션에서 동일 row FOR UPDATE, UPDATE 시 대기


5. Lock Modes

5.1 Conflicting Lock Modes

  ACCESS
SHARE
ROW
SHARE
ROW
EXCL.
SHATRE
UPDATE
EXCL.
SHARE SHARE
ROW
EXCL.
EXCL. ACCESS
EXCL.
ACCESS
SHARE

             
ROW
SHARE

           
ROW
EXCL.

       
SHARE
UPDATE
EXCL.
     
SHARE


     
SHARE
ROW
EXCL.
   
EXCL.


 
ACCESS
EXCL.


5.2 Conflicting Row-Level Locks

  FOR KEY SHARE FOR SHARE FOR NO KEY UPDATE FOR UPDATE
FOR KEY SHARE      
FOR SHARE    
FOR NO KEY UPDATE  
FOR UPDATE

 

13.3. Explicit Locking

13.3. Explicit Locking # 13.3.1. Table-Level Locks 13.3.2. Row-Level Locks 13.3.3. Page-Level Locks 13.3.4. Deadlocks 13.3.5. Advisory Locks PostgreSQL provides various …

www.postgresql.org


6. Lock 관련 파라미터

파라미터 설명 기본값
deadlock_timeout Deadlock 감지 주기 1s
lock_timeout 쿼리 대기 최대 시간 0 (무제한)
max_locks_per_transaction 트랜잭션당 최대 Lock 수 64

+ 락 체크 방법은 아래 포스팅 참고 부탁드립니다.

 

PostgreSQL: 락 체크 쿼리

※ PostgreSQL: Lock check query. 안녕하세요. 듀스트림입니다. 운영용 쿼리에 대한 문의가 많아서 하나씩 올려보겠습니다.이번 포스팅은 테이블에 걸린 락과 락, 홀더를 확인 할 수 있는 쿼리입니다.1

dewstream.tistory.com

 

++ 팁을 드리자면

  1. 모니터링 잘하시고..
  2. 가능한 한 Lock Hold Time 줄이기
  3. SELECT FOR UPDATE는 WHERE 절로 범위 최소화
  4. DDL 수행 시 트래픽 분산 시간에 수행
  5. 적절한 lock_timeout, deadlock_timeout 설정
  6. Advisory Lock은 범용 로직에만 제한적으로 사용

오늘은 여기까지~

 

728x90

'PostgreSQL' 카테고리의 다른 글

PostgreSQL: io_combine_limit  (0) 2025.07.01
PostgreSQL: Partition  (4) 2025.06.26
PostgreSQL: credcheck  (0) 2025.06.17
PostgreSQL: Disk I/O 및 WAL 흐름  (0) 2025.06.11
PostgreSQL: Streaming Replication  (0) 2025.06.10