2011-03-28 4 views
6

현재 SQL Server 2008 데이터베이스에서 몇 가지 실험을하고 있습니다.SQL Server 2008 : 교착 상태가 발생했습니다 ... 잠김없이 ...

UPDATE from Table A where rowID='123' 

는 그러나, 나는이 교착 상태 오류의 톤을 받고 있어요 (: 더 구체적으로, 나는 데이터베이스에서 다음 쿼리를 실행합니다 각각의 작업의 수천을 실행하는 동시에 수백 개의 스레드를 사용하는 JDBC 응용 프로그램을 가지고 SQL Exception 1205). 격리 수준을 READ_UNCOMMITTED보다 높게 설정할 때마다. 행 잠금, 테이블 잠금 및 배타적 잠금 힌트를 설정하더라도 발생합니다! 그리고 잠금을 사용하지 않는 스냅 샷 격리에서도 여전히 교착 상태 오류가 발생합니다.

이런 일이 발생하면 SQL 프로파일 러를 통해 추적을 실행하여 교착 상태 그래프를 얻었지만 그다지 유용하지 않았습니다. 그것은 수백 개의 다른 프로세스와 연결된 "스레드 풀 (Thread Pool)"에 연결된 희생자 프로세스를 보여줍니다. 당신은 여기에서 확인할 수 있습니다 :

http://i.stack.imgur.com/7rlv3.jpg

이 사람이 왜 이런 일이에 관해서는 어떤 힌트가 있습니까? 나는 그것을 알아 내려고 노력하는 지난 며칠 동안 미쳐 버렸습니다. 현재의 가설은 DB 인스턴스의 사용 가능한 작업자 스레드, 사용 가능한 메모리의 양 또는 실제 쿼리 수준 잠금과 관련이없는 것 중 하나와 관련이 있다는 것입니다.

감사합니다.

+0

[이미 본가?] (http://blogs.msdn.com/b/bartd/archive/2008/09/24/today-s-annoyingly-unwieldy-term-intra-query-parallel-thread- deadlocks.aspx) 업데이트 문에 병렬 계획이 있습니까? –

+0

그리고'READ_UNCOMMITTED'가 적용될 때 이러한 교착 상태 **가 발생하지 않는다고 말하는가? 표시된'update' 문에 어떻게 영향을 미칠지 전혀 명확하지 않습니다. –

+0

와우! 짧은 시간에 그렇게 많은 반응을 기대하지 않았습니다! 교착 상태는 READ_UNCOMMITTED에서 계속 발생하지만 많은 동시 스레드가 계속 발생합니다 (약 1000 개). 나는 모호한 것에 대해 사과합니다. – akwok

답변

1

이와 같은 교착 상태/잠금은 이상하고 SQL 서버 외부의 것을 가리 킵니다. 가치가있는 것을 위해, 우리는 디스크 병목 현상으로 판명 된 교착 상태 문제를 많이 겪었습니다!

나는 perfmon (그리고 분명히 많은 다른 도구들)을 실행하고 그것이 어떻게되는지 보길 권한다.

1

을 잠금없이 SQL 서버에 넣을 수 없습니다. NOLOCK 문으로 채워진 가장 기본적인 쿼리조차도 최소한의 페이지 잠금과 스키마 잠금을 발급합니다.

교착 상태를 해결하려면 데드락과 관련된 정확한 잠금 및 개체를 나열하는 T1204 교착 상태 추적 (자세한 내용은 Deadlock Troubleshooting, Part 1 참조)을 얻어야합니다. 이는 충분한 정보로 파악해야합니다 머리 긁기 양) 정확히 무엇이 잘못되었는지. 완전히 교착 상태 뒤에 이유를 이해하지 않고 격리 수준을 변경

이 내가 몇 년 전에했습니다 문제가 생각 나는 직감으로

