SQL Server'ın varsayılan olarak sizin için izlediği oldukça değerli bilgiler var. SQL Server 2005'ten beri arka planda çalışan bir "varsayılan izleme" olmuştur ve SQL Server 2008'den beri otomatik olarak çalışan bir Genişletilmiş Olaylar oturumu vardır system_health
.
Ayrıca belirli bilgileri SQL Server hata günlüğünden, SQL Server Agent günlüğünden, Windows olay günlüğünden ve SQL Server Denetimi , Yönetim Veri Ambarı , Olay Bildirimleri , DML Tetikleyicileri , DDL Tetikleyicileri , SCOM / Sistem Merkezi gibi şeylerden gelen ek günlük bilgileri de bulabilirsiniz. kendi sunucu tarafınızdaki izler veya Genişletilmiş Etkinlikler oturumları veya üçüncü taraf izleme çözümleri ( işverenim SQL Sentry tarafından yapılanlar gibi ). İsteğe bağlı olarak , sorun gidermeye yardımcı olması için "Blackbox izleme" adı verilen bir özelliği de etkinleştirebilirsiniz .
Ancak bu yazı için kapsamı her yerde genellikle en etkin olan şeylere odaklayacağım: varsayılan izleme, Genişletilmiş Olaylar oturumları ve hata günlüğü.
Varsayılan İzleme
Varsayılan izleme, kullanmayı devre dışı bırakmadığınızsp_configure
sürece genellikle çoğu sistemde çalışır . Etkin olduğu sürece, bu, zengin bir değerli bilgi kaynağı olabilir. Aşağıdakiler yakalanan izleme olaylarını listeler:
DECLARE @TraceID INT;
SELECT @TraceID = id FROM sys.traces WHERE is_default = 1;
SELECT t.EventID, e.name as Event_Description
FROM sys.fn_trace_geteventinfo(@TraceID) t
JOIN sys.trace_events e ON t.eventID = e.trace_event_id
GROUP BY t.EventID, e.name;
sys.trace_columns
Hangi olayların hangi verilerle geldiğini görmek için katılarak daha fazla ayrıntıya girebilirsiniz , ancak şimdilik bunu atlayacağım, çünkü belirli olaylar için izleme verilerini gerçekten sorguladığınızda ne olduğunu görebilirsiniz. Bunlar sistemimde mevcut olan olaylar (eşleşmelerini sağlamak için sorguyu sizde çalıştırmalısınız, yine de bu, SQL Server 2019 CTP 2.4 ile aynı olay kümesi olmasına rağmen):
EventID Event_Description
------- ----------------------------------------------
18 Audit Server Starts And Stops
20 Audit Login Failed
22 ErrorLog
46 Object:Created
47 Object:Deleted
55 Hash Warning
69 Sort Warnings
79 Missing Column Statistics
80 Missing Join Predicate
81 Server Memory Change
92 Data File Auto Grow
93 Log File Auto Grow
94 Data File Auto Shrink
95 Log File Auto Shrink
102 Audit Database Scope GDR Event
103 Audit Schema Object GDR Event
104 Audit Addlogin Event
105 Audit Login GDR Event
106 Audit Login Change Property 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
115 Audit Backup/Restore Event
116 Audit DBCC Event
117 Audit Change Audit Event
152 Audit Change Database Owner
153 Audit Schema Object Take Ownership Event
155 FT:Crawl Started
156 FT:Crawl Stopped
164 Object:Altered
167 Database Mirroring State Change
175 Audit Server Alter Trace Event
218 Plan Guide Unsuccessful
Varsayılan izlemenin rollover dosyaları kullandığını ve bu nedenle size sunulan verilerin yalnızca şu ana kadar geri döneceğini unutmayın; mevcut verilerin tarih aralığı, yukarıdaki olayların kaç tanesinin yakalandığına ve hangi sıklıkta yapıldığına bağlıdır. Daha uzun bir geçmişi sakladığınızdan emin olmak istiyorsanız, izlemeyle ilişkili olarak etkin olmayan dosyaları periyodik olarak arşivleyen bir iş ayarlayabilirsiniz.
Örnekler
Soruda bulduğum birkaç soru sordum. İşte bu belirli bilgileri varsayılan izlemeden almak için örnek sorgular.
Soru: En son ne zaman AdventureWorks veritabanında bir otomatik büyüme oldu ve bu ne kadar sürdü?
Bu sorgu, hala varsayılan izleme günlük dosyalarında bulunan günlük ve veri dosyaları için AdventureWorks veritabanındaki tüm AutoGrow olaylarını çeker:
DECLARE @path NVARCHAR(260);
SELECT
@path = REVERSE(SUBSTRING(REVERSE([path]),
CHARINDEX(CHAR(92), REVERSE([path])), 260)) + N'log.trc'
FROM sys.traces
WHERE is_default = 1;
SELECT
DatabaseName,
[FileName],
SPID,
Duration,
StartTime,
EndTime,
FileType = CASE EventClass WHEN 92 THEN 'Data' ELSE 'Log' END
FROM sys.fn_trace_gettable(@path, DEFAULT)
WHERE EventClass IN (92,93)
AND DatabaseName = N'AdventureWorks'
ORDER BY StartTime DESC;
Soru: dbo.EmployeeAuditData tablosunu kim ve ne zaman sildi?
Bu DROP
adında bir nesne için herhangi bir olay döndürür EmployeeAuditData
. Yalnızca DROP
tablolar için olayları algıladığından emin olmak istiyorsanız, bir filtre ekleyebilirsiniz: ObjectType = 8277
( tam liste burada belgelenmiştir ). Belirli bir veritabanına arama alanını kısıtlamak istiyorsanız, bir filtre ekleyebilirsiniz: DatabaseName = N'db_name'
.
DECLARE @path NVARCHAR(260);
SELECT
@path = REVERSE(SUBSTRING(REVERSE([path]),
CHARINDEX(CHAR(92), REVERSE([path])), 260)) + N'log.trc'
FROM sys.traces
WHERE is_default = 1;
SELECT
LoginName,
HostName,
StartTime,
ObjectName,
TextData
FROM sys.fn_trace_gettable(@path, DEFAULT)
WHERE EventClass = 47 -- Object:Deleted
AND EventSubClass = 1
AND ObjectName = N'EmployeeAuditData'
ORDER BY StartTime DESC;
Burada bir komplikasyon var ve bu çok uç bir durum ama yine de bahsetmeye istekliydi. Birden fazla şema kullanıyorsanız ve birden fazla şemada aynı nesne adına sahipseniz, bunun hangisi olduğunu söyleyemezsiniz (karşı taraf (lar) hala mevcut değilse). KullanıcıA'nın SchemaB.Tablename'i bırakmış olabileceği bir dış durum vardır. Varsayılan izleme , nesnenin şemasını izlemez ( TextData
bu olay için de yakalamaz ) veObjectID
ize dahil edilen doğrudan bir eşleşme için kullanışlı değildir (çünkü nesne bırakılmış ve artık mevcut değildir). Bu durumda çıktıya bu sütunu dahil etmek, tablonun herhangi bir kopyasına hala aynı isimle sahip olmakla, ancak sistem bu kadar kargaşa içindeyse (veya tüm bu kopyaların silinmiş olması durumunda) çapraz referans vermek için faydalı olabilir. Yine de, tablonun hangi kopyasının kimin tarafından bırakıldığını tahmin etmenin güvenilir bir yolu olmayabilir.
Genişletilmiş Etkinlikler
Gönderen SQL Server 2008 Destekleyen: system_health oturumu (SQLCSS Blog) aşağıdaki aralarından itlaf veri listesi aşağıdadır system_health
SQL Server 2008 ve 2008 R2 oturumu:
- Ciddiyetle hatayla karşılaşan oturumlar için sql_text ve session_id> = 20
- Sql_text ve session_id, 17803, 701 vb. Gibi bir "bellek" hatasıyla karşılaşan oturumlar için (tüm bellek hatalarının ciddiyeti olmadığı için bunu ekledik> = 20)
- Herhangi bir "verimsiz" sorunun kaydı (bunları ERRORLOG'da Msg 17883 olarak gördünüz)
- Tespit edilen kilitlenmeler
- Mandallarda (veya diğer ilginç kaynaklarda)> 15 saniye beklemiş olan oturumlar için callstack, sql_text ve session_id
- Çağrılar, sql_text ve session_id,> 30 saniye boyunca kilitlerde bekleyen oturumlar için
- "Harici" bekler veya "önleyici bekler" için uzun süre beklemiş olan herhangi bir oturum için çağrı işareti, sql_text ve session_id.
Gönderen Kullanım system_health olay oturumu (MSDN) , liste biraz SQL Server 2012 genişletilmiş (ve SQL Server 2014 için aynı kalır) olduğu:
- Sql_text ve session_id, önem derecesi> 20 olan bir hatayla karşılaşan oturumlar için.
- Bellekle ilgili bir hatayla karşılaşan tüm oturumlar için sql_text ve session_id. Hatalar 17803, 701, 802, 8645, 8651, 8657 ve 8902'yi içerir.
- Getirici olmayan zamanlayıcı sorunlarının bir kaydı. (Bunlar, SQL Server hata günlüğünde 17883 hatası olarak görünür.)
- Tespit edilen kilitlenmeler.
- Çağrılar, sql_text ve session_id, mandallarda (veya diğer ilginç kaynaklar)> 15 saniye beklemiş olan oturumlar için.
- Çağrılar, sql_text ve session_id,> 30 saniye boyunca kilitlerde bekleyen oturumlar için.
- Çağrıcı, sql_text ve session_id, uzun süre beklemiş olan beklemeler için herhangi bir oturum için. Süre, bekleme türüne göre değişir. Öncelikli bir bekleme, SQL Server'ın harici API çağrıları için beklediği yerdir.
- CLR tahsisi ve sanal tahsis başarısızlıkları için çağrı dizisi ve session_id.
- Bellek aracısı, zamanlayıcı izleyicisi, OOM bellek düğümü, güvenlik ve bağlantı için ring_buffer olayları.
- Sistem bileşeni sp_server_diagnostics'ten kaynaklanıyor.
- Scheduler_monitor_system_health_ring_buffer_recorded tarafından toplanan örnek sağlığı.
- CLR Tahsis başarısızlıkları.
- Connectivity_ring_buffer_recorded kullanarak bağlantı hataları.
- Security_error_ring_buffer_recorded kullanarak güvenlik hataları.
SQL Server 2016'da iki olay daha yakalanır:
- Bir işlem
KILL
komut kullanılarak öldürüldüğünde .
- SQL Server kapanması başlatıldığında.
(Dokümantasyon henüz güncellenmedi, ancak bunları ve diğer değişiklikleri nasıl keşfettiğim hakkında blog yazdım .)
Özel sürümünüz için daha şifreli bir konfigürasyon elde etmek için, aşağıdaki sorguyu her zaman doğrudan çalıştırabilirsiniz, ancak isimleri yorumlamanız ve tahminleri yukarıdaki daha doğal dil listelerine uyacak şekilde ayrıştırmanız gerekir:
SELECT e.package, e.event_id, e.name, e.predicate
FROM sys.server_event_session_events AS e
INNER JOIN sys.server_event_sessions AS s
ON e.event_session_id = s.event_session_id
WHERE s.name = N'system_health'
ORDER BY e.package, e.name;
Kullanılabilirlik Grupları kullanıyorsanız, koşarken bulacağınız iki yeni oturum vardır: AlwaysOn_failover
ve AlwaysOn_health
. Topladıkları verileri aşağıdaki sorgu ile görebilirsiniz:
SELECT s.name, e.package, e.event_id, e.name, e.predicate
FROM sys.server_event_session_events AS e
INNER JOIN sys.server_event_sessions AS s
ON e.event_session_id = s.event_session_id
WHERE s.name LIKE N'AlwaysOn[_]%'
ORDER BY s.name, e.package, e.name;
Bu olay oturumları, verileri depolamak için halka arabellek hedeflerini kullanır; bu nedenle - arabellek havuzu ve plan önbelleği gibi - eski olaylar aşamalı olur, böylece istediğiniz zaman aralığından etkinlikleri çekemezsiniz.
Örnek
Soruda bu hayali soruyu sordum:
Bugün bellekle ilgili kaç hata oldu?
Bu bilgiyi system_health
oturumdan çekebilecek bir örnek (ve muhtemelen çok verimli değil) sorgusu :
;WITH src(x) AS
(
SELECT y.query('.')
FROM
(
SELECT x = CONVERT(XML, t.target_data)
FROM sys.dm_xe_sessions AS s
INNER JOIN sys.dm_xe_session_targets AS t
ON s.[address] = t.event_session_address
WHERE s.name = N'system_health'
) AS x
CROSS APPLY x.x.nodes('/RingBufferTarget/event') AS y(y)
)
SELECT
x, ts = CONVERT(DATETIME, NULL), err = CONVERT(INT, NULL)
INTO #blat FROM src;
DELETE #blat WHERE x.value('(/event/@name)[1]', 'varchar(255)') <> 'error_reported';
UPDATE #blat SET ts = x.value('(/event/@timestamp)[1]', 'datetime');
UPDATE #blat SET err = x.value('(/event/data/value)[1]', 'int');
SELECT err, number_of_events = COUNT(*)
FROM #blat
WHERE err IN (17803, 701, 802, 8645, 8651, 8657, 8902)
AND ts >= CONVERT(DATE, CURRENT_TIMESTAMP)
GROUP BY err;
DROP TABLE #blat;
(Bu örnek, Amit Banerjee'nin system_health
oturumdaki giriş blog gönderisinden gevşekçe ödünç alıyor .)
Genişletilmiş Olaylar hakkında daha fazla bilgi için (belirli verileri sorgulayabileceğiniz birçok örnek dahil), Jonathan Kehayias'ın bu 31 bölümlü blog serisine bakın:
https://www.sqlskills.com/blogs/jonathan/an-xevent-a-day-31-days-of-extended-events/
Hata Günlüğü
SQL Server, varsayılan olarak geçerli artı en son 6 hata günlüğü dosyasını tutar (ancak bunu değiştirebilirsiniz ). Başlangıç bilgileri (kaç tane çekirdek kullanımda olduğu, bellekte kilitlenen sayfaların ayarlanmış olup olmadığı, kimlik doğrulama modu, vb.) Ve ayrıca belgelenebilecek (ve başka bir yerde ele alınmamış) ciddi senaryolar dahil olmak üzere birçok bilgi saklanır. Son örneklerden biri, bir veritabanının çevrimdışına alındığı zaman arayan biriydi. Bunu, metin için en son 7 hata günlüğünün her birini tarayarak belirleyebilirsiniz Setting database option OFFLINE
:
EXEC sys.sp_readerrorlog 0,1,'Setting database option OFFLINE';
EXEC sys.sp_readerrorlog 1,1,'Setting database option OFFLINE';
EXEC sys.sp_readerrorlog 2,1,'Setting database option OFFLINE';
EXEC sys.sp_readerrorlog 3,1,'Setting database option OFFLINE';
EXEC sys.sp_readerrorlog 4,1,'Setting database option OFFLINE';
EXEC sys.sp_readerrorlog 5,1,'Setting database option OFFLINE';
EXEC sys.sp_readerrorlog 6,1,'Setting database option OFFLINE';
Bu son cevabın diğer bazı detaylarını da ele aldım ve ayrıca kara kurbağasında ve resmi belgelerde bazı iyi bilgiler var .
"Hata" grubundan biri hata günlüğünün varsayılan olarak izlemesini sağlar - ve önemli bilgilerin kuyruktan daha hızlı düşmesini sağlayabilir - her başarılı yedekleme mesajıdır. İz bayrağı 3226'yı etkinleştirerek bunların hata günlüğünü gürültü ile doldurmasını engelleyebilirsiniz .