SQL Server의 디스크 I / O가 높거나 SQL Server의 디스크 I / O 속도가 느려 집니까?


18

나는 SQLA의 성능 문제에 대해 DBA와 몇 명의 하드웨어 담당자와 논쟁을 벌였습니다. 일반적으로 모든 것이 정상이지만 지난 몇 주 동안 우리는 SQL Server에서 엄청난 지연 시간이 발생했습니다. SQL Server가 디스크 I / O를 기다리고 있다는 것은 분명합니다. 그러나 SQL Server가 비정상적으로 높은 I / O를 요구하고 있기 때문에 계속 들었습니다. 그렇지 않습니다. 나는 실행중인 것에서 정상적인 것 외에는 아무것도 없다는 것을 알 수 있으며, 모든 DBA가보아야 할 것은 블로킹을 일으키는 원인입니다. 예를 들어 백업하는 주요 사항은 웹 서버에서 ASP 세션 상태를 관리하는 데 사용하는 ASPState 데이터베이스에서의 작업입니다. 이러한 작업은 일반적으로 Sp_who2 활성 결과에서 너무 빨리 발생하기 때문에 전혀 보이지 않습니다. 데이터베이스가 단순 복구 모드에 있으며 로깅이 거의 없습니다. 그러나 이러한 지연 시간 동안 차단되거나 대기중인 데이터베이스에서 많은 선택 및 업데이트 작업을 볼 수 있습니다. 나는 무슨 일이 일어나고 있는지 누군가 또는 어떤 작업이 해당 데이터베이스 로그 및 데이터 파일에 사용되는 RAID 어레이에서 많은 디스크 사용을 일으키는 무언가를 실행하고 있다고 확신합니다. 아무도 우리 웹 사이트를 죽이는 일을 인정하고 싶지 않기 때문에 문제가 그것을 증명하고 있습니다.

내 질문은 SQL 서버가 I / O를 기다리고 있음을 나타내는 데 도움이되는 성능 카운터 또는 로깅 할 수있는 것입니다. 평소처럼 빨리?


3
Network I / O의 실제 대기 상태는 무엇입니까? 즉, SAN을 사용하고 있습니까?
Eric Higgins

DB 서버에서 리소스 사용량을 지배하는 쿼리가 있는지 확인하십시오. 있다면 조정하십시오. 잘못 작동하는 쿼리가없는 경우 PAGEIOLATCH 대기 시간이 길면 일반적으로 시스템이 I / O 바운드 상태임을 나타냅니다. 또한 @EricHiggins가 말했듯이 SAN은 종종 속도가 느려 데이터베이스 성능 문제를 유발합니다.
ConcernedOfTunbridgeWells

Qlogic 파이버 HBA를 사용하여 SQL Server에 연결된 NETAPP 배열입니다.
Edgey

나는 이것이 비교적 오래된 질문이라는 것을 알고 있으며 문제를 직접 해결할 수는 없지만 세션 상태를 위해 aspnet_state.exe로 전환하여 SQL Server에서 많은 부하를 겪었습니다. 잘 문서화되어 있지 않지만 설정이 매우 쉽습니다.
MattGWagner

그래서 당신 / DBA는 무엇을하고 있었고 문제는 무엇입니까?
Mukus

답변:


19

다음 perfmon 카운터를 살펴보십시오.

많은 수의 IO 요청을 수행하는 SQL Server는 많은 수의 스캔, 페이지 조회 및 페이지 읽기 증가 및 높은 페이지 IO 래치 대기로 확증됩니다. sys.dm_exec_query_stats실제 읽기 수가 많은 항목을 살펴볼 가치가 있습니다. 그들은 범인을 신속하게 찾아 낼 수있었습니다.

일반적으로 성능 문제 해결 문제로 문제에 접근하려면 대기 및 대기열과 같은 방법론을 따르는 것이 올바른 방법입니다. DBA가 올바른 일을하고있는 것 같습니다.


나는 DBA에 문제가 없다. 그는 내가 함께 일한 최고의 DBA 중 하나이다. 그리고 그는 나에게 높은 차단 저장 프로 시저 목록을 제공했습니다. 그러나 많은 블로킹을 일으키는 procs 중 하나를 언급했듯이 SQL 세션 상태 저장소에서 사용되는 proc 인 "TempUpdateStateItemLong"입니다. MS proc이며 테이블의 인덱스 된 기본 키인 sessionID로 단일 테이블 만 업데이트합니다. 또한이 표에는 최대 2000-3000 개의 레코드가 있으므로 업데이트에는 시간이 전혀 걸리지 않습니다.
Edgey

이곳은 시작하기에 좋은 곳입니다. 우리는 여전히 SQL Server 2000을 실행하고 있으며 업그레이드 과정에 있지만 몇 개월 동안 더 이상 발생하지 않으므로 PAge IO Latch 대기 카운터가 없습니다. 다시 감사합니다.
Edgey

