SQL सर्वर से डिफ़ॉल्ट रूप से मुझे कौन सी घटना की जानकारी मिल सकती है?


60

मैं अक्सर ऐसे प्रश्न देखता हूं जहां लोग जानना चाहते हैं कि क्या कोई निश्चित बात हुई, या कब हुई, या किसने कार्रवाई की। बहुत सारे मामलों में, SQL सर्वर इस जानकारी को अपने आप ही ट्रैक नहीं करता है। उदाहरण के लिए:

  • अंतिम बार संग्रहीत प्रक्रिया को किसने अंजाम दिया dbo.MyProcedure?
  • तालिका salaryमें स्तंभ को किसने अद्यतन किया dbo.Employees?
  • dbo.Ordersप्रबंधन स्टूडियो से तालिका को अंतिम रूप देने वाले कौन थे ?

लेकिन कई अन्य घटनाएं हैं जो SQL सर्वर डिफ़ॉल्ट रूप से अस्थायी रूप से ट्रैक करता है , और देशी प्रश्नों के बारे में उत्तर दे सकता है, जैसे:

  • आखिरी बार एडवेंचरवर्क्स डेटाबेस में एक ऑटो-ग्रो कब हुआ था, और इसमें कितना समय लगा?
  • dbo.EmployeeAuditDataतालिका को किसने और कब हटाया ?
  • आज स्मृति-संबंधी कितनी त्रुटियां हुई हैं?

मुझे यह जानकारी कैसे मिलती है, और यह कब तक उपलब्ध रहती है?

जवाबों:


65

डिफ़ॉल्ट रूप से आपके लिए SQL सर्वर ट्रैक करता है जो काफी मूल्यवान जानकारी है। SQL सर्वर 2005 के बाद से पृष्ठभूमि में चलने वाला "डिफ़ॉल्ट ट्रेस" हो गया है, और SQL सर्वर 2008 के बाद से एक विस्तारित ईवेंट सत्र स्वचालित रूप से चल रहा है, कहा जाता है system_health

आप SQL सर्वर त्रुटि लॉग, SQL सर्वर एजेंट लॉग, Windows ईवेंट लॉग और SQL सर्वर ऑडिट , प्रबंधन डेटा वेयरहाउस , इवेंट सूचनाएँ , DML ट्रिगर , डीडीएल ट्रिगर , SCOM / सिस्टम केंद्र जैसी चीजों से अतिरिक्त लॉगिंग भी प्राप्त कर सकते हैं। , अपने स्वयं के सर्वर-साइड निशान या विस्तारित ईवेंट सत्र, या तृतीय-पक्ष निगरानी समाधान (जैसे मेरे नियोक्ता, SQL संतरी द्वारा किए गए )। समस्या निवारण में सहायता के लिए आप वैकल्पिक रूप से तथाकथित "ब्लैकबॉक्स ट्रेस" को भी सक्षम कर सकते हैं ।

लेकिन इस पोस्ट के लिए मैं उन चीजों पर गुंजाइश पर ध्यान केंद्रित करने जा रहा हूं जो आम तौर पर हर जगह सक्षम हैं: डिफ़ॉल्ट ट्रेस, विस्तारित ईवेंट सत्र और त्रुटि लॉग।

डिफ़ॉल्ट ट्रेस

डिफ़ॉल्ट ट्रेस आमतौर पर अधिकांश प्रणालियों पर चल रहा है, जब तक कि आपने इसका उपयोग अक्षम नहीं किया हैsp_configure । जब तक यह सक्षम है, यह बहुमूल्य जानकारी का एक समृद्ध स्रोत हो सकता है। निम्नलिखित उन ट्रेस ईवेंट्स को सूचीबद्ध करता है जो कैप्चर किए गए हैं:

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देखने के लिए कि कौन-सी घटनाएं किस डेटा के साथ आती हैं, यह देखने के लिए जुड़कर आप और अधिक विस्तार से जान सकते हैं , लेकिन मैं इसे अभी के लिए छोड़ दूंगा, क्योंकि आप देख सकते हैं कि आपके पास क्या है जब आप विशिष्ट घटनाओं के लिए ट्रेस डेटा को क्वेरी करते हैं। ये ऐसी घटनाएँ हैं जो मेरे सिस्टम पर उपलब्ध हैं (आपको यह सुनिश्चित करने के लिए कि वे आपस में मेल खाती हैं, आपको यह क्वेरी चलानी चाहिए, हालाँकि यह अभी भी SQL Server 2019 CTP 2.4 के माध्यम से घटनाओं का एक ही सेट है):

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

