이번에는 DB DeadLock 교착 상태에 대해 정리하겠습니다.
DB 데드락이란?
DB 데드락이란 트랜잭션의 교착 상태입니다. 두 개 이상의 트랜잭션이 서로의 작업이 완료되기를 기다리면서 영원히 대기 상태에 빠지는 상황을 말합니다. 데드락은 동시에 여러 트랜잭션이 실행되는 다중 사용자 DB 시스템에서 자주 발생합니다.
데드락 발생 원인
데드락은 4가지 상황이 충족되면 발생합니다.
4가지 상황은 상호 배제, 소유와 대기, 비선점, 순환 대기 입니다. 하나씩 알아보겠습니다.
상호 배제(Mutual Exclusion)
각 트랜잭션 자원에 대해 베타적인 제어권을 가지고 있습니다. 베타적 제어권이란 한 트랜잭션이 자원을 독점하고 있어 다른 트랜잭션이 접근할 수 없는 것입니다.
소유와 대기(Hold and Wait)
트랜잭션이 최소한 하나의 자원을 보유하고 있으며 동시에 다른 트랜잭션이 보유한 자원을 기다립니다.
비선점(No Preemption)
트랜잭션이 자원을 스스로 해제할 때까지 다른 트랜잭션이 그 자원을 강제로 빼앗을 수 없습니다.
순환 대기(Circular wait)
트랜잭션들 사이에 순환 형태의 대기 상태가 존재합니다.
예를 들어 트랜잭션 A가 트랜잭션 B의 자원을 기다리고 트랜잭션 B가 트랜잭션 C의 자원을 기다리고 트랜잭션 C가 트랜잭션 A의 자원을 기다리는 상황이 순환 형태의 대기 상태입니다.
데드락은 이 4가지 중 하나라도 이루어지지 않으면 발생하지 않습니다.
DB 데드락 해결 방법
데드락을 예방하기 위해 여러 방법이 있습니다. 하나씩 알아보겠습니다.
예방 기법
각 트랜잭션이 실행되기 전에 필요한 데이터를 모두 잠금(Locking)하는 방법입니다. 하지만 데이터가 많이 필요한 경우 모든 데이터를 잠금하기에 트랜잭션의 병행성을 보장할 수 없습니다. 또한 몇몇 트랜잭션은 계속 처리하지 못하는 기아 상태가 발생할 수 있습니다.
예방은 확실하지만 성능이 안 좋아지는 방법입니다.
낙관적 병행 기법
다른 방법으로 낙관적 병행 기법이 있습니다. 이 기법은 트랜잭션이 실행되는 동안 아무런 검사를 하지 않습니다. 트랙잭션이 다 실행된 이후 검사를 하고 검사에 문제가 있다면 되돌리는 방식입니다.
회피 기법
위의 단점 때문에 실제로 교착 상태를 해결하기 위한 방법으로 회피 기법이 많이 사용됩니다. 회피 기법은 자원을 할당할 때 시간 스탬프를 사용하여 교착 상태가 일어나지 않도록 회피하는 방법입니다.
Wait-Die 방식과 Wound-Wait 방식이 있습니다.
(선행 트랜잭션, 후행 트랜잭션 있습니다. 선행 트랜잭션은 타임 스탬프가 더 적은 오래된 트랜잭션입니다. 후행 트랜잭션은 타임 스탬프가 많은 새로운 트랜잭션 입니다.)
Wait-Die 방식
Wait-Die 방식은 다른 트랜잭션이 데이터를 점유하고 있을 때 대기하거나 중단하는 방식입니다.
더 오래된 트랜잭션이 요청했을 때는 대기(Wait)하고 더 새로운 트랜잭션이 요청했을 땐 즉시 중단(die)되어 나중에 재시도하는 방식입니다. 이 방식은 더 오래된 트랜잭션의 우선순위를 보장합니다.
Wound-Wait 방식
Wound-Wait 방식은 다른 트랜잭션이 데이터를 점유하고 있을 때 빼앗거나(Wound) 대기(Wait)하는 방식입니다. 선행 트랜잭션이 접근하면 선점하고 후행 트랜잭션이 접근하면 대기합니다.
회피 기법에 대해
이러한 회피 기법은 분산 데이터베이스 시스템에서 데드락을 회피를 위해 설계되었으며 이론적으로 언급되는 이론입니다. 위의 방식은 분산 환경에서 네트워 크 지연, 다양한 노드 간의 동기화 문제 등 고유의 문제를 해결하기 위해 설계되었습니다.
반면 RDBMS는 이러한 문제들을 가지고 있지 않기 때문에 더 단순한 데드락 관리 방법을 사용합니다. 또한 현대 DBMS는 자체적으로 튜닝된 데드락 회피 및 탐지 메커니즘을 사용합니다.
MariaDB가 주로 사용하는 방법
제가 주로 사용하는 DB인 MariaDB는 어떤 식으로 해결하는지 궁금하여 정리해보았습니다.
자동 데드락 감지
MariaDB는 내부적으로 데드락을 감지하는 매커니즘을 가지고 있습니다. 데드락이 감지되면 하나 이상의 트랜잭션을 자동으로 롤백하여 데드락을 해결합니다. 일반적으로 진행 상태가 가장 낮은 트랜잭션을 롤백시킵니다.
메커니즘은 트랜잭션의 대기 그래프를 분석하여 순환 의존성을 찾는 방식으로 이루어집니다.
타입 아웃
트랜잭션이 일정 시간 동안 완료되지 않을 경우 자동으로 중단합니다.
자원 할당 전략
자원을 할당하는 순서를 엄격하게 정의하여 데드락 발생 가능성을 줄입니다.
로그 및 모니터링
MariaDB는 데드락에 대한 정보를 로그에 기록합니다. 관리자가 로그를 통해 문제를 분석하고 해결할 수 있도록 합니다.
마무리
이번에는 DB의 데드락에 대해 정리했습니다.
데드락은 4가지 조건이 충족해야 발생하는 문제점입니다.
- 상호 배제
- 소유와 대기
- 비선점
- 환형 대기
데드락을 해결하는 다양한 방법이 있습니다.
- 예방 기법 : 모든 자원에 락을 검
- 회피 기법 : 타임 스태프 기반으로 Wait-Die, Wound-Wait 방식이 있음
- 자동 데드락 감지 : 데드락을 감지하면 트랜잭션을 롤백
- 타임 아웃 : 트랜잭션이 일정 시간이 지나면 롤백
- 자원 할당 전략 : 엄격한 자원 할당 기준을 세워 데드락의 빈도를 줄임
이번 글은 여기서 마무리하겠습니다. 감사합니다.
참고 사이트
https://blog.naver.com/ndb796/221243161017
https://parkmuhyeun.github.io/etc/database/2022-07-03-Deadlock/