-
Notifications
You must be signed in to change notification settings - Fork 4
/
Management.VirtualFileStats.sql
272 lines (245 loc) · 10.2 KB
/
Management.VirtualFileStats.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
---------------------------------------------------------------------------------------
-- VirtualFileStats tables
-- by: Wesley D. Brown
-- date: 02/08/2011
-- mod:
-- description:
-- Tables needed for GatherVirtualFileStats stored procedure
-- parameters:
-- platforms:
-- SQL Server 2005
-- SQL Server 2008
-- SQL Server 2008 R2
-- tested:
-- SQL Server 2005 SP2
-- SQL Server 2008 R2
---------------------------------------------------------------------------------------
-- *** change log ***
-- *** end change log ***
---------------------------------------------------------------------------------------
--USE <Management>
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[VirtualFileStatsHistory]') AND type in (N'U'))
DROP TABLE [dbo].[VirtualFileStatsHistory]
GO
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[VirtualFileStats]') AND type in (N'U'))
DROP TABLE [dbo].[VirtualFileStats]
GO
CREATE TABLE dbo.VirtualFileStats
(
RecordID INT IDENTITY(1,1) NOT NULL,
ServerName VARCHAR(255) NOT NULL,
DBID INT NOT NULL,
FileID INT NOT NULL,
Reads BIGINT NULL,
ReadsFromStart BIGINT NULL,
Writes BIGINT NULL,
WritesFromStart BIGINT NULL,
BytesRead BIGINT NULL,
BytesReadFromStart BIGINT NULL,
BytesWritten BIGINT NULL,
BytesWrittenFromStart BIGINT NULL,
IostallInMilliseconds BIGINT NULL,
IostallInMillisecondsFromStart BIGINT NULL,
IostallReadsInMilliseconds BIGINT NULL,
IostallReadsInMillisecondsFromStart BIGINT NULL,
IostallWritesInMilliseconds BIGINT NULL,
IostallWritesInMillisecondsFromStart BIGINT NULL,
RecordedDateTime DATETIME NULL,
IntervalInMilliseconds BIGINT NULL,
FirstMeasureFromStart BIT NULL
)
GO
CREATE TABLE dbo.VirtualFileStatsHistory
(
RecordID INT NOT NULL,
ServerName VARCHAR(255) NOT NULL,
DBID INT NOT NULL,
FileID INT NOT NULL,
Reads BIGINT NULL,
ReadsFromStart BIGINT NULL,
Writes BIGINT NULL,
WritesFromStart BIGINT NULL,
BytesRead BIGINT NULL,
BytesReadFromStart BIGINT NULL,
BytesWritten BIGINT NULL,
BytesWrittenFromStart BIGINT NULL,
IostallInMilliseconds BIGINT NULL,
IostallInMillisecondsFromStart BIGINT NULL,
IostallReadsInMilliseconds BIGINT NULL,
IostallReadsInMillisecondsFromStart BIGINT NULL,
IostallWritesInMilliseconds BIGINT NULL,
IostallWritesInMillisecondsFromStart BIGINT NULL,
RecordedDateTime DATETIME NULL,
IntervalInMilliseconds BIGINT NULL,
FirstMeasureFromStart BIT NULL
)
IF EXISTS (SELECT
*
FROM
dbo.sysobjects
WHERE
id = Object_id(N'[dbo].[GatherVirtualFileStats]')
AND Objectproperty(id, N'IsProcedure') = 1)
DROP PROCEDURE [dbo].[GatherVirtualFileStats]
GO
---------------------------------------------------------------------------------------
-- GatherVirtualFileStats
-- by: Wesley D. Brown
-- date: 02/08/2011
-- mod: 04/14/2011
-- description:
-- This stored procedure is used to sample sys.dm_io_virtual_file_stats to track
-- performance at a database file level. This is useful for finding
-- hotspots on SAN's or under performing IO systems.
-- parameters:
-- @Duration = '01:00:00' How long to run before exiting
-- @IntervalInSeconds = 120 Number of seconds between samples
--@DB = -1 DB_ID to monitor, -1 for all
--@DBFile = -1 File_ID of file to monitor, -1 for all
-- usage:
-- DECLARE @RC INT,
-- @StartTime DATETIME,
-- @databaseID INT
-- SELECT @StartTime = Getdate(),
-- @databaseID = Db_id()
-- EXEC @RC = Gathervirtualfilestats
-- '00:45:30',
-- 30,
-- 10,
-- -1
-- SELECT *
-- FROM dbo.VirtualFileStats
-- WHERE DBID = 10
-- ORDER BY RecordID
-- platforms:
-- SQL Server 2005
-- SQL Server 2008
-- SQL Server 2008 R2
-- tested:
-- SQL Server 2005 SP2
-- SQL Server 2008 R2
---------------------------------------------------------------------------------------
-- *** change log ***
-- Added history table and perge on start up if there is data in the main table
-- *** end change log ***
---------------------------------------------------------------------------------------
IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[Gathervirtualfilestats]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[Gathervirtualfilestats]
GO
CREATE PROC dbo.GatherVirtualFileStats
@Duration DATETIME = '01:00:00',
@IntervalInSeconds INT = 120,
@DB INT = -1,
@DBFile INT = -1
AS
SET nocount ON
DECLARE
@StopTime DATETIME,
@LastRecordedDateTime DATETIME,
@CurrentDateTime DATETIME,
@ErrorNumber INT,
@NumberOfRows INT,
@ErrorMessageText NVARCHAR(4000),
@CurrentServerName VARCHAR(255),
@DifferenceInMilliSeconds BIGINT
IF EXISTS (SELECT
1
FROM
dbo.VirtualFileStats)
BEGIN
IF EXISTS (SELECT
*
FROM
dbo.sysobjects
WHERE
id = Object_id(N'[dbo].[VirtualFileStats]')
AND Objectproperty(id, N'IsTable') = 1)
BEGIN
INSERT INTO dbo.VirtualFileStatsHistory
SELECT
*
FROM
VirtualFileStats;
TRUNCATE TABLE dbo.VirtualFileStats;
END
END
SELECT
@CurrentServerName = Cast(Serverproperty('servername') AS VARCHAR(255))
SET @DifferenceInMilliSeconds = Datediff(ms, CONVERT(DATETIME, '00:00:00', 8), @Duration)
SELECT
@StopTime = Dateadd(ms, @DifferenceInMilliSeconds, Getdate())
WHILE Getdate() <= @StopTime
BEGIN
SELECT
@LastRecordedDateTime = @CurrentDateTime
SELECT
@CurrentDateTime = Getdate()
INSERT INTO dbo.VirtualFileStats
(ServerName,
DBID,
FileID,
Reads,
ReadsFromStart,
Writes,
WritesFromStart,
BytesRead,
BytesReadFromStart,
BytesWritten,
BytesWrittenFromStart,
IostallInMilliseconds,
IostallInMillisecondsFromStart,
IostallReadsInMilliseconds,
IostallReadsInMillisecondsFromStart,
IostallWritesInMilliseconds,
IostallWritesInMillisecondsFromStart,
RecordedDateTime,
IntervalinMilliseconds,
FirstMeasureFromStart)
SELECT
@CurrentServerName,
vfs.database_id,
vfs.[file_id],
vfs.num_of_reads - dbaf.ReadsFromStart AS Reads,
vfs.num_of_reads AS ReadsFromStart,
vfs.num_of_writes - dbaf.WritesFromStart AS Writes,
vfs.num_of_writes AS WritesFromStart,
vfs.num_of_bytes_read - dbaf.BytesReadFromStart AS BytesRead,
vfs.num_of_bytes_read AS BytesReadFromStart,
vfs.num_of_bytes_written - dbaf.BytesWrittenFromStart AS BytesWritten,
vfs.num_of_bytes_written AS BytesWrittenFromStart,
vfs.io_stall - dbaf.IostallInMillisecondsFromStart AS IostallInMilliseconds,
vfs.io_stall AS IostallInMillisecondsFromStart,
vfs.io_stall_read_ms - dbaf.IostallReadsInMillisecondsFromStart AS IostallReadsInMilliseconds,
vfs.io_stall_read_ms AS IostallReadsInMillisecondsFromStart,
vfs.io_stall_write_ms - dbaf.IostallWritesInMillisecondsFromStart AS IostallWritesInMilliseconds,
vfs.io_stall_write_ms AS IostallWritesInMillisecondsFromStart,
@CurrentDateTime,
CASE
WHEN @LastRecordedDateTime IS NULL THEN NULL
ELSE Datediff(ms, dbaf.RecordedDateTime, @CurrentDateTime)
END AS IntervalInMilliseconds,
CASE
WHEN @LastRecordedDateTime IS NULL THEN 1
ELSE 0
END AS FirstMeasureFromStart
FROM
sys.Dm_io_virtual_file_stats(@DB, @DBFile) vfs
LEFT OUTER JOIN VirtualFileStats dbaf
ON vfs.database_id = dbaf.dbid
AND vfs.[file_id] = dbaf.fileid
WHERE
( @LastRecordedDateTime IS NULL
OR dbaf.RecordedDateTime = @LastRecordedDateTime )
SELECT
@ErrorNumber = @@ERROR,
@NumberOfRows = @@ROWCOUNT
IF @ErrorNumber != 0
BEGIN
SET @ErrorMessageText = 'Error ' + CONVERT(VARCHAR(10), @ErrorNumber) + ' failed to insert file stats data!'
RAISERROR (@ErrorMessageText,
16,
1) WITH LOG
RETURN @ErrorNumber
END
WAITFOR DELAY @IntervalInSeconds
END