밤새 SQL Server DB를 사용할 수 없게 됨


9

어제 SQL Server 데이터베이스에 문제가 없었습니다. 오늘은 거의 사용할 수 없습니다. 때렸을 때에 따라 5에서 20 사이의 속도로 느려집니다.

야간로드 프로세스에서 일부 데이터가 서버에 추가되었지만 데이터베이스에 큰 영향을 미치는 볼륨과 같은 것은 없습니다. 약 50,000 개의 일반 텍스트 레코드 (XML 또는 기타 frippery 없음).

서버는 오늘 아침에 다시 부팅하기 전에 패치되었습니다. 그러나 패치 된 다른 데이터베이스 서버는 다르게 동작하지 않습니다.

리소스 모니터는 디스크 IO에 결함이 있다고 제안하는 것 같습니다. 실제로 데이터베이스에 별다른 문제가없는 경우에도 .mdf 파일에서 용량의 거의 100 %로 실행 중입니다. Templog.ldf에 대한 액세스도 상당히 높습니다.

여기에는 전문가 DBA (우리는 다양한 SQL 기술을 보유한 모든 개발자)가 없으며, 발생한 상황에 당황합니다. sp_updatestats를 실행하고 큰 인덱스 중 일부를 다른 디스크로 이동했지만 아무 소용이 없었습니다.

패치와 관련이 있다고 생각합니다. 너무 많은 부수적 인 것 같습니다. 동료는 데이터로드로 인해 mdf의 크기가 실행 계획이 비효율적으로되는 지점까지 증가했다고 확신합니다.

지구상에서 무엇이 원인입니까? 우리는 어떻게 알 수 있으며, 그것을 고치기 위해 무엇을 할 수 있습니까?

편집하다:

사용 sp_WhoIsActive하면 평범한 것이 없습니다. 현재 다른 인덱스를 이동하려고하는 동료의 sproc 사용 및 일부 명령을 등록합니다. 아마도 지금 DB를 유지하고 있지만 이전과 마찬가지로 제대로 실행 중이었습니다.

SQL Server 2008 R2의 표준 버전입니다. SELECT @@VERSION제공합니다 :

Microsoft SQL Server 2008 R2 (SP2)-10.50.4033.0 (X64)
2014 년 7 월 9 일 16:04:25
저작권 (c) Windows NT 6.1 (빌드 7601 : 서비스 팩 1)의 Microsoft Corporation Standard Edition (64 비트) (하이퍼 바이저 )

서버에는 72GB의 RAM과 3 개의 쿼드 코어 2GHz 프로세서가 있습니다.

패치는 Windows에만 적용되었습니다. 패치 이외의 변경 사항은 없습니다.

선택된 설정 :

_id     name                        value   minimum     maximum     value_in_use    description                                 is_dynamic  is_advanced
1540    min memory per query (KB)   1024    512         2147483647  1024            minimum memory per query (kBytes)           1           1
1541    query wait (s)              -1      -1          2147483647  -1              maximum time to wait for query memory (s)   1           1
1543    min server memory (MB)      0       0           2147483647  16              Minimum size of server memory (MB)          1           1
1544    max server memory (MB)      65536   16          2147483647  65536           Maximum size of server memory (MB)          1           1

업데이트 : 인덱스와 테이블을 다른 디스크 파티션으로 옮기는 것이 개선되고있는 것 같습니다. 나는 우리가 어떻게 그렇게 급격한 결과로 갑자기 티핑 포인트에 도달 할 수 있었는지에 대해 여전히 혼란 스럽다.


5 분 동안 sp_whoisactive 를 실행 하고 출력을 테이블로 캡처 할 수 있습니까? 당신은에서 다운로드 할 수 있습니다 여기 그리고 이것은 당신이 테이블에 출력을 캡처 할 수있는 방법을 보여줍니다
킨 샤

