3

deadlock graph in SQL Server 2008을 사용하는 SQL Server에서 교착 상태 문제를 진단했습니다.색인/키 관련 교착 상태를 해결하는 방법

문제는 내 인덱스와 관련이 있습니다. 두 가지 쿼리가 있습니다. 기본 테이블에서 서로 다른 두 날짜에 따라 데이터를 가져 오는 조인 및 하위 쿼리가 많은 장기 실행 보고서와 해당 기본 테이블에서 동일한 날짜를 업데이트하는 빠른 업데이트 쿼리입니다. 나는 두 개의 인덱스를 가지고 있으며, 보고서는 양쪽 모두에 대해 공유 된 KEY 잠금을 원하지만 업데이트 쿼리는 양쪽 모두에 대해 독점적 인 KEY 잠금을 원하며 어떻게 든 각 쿼리는 키 중 하나를 관리하기 만하므로 어느 것도 진행할 수 없습니다.

이 문제를 해결하려면 어떻게해야합니까? 여기

내 상황에 대한 모든 세부 사항을이다 :

내 기본 테이블은 다음과 같습니다

CREATE TABLE job_tb{ 
    job_id int IDENTITY(1,1), 
    createDate datetime NULL, 
    upDate datetime NULL, 
    dataField1 nchar(1), 
    dataField2 nchar(2), 
    --etc... 
} 

내 인덱스는 다음과 같이 :

CREATE NONCLUSTERED INDEX idx_createDate ON job_tb(
    createDate DESC 
) 
INCLUDE(dataField1, dataField2) 

CREATE NONCLUSTERED INDEX idx_upDate ON job_tb(
    upDate DESC 
) 
INCLUDE(dataField1, dataField2) 

마지막으로, 내 업데이트는 다음과 같습니다 :

BEGIN TRANSACTION; 
    UPDATE job_tb 
    SET 
     dataField1 = @data 
     upDate = @upDate 
    WHERE 
     job_id = @job_id 
COMMIT TRANSACTION; 

그리고 보고서는 모든 종류의 통계를 날짜별로 계산하므로 여기에 그 통계를 포함시키지 않겠습니다. 나는 의도적으로 idx_createDate와 idx_upDate를 "cover"하거나 dataField1을 포함하도록 고안했다. 왜냐하면 그 보고서에서 많이 사용되기 때문이다.

나는이 보고서가 색인 중 하나에 공유 잠금을 부여한 다음 하위 쿼리를 조회하고 두 번째 색인에서 잠금을 요청한다고 생각합니다. 한편 업데이트 쿼리는 upDate와 포함 된 dataField1을 모두 업데이트하기 위해 두 인덱스 모두에 대해 독점적 인 잠금을 원합니다.

너희들은 어떻게 생각하니?

는 편집 : 요청에 따라 여기에서 XML 교착 상태 그래프의 : 질문/의견과 교착 상태 그래프를 분석 한 후 논의를 바탕으로

<deadlock-list> <deadlock> 
<victim-list> 
    <victimProcess id="processcf65288"/> 
</victim-list> 
<process-list> 
    <process id="processcf65288" taskpriority="0" logused="0" waitresource="KEY: 6:72057597970874368 (eee1799e706c)" waittime="122" ownerId="421742704" transactionname="SELECT" lasttranstarted="2012-08-03T05:37:21.257" XDES="0x8611e8800" lockMode="S" schedulerid="50" kpid="8560" status="suspended" spid="70" sbid="0" ecid="0" priority="0" trancount="0" lastbatchstarted="2012-08-03T05:37:21.257" lastbatchcompleted="2012-08-03T05:37:21.257" clientapp="Internet Information Services" hostname="xxx" hostpid="11964" loginname="xxx" isolationlevel="read committed (2)" xactid="421742704" currentdb="6" lockTimeout="4294967295" clientoption1="671088672" clientoption2="128056"> 
     <executionStack> 
      <frame procname="" line="28" stmtstart="1276" stmtend="4826" sqlhandle="0x03000600311ac36c65a31701a1a000000100000000000000"> 
      </frame> 
      <frame procname="" line="1" sqlhandle="0x01000600f61bee3600932ae3090000000000000000000000"> 
      </frame> 
     </executionStack> 
     <inputbuf> exec MonthlyReport @id = 41 
     </inputbuf> 
    </process> 
    <process id="processd2b6bc8" taskpriority="0" logused="1908" waitresource="KEY: 6:72057597970939904 (8e8117a49479)" waittime="2242" ownerId="421742551" transactionname="user_transaction" lasttranstarted="2012-08-03T05:37:20.447" XDES="0x7e84ad0a0" lockMode="X" schedulerid="63" kpid="12700" status="suspended" spid="89" sbid="0" ecid="0" priority="0" trancount="2" lastbatchstarted="2012-08-03T05:37:20.443" lastbatchcompleted="2012-08-03T05:37:20.443" clientapp="Internet Information Services" hostname="xxx" hostpid="11964" loginname="xxx" isolationlevel="read committed (2)" xactid="421742551" currentdb="6" lockTimeout="4294967295" clientoption1="673185824" clientoption2="128056"> 
     <executionStack> 
      <frame procname="" line="47" stmtstart="2342" stmtend="2640" sqlhandle="0x03000600e7dd9c717cbbb900ec9f00000100000000000000"> 
      </frame> 
      <frame procname="" line="1" sqlhandle="0x01000600311d7a152032f9be040000000000000000000000"> 
      </frame> 
     </executionStack> 
     <inputbuf> exec UpdateJob @dataField1 = &apos;C&apos;, @upDate = &apos;8/3/2012 5:37:20 AM&apos;, @job_id = 1542687 
     </inputbuf> 
    </process> 
