SQL सर्वर ऑडिट डेटा से स्केलर वेटेड यूज़र-डिफ़ाइंड फ़ंक्शन उपयोग को कैसे फ़िल्टर करें?


12

हमारे पास एक SQL सर्वर डेटाबेस है जिसमें एक डेटाबेस ऑडिट विनिर्देश है जो डेटाबेस पर सभी कार्यों को निष्पादित करता है।

CREATE DATABASE AUDIT SPECIFICATION [dbAudit]
FOR SERVER AUDIT [servAudit]
ADD (EXECUTE ON DATABASE::[DatabaseName] BY [public])

हमने पाया है कि कुछ प्रश्न परिणाम सेट में प्रत्येक पंक्ति के लिए एक स्केलर फ़ंक्शन के उपयोग के लिए ऑडिट को लिखेंगे। जब ऐसा होता है, तो लॉग भरने से पहले हम इसे अंतिम रूप देने वाले स्थान पर ETL कर सकते हैं और हमारे लॉगिंग में एक अंतर है।

दुर्भाग्य से अनुपालन कारणों के कारण, हम बस हर EXECUTEबयान का ऑडिट नहीं कर सकते ।

इस समस्या के लिए हमारा पहला विचार यह है कि गतिविधि को फ़िल्टर करने के WHEREलिए सर्वर ऑडिट पर क्लॉज़ का उपयोग किया जाए । कोड इस तरह दिखता था:

WHERE [object_id] not in (Select object_id from sys.objects where type = 'FN' )

दुर्भाग्य से, एसक्यूएल सर्वर रिलेशनल इन ऑपरेटर की अनुमति नहीं देता है (शायद इसलिए कि यह हर बार क्वेरी को ऑडिट लॉग में लिखना नहीं चाहता है)।

हम संग्रहीत संग्रह लिखने से बचना चाहते हैं, जो क्लॉज़ object_idमें कठिन कोड है WHERE, लेकिन इस समस्या को हल करने के लिए सबसे अच्छी तरह से हमारी वर्तमान सोच है। क्या कोई वैकल्पिक दृष्टिकोण है जिस पर हमें विचार करना चाहिए?

हमने देखा है कि जब पुनरावर्ती CTE में स्केलर फ़ंक्शन का उपयोग होता है, तो यह परिणाम सेट में प्रत्येक पंक्ति के लिए ऑडिट लॉग को लिखने के लिए क्वेरी का कारण बनता है।

कुछ स्केलेर वैल्यूड फंक्शंस हैं जो एक वेंडर द्वारा दिए जाते हैं जिसे हम डिलीट नहीं कर सकते हैं या वैकल्पिक डेटाबेस में नहीं जा सकते हैं।


6
We've found that some queries will write to the audit log the use of a scalar function for every row in a result set.- यह स्केलर यूडीएफ के सबसे शानदार साइड इफेक्ट्स में से एक है जो मैंने कभी सुना है, और मैंने बहुत सुना है।
एरिक डार्लिंग

3
क्या यूडीएफ बनाने का एक विकल्प है जो आप एक अलग डेटाबेस में ऑडिट नहीं किया गया है (जो कि ऑडिट नहीं किया गया है) और उन्हें 3-पार्ट-नाम के माध्यम से इनवाइट कर रहा है?
स्कॉट हॉजिन

@ScottHodgin, मुझे वर्कअराउंड पसंद है, लेकिन हमारी परिस्थितियों में कुछ स्केलर वैल्यूड फंक्शंस हैं जो एक विक्रेता द्वारा वितरित किए जाते हैं जिसे हम हटा नहीं सकते हैं या वैकल्पिक डेटाबेस में स्थानांतरित नहीं कर सकते हैं।
मार्क इन्नुची

निम्नलिखित के साथ-साथ यह भी सोच सकते हैं कि परिणाम के सेट में प्रत्येक पंक्ति के लिए ऑडिट लॉग को लिखने के लिए क्वेरी किस मामले का कारण बनती है; हमने देखा है कि यह तब होता है जब स्केलर फ़ंक्शन पुनरावर्ती CTE में उपयोग में होता है।
मार्क इन्नुची

जवाबों:


6

कुछ विकल्प हैं जो मुझे काम करने में सक्षम थे। सभी विकल्प फ़िल्टर की विविधता के साथ सौदा करते हैं। नोट: आपको परिवर्तन करने के लिए सर्वर ऑडिट को अक्षम करना होगा , और फिर इसे सक्षम करना होगा।

