यह वास्तव में सभी पागल नहीं लगता है, लेकिन ध्यान दें कि कुछ यूआई संवादों में पूरी तरह से अद्यतित जानकारी नहीं हो सकती है (यही कारण है कि हमारे पास DBCC UPDATEUSAGE जैसी चीजें हैं ), और राउंडिंग भी उनमें से कुछ में शामिल हो सकते हैं गणना। अंत में, डायलॉग आपको पूरे डेटाबेस के लिए कुल स्थान दिखाते हैं , लेकिन अनलॉक्ड स्पेस की गणना केवल डेटा फ़ाइलों के लिए की जाती है , लॉग की नहीं।
आइए, कुछ चीजों को समेटते हैं।
- डेटाबेस गुण और हटना डेटाबेस एक ही बात दिखाते हैं (यह नहीं कि आपको कभी भी डेटाबेस यूआई में हटना चाहिए!)।
- डेटाबेस फ़ाइल गुण 17 + 75 = 92 दिखाते हैं, जो पहले जोड़ने के साथ, संभवतः 1 में 91.31 है।
- आवंटित की गई जगह के लिए, अलग-अलग फ़ाइलों के लिए सिकुड़ते हुए 16.38 + 74.94 = 91.32 - फिर से, शायद कुछ गोलाई वहाँ है, अन्यथा मिलान 1।
- उपलब्ध स्थान के लिए, व्यक्तिगत फ़ाइलों के लिए हटना एकमात्र ऐसी जगह है जहां मुझे वास्तविक विसंगति पर संदेह है, और इसका कारण यह है कि UI इस बारे में असंगत है कि उसे इसका डेटा कहां मिलता है, और इनमें से कुछ स्थान उन कैशिंग के अधीन हैं जो DBCCDATEUSAGE की आवश्यकता है।
चलिए एक नज़र डालते हैं कि एडवेंचरवर्क्स2012 की मेरी स्थानीय प्रति के लिए ये अलग-अलग संवाद क्या हैं (कुछ स्क्रिप्ट के साथ इस स्क्रिप्ट से बढ़े हुए )।
EXEC sp_spaceused;
यह रिटर्न (केवल पहले परिणाम):
database_size unallocated space
------------- -----------------
1545.81 MB 6.67 MB
अनिवार्य रूप से इसे चलाता है, जिसे मैंने ट्रेस के माध्यम से पुष्टि की है - डेटाबेस गुणों और डेटाबेस हटना संवादों से लगभग एक ही क्वेरी निष्पादित की गई है (मैंने संग्रहीत प्रक्रिया से अप्रासंगिक भागों को बाहर किया है, और गणित का प्रतिनिधित्व करने के लिए एक बाहरी क्वेरी जोड़ी है। वह SSMS प्रदर्शन के लिए करता है):
SELECT database_size = DbSize*8.0/1024 + LogSize*8.0/1024,
[unallocated space] = (DbSize-SpaceUsed)*8.0/1024
FROM
(
SELECT
(SELECT SUM(CAST(df.size as float)) FROM sys.database_files AS df
WHERE df.type in ( 0, 2, 4 ) ) AS [DbSize],
SUM(a.total_pages) AS [SpaceUsed],
(SELECT SUM(CAST(df.size as float)) FROM sys.database_files AS df
WHERE df.type in (1, 3)) AS [LogSize]
FROM sys.partitions p
join sys.allocation_units a on p.partition_id = a.container_id
left join sys.internal_tables it on p.object_id = it.object_id
) AS x;
यह एक मैच लौटाता है:
database_size unallocated space
------------- -----------------
1545.8125 6.671875
ये संवाद सभी इस जानकारी को सही तरीके से दिखाते हैं। डेटाबेस गुण संवाद:
डेटाबेस संवाद सिकोड़ें:
छोटा फ़ाइल संवाद, दूसरे हाथ पर, एक अलग क्वेरी चलाने (फिर से इस खुदी हुई है / सुविधा के लिए अनुकूलित):
SELECT SUBSTRING(name, CHARINDEX('_',name)+1, 4),
[Currently allocated space] = size/1024.0,
[Available free space] = (Size-UsedSpace)/1024.0
FROM
(
SELECT s.name,
CAST(FILEPROPERTY(s.name, 'SpaceUsed') AS float)*CONVERT(float,8) AS [UsedSpace],
s.size * CONVERT(float,8) AS [Size]
FROM sys.database_files AS s
WHERE (s.type IN (0,1))
) AS x;
ध्यान दें, यह भी, कि DMV के बजाय एक फ़ंक्शन से आकार डेटा प्राप्त करने के अलावा, नए फ़ाइल प्रकारों के लिए, फ़ाइलस्ट्रीम / हेकोटन जैसे विधेयकों को अपडेट नहीं किया गया है।
परिणाम:
Currently allocated space Available free space
---- ------------------------- --------------------
Data 1517 7.9375 -- wrong
Log 28.8125 25.671875 -- wrong
समस्या FILEPROPERTY()
फ़ंक्शन है, जो आज तक होने की गारंटी नहीं है (यहां तक DBCC UPDATEUSAGE(0);
कि चलाने के बाद ; नीचे अधिक)। यह संवाद पर इस भ्रामक जानकारी के साथ समाप्त होता है:
ध्यान दें, फिर से, 6.67 एमबी वास्तव में सटीक नहीं था, क्योंकि यह केवल कुल डेटाबेस आकार को माप रहा है - आवंटित पृष्ठों की संख्या, पूरी तरह से लॉग की अवहेलना।
सभी ईमानदारी से, यदि आप डेटाबेस में उपयोग किए गए स्थान की सटीक रिपोर्टिंग चाहते हैं, तो मिकी माउस यूआई का उपयोग करना बंद करें, जो इसे पता लगाने के लिए सभी प्रकार के विभिन्न प्रश्नों को चलाता है, और जानकारी प्राप्त करने के लिए हटना फ़ाइल संवादों का उपयोग करना बंद कर देता है। ये स्पष्ट रूप से कुछ मामलों में डेटा की समस्याओं के बासी हैं। जिस स्रोत पर आप भरोसा कर सकते हैं, उसके विरुद्ध वास्तविक क्वेरी चलाएँ। यहाँ मुझे पसंद है:
DECLARE @log_used DECIMAL(19,7);
CREATE TABLE #x(n SYSNAME, s DECIMAL(19,7), u DECIMAL(19,7), b BIT);
INSERT #x EXEC('DBCC SQLPERF(LogSpace);');
SELECT @log_used = u FROM #x WHERE n = DB_NAME();
DROP TABLE #x;
DECLARE @data_used DECIMAL(19,7);
SELECT @data_used = SUM(a.total_pages)*8/1024.0
FROM sys.partitions AS p
INNER JOIN sys.allocation_units AS a
ON p.[partition_id] = a.container_id;
;WITH x(t,s) AS
(
SELECT [type] = CASE
WHEN [type] IN (0,2,4) THEN 'data' ELSE 'log' END,
size*8/1024.0 FROM sys.database_files AS f
)
SELECT
file_type = t,
size = s,
available = s-CASE t WHEN 'data' THEN @data_used ELSE @log_used END
FROM x;
यह क्वेरी तीन नंबर देती है जो बहुत परिचित दिखना चाहिए, और एक जो नहीं होना चाहिए:
file_type size available
--------- ----------- ----------
data 1517.000000 6.6718750
log 28.812500 17.9008512
ध्यान दें कि DBCC SQLPERF भी अंतरिक्ष उपयोग के मुद्दों के लिए थोड़ा प्रवण है, उदाहरण के लिए दौड़ने के बाद:
DBCC UPDATEUSAGE(0);
उपर्युक्त क्वेरी इसकी जगह देती है:
file_type size available
--------- ----------- ----------
data 1517.000000 8.0781250
log 28.812500 17.8669481
sp_spaceused
अब मिलान संख्या के साथ-साथ ( 1545.81 MB / 8.08 MB
), भले ही - फिर से - कि केवल डेटा फ़ाइल (एस) में उपलब्ध स्थान है , और डेटाबेस संपत्ति और डेटाबेस हटना संवाद "सटीक" के रूप में अच्छी तरह से कर रहे हैं (लेकिन हटना फ़ाइल संवाद अभी भी हैं रास्ता बंद - FILEPROPERTY()
से प्रभावित नहीं लगता है UPDATEUSAGE
):
ओह, और साथ ही विंडोज एक्सप्लोरर इन फ़ाइलों के बारे में क्या सोचता है, यह दिखा सकता है, इसलिए आप एमबी निर्धारित करने के लिए की गई गणना से संबंधित हो सकते हैं:
यह सब कितना सटीक होना चाहिए, निश्चित रूप से, इस बात पर निर्भर करता है कि आप जानकारी के साथ क्या करने जा रहे हैं।