</process-list> 
<resource-list> 
    <keylock hobtid="72057597970874368" dbid="6" objectname="" indexname="" id="lock612859900" mode="X" associatedObjectId="72057597970874368"> 
     <owner-list> 
      <owner id="processd2b6bc8" mode="X"/> 
     </owner-list> 
     <waiter-list> 
      <waiter id="processcf65288" mode="S" requestType="wait"/> 
     </waiter-list> 
    </keylock> 
    <keylock hobtid="72057597970939904" dbid="6" objectname="" indexname="" id="lock612a15300" mode="S" associatedObjectId="72057597970939904"> 
     <owner-list> 
      <owner id="processcf65288" mode="S"/> 
     </owner-list> 
     <waiter-list> 
      <waiter id="processd2b6bc8" mode="X" requestType="wait"/> 
     </waiter-list> 
    </keylock> 
</resource-list> 
</deadlock> /deadlock-list> 
+0

보고서 쿼리는'begin transaction'에서 여러 개의 선택으로 구성됩니까? – Ankush

+0

또한 교착 상태 그래프 XML 파일을 공유 할 수 있습니까? – Ankush

+0

아니요 보고서에'begin transaction'이 포함되어 있지 않습니다 – Slider345

답변

5

,이 경우입니다 보고서 쿼리 ISN 현재의 두 지수에 완전히 포함되어 있지 않다. 보고서는 우선 클러스터되지 않은 색인을 조사합니다. 필요한 모든 정보를 찾지 못했습니다. 따라서 나머지 데이터를 얻으려면 기본 테이블에서 주요 조회를 수행합니다. 그러나 업데이트는 정반대의 방식으로 작동합니다. 업데이트는 먼저 기본 테이블을 잠그고 데이터를 업데이트 한 다음 모든 인덱스를 찾아서 업데이트합니다. 따라서 교착 상태.

이 문제를 해결하는 한 가지 방법은 전체 보고서 쿼리를 인덱스별로 처리하는 것입니다. 그러나 이것은 업데이트가 느려질 것이라는 암시를줍니다.

다른 해결책은 보고서 쿼리를 두 개로 나누고 임시 테이블 변수를 사용하여 인덱스에서 데이터를 수집 한 다음 키 조회를 수행하는 것입니다. 참고 보고서 쿼리는 직렬화 가능 트랜잭션 모드에서 실행하면 안됩니다. 그렇지 않으면 트랜잭션은 방금 읽은 읽기 잠금을 해제하지 않습니다.

희망이 있습니다. 의심이 있으시면 알려주세요.

+0

이 경우 인덱스에 해당 필드를 추가합니다. 교착 상태 그래프를 다시 확인하여이 교착 상태가 사라지는 지 확인하십시오. – Slider345

+0

보고서 쿼리의 쿼리 계획에 기본 테이블까지의 키록이 포함되어 있지 않은지 확인하십시오. – Ankush

+0

한 가지 더, 교착 상태에 빠지면 리소스 키 잠금 인덱스를 얻을 수 있는지 확인하십시오. 마지막 그래프에서 그것은 비어있었습니다. 최악의 경우 업데이트를 통해 보고서 쿼리에서 읽는 방법과 다른 순서로 이러한 인덱스를 업데이트 할 수 있습니다. – Ankush

관련 문제