Der freie Speicherplatz von mdf und ldf stimmt nicht mit dem freien Speicherplatz der Datenbank überein

9

In SSMS habe ich Eigenschaften im Zusammenhang mit der Dateigröße gesehen und unten Details für eine Datenbank gefunden. Hier stimmen die Werte nicht mit anderen Eigenschaften überein. Hier stimmt die Größe von mdf, ldf und der Gesamtgröße mit anderen Werten unter jedem Fenster überein. Der verfügbare freie Speicherplatz von mdf und ldf entspricht jedoch nicht dem verfügbaren freien Speicherplatz, der im Fenster zum Verkleinern der Datenbank angezeigt wird, und dem freien Speicherplatz, der in den Datenbankeigenschaften angezeigt wird. Dies gilt für jede Datenbank. Wieso ist es so? Kann mir bitte jemand die Logik dahinter erklären?

Unter Datenbankeigenschaften:

Größe: 91,31 MB
Verfügbarer Speicherplatz: 13,40 MB

Unter Eigenschaften der Datenbankdatei:

mdf-größe: 17 MB
ldf-größe: 75 MB

unter Datenbank verkleinern:

Derzeit zugewiesene Größe: 91,31 MB
Verfügbarer freier Speicherplatz: 13,40 MB

unter Datei verkleinern - für Datendatei:

Derzeit zugewiesene Größe: 16,38 MB
Verfügbarer freier Speicherplatz: 12,63 MB

unter Datei verkleinern - für Protokolldatei:

Derzeit zugewiesene Größe: 74,94 MB
Verfügbarer freier Speicherplatz: 55,62 MB

IT-Forscher
quelle

Antworten:

11

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.

  1. Datenbankeigenschaften und Verkleinerungsdatenbank zeigen dasselbe (nicht, dass Sie sich jemals in der Benutzeroberfläche der Verkleinerungsdatenbank befinden sollten!).
  2. 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.
  3. 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.
  4. 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 "Datenbankeigenschaften"

Dialogfeld "Datenbank verkleinern":

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:

Falscher Platz verfügbar Messwerte

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_spaceusedJetzt 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 UPDATEUSAGEzu sein):

Dialogfeld "Datenbankeigenschaften" nach Aktualisierung

Dialogfeld zum Verkleinern der Datenbank nach der Aktualisierung

Dialog zum Verkleinern von Datendateien nach der Aktualisierung

Dialogfeld zum Verkleinern der Protokolldatei nach der Aktualisierung

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:

Dateigrößen in Windows

Wie genau dies alles sein muss, hängt natürlich davon ab, was Sie mit den Informationen tun werden.

Aaron Bertrand
quelle