आज मैंने हार्डड्राइव की खोज की है जो मेरे डेटाबेस को भरता है। ऐसा पहले भी हो चुका है, आमतौर पर इसका कारण काफी स्पष्ट है। आमतौर पर एक खराब क्वेरी होती है, जिससे टेम्पर्ड बी पर भारी फैल होती है जो डिस्क के पूर्ण होने तक बढ़ती रहती है। इस बार यह थोड़ा कम स्पष्ट था कि क्या हुआ, क्योंकि टेम्पर्डब पूर्ण ड्राइव का कारण नहीं था, यह डेटाबेस ही था।
तथ्यों:
- सामान्य डेटाबेस का आकार लगभग 55 जीबी है, यह बढ़कर 605 जीबी हो गया।
- लॉग फ़ाइल का आकार सामान्य है, डेटाफ़ाइल विशाल है।
- Datafile में 85% उपलब्ध स्थान है (मैं इसे 'हवा' के रूप में व्याख्या करता हूं: जिस स्थान का उपयोग किया गया था, लेकिन उसे फ्रीज कर दिया गया है। SQL सर्वर एक बार आवंटित किए गए सभी स्थान को सुरक्षित रखता है)।
- Tempdb का आकार सामान्य है।
मुझे संभावित कारण मिल गया है; एक क्वेरी है जो बहुत अधिक पंक्तियों का चयन करती है (खराब जुड़ाव 11 बिलियन पंक्तियों के चयन का कारण बनता है जहां एक सौ हजार की उम्मीद है)। यह एक SELECT INTO
क्वेरी है, जिसने मुझे आश्चर्यचकित किया है कि क्या निम्न परिदृश्य हो सकता है:
- Select INTO को अंजाम दिया जाता है
- लक्ष्य तालिका बनाई गई है
- डेटा का चयन करते ही डाला जाता है
- डिस्क भरता है, जिससे इन्सर्ट विफल हो जाता है
- चयन INTO का गर्भपात किया जाता है और उसे वापस लाया जाता है
- रोलबैक अंतरिक्ष को मुक्त करता है (पहले से डाला गया डेटा हटा दिया गया है), लेकिन SQL सर्वर मुक्त किए गए स्थान को जारी नहीं करता है।
इस स्थिति में, हालाँकि, मुझे उम्मीद नहीं थी कि तालिका SELECT INTO
अभी भी बनी होगी, इसे रोलबैक द्वारा छोड़ दिया जाना चाहिए। मैंने इसका परीक्षण किया:
BEGIN TRANSACTION
SELECT T.x
INTO TMP.test
FROM (VALUES(1))T(x)
ROLLBACK
SELECT *
FROM TMP.test
इसका परिणाम यह होगा:
(1 row affected)
Msg 208, Level 16, State 1, Line 8
Invalid object name 'TMP.test'.
फिर भी लक्ष्य तालिका मौजूद है। वास्तविक क्वेरी को स्पष्ट लेनदेन में निष्पादित नहीं किया गया था, लेकिन क्या यह लक्ष्य तालिका के अस्तित्व की व्याख्या कर सकता है?
क्या मैंने जो धारणाएँ बनाई हैं, वे यहाँ सही हैं? क्या ऐसा होने की संभावना है?