ध्यान दें कि डिफ़ॉल्ट ट्रेस रोलओवर फ़ाइलों का उपयोग करता है और इसलिए आपके लिए उपलब्ध डेटा केवल इतना ही वापस जाएगा - उपलब्ध डेटा की तिथि सीमा इस बात पर निर्भर करती है कि उपरोक्त घटनाओं में से कितने पर कब्जा किया जा रहा है और किस आवृत्ति पर। यदि आप यह सुनिश्चित करना चाहते हैं कि आप एक लंबा इतिहास रखते हैं, तो आप एक नौकरी सेट कर सकते हैं जो समय-समय पर अभिलेखों से जुड़ी वर्तमान में निष्क्रिय फ़ाइलों को दूर करती है।

उदाहरण

सवाल में मैंने कुछ सवाल पूछे जो मुझे मिले हैं। डिफ़ॉल्ट ट्रेस से उस विशिष्ट जानकारी को खींचने के लिए उदाहरण प्रश्न हैं।

प्रश्न: एडवेंचरवर्क्स डेटाबेस में आखिरी बार ऑटो-ग्रो कब हुआ था, और इसमें कितना समय लगा?

यह क्वेरी एडवेंचरवर्क्स डेटाबेस में लॉग और डेटा फ़ाइलों दोनों के लिए सभी ऑटो-एरो इवेंट्स को खींच लेगी, जो अभी भी डिफॉल्ट ट्रेस लॉग फ़ाइलों में हैं:

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;

प्रश्न: dbo.EmployeeAuditData तालिका को किसने और कब हटाया?

यह किसी भी DROPनाम की घटना के लिए घटनाओं को वापस कर देगा EmployeeAuditData। यदि आप यह सुनिश्चित करना चाहते हैं कि यह केवल DROPतालिकाओं के लिए घटनाओं का पता लगाता है , तो आप एक फिल्टर जोड़ सकते हैं: ObjectType = 8277( पूरी सूची यहां प्रलेखित है )। यदि आप किसी विशिष्ट डेटाबेस में खोज स्थान को प्रतिबंधित करना चाहते हैं, तो आप एक फ़िल्टर जोड़ सकते हैं 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;

यहां एक जटिलता है, और यह बहुत ही किनारे का मामला है लेकिन यह वैसे भी उल्लेख करने के लिए विवेकपूर्ण है। यदि आप एक से अधिक स्कीमा का उपयोग करते हैं और कई स्कीमाओं में समान ऑब्जेक्ट नाम हो सकता है, तो आप यह नहीं बता पाएंगे कि यह कौन सा है (जब तक कि इसका समकक्ष (s) अभी भी मौजूद है)। एक बाहर का मामला है कि UserA ने स्कीमाबी को छोड़ दिया हो सकता है। टेबलेनाम जबकि यूजर ने स्कीमा को छोड़ दिया हो सकता है। टैबलन। डिफ़ॉल्ट ट्रेस वस्तु के स्कीमा को ट्रैक नहीं करता है (न ही TextDataइस घटना के लिए कब्जा करता है ), औरObjectIDट्रेस में शामिल एक प्रत्यक्ष मैच के लिए उपयोगी नहीं है (क्योंकि ऑब्जेक्ट गिरा दिया गया था और अब मौजूद नहीं है)। इस मामले में आउटपुट में उस कॉलम को शामिल करना उस तालिका की किसी भी कॉपी के खिलाफ क्रॉस-रेफरेंस के लिए उपयोगी हो सकता है, जिसका नाम अभी भी मौजूद है, लेकिन अगर सिस्टम इस बहुत अधिक अव्यवस्था में है (या यदि ऐसी सभी प्रतियां हटा दी गई हैं) अभी भी यह अनुमान लगाने का एक विश्वसनीय तरीका नहीं हो सकता है कि तालिका की कौन सी प्रतिलिपि किसके द्वारा गिराई गई थी।

विस्तारित कार्यक्रम