per-se를 차단한다고 IO가 높음을 의미하지는 않습니다. 잠금 경합이 될 수 있으며, 특히 옵티마이 저가 테이블 스캔 기반 계획을 선택하는 경우 크기에 상관없이 테이블에 영향을 미칩니다.
Remus Rusanu

또한 프로세스 를 확인하고 IO Data Bytes/sec다른 프로세스가 디스크를 휴지통에 있는지 확인 하십시오.
Remus Rusanu

12

Glenn Berry의 진단 쿼리 와 Adam Machanic의 SP_Whoisactive 를 사용하여 실제로 일어나는 일을 찾으십시오.

먼저이 쿼리를 실행하여 IO 병목 현상이 가장 많은 데이터베이스 파일을 확인하십시오 (Query by Glenn Berry)

SELECT  DB_NAME(fs.database_id) AS [Database Name] ,
        mf.physical_name ,
        io_stall_read_ms ,
        num_of_reads ,
        CAST(io_stall_read_ms / ( 1.0 + num_of_reads ) AS NUMERIC(10, 1)) AS [avg_read_stall_ms] ,
        io_stall_write_ms ,
        num_of_writes ,
        CAST(io_stall_write_ms / ( 1.0 + num_of_writes ) AS NUMERIC(10, 1)) AS [avg_write_stall_ms] ,
        io_stall_read_ms + io_stall_write_ms AS [io_stalls] ,
        num_of_reads + num_of_writes AS [total_io] ,
        CAST(( io_stall_read_ms + io_stall_write_ms ) / ( 1.0 + num_of_reads
                                                          + num_of_writes ) AS NUMERIC(10,
                                                              1)) AS [avg_io_stall_ms]
FROM    sys.dm_io_virtual_file_stats(NULL, NULL) AS fs
        INNER JOIN sys.master_files AS mf WITH ( NOLOCK ) ON fs.database_id = mf.database_id
                                                             AND fs.[file_id] = mf.[file_id]
ORDER BY avg_io_stall_ms DESC
OPTION  ( RECOMPILE );

그런 다음이 쿼리를 실행하여 서버가 대기중인 상위 10 개 이벤트를 확인하십시오 ( Jonathan Kehayias의 쿼리 ). Glenn Berry 진단 쿼리에서도 유사한 쿼리를 찾을 수 있습니다.

SELECT TOP 10
        wait_type ,
        max_wait_time_ms wait_time_ms ,
        signal_wait_time_ms ,
        wait_time_ms - signal_wait_time_ms AS resource_wait_time_ms ,
        100.0 * wait_time_ms / SUM(wait_time_ms) OVER ( ) AS percent_total_waits ,
        100.0 * signal_wait_time_ms / SUM(signal_wait_time_ms) OVER ( ) AS percent_total_signal_waits ,
        100.0 * ( wait_time_ms - signal_wait_time_ms )
        / SUM(wait_time_ms) OVER ( ) AS percent_total_resource_waits
FROM    sys.dm_os_wait_stats
WHERE   wait_time_ms > 0 -- remove zero wait_time
        AND wait_type NOT IN -- filter out additional irrelevant waits
( 'SLEEP_TASK', 'BROKER_TASK_STOP', 'BROKER_TO_FLUSH', 'SQLTRACE_BUFFER_FLUSH',
  'CLR_AUTO_EVENT', 'CLR_MANUAL_EVENT', 'LAZYWRITER_SLEEP', 'SLEEP_SYSTEMTASK',
  'SLEEP_BPOOL_FLUSH', 'BROKER_EVENTHANDLER', 'XE_DISPATCHER_WAIT',
  'FT_IFTSHC_MUTEX', 'CHECKPOINT_QUEUE', 'FT_IFTS_SCHEDULER_IDLE_WAIT',
  'BROKER_TRANSMITTER', 'FT_IFTSHC_MUTEX', 'KSOURCE_WAKEUP',
  'LAZYWRITER_SLEEP', 'LOGMGR_QUEUE', 'ONDEMAND_TASK_QUEUE',
  'REQUEST_FOR_DEADLOCK_SEARCH', 'XE_TIMER_EVENT', 'BAD_PAGE_PROCESS',
  'DBMIRROR_EVENTS_QUEUE', 'BROKER_RECEIVE_WAITFOR',
  'PREEMPTIVE_OS_GETPROCADDRESS', 'PREEMPTIVE_OS_AUTHENTICATIONOPS', 'WAITFOR',
  'DISPATCHER_QUEUE_SEMAPHORE', 'XE_DISPATCHER_JOIN', 'RESOURCE_QUEUE' )
ORDER BY wait_time_ms DESC

이 정보를 가지고 있으면 문제를 해결하기가 훨씬 쉬울 것입니다.

BTW 여기 에서 문제 해결을 위해 sp_whoisactive를 사용하는 방법에 대한 많은 게시물을 찾을 수 있습니다.


1
방금이 목록의 마지막 스크립트 인 킥 엉덩이를 사용했습니다.
the_good_pony

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