... 나에게 조금 위험한 것 - UPDATE 문 교착이다 SELECT 진술에 대해? (T1024 추적에서이를 알 수 있습니다.) rowID에 클러스터되지 않은 색인이 있습니까? 그렇다면 this MSDN article, 특히 예제 6 : 비 클러스터형 인덱스를 살펴볼 수 있습니다. 그렇지 않다면 다른 관련 교착 상태 시나리오를 설명하는 데 도움이 될 수 있으므로 해당 기사를 살펴보고 도움이 필요한 경우 T1024 추적 결과를 게시하십시오.

6

더 난해한 괴물, 즉 리소스 교착 상태가 발생했습니다. 모든 작업자 (sys.dm_os_workers)가 사용 중이므로 하위 작업 (sys.dm_os_tasks)을 생성하여 작업을 실행할 수없는 스레드가 있습니다. 교대로 바쁜 작업자는 피해자가 차단 한 작업 (보통 자물쇠가있는 작업)을 실행합니다.

1) 당신이 게시 업데이트가 평행 이동을 시도 :

가정을 위해 내가 여기에 볼이 개 수업이 있습니다. 업데이트가 게시 한 내용과 정확히 일치하는 경우 하나만 허용됩니다. rowId에 대한 색인이 없습니다.

2) 위 천장을 max worker threads으로 설정하여 반송했습니다. 클라이언트 (hundreds of concurrent threads to execute thousands of task)의 스레드를 악용하여 원치 않는 병렬 처리로 인해 서버에서이 스레드를 다중화한다고 생각해도 이상하지 않습니다.

실용적인 비동기 연결 (AsynchronousProcessing=true)에서 비동기 실행 (BeginExecuteNonQuery)을 사용하고 보류중인 요청 풀을 사용하므로 특정 임계 값을 초과하지 않습니다. 더 많은 경우, table valued parameter으로 업데이트 값 전체를 전달한 다음 단일 문에서 일괄 처리 된 전체 집합을 업데이트해야합니다. 내 모든 링크가 닷넷을위한 것임을 이해합니다. 자바가 아닙니다. 나는 상관 없습니다. 당신은 동등한 자바 기능을 스스로 파헤 칠 수 있습니다.

그런 밀교 교착 상태를 발견 한 것이 흥미 롭긴하지만 설계가 잘 되었기 때문에 나타납니다.

+1

나는 훌륭한 분석을 위해 +1 할 것이지만, -1로, 우리가 말 할까, 납품 할 것인가? 2 단어의 생략은 이렇게 읽었을 것입니다. 좋네요? – RichardTheKiwi

+1

Remus에 감사드립니다. 나는 디자인이 짜증 난다는 것을 이해하지만, 그것은 의도적으로 행해진 다! 나는 다음과 같은 사실을 보여 주어야하는 프로젝트를 진행하고있다. 1. 선택된 격리 수준의 유형에 따라 다른 읽기 예외가 존재하고 2. 필요 이상으로 동시성을 제한하는 격리 수준을 선택하기위한 경험적 성능 히트. 어쨌든 귀하의 의견은 이해가되며, 좀 더 살펴 보겠습니다. 적어도 당신은 저에게 더 읽을 거리를 제공 할 수있었습니다 :-) – akwok

+0

@akwok : 알겠습니다. UPDATE가 먼저 갱신 할 행을 찾아서 갱신해야한다고 고려하십시오. '찾기'부분은 격리 수준의 영향을받습니다. REPEATABLE_READ조차도 높은 세분성 잠금 레벨 (페이지, 테이블)에서 스캔하도록 선택할 수 있습니다. 두 번째 고려해야 할 사항은 '업데이트'부분이 스냅 샷을 비롯한 모든 격리 수준에서 다른 업데이트와 충돌한다는 것입니다. 또한 해시 충돌로 인해 * 다른 * 행의 업데이트가 충돌합니다. http://rusanu.com/2009/05/29/lockres-collision-probability-magic-marker-16777215/ –

관련 문제