개발공부

PostgreSQL의 Lock

Mactto 2024. 6. 28. 16:47
728x90

PostgreSQL은 동시성 이슈를 해결하고 데이터 무결성을 보장하기 위해 다양한 Lock을 제공합니다.

( 동시성 이슈가 무엇인지 모르겠다면 해당 포스팅을 참고해 주세요. )

이번 포스팅은 PostgreSQL이 제공하는 강력한 기능 중 하나인 Lock에 대해 기술해보려 합니다.

 

1. Lock 이란?

Lock은 특정 리소스에 대한 접근을 제한하는 메커니즘입니다.

PostgreSQL은 트랜잭션의 동시성을 제어하고 데이터 손상을 방지하기 위해 여러 수준의 잠금을 제공합니다.

 

2. PostgreSQL Lock의 종류

2-1. 테이블 수준 Lock

테이블 수준 Lock은 테이블 전체에 다른 트랜잭션이 접근하지 못하도록 Lock을 거는 작업입니다.

해당 Lock이 걸려있다면 해제되기 전까지 권한이 충돌하는 다른 Lock은 해당 테이블에 접근할 수 없습니다.

 

테이블 수준 Lock은 PostgreSQL에서 총 아래 8개가 존재합니다.

1. Access Share Lock

Select 절로 테이블을 조회할 때 걸리는 Lock입니다.

실제로 아래와 같이 Select 쿼리를 트랜잭션에서 실행시키고

 

걸려있는 Lock들을 pg_lock에서 조회해 보면

 

아래와 같이 item 테이블에 대해 AccessShareLock을 요청했고 허가받았다(granted=True)라는 것을 알 수 있습니다.

이 Lock은 Commit이 수행될 때까지 유지됩니다.

 

2. Row Share Lock 

Row Share Lock은 외래키로 연결된 테이블에 Insert, Update 등의 작업이 이루어질 때 걸리는 Lock입니다.

외래키로 연결된 데이터의 변경을 방지하기 위해 존재하며 이름에 Row가 들어가 있지만 행 수준의 Lock이 아닌 테이블 수준 Lock입니다.

 

Item 테이블과 Item의 Id를 외래키로 가지는 Orders 테이블이 있다고 가정했을 때

아래와 같이 Orders 테이블에 Item의 1번 PK를 외래키로 가지는 데이터를 Insert 하고 걸리는 Lock을 확인해 보면

Row Share Lock이 걸리는 것을 확인할 수 있습니다.

Orders Insert Query
Lock 확인

 

3. Row Exclusive Lock

Insert, Update, Delete 쿼리 수행 시 걸리는 Lock입니다.

Access Share Lock과 충돌하지 않기 때문에 업데이트 시에도 조회 쿼리는 처리가 가능합니다.

위에서 Orders 테이블에 Insert 쿼리를 수행할 때 orders 테이블에는 Row Exclusive Lock이 걸린 것을 확인할 수 있습니다.

 

4. Share Update Exclusive Lock

Share Update Exclusive Lock은 VACUUM, ANALYZE, CREATE INDEX CONCURRENTLY, REINDEX, CLUSTER와 같은 명령을 실행할 때 발생합니다.

 

5. Share Lock

Share Lock은 테이블을 공유 모드로 잠그는 Lock입니다.

다른 트랜잭션이 테이블을 읽을 수 있지만, 업데이트는 할 수 없습니다.

이는 테이블을 동시에 업데이트하는 상황을 방지합니다.

 

예를 들어 아래와 같이 item 테이블이 있고 두 개의 트랜잭션이 모두 selected 필드의 값에 1을 더하는 쿼리를 날려보겠습니다.

item table

 

각 트랜잭션으로 업데이트 쿼리 실행

 

Lock 현황을 조회해 보면 아래와 같이 확인할 수 있는데

5008 transaction에 ShareLock이 걸린 것을 볼 수 있습니다.

이는 이미 5009 transaction이 Lock을 걸어놓은 상태이기 때문에 Share Lock을 요청했지만

granted 되지 않아 자원에 접근을 하지 못하고 있는 걸 볼 수 있습니다.

 

5009 트랜잭션을 Commit 하면 Share Lock의 granted가 부여되고 해제되는 것을 확인할 수 있습니다.

5009 Transaction Commit 이후

 

6. Share Row Exclusive Lock

Share Row Exclusive Lock은 CREATE TRIGGER 쿼리나 일부 ALTER 쿼리를 실행할 때 걸리는 Lock입니다.

 

7. Exclusive Lock

Exclusive Lock은 Materialized View를 Refresh 할 때 걸리는 Lock입니다.

 

8. Access Exclusive Lock

DROP TABLE, TRUNCATE와 같이 DDL 언어에서 걸리는 Lock이며 모든 Lock과 충돌하는 강력한 Lock입니다.

 

3. 각 Lock들의 충돌 관계

PostgreSQL이 이렇게 다양한 Lock을 지원하는 이유는 불필요하게 자원 접근을 제한하지 않기 위함입니다.

각각의 Lock들은 자신의 작업과 무관한 작업의 경우 Lock 여부에 상관없이 리소스 접근을 허용합니다.

각각의 Lock의 충돌 관계는 공식문서에 있는 아래 표를 참고해 주시면 됩니다.

 

 

728x90