Redémarrer la trace par défaut

SQL Server fournit de nombreux outils de monitoring d’arrière-plan par défaut, comme le journal SQL Server, la session d’événements étendus system_health, mais aussi une trace SQL Profiler. Cette dernière est enregistrée dans un fichier dans le répertoire des journaux, et SQL Server conserve 6 fichiers de cette trace.

Elle capture, entre autres, les événements d’échec d’authentification, la création d’objets dans TempDB, les warnings sur Hash et Sort, les grossissements de fichiers, et de nombreux autres événements. Ceux-ci peuvent aider à comprendre, a posteriori, ce qui a causé une grande consommation de CPU, des latences disque, …

Comme cette trace est écrite sur disque, il peut malencontreusement arriver que ce dernier devienne plein, provoquant alors l’arrêt automatique et forcé de la trace. Ce léger incident (l’arrêt de la trace, pas l’absence d’espace disque libre !) n’empêche aucunement l’instance de fonctionner, ou au moins d’être accessible. Cependant, comment peut-on redémarrer cette trace sans redémarrer l’instance SQL Server ?

En effet, la documentation nous indique que la trace par défaut n’est démarrée que lorsque l’instance démarre aussi … nous allons voir que c’est incomplet. Une fois le disque supportant la trace disposant à nouveau d’espace disque libre, on constate que la trace par défaut est arrêtée à l’aide de l’instruction suivante :

1
2
SELECT  *
FROM    sys.traces

Lorsque la trace par défaut est active, cette requête retourne une ligne, dont la colonne id est à 1. On peut vérifier que c’est la trace par défaut à l’aide de la valeur de la colonne is_default : 1 si c’est le cas, 0 à l’inverse :

Dans la situation de l’incident que nous évoquons, cette même requête ne retournera pas de ligne (ou tout du moins aucune dont la colonne is_default est à 1). Pour démarrer la trace par défaut, il suffit de s’en remettre à l’option de configuration d’instance default trace enabled :

1
2
3
SELECT  *
FROM    sys.configurations
WHERE   name LIKE '%trace%'

On voit que c’est une option avancée et dynamique, ce qui signifie qu’un redémarrage de l’instance SQL Server n’est pas nécessaire. Dès lors, pour réactiver la trace par défaut, il suffit de positionner cette option à 0, puis immédiatement ensuite à 1, ce qui est sa valeur par défaut :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
-- Activation de la modification des options d'instance avancées
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO

-- Désactivation de la trace par défaut
EXEC sp_configure 'default trace enabled', 0
GO
RECONFIGURE
GO

-- Ré-activation de la trace par défaut
EXEC sp_configure 'default trace enabled', 1
GO
RECONFIGURE
GO

-- Désactivation de la modification des options d'instance avancées
EXEC sp_configure 'show advanced options', 0
GO
RECONFIGURE
GO

Sur exécution de ce lot, l’onglet Messages du panneau de résultats de SQL Server Management Studio affiche :

Configuration option ‘show advanced options’ changed from 0 to 1. Run the RECONFIGURE statement to install.
Configuration option ‘default trace enabled’ changed from 1 to 0. Run the RECONFIGURE statement to install.
Configuration option ‘default trace enabled’ changed from 0 to 1. Run the RECONFIGURE statement to install.
Configuration option ‘show advanced options’ changed from 1 to 0. Run the RECONFIGURE statement to install.

Et l’on voit alors que la trace a été démarrée, en interrogeant une nouvelle fois la vue sys.traces.
On trouvera aussi dans les journal de SQL Server les lignes suivantes :

1
2
3
4
5
-- Recherche de l'heure de dernier démarrage de l'instance SQL Server
SELECT sqlserver_start_time FROM sys.dm_os_sys_info

-- Recherche du démarrage de la trace par défaut
EXEC xp_readerrorlog 0, 1, N'Trace ID 1'

Ici on voit bien que la trace par défaut a été démarré par le système (le SPID est inférieur à 50), quelques millisecondes après le démarrage de celui-ci. Elle a ensuite été redémarrée par nos soins un peu plus tard.

Petite note finale : les fonctionnalités SQL Trace et SQL Profiler sont obsolètes, et remplacées par la fonctionnalité d'événements étendus, plus puissante et performante. Vous pouvez voir comment les utiliser dans cette vidéo, en gardant bien à l’esprit que dès SQL Server 2012, une interface graphique intégrée à SQL Server Management Studio permet de créer une session sans écrire de code, et de visualiser les événements capturés à la façon de ce que permet SQL Profiler.

Enfin, pour interroger un fichier de trace SQL Profiler, il suffit d’utiliser la fonction sys.fn_trace_gettable(). Donc pour en faire l’analyse, on peut utiliser le lot suivant :

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
DECLARE @events TABLE
(
        event_id tinyint
        , event_name sysname
)

