Question et compréhension IO_STALL


9

Je collecte des IO_STALLS à partir de sys.dm_io_virtual_file_stats toutes les 5 minutes, puis je fais un delta pour voir quels fichiers sont les plus affectés par les E / S.

En une période de 5 minutes, j'obtiens un delta de 5826331 ms, soit 97 minutes.

Je suis un peu confus par cela, est-ce à dire qu'une opération commencée il y a 97 minutes vient juste de se terminer à ce moment-là et a donc enregistré ce temps d'attente?

Merci

Code ajouté comme demandé:

/*

USE [SysDBA]
GO
*/
/****** Object:  Table [dbo].[DISKIOPS]    Script Date: 04/07/2013 11:40:15 ******/
/*
DROP TABLE [dbo].[DISKIOPS]
GO
*/
--Create the table
/****** Object:  Table [dbo].[DISKIOPS]    Script Date: 04/07/2013 11:40:15 ******/
/*
SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

SET ANSI_PADDING ON
GO

CREATE TABLE [dbo].[DISKIOPS](
    [IO_STALL] [bigint] NULL,
    [IO_STALL_READ_MS] [bigint] NULL,
    [IO_STALL_WRITE_MS] [bigint] NULL,
    [NUM_OF_READS] [bigint] NULL,
    [NUM_OF_WRITES] [bigint] NULL,
    [SIZE_ON_DISK_MB] [bigint] NULL,
    [DBNAME] [varchar](max) NULL,
    [NAME] [varchar](max) NULL,
    [FILE_ID] [int] NULL,
    [DB_FILE_TYPE] [varchar](max) NULL,
    [DISK] [varchar](max) NULL,
    [FILE_LOCATION] [varchar](max) NULL,
    [TIMESTAMP] [datetime] NULL
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO

SET ANSI_PADDING OFF
GO

*/

--Capture IO information from DMV and query to find deltas over time.
/*
USE [SysDBA]
GO

INSERT INTO [dbo].[DISKIOPS]
           ([IO_STALL]
           ,[IO_STALL_READ_MS]
           ,[IO_STALL_WRITE_MS]
           ,[NUM_OF_READS]
           ,[NUM_OF_WRITES]
           ,[SIZE_ON_DISK_MB]
           ,[DBNAME]
           ,[NAME]
           ,[FILE_ID]
           ,[DB_FILE_TYPE]
           ,[DISK]
           ,[FILE_LOCATION]
           ,[TIMESTAMP])
SELECT a.io_stall, a.io_stall_read_ms, a.io_stall_write_ms, a.num_of_reads, 
a.num_of_writes, 
--a.sample_ms, a.num_of_bytes_read, a.num_of_bytes_written,
( ( a.size_on_disk_bytes / 1024 ) / 1024.0 ) AS size_on_disk_mb, 
db_name(a.database_id) AS dbname, 
b.name, a.file_id, 
db_file_type = CASE 
                   WHEN a.file_id = 2 THEN 'Log' 
                   ELSE 'Data' 
                   END, 
UPPER(SUBSTRING(b.physical_name, 1, 2)) AS disk_location,
b.physical_name AS File_location,
GETDATE() AS Timestamp
FROM sys.dm_io_virtual_file_stats (NULL, NULL) a 
JOIN sys.master_files b ON a.file_id = b.file_id 
AND a.database_id = b.database_id
GO
*/
DECLARE @File_Name VARCHAR(8000),
        @Disk VARCHAR(5)
SET @File_Name = 'DBTEST'
SET @Disk = 'I:'
--Code to pull out deltas between collected IO stats.
;WITH IOPS   ([IO_STALL]
           ,[IO_STALL_READ_MS]
           ,[IO_STALL_WRITE_MS]
           ,[NUM_OF_READS]
           ,[NUM_OF_WRITES]
           ,[SIZE_ON_DISK_MB]
           ,[DBNAME]
           ,[NAME]
           ,[FILE_ID]
           ,[DB_FILE_TYPE]
           ,[DISK]
           ,[FILE_LOCATION]
           ,[TIMESTAMP]
           ,[ROW])
AS
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY FILE_LOCATION ORDER BY TIMESTAMP DESC) AS [ROW]
FROM dbo.DISKIOPS 
)

SELECT MAX([IO2].[IO_STALL] - [IO1].[IO_STALL])
FROM IOPS IO1 JOIN IOPS IO2 ON IO1.ROW = (IO2.ROW+1)
WHERE IO1.NAME = IO2.NAME
AND IO1.Disk = @Disk

1
io_stallen soi ne signifie pas trop. Si en 10 secondes vous aviez 1000 opérations bloquées pendant 1 seconde chacune, vous aurez 1000 secondes de décrochages. Ce serait plus de 16 minutes de décrochage en 10 secondes. Vous devez corréler cela avec les opérations d'E / S. Pouvez-vous publier votre requête réelle dans votre question?
Thomas Stringer

Salut, j'ai ajouté le code, j'avais un peu de mal à le formater donc j'espère que ça va.
Tom

Réponses:


10

Commentaire de question collé ci-dessous:

io_stallen soi ne signifie pas trop. Si en 10 secondes vous aviez 1000 opérations bloquées pendant 1 seconde chacune, vous aurez 1000 secondes de décrochages. Ce serait plus de 16 minutes de décrochage en 10 secondes. Vous devez corréler cela avec les opérations d'E / S ...

Ce qui précède est un assez bon exemple de la façon dont vous pouvez voir des nombres monumentaux et apparemment exagérés. En soi, io_stallcela ne veut vraiment rien dire. Vous devez connaître l'échelle des opérations d'E / S pour ce décrochage cumulatif.

Au lieu d'avoir ceci:

SELECT MAX([IO2].[IO_STALL] - [IO1].[IO_STALL])
FROM IOPS IO1 JOIN IOPS IO2 ON IO1.ROW = (IO2.ROW+1)
...

Vous devez diviser le décrochage par opérations d'E / S pour obtenir le décrochage moyen par E / S (ou par lecture, ou écriture, ou quelle que soit la granularité que vous recherchez). En d'autres termes, ma recommandation serait de modifier votre requête pour ressembler à ceci:

SELECT
    MAX(([IO2].[IO_STALL] - [IO1].[IO_STALL]) / (IO2.NUM_OF_READS + IO2.NUM_OF_WRITES - IO1.NUM_OF_READS - IO1.NUM_OF_WRITES))
FROM IOPS IO1 JOIN IOPS IO2 ON IO1.ROW = (IO2.ROW+1)

Et puis vous devez avoir une clause de prédicat supplémentaire pour vous assurer que vous ne divisez pas par zéro:

...
WHERE IO1.NAME = IO2.NAME
and (IO2.NUM_OF_READS + IO2.NUM_OF_WRITES - IO1.NUM_OF_READS - IO1.NUM_OF_WRITES) > 0
AND IO1.Disk = @Disk

Ce que cela fait essentiellement est de calculer la moyenne io_stallpar opération E / S . En soi, un niveau élevé io_stallpourrait simplement signifier une charge de travail plus élevée et pas nécessairement le signe d'un problème.


2
Ah oui je comprends, merci beaucoup, j'espère que mon erreur sera utile aux autres.
Tom

2
C'est une erreur courante, non seulement avec les statistiques des fichiers virtuels, mais aussi avec les statistiques d'attente. Heureux que cela ait aidé!
Thomas Stringer
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.