SQL सर्वर 2008 का समर्थन करने से : system_health session (SQLCSS ब्लॉग) , निम्न डेटा की सूची है जिसे आप system_healthSQL Server 2008 और 2008 R2 में सत्र से हटा सकते हैं :

  • किसी भी सत्र के लिए sql_text और session_id जो गंभीरता> = 20 के साथ त्रुटि का सामना करते हैं
  • किसी भी सत्र के लिए sql_text और session_id जो "मेमोरी" प्रकार की त्रुटि का सामना करते हैं जैसे कि 17803, 701, आदि (हमने इसे इसलिए जोड़ा क्योंकि सभी मेमोरी त्रुटियां गंभीरता नहीं हैं> = 20)
  • किसी भी "गैर-पैदावार" समस्याओं का एक रिकॉर्ड (आपने कभी-कभी ERRORLOG में Msg 17883 पेज के रूप में देखा है)
  • किसी भी गतिरोध का पता लगाया जाता है
  • किसी भी सत्र के लिए कॉलस्टैक, sql_text, और session_id जिन्होंने> 15 सेकंड के लिए latches (या अन्य दिलचस्प संसाधनों) पर प्रतीक्षा की है
  • किसी भी सत्र के लिए कॉलस्टैक, sql_text, और session_id, जिन्होंने 30 सेकंड के लिए ताले का इंतजार किया है
  • किसी भी सत्र के लिए कॉलस्टैक, sql_text, और session_id जो "बाह्य" प्रतीक्षा या "पूर्व-खाली प्रतीक्षा" के लिए विस्तारित अवधि के लिए प्रतीक्षा कर रहे हैं।

System_health इवेंट सत्र (MSDN) का उपयोग करने से , सूची कुछ हद तक SQL Server 2012 में विस्तारित हो जाती है (और SQL Server 2014 के लिए समान रहती है):

  • किसी भी सत्र के लिए sql_text और session_id जो उस त्रुटि का सामना करता है जिसमें गंभीरता> = 20 है।
  • किसी भी सत्र के लिए sql_text और session_id जो मेमोरी से संबंधित त्रुटि का सामना करते हैं। त्रुटियों में 17803, 701, 802, 8645, 8651, 8657 और 8902 शामिल हैं।
  • किसी भी गैर-उपज वाले शेड्यूलर समस्याओं का रिकॉर्ड। (ये SQL सर्वर त्रुटि लॉग 17883 त्रुटि के रूप में दिखाई देते हैं।)
  • किसी भी गतिरोध का पता लगाया जाता है।
  • किसी भी सत्र के लिए कॉलस्टैक, sql_text, और session_id, जो 15 सेकंड के लिए latches (या अन्य दिलचस्प संसाधनों) पर प्रतीक्षा कर रहे हैं।
  • किसी भी सत्र के लिए कॉलस्टैक, sql_text, और session_id जो कि 30 सेकंड के लिए ताले पर इंतजार कर रहे हैं।
  • किसी भी सत्र के लिए कॉलस्टैक, sql_text, और session_id जो प्रीमेच्योर वेट के लिए लंबे समय से इंतजार कर रहे हैं। अवधि प्रतीक्षा प्रकार से भिन्न होती है। एक पूर्व-प्रतीक्षित प्रतीक्षा है जहाँ SQL सर्वर बाहरी API कॉल की प्रतीक्षा कर रहा है।
  • सीएलआर आवंटन और आभासी आवंटन विफलताओं के लिए कॉलस्टैक और सेशन_आईडी।
  • मेमोरी ब्रोकर, शेड्यूलर मॉनिटर, मेमोरी नोड OOM, सुरक्षा और कनेक्टिविटी के लिए ring_buffer ईवेंट।
  • सिस्टम घटक sp_server_diagnostics से परिणाम देता है।
  • शेड्यूलर द्वारा एकत्र किया गया स्वास्थ्य
  • सीएलआर आवंटन विफलताओं।
  • कनेक्टिविटी त्रुटियों का उपयोग कर कनेक्टिविटी_रंग_बफर_क्रिकेट किया गया।
  • सुरक्षा त्रुटियों का उपयोग कर सुरक्षा_रोर_रिंग_बफ़र_क्रिकेट किया गया।