INSERT @events VALUES (0, 'Reserved')
, (1, 'Reserved')
, (2, 'Reserved')
, (3, 'Reserved')
, (4, 'Reserved')
, (5, 'Reserved')
, (6, 'Reserved')
, (7, 'Reserved')
, (8, 'Reserved')
, (9, 'Reserved')
, (10, 'RPC:Completed')
, (11, 'RPC:Starting')
, (12, 'SQL:BatchCompleted')
, (13, 'SQL:BatchStarting')
, (14, 'Audit Login')
, (15, 'Audit Logout')
, (16, 'Attention')
, (17, 'ExistingConnection')
, (18, 'Audit Server Starts and Stops')
, (19, 'DTCTransaction')
, (20, 'Audit Login Failed')
, (21, 'EventLog')
, (22, 'ErrorLog')
, (23, 'Lock:Released')
, (24, 'Lock:Acquired')
, (25, 'Lock:Deadlock')
, (26, 'Lock:Cancel')
, (27, 'Lock:Timeout')
, (28, 'Degree of Parallelism Event (7.0 Insert)')
, (29, 'Reserved')
, (30, 'Reserved')
, (31, 'Reserved')
, (32, 'Reserved')
, (33, 'Exception')
, (34, 'SP:CacheMiss')
, (35, 'SP:CacheInsert')
, (36, 'SP:CacheRemove')
, (37, 'SP:Recompile')
, (38, 'SP:CacheHit')
, (39, 'Deprecated')
, (40, 'SQL:StmtStarting')
, (41, 'SQL:StmtCompleted')
, (42, 'SP:Starting')
, (43, 'SP:Completed')
, (44, 'SP:StmtStarting')
, (45, 'SP:StmtCompleted')
, (46, 'Object:Created')
, (47, 'Object:Deleted')
, (48, 'Reserved')
, (49, 'Reserved')
, (50, 'SQL Transaction')
, (51, 'Scan:Started')
, (52, 'Scan:Stopped')
, (53, 'CursorOpen')
, (54, 'TransactionLog')
, (55, 'Hash Warning')
, (56, 'Reserved')
, (57, 'Reserved')
, (58, 'Auto Stats')
, (59, 'Lock:Deadlock Chain')
, (60, 'Lock:Escalation')
, (61, 'OLE DB Errors')
, (62, 'Reserved')
, (63, 'Reserved')
, (64, 'Reserved')
, (65, 'Reserved')
, (66, 'Reserved')
, (67, 'Execution Warnings')
, (68, 'Showplan Text (Unencoded)')
, (69, 'Sort Warnings')
, (70, 'CursorPrepare')
, (71, 'Prepare SQL')
, (72, 'Exec Prepared SQL')
, (73, 'Unprepare SQL')
, (74, 'CursorExecute')
, (75, 'CursorRecompile')
, (76, 'CursorImplicitConversion')
, (77, 'CursorUnprepare')
, (78, 'CursorClose')
, (79, 'Missing Column Statistics')
, (80, 'Missing Join Predicate')
, (81, 'Server Memory Change')
, (82, 'User Configurable (0-9)')
, (83, 'User Configurable (0-9)')
, (84, 'User Configurable (0-9)')
, (85, 'User Configurable (0-9)')
, (86, 'User Configurable (0-9)')
, (87, 'User Configurable (0-9)')
, (88, 'User Configurable (0-9)')
, (89, 'User Configurable (0-9)')
, (90, 'User Configurable (0-9)')
, (91, 'User Configurable (0-9)')
, (92, 'Data File Auto Grow')
, (93, 'Log File Auto Grow')
, (94, 'Data File Auto Shrink')
, (95, 'Log File Auto Shrink')
, (96, 'Showplan Text')
, (97, 'Showplan All')
, (98, 'Showplan Statistics Profile')
, (99, 'Reserved')
, (100, 'RPC Output Parameter')
, (101, 'Reserved')
, (102, 'Audit Statement GDR Event')
, (103, 'Audit Object GDR Event')
, (104, 'Audit AddLogin Event')
, (105, 'Audit Login GDR Event')
, (106, 'Audit Login Change Property Event')
, (107, 'Audit Login Change Password Event')
, (108, 'Audit Add Login to Server Role Event')
, (109, 'Audit Add DB User Event')
, (110, 'Audit Add Member to DB Role Event')
, (111, 'Audit Add Role Event')
, (112, 'Audit App Role Change Password Event')
, (113, 'Audit Statement Permission Event')
, (114, 'Audit Schema Object Access Event')
, (115, 'Audit Backup/Restore Event')
, (116, 'Audit DBCC Event')
, (117, 'Audit Change Audit Event')
, (118, 'Audit Object Derived Permission Event')
, (119, 'OLEDB Call Event')
, (120, 'OLEDB QueryInterface Event')
, (121, 'OLEDB DataRead Event')
, (122, 'Showplan XML')
, (123, 'SQL:FullTextQuery')
, (124, 'Broker:Conversation')
, (125, 'Deprecation Announcement')
, (126, 'Deprecation Final Support')
, (127, 'Exchange Spill Event')
, (128, 'Audit Database Management Event')
, (129, 'Audit Database Object Management Event')
, (130, 'Audit Database Principal Management Event')
, (131, 'Audit Schema Object Management Event')
, (132, 'Audit Server Principal Impersonation Event')
, (133, 'Audit Database Principal Impersonation Event')
, (134, 'Audit Server Object Take Ownership Event')
, (135, 'Audit Database Object Take Ownership Event')
, (136, 'Broker:Conversation Group')
, (137, 'Blocked Process Report')
, (138, 'Broker:Connection')
, (139, 'Broker:Forwarded Message Sent')
, (140, 'Broker:Forwarded Message Dropped')
, (141, 'Broker:Message Classify')
, (142, 'Broker:Transmission')
, (143, 'Broker:Queue Disabled')
, (144, 'Reserved')
, (145, 'Reserved')
, (146, 'Showplan XML Statistics Profile')
, (148, 'Deadlock Graph')
, (149, 'Broker:Remote Message Acknowledgement')
, (150, 'Trace File Close')
, (151, 'Reserved')
, (152, 'Audit Change Database Owner')
, (153, 'Audit Schema Object Take Ownership Event')
, (154, 'Reserved')
, (155, 'FT:Crawl Started')
, (156, 'FT:Crawl Stopped')
, (157, 'FT:Crawl Aborted')
, (158, 'Audit Broker Conversation')
, (159, 'Audit Broker Login')
, (160, 'Broker:Message Undeliverable')
, (161, 'Broker:Corrupted Message')
, (162, 'User Error Message')
, (163, 'Broker:Activation')
, (164, 'Object:Altered')
, (165, 'Performance statistics')
, (166, 'SQL:StmtRecompile')
, (167, 'Database Mirroring State Change')
, (168, 'Showplan XML For Query Compile')
, (169, 'Showplan All For Query Compile')
, (170, 'Audit Server Scope GDR Event')
, (171, 'Audit Server Object GDR Event')
, (172, 'Audit Database Object GDR Event')
, (173, 'Audit Server Operation Event')
, (175, 'Audit Server Alter Trace Event')
, (176, 'Audit Server Object Management Event')
, (177, 'Audit Server Principal Management Event')
, (178, 'Audit Database Operation Event')
, (180, 'Audit Database Object Access Event')
, (181, 'TM: Begin Tran starting')
, (182, 'TM: Begin Tran completed')
, (183, 'TM: Promote Tran starting')
, (184, 'TM: Promote Tran completed')
, (185, 'TM: Commit Tran starting')
, (186, 'TM: Commit Tran completed')
, (187, 'TM: Rollback Tran starting')
, (188, 'TM: Rollback Tran completed')
, (189, 'Lock:Timeout (timeout > 0)')
, (190, 'Progress Report: Online Index Operation')
, (191, 'TM: Save Tran starting')
, (192, 'TM: Save Tran completed')
, (193, 'Background Job Error')
, (194, 'OLEDB Provider Information')
, (195, 'Mount Tape')
, (196, 'Assembly Load')
, (197, 'Reserved')
, (198, 'XQuery Static Type')
, (199, 'QN: subscription')
, (200, 'QN: parameter table')
, (201, 'QN: template')
, (202, 'QN: dynamics')

SELECT          FTG.DatabaseName
                , E.event_name
                , FTG.ApplicationName
                , COUNT(*) AS occurences
                , MIN(FTG.StartTime) AS first_time
                , MAX(FTG.StartTime) AS last_time
                , FTG.SessionLoginName
                , E.event_id
FROM            sys.fn_trace_gettable
                (
                        (
                                SELECT  LEFT(path, LEN(path) - CHARINDEX('\', REVERSE(path))) + '\Log.trc'
                                FROM    sys.traces
                                WHERE   is_default = 1
                        )
                        , 6
                ) AS FTG
LEFT JOIN       @events AS E
                        ON E.event_id = FTG.EventClass
WHERE           FTG.EventClass NOT BETWEEN 65527 AND 65528
GROUP BY        FTG.DatabaseName, E.event_name, FTG.ApplicationName, E.event_id, FTG.SessionLoginName
ORDER BY        first_time

Alors bon traçage à tous !

Laisser un commentaire