본문으로 바로가기

[MSSQL] 교착상태 (DeadLock)

category MSSQL/SQL Server 2017. 10. 24. 11:01

교착상태(Dead Lock)

교착상태(Dead Lock)란?

어떤 집합 내에 있는 모든 프로세스가 대기 상태이며 이 집합 내에 있는 각 프로세스가 이 집합 내에 다른 프로세스가 가지고 있는 자원을 기다리고 있으면 '교착상태' 라고 한다.

 

  • 작업 T1 리소스 R1 (R1에서 T1까지의 화살표로 표시) 대한 잠금을 가지며 리소스 R2 대한 잠금을 요청했다 (T1에서 R2 로의 화살표로 표시됨).
  • 작업 T2 자원 R2 대한 잠금을 가지며 (R2에서 T2 로의 화살표로 표시됨) 자원 R1 대한 잠금을 요청했다 (T2에서 R1 로의 화살표로 표시됨).
  •  작업은 자원이 사용 가능할 때까지 계속 수행   없으며 Task 계속  때까지 자원을 해제   없기  교착 상태가 존재한다.

SQL Server 데이터베이스 엔진은 SQL Server 내에서 교착 상태 사이클을 자동으로 감지한다데이터베이스 엔진은 세션 하나를 교착 상태로 선택하고 현재 트랜잭션이 교착 상태를 중단하기 위해 오류로 종료된다.

 


교착 상태의 필요 조건

다음의 네가지의 조건이 모두 충족되어야 교착상태가 발생한다.


1. 상호배제 : 최소한 하나는 비공유 방식으로 점유되어야한다.
                   비공유 방식의 점유란 한번에 하나의 프로세스만 자원을 사용 할 수 있음을 말한다.

2. 점유와 대기 : 프로세스는 최소한 하나의 자원을 점유하고 있고, 다른 프로세스가 점유하고 있는 다른 프로세스를 
                       기다리고 있어야 한다.

3. 비선점 : 점유된 자원은 강제로 해제될 수 없고, 프로세스가 자원의 사용을 끝마치고 자발적으로 해제할 때 까지는
                그 자원을 얻을 수 없어야 한다.

4. 순환 대기 : P0, P1, P2 순으로 프로세스의 집합이 존재 하여야 한다.

                    P1은 P0의 자원을 기다리고 있어야 하고, P2는 P1의 자원 해제를 기다리고 있어야 한다.


* 프로세스의 자원 이용 순서


 요청(Request) -> 사용(Use) -> 해제(release)



교착 상태를 처리하는 방법


1. 프로토콜을 사용하여 교착상태가 미리 일어나지 않도록 하는 방법

2. 교착상태를 허용하지만 주기적으로 검사 하여 교착상태를 제거 하는 방법

3. 교착상태를 무시하는 방법 Ex) Unix


교착 상태 예방

- 교착상태의 네가지 필요 조건 중 한 가지가 발생하지 않도록 하여 예방한다. 
   이 방법은 자원 요청을 제한하여 교착상태를 예방한다.

교착 상태 회피

- 운영체제가 사전에 프로세스가 어떤 자원들을 요청 할 지 알아야 한다.

   운영체제는 이 정보를 이용하여 프로세스가 자원을 요청하였을 때 이것을 허용할지 여부를 결정한다.

교착상태 탐지

- 교착상태를 발견하는 알고리즘과 교착상태를 해결하는 알고리즘을 제공하여 교착상태를 해결


 

잠금의 종류는 크게 공유잠금(shared lock)과 배타적 잠금(exclusive lock)으로 나뉜다.


l  공유잠금 : select

l  배타적 잠금 : insert, update, delete

 



-> lock 프로시저에 대해 조치하는 방법 


 

[Test]


1. commit 되지 않은 update가 진행되도록 한다.


2. 추가로 update를 진행하여, lock을 발생시켜 본다. (lock 발생)


3. 아래와 같이 exec sp_lock 쿼리로 lock 정보를 확인한다.

- spid : 잠금을 요청하는 프로세스 세션 ID

- dbid : 데이터베이스의 식별번호

- Indid : 개체의 식별번호

- Type : 잠금유형

- Resource : 리소스 식별값

- Mode : 잠금 모드

- Status : 잠금요청 상태


S – 공유 잠금

U – 업데이트 잠금

X – 독점 잠금

IS – 의도 공유

IU – 의도 업데이트

IX – 독점 의도

BU – 대량 업데이트


4. dbcc inputbuffer (spid)를 통해 수행된 쿼리정보를 확인 할 수 있다.             


추가적으로 sp_who2 프로시저를 사용하여, 좀 더 정확한 정보를 확인할 수 있다.


5. kill (spid) 한 후, 문제가 발생된 해당 프로시저를 kill 한다.




# 궁금한점은 댓글 남겨주시면 부족한 지식이지만 답변 드리겠습니다.



참고자료 : 

1. 교착 상태 검색 및 종료 - TechNet - Microsoft

2. JKMoon [MSSQL 잠금, sp_lock] - http://jkmoon.tistory.com/entry/MSSQL-%EC%9E%A0%EA%B8%88-splock

3. Soul [운영체제 - 교착상태] - http://soul10.tistory.com/entry/운영체제-교착상태