
핵심요약
PostgreSQL에서 읽기 위주 워크로드의 성능 저하는 빠른 경로 잠금 메커니즘의 제한을 초과하여 발생하는 LWLock 경합 때문입니다. 파티션 프루닝, 인덱스 최적화, 쿼리 단순화 등의 전략으로 이러한 병목 현상을 진단하고 완화하여 데이터베이스 성능을 크게 향상시킬 수 있습니다.
PostgreSQL LWLock 경합 진단 및 완화 전략
LWLock 경합 및 Fast Path 잠금 메커니즘 이해
- LWLock은 PostgreSQL의 공유 메모리 구조 접근을 제어하는 경량 동기화 기법입니다.
- Fast Path 잠금은 충돌 없는 약한 락 (AccessShareLock, RowShareLock 등)에 대해 공유 메모리 락 해시 테이블을 우회하는 메커니즘입니다.
- 각 백엔드 프로세스는 16개의 Fast Path 슬롯을 가지며, 이 제한을 초과하거나 강한 락 요청 시 Slow Path로 전환됩니다.
- Slow Path 전환 시 공유 메모리 락 해시 테이블을 사용하며, 이 과정에서 LWLock:LockManager 대기 이벤트가 발생하여 성능이 저하됩니다.
- 테스트 결과, Fast Path 사용 시 최대 34%의 성능 향상을 확인할 수 있습니다.
LWLock 경합 발생 시나리오 분석 (실험)
- 파티션 테이블 쿼리: 파티션 프루닝 없이 모든 파티션 쿼리 시 Fast Path 슬롯이 소진되고 Slow Path로 전환되어 LWLock:LockManager 경합이 발생했습니다.
- 파티션 프루닝 활용: PL/pgSQL 블록을 통한 효과적인 파티션 프루닝은 Fast Path를 유지하여 경합을 줄이고 성능을 크게 향상시켰습니다.
- 불필요한 인덱스: 비파티션 테이블에 과도한 수의 인덱스 존재 시, 쿼리 플래너가 모든 인덱스에 대해 AccessShareLock을 획득하려 하여 Fast Path 슬롯 소진 및 LWLock:LockManager 경합을 유발했습니다.
- 다중 조인 쿼리: 여러 테이블에 걸친 복잡한 조인 쿼리는 필요한 락 수가 많아 Fast Path 슬롯을 쉽게 소진시키고 Slow Path 전환을 통해 LWLock:LockManager 경합과 높은 CPU 사용률을 발생시켰습니다.
PostgreSQL 락 경합 주요 완화 전략
- 파티션 테이블 최적화: 파티션 프루닝 활성화, 동적 SQL 대신 PL/pgSQL 블록 사용, 파티션 수 제한 (예: 월별 대신 분기별)을 통해 Fast Path 유지.
- 인덱스 조정: 사용되지 않거나 중복된 인덱스 제거/통합, 과도한 인덱싱 피하기 (예: 테이블당 10개 이하)로 락 오버헤드 감소.
- 스키마 디자인 조정: 불필요한 파티셔닝 피하기, 커버링 인덱스 활용 (INCLUDE 컬럼 추가), 높은 동시성 테이블 정규화를 통한 인덱스 확산 방지.
- 쿼리 최적화 및 PostgreSQL 튜닝: 조인 단순화 (Materialized View 활용), 작은 읽기 일괄 처리, 필요한 경우 max_locks_per_transaction 조정, pg_locks 뷰를 통한 Fast Path 사용량 모니터링.