Dies scheint nicht wirklich verrückt zu sein, aber beachten Sie, dass einige der UI-Dialoge möglicherweise nicht vollständig aktuelle Informationen enthalten (aus diesem Grund haben wir Dinge wie DBCC UPDATEUSAGE ), und in einigen davon kann auch Rundung enthalten sein Berechnungen. Schließlich zeigen die Dialogfelder den gesamten Speicherplatz für die gesamte Datenbank an , aber nicht zugewiesener Speicherplatz wird nur für die Datendateien berechnet , nicht für das Protokoll.
Lassen Sie uns einige Dinge zusammenführen.
- Datenbankeigenschaften und Verkleinerungsdatenbank zeigen dasselbe (nicht, dass Sie sich jemals in der Benutzeroberfläche der Verkleinerungsdatenbank befinden sollten!).
- Die Eigenschaften der Datenbankdatei zeigen 17 + 75 = 92, was bei Rundung vor dem Hinzufügen wahrscheinlich der gleiche Wert von 91,31 in 1 ist.
- Für den zugewiesenen Speicherplatz zeigt das Verkleinern für einzelne Dateien 16,38 + 74,94 = 91,32 - wieder wahrscheinlich eine Rundung, ansonsten genau passend zu 1.
- Für den verfügbaren Speicherplatz ist das Verkleinern einzelner Dateien der einzige Ort, an dem ich eine echte Diskrepanz vermute. Dies liegt daran, dass die Benutzeroberfläche nicht konsistent darüber ist, woher sie ihre Daten bezieht, und einige dieser Orte unterliegen dem Caching, das DBCC UPDATEUSAGE erfordert.
Lassen Sie mich einen Blick darauf werfen, was diese verschiedenen Dialoge für meine lokale Kopie von AdventureWorks2012 ausführen (wobei bestimmte Tabellen aus diesem Skript vergrößert wurden ).
EXEC sp_spaceused;
Dies gibt zurück (nur erste Ergebnismenge):
database_size unallocated space
------------- -----------------
1545.81 MB 6.67 MB
Im Wesentlichen wird dies ausgeführt. Dies ist - wie ich über die Ablaufverfolgung bestätigt habe - ungefähr dieselbe Abfrage, die aus den Datenbankeigenschaften und den Datenbankverkleinerungsdialogen ausgeführt wurde (ich habe die irrelevanten Teile aus der gespeicherten Prozedur herausgeschnitten und eine äußere Abfrage hinzugefügt, um die Mathematik darzustellen das SSMS für die Anzeige tut):
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;
Dies gibt eine Übereinstimmung zurück:
database_size unallocated space
------------- -----------------
1545.8125 6.671875
Diese Dialoge zeigen alle diese Informationen korrekt an. Dialogfeld "Datenbankeigenschaften":
Dialogfeld "Datenbank verkleinern":
In den Dialogfeldern zum Verkleinern von Dateien wird dagegen eine etwas andere Abfrage ausgeführt (auch diese ist der Einfachheit halber geschnitzt / angepasst):
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;
Beachten Sie auch, dass zusätzlich zum Abrufen von Größendaten von einer Funktion anstelle einer DMV die Prädikate für neue Dateitypen wie Dateistream / Hekaton nicht aktualisiert wurden.
Ergebnisse:
Currently allocated space Available free space
---- ------------------------- --------------------
Data 1517 7.9375 -- wrong
Log 28.8125 25.671875 -- wrong
Das Problem ist die FILEPROPERTY()
Funktion, die nicht garantiert auf dem neuesten Stand ist (auch nach dem DBCC UPDATEUSAGE(0);
Ausführen; mehr unten). Dies führt zu folgenden irreführenden Informationen in den Dialogen:
Beachten Sie erneut, dass 6,67 MB nie wirklich genau waren, da hier nur die gesamte Datenbankgröße gemessen wird - die Anzahl der zugewiesenen Seiten, wobei das Protokoll vollständig ignoriert wird.
Wenn Sie eine genaue Berichterstattung über den in der Datenbank verwendeten Speicherplatz wünschen, verwenden Sie ehrlich gesagt nicht mehr die Mickey-Mouse-Benutzeroberflächen, in denen alle Arten von Abfragen ausgeführt werden, um dies herauszufinden, und verwenden Sie nicht mehr die Dialogfelder zum Verkleinern von Dateien zum Abrufen von Informationen. Diese unterliegen in bestimmten Fällen eindeutig veralteten Datenproblemen. Führen Sie eine tatsächliche Abfrage für eine Quelle aus, der Sie vertrauen können. Folgendes bevorzuge ich:
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;
Diese Abfrage gibt drei Zahlen zurück, die sehr vertraut aussehen sollten, und eine, die nicht:
file_type size available
--------- ----------- ----------
data 1517.000000 6.6718750
log 28.812500 17.9008512
Beachten Sie, dass DBCC SQLPERF auch leicht anfällig für Probleme mit der Speicherplatznutzung ist, z. B. nach dem Ausführen von:
DBCC UPDATEUSAGE(0);
Die obige Abfrage ergibt stattdessen Folgendes:
file_type size available
--------- ----------- ----------
data 1517.000000 8.0781250
log 28.812500 17.8669481
sp_spaceused
Jetzt werden auch übereinstimmende Zahlen ausgegeben ( 1545.81 MB / 8.08 MB
), obwohl dies wiederum nur der in den Datendateien verfügbare Speicherplatz ist und die Datenbankeigenschaften- und Datenbank-Verkleinerungsdialoge ebenfalls "genau" sind (die Verkleinerungsdateidialoge jedoch weiterhin vorhanden sind) weit weg - FILEPROPERTY()
scheint überhaupt nicht betroffen UPDATEUSAGE
zu sein):
Oh, und könnte genauso gut zeigen, was Windows Explorer von diesen Dateien hält, sodass Sie sich auf die Berechnungen beziehen können, die zur Bestimmung von MB durchgeführt wurden:
Wie genau dies alles sein muss, hängt natürlich davon ab, was Sie mit den Informationen tun werden.