프로그래밍/시스템

Deadlock(교착 상태) - 4. 실제 사례로 보는 데드락

개발_노트 2025. 3. 25. 22:51

 

4. 실제 사례로 보는 데드락

데드락(교착 상태)은 이론에서만 다뤄지는 문제가 아닙니다.
운영체제, 데이터베이스, 멀티스레드 프로그래밍, 분산 시스템 등 다양한 실무 환경에서 실제로 발생하며,
시스템 정지나 성능 저하의 직접적인 원인이 됩니다. 아래에 환경별 사례를 정리합니다.


✅ 운영체제에서의 데드락

● 파일과 프린터 자원 충돌

  • 프로세스 A는 파일을 점유한 후 프린터를 요청
  • 프로세스 B는 프린터를 점유한 후 파일을 요청
  • 서로가 필요한 자원을 상대가 점유하고 있어, 무한 대기 상태 발생 → 데드락

● 시스템 콜 간 커널 락 충돌

  • 두 커널 스레드가 read()와 write() 시스템 콜을 처리 중
  • 락 획득 순서가 어긋나면서 커널 내부에서 데드락 발생 가능성 존재

✅ 데이터베이스 트랜잭션 충돌 사례

● 교차 테이블 접근

  • 트랜잭션 A: 테이블 X의 행을 점유한 후 테이블 Y 접근 시도
  • 트랜잭션 B: 테이블 Y의 행을 점유한 후 테이블 X 접근 시도
  • 교차 잠금 발생 → 트랜잭션 간 순환 대기 → 데드락

● 외부 I/O 대기 포함 트랜잭션

  • 트랜잭션이 자원을 점유한 상태로 외부 API 응답을 기다리는 동안,
    다른 트랜잭션이 해당 자원을 요청하며 시스템 전체가 교착 상태에 빠질 수 있음

※ 주요 RDBMS는 데드락을 감지하여 자동으로 트랜잭션을 강제 종료(rollback)함


✅ 멀티스레드 환경에서의 데드락

● 락 순서 충돌

  • 스레드 A: 락 X → 락 Y 순서로 획득
  • 스레드 B: 락 Y → 락 X 순서로 획득
  • 서로가 상대방이 점유한 락을 기다리며 무한 대기 상태 → 데드락

● 잘못된 재귀 락 사용

  • 스레드가 자신이 이미 점유한 락을 중첩 요청하거나,
    락 해제를 누락한 경우 교착 상태가 발생할 수 있음

✅ 분산 시스템에서의 데드락 (심화)

분산 시스템, 특히 마이크로서비스 아키텍처에서는
서비스 간의 호출 흐름과 분산된 자원 점유가 맞물리며 복잡한 형태의 데드락이 발생할 수 있습니다.

● 서비스 간 순환 호출 + 자원 점유

  • 서비스 A는 데이터베이스 락을 점유한 상태로 서비스 B 호출
  • 서비스 B는 Redis 락을 점유한 상태로 서비스 C 호출
  • 서비스 C는 다시 A를 호출 → 순환 호출 구조 + 자원 점유 상태 → 분산 데드락 발생

● 증상은 있으나 오류는 없음

  • 표면적으로는 단순한 응답 지연이나 타임아웃 현상처럼 보이지만,
    실제로는 서비스 간 순환 대기로 인해 전체 처리가 중단되는 상황
  • 일반적인 데드락 탐지 도구로는 식별이 어려움 → 분산 트레이싱 및 호출 경로 분석 필요

📝 요약 정리

환경 데드락 주요 원인 대응 전략 예시
운영체제 자원 요청 순서 충돌 자원 요청 순서 통일, 커널 락 최소화
데이터베이스 레코드 락 교차 점유 트랜잭션 구조 개선, 타임아웃 설정
멀티스레드 락 획득 순서 불일치 락 순서 고정, 재귀 락 사용 주의
분산 시스템 서비스 간 순환 호출 + 락 점유 서비스 설계 정비, 락 최소화, 트레이싱 도입

데드락은 시스템의 규모와 복잡도가 커질수록 더 다양한 형태로 발생하며,
구조적인 설계와 자원 관리 전략 없이는 쉽게 발견되거나 해결되지 않습니다.
사례를 통해 데드락의 실전 위협을 정확히 이해하고, 사전 예방이 가능한 시스템을 설계해야 합니다.