서버를 다시 시작하면 캐시 된 모든 데이터가 버퍼 풀에서 덤프되고 캐시 된 모든 실행 계획도 덤프됩니다. 즉, SQL Server는 두 가지를 모두 증가시켜야합니다. 모든 실행 계획을 다시 컴파일해야하며 통계가 오래되면 가장 효율적인 계획을 얻지 못할 수 있습니다. 또한 데이터를 디스크에서 메모리로 읽어야하는 반면 다시 시작하기 전에 메모리의 데이터와 함께 윙윙 거리는 것일 수 있습니다. 이것은 수명이 짧아야합니다.
Aaron Bertrand

@AaronBertrand 8 시간 동안 이렇게되었습니다. 패치를 위해 서버를 정기적으로 재부팅하며 이전에는 이와 같은 것을 본 적이 없습니다.
Bob Tway

1
UI를 사용하여 구성 설정을 확인하지 마십시오. SELECT * FROM sys.configurations;-당신은 value, value_in_use같은 것을 원합니다 max server memory (MB). 또한 빌드 번호 SELECT @@VERSION;는 하이퍼 바이저에 있는지 여부와 어제 이후 (또는 마지막으로 SQL Server를 다시 시작한 이후) 호스트에서 변경된 사항이있는 경우에도 유용합니다.
Aaron Bertrand

2
어떤 유형의 IO 하위 시스템을 사용하고 있습니까? SAN, 로컬 디스크 등? 우연히 드라이브가 나빠질 가능성이 있습니까? 또한 DB가 OS 파일과 동일한 위치에 저장되어 있습니까? 그리고 마지막 질문입니다. OS 업그레이드를 수행하기 전의 프로세스 중 일부는 사전에 VM 스냅 샷을 생성하는 것이 었습니다. 불행히도 책임자는 그것을 저지르는 것을 잊었다. 매우 빠르게 전체 시스템이 느려지고 느려졌습니다. 이런 일이 당신에게 일어 났습니까?
케네스 피셔

답변:


3

SQL Server에서 소량의 데이터가 특정 한도에 도달하여 다른 계획이나 이와 유사한 것을 강요 할 수 있습니다. 이것은 가능하지 않습니다. 그러나 당신의 디스크가 엄청나게 많은 것 같다는 사실로 인해 또 다른 결론이 나옵니다.

속도 저하에 대한 두 가지 가능한 기본 이유가 있습니다.

  1. 시스템을 업그레이드하고 재부팅했습니다
  2. 당신은 그것에 많은 데이터를로드

1 번을 보자

SQL Server 구성이 손상되었을 수 있습니다. 이로 인해 서버 속도 및 디스크 사용량과 관련하여 심각한 문제가 발생할 수 있습니다.

첫 번째 인스턴스에서 기본 서버 설정을 확인하십시오. 이러한 기본 설정은 max server memory, affinity I/O mask, affinity maskmax degree of parallelism. 을 사용하여 고급 옵션을 활성화해야 할 수도 있습니다 show advanced options.

완전한 스크립트는 다음과 같습니다.

-- enable advanced options
EXEC sp_configure 'show advanced options',1
-- apply configuration
RECONFIGURE
-- how much memory can the sql server allocate?
EXEC sp_configure 'max server memory'
-- which cpu is used to run I/O operations
EXEC sp_configure 'affinity I/O mask'
-- which cpus can run processes?
EXEC sp_configure 'affinity mask'
-- how many threads can work on one query part?
EXEC sp_configure 'max degree of parallelism'

설치 단계에서 결과를 문서화 된 값과 비교하십시오. 그들은 여전히 ​​동일합니까?

서버가 그렇게 이상하게 행동하는 데는 여러 가지 이유가있을 수 있습니다. 나는 보통 당신의 max server memory잘못이라고 생각합니다. 이로 인해 SQL Server가 데이터 페이지를 영구적으로 교환하게됩니다. 그는 자신의 기억 속에 모든 것을 담을 수 없습니다. 이것은 디스크에서 페이지를 읽고, 업데이트하고, 즉시 다시 써야한다는 것을 의미합니다. 다른 업데이트가 와서 동일한 페이지를 사용하여 업데이트하면 메모리에서 읽을 수 없습니다. 대신 서버는 디스크에서 다시 읽어야합니다. 그냥 교환 ...

