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.