IO_STALL Frage und Verständnis

9

Ich sammle alle 5 Minuten IO_STALLS aus sys.dm_io_virtual_file_stats und mache dann ein Delta, um zu sehen, welche Dateien am meisten von IO betroffen sind.

In einem Zeitraum von 5 Minuten erhalte ich ein Delta von 5826331 ms, was 97 Minuten entspricht.

Ich bin ein wenig verwirrt darüber. Bedeutet dies, dass eine Operation, die vor 97 Minuten begonnen wurde, erst zu diesem Zeitpunkt beendet wurde und daher diese Wartezeit aufzeichnete?

Vielen Dank

Code wie gewünscht hinzugefügt:

/*

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
Tom
quelle
1
io_stallan sich bedeutet nicht zu viel. Wenn Sie in 10 Sekunden 1000 Vorgänge für jeweils 1 Sekunde zum Stillstand gebracht haben, haben Sie 1000 Sekunden Stillstand. Das wären mehr als 16 Minuten Stand in 10 Sekunden. Sie müssen dies mit E / A-Operationen korrelieren. Können Sie Ihre aktuelle Anfrage in Ihrer Frage posten?
Thomas Stringer
Hallo, ich habe den Code hinzugefügt. Ich hatte einige Probleme, ihn zum Formatieren zu bringen, also hoffe ich, dass er in Ordnung ist.
Tom

Antworten:

10

Frage Kommentar unten eingefügt:

io_stallan sich bedeutet nicht zu viel. Wenn Sie in 10 Sekunden 1000 Vorgänge für jeweils 1 Sekunde zum Stillstand gebracht haben, haben Sie 1000 Sekunden Stillstand. Das wären mehr als 16 Minuten Stand in 10 Sekunden. Sie müssen dies mit E / A-Operationen korrelieren ...

Das Obige ist ein ziemlich gutes Beispiel dafür, wie Sie monumentale und scheinbar übertriebene Zahlen sehen können. An sich io_stallbedeutet das eigentlich nichts. Sie müssen den Umfang der E / A-Operationen für diesen kumulativen Stillstand kennen.

Anstatt dies zu haben:

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

Sie müssen den Stall durch E / A-Operationen teilen, um den durchschnittlichen Stall pro E / A (oder pro Lese- oder Schreibzugriff oder nach der gewünschten Granularität) zu erhalten. Mit anderen Worten, meine Empfehlung wäre, Ihre Abfrage so zu ändern, dass sie ungefähr so ​​aussieht:

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)

Und dann benötigen Sie eine zusätzliche Prädikatklausel, um sicherzustellen, dass Sie nicht durch Null teilen:

...
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

Grundsätzlich wird der Durchschnitt io_stallpro E / A-Vorgang berechnet . Ein Hoch an sich io_stallkönnte einfach eine höhere Arbeitsbelastung bedeuten und nicht unbedingt das Zeichen eines Problems.

Thomas Stringer
quelle
2
Ah richtig, ich verstehe, vielen Dank, hoffentlich wird sich mein Fehler für andere als nützlich erweisen.
Tom
2
Dies ist ein häufiger Fehler, nicht nur bei virtuellen Dateistatistiken, sondern auch bei Wartestatistiken. Ich bin froh, dass es geholfen hat!
Thomas Stringer