다른 문제는 디스크 나 프로세스에 대한 선호도가 높을 수 있습니다. 드문 경우지만 그럴 수도 있지만 SQL Server 전용 디스크와 함께 공유 서버 (SQL Server + 기타 서비스)를 사용하는 경우 문제가 될 수 있습니다. 일반적으로 서버는 예를 들어 프로세스에 대해 3 CPU를, I / O에 대해 1 CPU를 사용했습니다. 다른 12 CPU는 다른 서비스에 사용됩니다. 이 경우 선호도 마스크가 잘못되어 예를 들어 자동 구성이 사용됩니다. 이는 서버가 프로세스 및 I / O에 16 개의 코어를 모두 동적으로 사용함을 의미합니다. 거대한 프로세스가 실행중인 경우 디스크에 큰 부하를 가하여 처리하지 못할 수 있습니다. 그러나 사실, 나는 이것이 당신의 경우라고 생각하지 않습니다. 이것이 적용된다면 더 빠를 것이지만 (조금이라도), 귀하의 경우는 느려집니다.

또 다른 문제는 너무 높은 수준의 병렬 처리 일 수 있습니다. 이는 쿼리의 한 부분에 유휴 상태 인 스레드가 너무 많다는 것을 의미합니다. 병렬 처리가 예상대로 작동하지 않으면 속도가 크게 느려질 수도 있습니다. 그러나 이것은 전체 I / O를 설명하지는 않습니다.

이제 2 번도 살펴 보겠습니다

시스템에 여러 행을로드합니다. 이 작업이 정규 작업 인 경우에도 쿼리 계획이 에스컬레이션되는 한도를 높일 수 있습니다. 삽입을 SQL Server와 함께 사용하면이 동작이 발생할 수도 있습니다.

당신은 당신이 이미 다른 디스크로 색인을 마이그레이션하려고 시도했다고 언급했는데, 도움이 될 것 같습니다. 로드를 두 개의 다른 디스크로 분할한다는 사실 때문에 이런 일이 발생할 수 있습니다.

지수가 파산되었거나 계획이 파산되었거나 통계가 구식 일 수 있습니다.

1. 통계 마지막 업데이트 확인 가능 각 단일 통계 요소의 인터페이스를 통해 수동으로 수행 할 수 있습니다. 어느 것이 고통일까요. 또는이 코드를 사용해보십시오 :

SELECT name AS indexname,
STATS_DATE(OBJECT_ID, index_id) AS StatsUpdated
FROM sys.indexes

그러면 각 인덱스 (및 힙)에 대한 완전한 정보와 그 뒤에있는 통계가 제공됩니다. 실행하더라도 sp_updatestats통계가 업데이트 된 것은 아닙니다. 업데이트가 까다로운 부분은 실행 sp_updatestats하거나 auto update statistics활성화 하더라도 통계가 제 시간에 업데이트되지 않습니다. 다음은 업데이트가 필요할 때 생성되는 몇 가지 요점입니다.

  • 빈 테이블은 하나 이상의 행을 가져옵니다.
  • 500 개가 넘는 행이있는 테이블은 20 % + 500 개의 추가 행을 업데이트하고 이후에 삽입이 발생했습니다.
  • 500 개 미만의 행을 보유하는 테이블에서 500 개 행이 변경된 경우

즉, 업데이트를 실행하더라도 통계가 오래되었을 수 있습니다.

위의 쿼리를 살펴볼 수 있습니다. 일부 테이블에서 꽤 오래된 통계를 찾으면이 테이블에 대한 수동 통계 업데이트를 실행할 수 있습니다.

UPDATE STATISTICS dbo.YourBadTable WITH FULLSCAN