सबसे पहले, सबसे सामान्य दृष्टिकोण सभी स्केलर यूडीएफ को फ़िल्टर करना है। आप class_typeऑडिट फ़ील्ड का उपयोग करके ऐसा कर सकते हैं । दस्तावेज़ इंगित करता है कि यह फ़ील्ड है VARCHAR(2), लेकिन यह किसी स्ट्रिंग को निर्दिष्ट करने की अनुमति नहीं देता है। हालांकि, मुझे काम करने के लिए निम्नलिखित मिला:

ALTER SERVER AUDIT [servAudit]
WHERE ([class_type] <> 20038); -- EXECUTE Scalar UDF

(उस जाँच के बारे में अधिक जानकारी यहाँ: सर्वर ऑडिट मिस्ट्री: फ़िल्टरिंग class_type में त्रुटि हो जाती है Msg 25713 )

अगला सबसे सामान्य दृष्टिकोण एक विकल्प नहीं है क्योंकि यह कहा गया था कि यह एक विक्रेता-आपूर्ति डेटाबेस है और इसलिए कोई बदलाव नहीं किया जा सकता है। तो मैं उस अंतिम को कवर करूंगा।

कम से कम सामान्य दृष्टिकोण (लेकिन एक जो निश्चित रूप से काम करता है) विशिष्ट फ़ंक्शन नाम को फ़िल्टर करने के लिए है:

ALTER SERVER AUDIT [servAudit]
WHERE ([object_name]<>'function_name');

या, यदि कई नाम:

ALTER SERVER AUDIT [servAudit]
WHERE ([object_name]<>'function_name1' AND [object_name]<>'function_name2');

हालांकि बहुत सामान्य नहीं है, यह दृष्टिकोण ठीक होना चाहिए क्योंकि फ़िल्टर करने के लिए कार्यों की संख्या काफी कम होनी चाहिए, और यह बहुत बार नहीं होगा कि नए फ़ंक्शन पेश किए जाते हैं।

अंत में, दूसरों के लिए जो इस स्थिति का सामना करते हैं और परिवर्तन करने से प्रतिबंधित नहीं होते हैं: आप कार्यों को अपने स्कीमा में रख सकते हैं और फिर केवल स्कीमा को फ़िल्टर कर सकते हैं। यह व्यक्तिगत रूप से कार्यों को फ़िल्टर करने की तुलना में अधिक सामान्य है। यह मानते हुए कि आप एक स्कीमा नामित करते हैं fnऔर फ़ंक्शन को उसमें डालते हैं:

ALTER SERVER AUDIT [servAudit]
WHERE ([schema_name]<>'fn');

ALSO, प्रश्न में निम्नलिखित दो टिप्पणियों के बारे में:

दुर्भाग्य से, एसक्यूएल सर्वर रिलेशनल इन ऑपरेटर की अनुमति नहीं देता है (शायद इसलिए कि यह हर बार क्वेरी को ऑडिट लॉग में लिखना नहीं चाहता है)।

तथा:

हम संग्रहीत संग्रह को लिखने से बचना चाहते हैं, जो WHO क्लॉज में object_id को कोड करता है

INऑपरेटर मुद्दा नहीं है। सच है, यह समर्थित नहीं है, लेकिन ORशर्तों की सूची के लिए यह केवल आशुलिपि है । वास्तविक मुद्दा टी-एसक्यूएल का उपयोग है। केवल शाब्दिक - तार या संख्या - की अनुमति है। तो आप वैसे भी एक संग्रहीत प्रक्रिया को निष्पादित करने में सक्षम नहीं होंगे। न ही आप अंतर्निहित कार्यों का उपयोग कर सकते हैं।


इस प्रतिक्रिया के लिए धन्यवाद। हम इस बदलाव को लागू करने की प्रक्रिया में हैं, और हम इस जवाब को स्वीकार करेंगे जब हम इसकी पुष्टि करेंगे कि यह हमारे पर्यावरण में काम करता है।
मार्क इन्नुची

1
@MarkIannucci धन्यवाद! इसके अलावा, मैंने सिर्फ अपने आदर्श सुझाव में एक मामूली बग तय किया। मैंने परीक्षण से कॉपी और पेस्ट किया था जहां मैं कुछ भी फ़ंक्शन के बजाय फ़ंक्शंस के लिए फ़िल्टर कर रहा था। मैंने अपने उत्तर में =होने के लिए बदल दिया <>। मैंने भी सिर्फ इसका परीक्षण किया और यह विज्ञापित :-) के रूप में काम करता है
सोलोमन रटज़की
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.