SQL सर्वर 2016 में, दो और इवेंट कैप्चर किए जाते हैं:

  • जब KILLकमांड का उपयोग करके एक प्रक्रिया को मार दिया जाता है ।
  • जब SQL सर्वर शटडाउन शुरू किया गया है।

(दस्तावेज़ीकरण अभी तक अपडेट नहीं किया गया है, लेकिन मैंने इस बारे में ब्लॉग किया है कि मैं कैसे इन और अन्य परिवर्तनों की खोज करता हूं ।)

अपने विशिष्ट संस्करण के लिए अधिक क्रिप्टिक कॉन्फ़िगरेशन लागू करने के लिए, आप हमेशा निम्नलिखित क्वेरी को सीधे चला सकते हैं, लेकिन आपको नामों की व्याख्या करनी होगी और उपर्युक्त अधिक प्राकृतिक भाषा सूचियों से मिलान करने के लिए विधेय को पार्स करना होगा:

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;

यदि आप उपलब्धता समूह का उपयोग कर रहे हैं, तो दो नए सत्र भी हैं जो आपको चलेंगे: AlwaysOn_failoverऔर AlwaysOn_health। आप निम्न क्वेरी के साथ एकत्रित डेटा देख सकते हैं:

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;

ये ईवेंट सत्र डेटा को संग्रहीत करने के लिए रिंग बफर लक्ष्यों का उपयोग करते हैं, इसलिए - जैसे बफर पूल और प्लान कैश - पुरानी घटनाओं को चरणबद्ध रूप से प्राप्त किया जाएगा, इसलिए आप आवश्यक रूप से घटनाओं को उस तिथि सीमा से खींचने में सक्षम नहीं होंगे जो आप चाहते हैं।

उदाहरण

प्रश्न में मैंने यह काल्पनिक प्रश्न प्रस्तुत किया है:

आज स्मृति-संबंधी कितनी त्रुटियां हुई हैं?

यहां एक नमूना है (और शायद बहुत कुशल नहीं) क्वेरी जो इस जानकारी को system_healthसत्र से खींच सकती है :

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

(यह उदाहरण सत्र पर अमित बनर्जी के परिचयात्मक ब्लॉग पोस्टsystem_health से बहुत उधार लेता है ।)

विस्तारित घटनाओं के बारे में अधिक जानकारी के लिए (कई उदाहरणों में जहां आप विशिष्ट डेटा के लिए क्वेरी कर सकते हैं), जोनाथन पंचायत की 31-भाग ब्लॉग श्रृंखला देखें:

https://www.sqlskills.com/blogs/jonathan/an-xevent-a-day-31-days-of-extended-events/

त्रुटि संग्रह

डिफ़ॉल्ट रूप से SQL सर्वर वर्तमान प्लस 6 सबसे हाल की त्रुटि लॉग फ़ाइलों को रखता है (लेकिन आप इसे बदल सकते हैं )। स्टार्टअप जानकारी (कितने कोर उपयोग में हैं, क्या मेमोरी में लॉक पेज सेट हैं, प्रमाणीकरण मोड, आदि) के साथ-साथ त्रुटियों और अन्य परिदृश्यों को काफी गंभीर रूप से संग्रहीत किया जाता है, जिसमें त्रुटि और अन्य परिदृश्यों को पर्याप्त रूप से प्रलेखित किया जाता है (और अन्यत्र कब्जा नहीं किया गया है)। हाल ही में एक उदाहरण था जब कोई डेटाबेस ऑफ़लाइन लिया गया था। आप पाठ के लिए सबसे हाल के 7 त्रुटि लॉग में से प्रत्येक को स्कैन करके यह निर्धारित कर सकते हैं 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';

मैंने इस हालिया उत्तर में कुछ अन्य विवरणों को कवर किया , और टॉडवर्ल्ड में कुछ अच्छी पृष्ठभूमि की जानकारी और आधिकारिक दस्तावेज में भी है

"त्रुटियों" का एक समूह त्रुटि लॉग डिफ़ॉल्ट रूप से ट्रैक करता है - और पूंछ को बहुत तेजी से गिराने के लिए महत्वपूर्ण जानकारी बना सकता है - हर सफल बैकअप संदेश है। आप ट्रेस ध्वज 3226 को सक्षम करके शोर के साथ त्रुटि लॉग को भरने से रोक सकते हैं ।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.