그 후, 당신은 당신의 서버가 엉덩이에 킥을 줘서 모든 오래된 계획을 버릴 수 있습니다.

DBCC FREEPROCCACHE 

모든 캐시를 정리하려면 대신 다음을 실행하십시오.

DBCC FREESYSTEMCACHE ('ALL')

계획 캐시뿐만 아니라 모든 캐시가 정리됩니다. 나는 보통 프로덕션 단계에서 프로덕션 서버에서 이것을 사용하도록 경고합니다. 그러나 현재 서버가 작동하지 않기 때문에 서버를 너무 손상시킬 수 없습니다. 모든 캐시를 다시 작성해야하기 때문에 1-2 초 정도 속도가 느려질 수 있지만 그 후에는 올바른 계획으로 실행해야합니다.

또 다른 이유는 완전히 조각난 지수 일 수 있습니다. 다음 명령문을 사용하여 전체 서버에서 확인할 수 있습니다.

SELECT * 
FROM sys.dm_db_index_physical_stats (NULL, NULL, NULL, NULL, NULL)

조각화가 매우 높은 경우이를 재구성 (조각화 <20 %)하거나 완전히 재구성 (> 20 %)해야합니다. 디스크에 압력이 가해져 문제가 발생할 수 있습니다. 반면에 지수가 그렇게 나쁘면 결국 해를 끼치는 것보다 더 도움이 될 것입니다.

이 두 가지 이유 외에도 여전히 세 번째 문제가있을 수 있습니다

서버가 구성되었을 수 있습니다.이 시점에서 코드를 변경하지 않았으며 몇 행을 추가했습니다. 모든 통계가 업데이트되고 모든 캐시가 다시 작성됩니다. 모든 지수는 필요한 방식으로 재구성되지만 여전히 작동하지 않습니다. 프로세스에서 사용 가능한 메모리 한계에 도달했을 수 있습니다. 아마도 더 필요할 것입니다. 기존보다 많은 메모리를 확보하려는 프로세스가 있는지 간단히 확인할 수 있습니다.

이 명령을 사용하여이를 확인할 수 있습니다.

SELECT * FROM sys.dm_exec_query_memory_grants

메모리를 소비하는 모든 세션 목록을 제공합니다. 여전히 메모리를 얻기 위해 대기중인 쿼리가있을 수 있습니다. 이러한 쿼리는 쉽게 필터링 할 수 있습니다. 모든 세션 granted_memory_kb IS NULL. 이것은 메모리를 요청했지만 얻지 못하는 세션입니다. 또 다른 것은 메모리 부족 일 수 있습니다. 당신은 열을 비교할 수 있습니다 requested_memory_kbgranted_memory_kb. 요청은 프로세스가 최적으로 실행하는 데 필요한 메모리 양을 표시하고 부여 된 프로세스는 프로세스에 사용할 수있는 메모리를 표시합니다. 프로세스를 실행하는 데 2GB가 필요하지만 2MB 만 가져 오는 경우 직접 처리 할 수 ​​있습니다. ;-)

다른 방법은 다음을 확인하는 것입니다 RESSOURCE_SEMAPHORE.

SELECT * FROM sys.dm_exec_query_resource_semaphore

당신은 한 번 봐 걸릴 수 waiter_count와를 grantee_count. 웨이터가 0보다 높으면 메모리에 압력이 가해져 스왑이 발생하고 perfmon에서 디스크 압력이 발생할 수 있습니다.


0

가능한 드라이브 오류 외에도 RAID 하위 시스템의 상태를 확인하십시오. 우리는 비슷한 것을 보았고 RAID 컨트롤러의 배터리가 고장 나서 쓰기 캐시가 없었습니다. 모든 쓰기는 디스크로 직접 이동해야했습니다. 한 가지 참고 사항-RDC가 시스템을 일시 중지하는 동안 시스템이 일시 중지되는 것을 느낄 수 있습니다.

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