프로세스가 교착 상태의 희생양이되는 원인


105

완료하는 데 5 ~ 10 분 정도 걸리는 Select 프로세스가 있습니다.
현재 MS SQL 데이터베이스 엔진에 대한 힌트로 NOLOCK을 사용하지 않습니다.
동시에 동일한 데이터베이스 및 동일한 테이블에 업데이트 및 삽입을 수행하는 다른 프로세스가 있습니다.
첫 번째 프로세스가 시작되었으며 최근에 메시지와 함께 조기 종료됩니다.

SQLEXCEPTION : 트랜잭션이 다른 프로세스와 함께 잠금 리소스에서 교착 상태가되었고 교착 상태 희생자로 선택되었습니다.

이 첫 번째 프로세스는 동일한 조건으로 다른 사이트에서 실행되지만 데이터베이스가 더 작아서 문제의 select 문이 훨씬 더 짧은 시간 (약 30 초 정도)이 걸립니다. 이러한 다른 사이트에서는 이러한 다른 사이트에서 교착 상태 메시지가 표시되지 않습니다. 또한 처음에 문제가 발생한 사이트에서이 메시지를받지 못했지만 데이터베이스가 커짐에 따라 어느 정도 임계 값을 넘었을 것입니다. 내 질문은 다음과 같습니다.

  1. 트랜잭션을 실행하는 데 걸리는 시간으로 인해 관련 프로세스가 교착 상태로 표시 될 가능성이 높아질 수 있습니다.
  2. NOLOCK 힌트로 선택을 실행하면 문제가 제거됩니까?
  3. select 문에서 WHERE 절의 일부로 확인 된 datetime 필드로 인해 조회 시간이 느려진 것 같습니다. 이 필드를 기반으로 색인을 만들 수 있습니까? 권장됩니까?

요점 1에 대한 부분적 대답 : 교착 상태와 시간 제한을 혼동하지 마십시오. 시간 초과가 발생한 경우 한 트랜잭션을 완료하는 데 관련된 시간이 다른 트랜잭션을 종료 할 수 있습니다. 또한 교착 상태가되는 리소스 (인덱스 또는 테이블입니까?)를 아는 것이 유용합니다.
NealB 2011

1
SET DEADLOCK_PRIORITY HIGH ALTER DATABASE dbname SET MULTI_USER;
gstackoverflow 2011

답변:


128

Q1 : 트랜잭션이 실행되는 데 걸리는 시간으로 인해 관련 프로세스가 교착 상태로 표시 될 가능성이 높아질 수 있습니다.

아니요. SELECT는 데이터를 읽기만 했으므로 희생자이므로 트랜잭션 과 관련된 비용이 더 낮 으므로 희생자로 선택됩니다.

기본적으로 데이터베이스 엔진은 롤백하는 데 가장 비용적게 드는 트랜잭션을 실행하는 세션을 교착 상태로 선택합니다 . 또는 사용자가 SET DEADLOCK_PRIORITY명령문을 사용하여 교착 상태 상황에서 세션의 우선 순위를 지정할 수 있습니다 . DEADLOCK_PRIORITY는 LOW, NORMAL 또는 HIGH로 설정하거나 또는 범위 (-10 ~ 10)의 정수 값으로 설정할 수 있습니다.

Q2. NOLOCK 힌트로 선택을 실행하면 문제가 제거됩니까?

아니요. 몇 가지 이유가 있습니다.

Q3. select 문에서 WHERE 절의 일부로 확인 된 datetime 필드로 인해 조회 시간이 느려진 것 같습니다. 이 필드를 기반으로 색인을 만들 수 있습니까? 권장됩니까?

아마. 교착 상태의 원인은 거의 색인이 제대로되지 않은 데이터베이스 일 가능성이 매우 높습니다. 10 분 쿼리는 이러한 좁은 조건에서 허용되며, 귀하의 경우 100 % 확신 할 수 없습니다 .

99 %의 신뢰를 바탕으로 업데이트와 충돌하는 대형 테이블 스캔으로 인해 교착 상태가 발생한다고 선언합니다. 교착 상태 그래프 를 캡처 하여 원인을 분석하십시오. 데이터베이스의 스키마를 최적화해야 할 가능성이 높습니다. 수정하기 전에 색인 및 하위 문서 디자인 주제를 읽으십시오 .


철저한 답변 감사합니다. 그래도 여전히 질문이 하나 있다고 생각합니다. 왜 다른 환경이 아닌 한 환경에서만 교착 상태가 발생합니까? 소프트웨어는 동일하지만. 귀하의 대답은 Select 쿼리를 실행하는 데 걸리는 시간이 차이를 만들지 않으며 프로세스 실패를 일으키는 것은 Select 쿼리 자체라는 사실을 암시합니다. 그런데 왜 선택 쿼리를 실행하는 데 오랜 시간이 걸리는 경우에만?
Elliott 2011

4
쿼리의 길이 는 교착 상태 희생자선택하는 데 영향을주지 않습니다 . 최소한 두 가지 요인에 의해 교착 상태가 발생하는 데 차이가 있습니다. 1) 단순 확률. 쿼리가 길수록 동시 업데이트가 겹치고 교착 상태가 발생할 가능성이 높습니다. 2) 더 큰 테이블은 교착 상태에 취약한 완전히 다른 쿼리 계획을 사용할 수 있습니다.
Remus Rusanu 2011

12

이 특정 교착 상태 문제가 실제로 발생하는 방법과 실제로 해결 된 방법은 다음과 같습니다. 이것은 매일 130K 트랜잭션이 발생하는 상당히 활동적인 데이터베이스입니다. 이 데이터베이스의 테이블에있는 인덱스는 원래 클러스터링되었습니다. 클라이언트는 인덱스를 클러스터링하지 않도록 요청했습니다. 그렇게하자마자 교착 상태가 시작되었습니다. 인덱스를 클러스터 된 상태로 다시 설정하면 교착 상태가 중지되었습니다.


34
누군가 이유를 설명 할 수 있습니까? (매직 솔루션은별로 도움이되지 않습니다.)
OGrandeDiEnne

1
이 사람은 자신의 게시물에서 설명합니다 : mssqltips.com/sqlservertip/2517/…
siga0984

6

여기에있는 답변은 시도해 볼 가치가 있지만 코드도 검토해야합니다. 특히 Polyfun의 답변을 읽으십시오. SQL Server 2005 및 C # 응용 프로그램에서 교착 상태를 제거하는 방법은 무엇입니까?

동시성 문제와 쿼리에서 "with (updlock)"를 사용하면 실제로 코드가 수행하는 작업에 따라 교착 상태 상황을 수정할 수있는 방법에 대해 설명합니다. 코드가이 패턴을 따르는 경우 더티 읽기 등에 의존하기 전에 이것이 더 나은 수정일 가능성이 높습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.