728x90
※ PostgreSQL: Lock.
안녕하세요. 듀스트림입니다.
오늘은 드디어 Lock에 관한 내용입니다.
1. PostgreSQL Lock 처리 구조
PostgreSQL에서 Lock은 내부적으로 LockManager에 의해 관리되며 동시성 제어, 무결성 보장, 데이터 경합 제어에 사용됩니다.

주요 함수 설명
| 단계 | 함수 | 설명 | 소스 코드 |
| 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
++ 팁을 드리자면
- 모니터링 잘하시고..
- 가능한 한 Lock Hold Time 줄이기
- SELECT FOR UPDATE는 WHERE 절로 범위 최소화
- DDL 수행 시 트래픽 분산 시간에 수행
- 적절한 lock_timeout, deadlock_timeout 설정
- 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 |