교착상태(Dead lock)에 대해서 아는 대로 설명해보세요.

  • 교착 상태(deadlock)

교착 상태란 두 개 이상의 작업이 서로 상대방의 작업이 끝나기만을 기다리고 있기 때문에 결과적으로 아무것도 완료되지 못하는 상태를 가리킨다. 예를 들어 하나의 사다리가 있고, 두 명의 사람이 각각 사다리의 위쪽과 아래쪽에 있다고 가정한다.

이때 아래에 있는 사람은 위로 올라가려고 하고, 위에 있는 사람은 아래로 내려오려고 한다면, 두 사람은 서로 상대방이 사다리에서 비켜줄 때까지 하염없이 기다리고 있을 것이고 결과적으로 아무도 사다리를 내려오거나 올라가지 못하게 되듯이, 전산학에서 교착 상태란 다중 프로그래밍 환경에서 흔히 발생할 수 있는 문제이다. 이 문제를 해결하는 일반적인 방법은 아직 없는 상태이다.

  • 교착 상태의 조건

1971년에 E. G. 코프만 교수는 교착상태가 일어나려면 다음과 같은 네 가지 필요 조건을 충족시켜야 함을 보였다.

① 상호배제(Mutual exclusion) : 프로세스들이 필요로 하는 자원에 대해 배타적인 통제권을 요구한다.

② 점유대기(Hold and wait) : 프로세스가 할당된 자원을 가진 상태에서 다른 자원을 기다린다.

③ 비선점(No preemption) : 프로세스가 어떤 자원의 사용을 끝낼 때까지 그 자원을 뺏을 수 없다.

④ 순환대기(Circular wait) : 각 프로세스는 순환적으로 다음 프로세스가 요구하는 자원을 가지고 있다.

이 조건 중에서 한 가지라도 만족하지 않으면 교착 상태는 발생하지 않는다. 이중 순환대기 조건은 점유대기 조건과 비선점 조건을 만족해야 성립하는 조건이므로, 위 4가지 조건은 서로 완전히 독립적인 것은 아니다.

- 교착 상태의 종류

1) 순환 교착 (Cycle Deadlock)

교착상태를 설명할 때 보통 예로 드는 것이 "Cycle Dead Lock"이다. 두 세션이 필요한 리소스를 얻기 위해 서로 상대방이 Lock을 풀기를 기다리는 상태라고 설명할 수 있다. 예를 들면 아래와 같다.

위와 같이 실행시키면 한쪽 세션에서는 다음과 같은 결과를 볼 수 있다.

(1개 행 적용됨)

서버: 메시지 1205, 수준 13, 상태 50, 줄 1

트랜잭션(프로세스 ID 54)이 lock 리소스에서 다른 프로세스와의 교착 상태가 발생하여 실행이 중지되었습니다. 트랜잭션을 다시 실행하십시오.

▲교착상태란 무엇인가를 직관적으로 알려주는 예시

2) 변환 교착 (Conversion DeadLock)

Conversion DeadLock 은 잠금모드가 SharedLock에서 UPD-Lock 혹은 X-Lock으로 전환될 때 발생하는 문제로서, 채번(일련번호 매기는 일)과 관련해서 발생하는 경우가 많다.

① 세션 A가 트랜젝션을 건 후 어떤 Row에 공유잠금(S-Lock)을 걸었다고 가정해보자

② 세션 B도 트랜젝션을 건 후 그 Row에 공유잠금을 걸었다. 공유잠금끼리는 서로 호환이 되므로 당연히 가능하다.

③ 이 상태에서 세션 A는 그 Row에 Update를 시도한다. 이 Row에는 세션 B에서 공유잠금을 걸었으므로 세션 A는 배타적 잠금을 을 걸기 위해 세션 B가 공유잠금을 풀어주기를 기다린다.

④ 이때, 세션 B도 그 Row에 Update를 시도한다

과연 어떻게 될까? A는 B의 공유잠금 때문에 Update를 진행하지 못하고, B는 A의 공유잠금 때문에 Update를 진행하지 못하게 된다. 이것이 Conversion DeadLock이다. 실제 테스트를 해보면 다음과 같다.

테스트해보면 데드락이 발생하는 것을 확인할 수 있다. 위와 같은 SQL이 데드락이 발생하지 않도록 하려면 어떻게 해야 할까? 의 교착상태는 SELECT시 공유잠금이 동시에 걸렸기 때문에 발생한 것이므로, ELECT시에 다음과 같이 잠금 힌트를 주어 처음부터 명시적으로 UPDLOCK을 걸어주면 교착상태를 방지할 수 있다.

SELECT @NUM = VAL + 1 FROM TAB1 WITH (UPDLOCK) WHERE NUMTYPE = 'TestApp’

  • 교착상태를 줄이는 5가지 방법

DeadLock을 줄이기 위해서는 다음과 같은 방법들이 있다.

① 인덱스를 설정한다. 인덱스가 없으면 Lock이 걸리는 범위가 훨씬 넓어지기 때문에 교착상태가 발생하기 쉬워진다.

② 자원들을 한쪽으로 사용한다. A와 B라는 테이블이 있다면 모든 세션에서 A->B 순서로 사용하도록 한다.

③ 트랜잭션은 가급적이면 짧게 만든다.

④ 테이블의 크기를 작게 쪼갠다. (정규화)

⑤ Transaction Isolation Level을 "Read Uncommitted"로 설정한다.

운영체제

하드디스크(HDD)를 긁는 것 같은 시끄러운 이 소음의 원인은 무엇입니까?

운영체제

Linux의 장점과 단점이 무엇이라고 생각합니까?

커뮤니티 Q&A

이론과 관련된 게시글이에요.

이해가 안 되거나 궁금한 점이 있다면 커뮤니티에 질문해 보세요!

게시글 작성하기