IO_STALL câu hỏi và hiểu


9

Tôi đang thu thập IO_STALLS từ sys.dm_io_virtual_file_stats cứ sau 5 phút và sau đó thực hiện một delta để xem tệp nào bị ảnh hưởng nhiều nhất bởi IO.

Trong một khoảng thời gian 5 phút, tôi nhận được một đồng bằng 582631 ms là 97 phút.

Tôi hơi bối rối bởi điều này, có phải nó nói rằng một hoạt động đã bắt đầu 97 phút trước chỉ mới kết thúc tại thời điểm đó và do đó ghi lại thời gian chờ đợi đó?

Cảm ơn

Đã thêm mã theo yêu cầu:

/*

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_stalltự nó không có nghĩa là quá nhiều. Nếu trong 10 giây bạn có 1000 thao tác bị đình trệ trong 1 giây, bạn sẽ có 1000 giây hoạt động. Đó sẽ là hơn 16 phút của các quầy hàng trong 10 giây. Bạn cần tương quan điều này với các hoạt động IO. Bạn có thể gửi câu hỏi thực tế của bạn trong câu hỏi của bạn?
Thomas Stringer

Xin chào tôi đã thêm mã, tôi đã gặp một chút rắc rối khi định dạng mã vì vậy tôi hy vọng nó ổn.
Tom

Câu trả lời:


10

Câu hỏi bình luận dán bên dưới:

io_stalltự nó không có nghĩa là quá nhiều. Nếu trong 10 giây bạn có 1000 thao tác bị đình trệ trong 1 giây, bạn sẽ có 1000 giây hoạt động. Đó sẽ là hơn 16 phút của các quầy hàng trong 10 giây. Bạn cần tương quan điều này với các hoạt động IO ...

Trên đây là một ví dụ khá hay về cách bạn có thể nhìn thấy những con số hoành tráng và dường như cường điệu. Chính nó, io_stallkhông thực sự có ý nghĩa gì. Bạn cần biết quy mô của các hoạt động I / O cho gian hàng tích lũy đó.

Thay vì có điều này:

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

Bạn cần chia gian hàng theo các thao tác I / O để có được gian hàng trung bình trên mỗi I / O (hoặc mỗi lần đọc, hoặc viết hoặc bất kỳ mức độ chi tiết nào bạn đang tìm kiếm). Nói cách khác, khuyến nghị của tôi sẽ là sửa đổi truy vấn của bạn để trông giống như thế này:

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)

Và sau đó, bạn cần có một mệnh đề vị ngữ bổ sung để đảm bảo bạn không chia cho 0:

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

Điều này về cơ bản không có tính trung bình io_stallmỗi I / O hoạt động . Chính nó, cao io_stallcó thể đơn giản có nghĩa là khối lượng công việc cao hơn và không nhất thiết là dấu hiệu của một vấn đề.


2
À đúng rồi tôi hiểu, cảm ơn rất nhiều, hy vọng lỗi lầm của tôi sẽ hữu ích với người khác.
Tom

2
Đó là một lỗi phổ biến, không chỉ với số liệu thống kê tệp ảo mà còn cả số liệu thống kê chờ. Vui vì nó đã giúp!
Thomas Stringer
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.