Database/Real MySQL Season1 ,2

20) Dead Lock

Tony Lim 2024. 11. 4. 17:58
728x90

Deadlock원인

  • tx1 이 pk=2 레코드에 exclusive lock (x-lock)획득
  • tx-2,3 이 중복된 레코드에 대해서 s-lock 이 필요해서 대기
  • tx1 commit하면 tx2,3 shared lock 동시획득
  • tx2,3 pk=2레코드에 대해서 동시에 x-lock 획득 대기

의문 사항

  • 왜 shared lock을 먼저걸고 , exclusive lock을 걸어야 하는가?
    • insert시에 pk는 unique해야함으로 해당 record에대해서 s lock을 걸고 확인을 먼저하게 된다.
  • 어떻게 이미 삭제된 레코드에 대해서 lock을 걸수 있는가?
    • 해당 레코드들을 영구적으로 삭제하지 않고 일정시간 동안 삭제표시만 상태로 유지한다.
      (Deletion-mark [Tomb stone])
    • 쿼리에서만 해당 레코드가 보이지 않는다.

tx 2,3이 이미 s lock을 잡고있으므로 그 누구도 x lock을 획득못하는 데드락 상황이 발생한것이다.

 

MySQL Deadlock 감지

  • DeadLock detection thread가 모든 트랜잭션이 획득 또는 대기하고 있는 잠금 graph를 계속 감시한다.
  • 동시 트랜잭션이 많은 경우, deadlock 체크 작업으로 인한 대기가 발생한다.
    • 어떤 회사(구글)에서는 deadlock detection therad를 비활성화 하기도 한다.
  • innodb_deadlock_detect = OFF
    • innodb_lock_wait_timeout 기본 값은 50초이다. 무한정 대기하지 않음
    • innodb_lock_wait_timeout = 2~3초 정도로 조정 검토가 필요하다.
  • MySQL은 롤백이 쉬운 트랜잭션을 Victim trx 로 선정한다.
    • 롤백이 쉬운 트랜잭션 == undo 레코드가 적은 트랜잭션
  • Victim으로 선정된 트랜잭션은 강제 롤백처리
  • 남은 트랜잭션은 정상 처리
  • 배치 작업과 서비스 쿼리가 경합하면, 항상 배치 프로세스가 살아남게 된다.

 

MySQL deadlock 해석과 원인 분석은 매우 어려운편이다.

  • 동일 SQL문장이더라도 , 항상 동일한 잠금을 사용하지 않는다.
    • 현재 데이터 상태에 따라서
    • 동시 실행중인 잠금 경합 DML의 실행시점에 따라서
  • Record 뿐만 아니라 , Record 간의 간격(gap) 도 잠금(next key lock)의 대상이다.
  • deadlock 시점의 관련 트랜잭션을 모두 로깅하지 않는다.
  • 사용하는 잠금이나 상황에 따라서 중간 중간 잠금이 해제 되기도 한다.
    • 각 잠금의 lifecycle이 다르다. (기본은 트랜잭션 단위)
    • 찰나의 시간차이로 deadlock이 발생가능
  • 잠금의 대상은 모든 index key (Cluster key , Secondary key, Foreign key)

 

dead lock에 관한 개발자들의 많은 오해

  • 프로그램 코드의 오류로 dead lock이 발생한다.
  • 개발능력이나 db 문제로 deadlock이 발생한다.
  • dead lock이 발생하면 , 프로그램 코드 개선이 필요하다.

하지만

  • dead lcok은 회피 할 수 있는 경우도 있지만, 회피할 수 없는 경우가 더 많다.
  • deadlock이 발생했다고 해서 , unique key나 pk를 삭제할 수는 없다.
    • (가능하다면 , 모딜링 시점에서 최소화하는게 좋다)
    • unique key 같은 경우 , 성능적인 장점보다는 deadlock의 빈도를 높이는 경우가 많다.
  • deadlock의 발생빈도와 서비스 영향도에 따라서 무시하는게 좋다 ( 로깅 및 별도의 재처리)
  • 프로그램 코드에서의 트랜잭션 재처리
  • if (sqlEx.getSqlState() == "40001" { retry;}
  • retry 코드를 넣었다고 해서 , 코드 품질이 낮아지는것은 아니다.

 

728x90

'Database > Real MySQL Season1 ,2' 카테고리의 다른 글

23) 테이블 파티셔닝  (0) 2024.11.08
21) Join Update & Join Delete  (0) 2024.11.07
19) JSON 타입 활용  (0) 2024.10.30
17) NoWait & Skip Locked , 18) Union vs Union All  (0) 2024.10.24
16) Count(*) vs Count(column)  (0) 2024.10.22