본문 바로가기

소프트웨어-이야기/데이터 저장소 + 시각화

(PostgreSQL) Transaction과 Lock에 대한 이모저모

Table Lock Mode

  • Table Lock Mode에 따라 공존할 수 있는 Lock이 있고, Conflict나는 Lock이 있다. 
  • SELECT를 막는 Table Lock은 ACCESS EXCLUSIVE 뿐이다. Lock Mode의 최종보스다. 
  • SELECT FOR SHARE는 FOR UDPATE, FOR SHARE 쿼리에서 필요하다.
  • EXCLUSIVE는 UDPATE / DELETE 등의 쿼리에서 필요하다. EXCLUSIVE Lock 모드는 서로 충돌난다. 그래서 동일한 Row를 여러 트랜잭션에서 동시에 업데이트할 수 없는거다. 
  • SHARE UPDATE EXCLUSIVE는 Vacuum, 인덱스 추가 등의 쿼리에서 필요하다. 
 

Transaction과 Lock Blocking

  • 트랜잭션이 느린 경우, Lock Blocking이 발생하고 있는지 검토해봐야한다. 
    • Transaction A가 특정 Row에 Lock을 잡았다고 생각해보자. 그리고 Transaction B가 Lock을 잡으려는데, Transaction A와 충돌나는 Lock Mode를 갖고있다고 생각해보자. 그러면 Transaction B는 Transaction A가 Commit되거나 Rollback 될 때까지 기다려야한다. 
    • 이와중에 Transaction C가 나타났는데, Transaction C가 필요로하는 Lock이, Trasaction A와는 공존할 수 있지만, Transcation B와는 공존할 수 없는 Lock이라면, Transaction B가 Commit되거나, Rollback 될 때까지 기다려야한다. 
    • 이런 순서로 Lock Blocking이 시작된다.
  • 그래서 Lock을 빨리 반환할 수 있도록, Transaction을 짧게 유지해야한다. 
  • DeadLock이 발생하는 경우, 에러가 나기 때문에 문제를 인지하기 쉽다. 
  • 그러나 서로 다른 트랜잭션에서 연달아 발생하는 Lock Blocking은 추적이 어렵다.
  • 그리고 서비스 장애 전파도 쉽게 발생한다.
    • Lock Blocking이 발생하면, Idle in Transaction 상태인 DB Connection 수가 늘어나게 된다.
    • 그러면서 점점 WAS Connection 수도 늘어나게 되면서, 서비스 장애로 이어지게 된다. 

DeadLock

  • 트랜잭션들이 서로가 잡고있는 Lock을 얻으려고 할 때, DeadLock이 발생한다.
  • 서로가 쥐고 있는 Lock을 얻어야지만, 트랜잭션이 끝날 수 있으니, 영원히 Transaction이 안끝나게 된다. 
  • 그래서 트랜잭션 짤 때, DeadLock 안걸리게 순서를 잘 구성해야한다. 
 

Postgres Locking Revealed

PostgreSQL Rocks, Except When it Blocks: Understanding Locks

13.4. Data Consistency Checks at the Application Level