"데이터 이동으로 인해 NOLOCK으로 스캔을 계속할 수 없습니다"를 재현하는 방법


10

선택 쿼리에 대한 NOLOCK일부 큰 작업에서 "데이터 이동으로 인해 스캔을 계속할 수 없습니다 "라는 메시지가 표시되는 경우가 있습니다 WITH (NOLOCK).

나는 페이지 분할이있을 때 데이터를 더 이상 원래의 위치에 두지 않았을 때 데이터를 선택하려고 시도하는 것과 관련이 있음을 이해합니다. 내 환경에서 일어나는 일이라고 가정합니다.

이것을 어떻게 재현합니까?

오류를 포착 하고이 문제가 발생하면 다시 시도하기 위해 단기 해결 방법을 시도하고 있지만 오류를 재현 할 수 없으면 테스트 할 수 없습니다. 이것을 일으키는 합리적으로 신뢰할 수있는 방법이 있습니까?

이런 일이 발생하면 쿼리를 다시 실행하면 성공하게되므로 실제 데이터 나 데이터베이스가 영구적으로 손상 될 염려는 없습니다. 쿼리의 일부 테이블 (인덱스와 함께)이 자주 삭제, 재 작성 및 다시 채워 지므로 이와 관련된 것으로 가정합니다.

제거하는 NOLOCK것이 장기적인 문제입니다. 그 이유 NOLOCK는 쿼리가 너무 나빠서 일일 트랜잭션으로 NOLOCK교착 상태에 빠졌기 때문에 교착 상태를 막기위한 반창고 (작동 한) 이기 때문 입니다. 그래서 영구적 인 해결책을 찾을 수있을 때까지 반창고에 반창고가 필요합니다.

Hello World로 복제 할 수 있다면 1 시간 이내에 반창고를 업무에 옮길 계획입니다. NOLOCK앱 교착 상태를 다시 시작하기 때문에 검색 및 교체 제거를 수행 할 수 없습니다 . 이는 때때로 실패한 작업보다 나에게 좋지 않습니다.

커밋 된 읽기 스냅 샷 격리를 사용하는 것이 좋습니다. 자세한 내용을 확인하려면 데이터베이스 팀과 협력해야합니다. 우리의 문제 중 하나는 우리가 SQL Server 전문가가 그런 종류의 일을 처리하지 못한다는 것입니다. 그리고 지금 당장 그러한 변경을 할 정도로 격리 수준을 충분히 이해하지 못하고 있습니다.


1
NOLOCK이 작업에서 단순히 제거하는 것을 고려 했습니까 ? 이 쿼리의 결과가 정확해야한다면 601은 걱정할 것이 가장 적어야합니다 . 폴 화이트 (Paul White)는 여기서는 불가능한 데이터 읽기의 끔찍한 예를 보여줍니다 .
Aaron Bertrand

3
당신은 설정할 수 DEADLOCK_PRIORITYLOW응용 프로그램을 교착 상태가있는 경우, 작업이 실패 할 수 있도록, 작업에, 그리고. 그 후에 교착 상태를 조사하고 그 원인이 발생하는 이유를 찾아 해당 문제를 해결할 수 있습니다. 두 문장의 순서를 바꾸는 것과 같이 매우 간단한 수정 일 수 있습니다. 문제가 무엇이든간에 해결책NOLOCK아니므로 가장 쉬운 방법이므로 강제로 시도 하지 마십시오 .
Aaron Bertrand

@AaronBertrand 감사합니다. DEADLOCK_PRIORITY에 대해 몰랐습니다. 살펴 보겠습니다. 교착 상태를 추적하려고 시도했지만 하루에 한두 번 다양한 임의의 시간에 발생했으며 요청시 재현 할 수 없었습니다. 예약 된 작업은 매시간 수만 건의 쿼리를 실행하고 앱은 수백 건을 실행합니다. 페이지를로드하거나 무언가를 저장할 때마다 쿼리 수, 교착 상태와 관련된 어느 쿼리가 추적되지 않았습니다. 나는 NOLOCK을 영원히 남겨 두려는 의도가 없었기 때문에 더 나은 장기 솔루션을 연구하고 있습니다.
wookie23

1
교착 상태를 추적하는 데 어려움을 겪고 있다고 언급했습니다. 2008 R2에 있다고 가정하면 다음을 볼 수 있습니다. sqlservercentral.com/articles/deadlock/65658 Jonathan Kehayias는 링 버퍼에서 교착 상태 정보를 가져옵니다.
케네스 피셔

답변과 의견은 근본적인 문제를 잘 해결하지만 지적 운동으로 이것을 재현하는 방법을 찾는 데 여전히 관심이 있습니까?
James L

답변:


8

NOLOCK 문제에 대한 잠재적 인 '밴드 원조'는 NOLOCK 사용을 중단하고 READ_COMMITTED_SNAPSHOT 격리 사용을 시작하는 것이므로 Kendra Little : http://www.brentozar.com (Kendra Little)의 스냅 샷 또는 읽기 커밋 된 블로그 게시물을 알려 드리고자합니다. SQL Server의 스냅 샷 격리 : 가이드 .

Kendra는 READ_COMMITTED_SNAPSHOT 격리 수준을 사용하여 이점과 위험에 대해 상당한 세부 정보를 제공합니다.

  1. 이 격리 수준은 데이터베이스 코드의 기본 격리 수준이됩니다.
  2. READ_COMMITTED_SNAPSHOT 격리 수준을 변경하려면 데이터베이스에 한 명의 사용자 만 있어야합니다.
  3. READ_COMMITTED_SNAPSHOT 격리를 사용하더라도 NOLOCK 힌트 는 기본값을 무시하므로 여전히 제거해야합니다 .
  4. 일부 코드에는 치료가 필요한 문제가있을 수 있습니다.

몇 년 전 우리 는 블로킹 으로 인해 심각한 데이터베이스에서 READ_COMMITTED_SNAPSHOT 격리를 구현했습니다 . 그러나 일단 격리 수준을 변경하면 몇 가지 중요한 영역에서 교착 상태발생 하기 시작했습니다 .

왜 이런 일이 일어 났습니까? 이전의 격리 수준으로 인해 강력한 차단이 발생했기 때문에 코드는 교착 상태에 도달 할 수 없었습니다. 그러나 READ_COMMITTED_SNAPSHOT 격리를 사용하면 쿼리가 계속 진행될 수 있습니다. 그러나 더 이상 대기하지 않는 트랜잭션의 일부 비율이 교착 상태에 빠지기 시작했습니다.

다행히 교착 상태 지점을 결정하고보다 합리적인 열 순서를 갖도록 두 테이블의 인덱스를 조정하여 사례를 신속하게 해결했습니다. 이것은 잠금 문제를 크게 줄였습니다.

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