L'espace libre de mdf et ldf ne correspond pas à l'espace libre de la base de données

9

Dans SSMS, j'ai vu les propriétés liées à la taille du fichier et j'ai trouvé ci-dessous les détails d'une base de données. Ici, les valeurs ne correspondent pas aux autres propriétés. Ici, la taille du mdf, du ldf et de la taille totale correspond à d'autres valeurs sous chaque fenêtre. Mais l'espace libre disponible de mdf et ldf s'il est ajouté, il n'est pas égal à l'espace libre disponible affiché dans la fenêtre de réduction de la base de données et l'espace libre affiché dans les propriétés de la base de données. Cela est vrai pour n'importe quelle base de données. Pourquoi en est-il ainsi? S'il vous plaît quelqu'un peut-il expliquer la logique derrière cela?

Sous les propriétés de la base de données:

Taille: 91,31 Mo
Espace disponible: 13,40 Mo

Sous les propriétés du fichier de base de données:

taille mdf: 17 Mo
taille ldf: 75 Mo

sous la base de données rétrécie:

Taille actuellement allouée: 91,31 Mo
Espace libre disponible: 13,40 Mo

sous rétrécir fichier pour fichier de données:

taille actuellement allouée: 16,38 Mo
Espace libre disponible: 12,63 Mo

sous réduire le fichier journal pour le fichier journal:

taille actuellement allouée: 74,94 Mo
Espace libre disponible: 55,62 Mo

Chercheur informatique
la source

Réponses:

11

Cela ne semble pas vraiment fou, mais notez que certaines boîtes de dialogue d'interface utilisateur peuvent ne pas avoir d'informations complètement à jour (c'est pourquoi nous avons des choses comme DBCC UPDATEUSAGE ), et l'arrondi peut également être impliqué dans certaines de ces calculs. Enfin, les boîtes de dialogue vous montrent l'espace total pour toute la base de données , mais l'espace non alloué n'est calculé que pour les fichiers de données , pas le journal.

Faisons fusionner certaines choses.

  1. Les propriétés de la base de données et la base de données de réduction montrent la même chose (pas que vous devriez de toute façon être dans l'interface utilisateur de la base de données de réduction!).
  2. Les propriétés du fichier de base de données affichent 17 + 75 = 92, ce qui, avec l'arrondi avant l'addition, est probablement le même 91,31 en 1.
  3. Pour l'espace alloué, la réduction pour les fichiers individuels affiche 16,38 + 74,94 = 91,32 - encore une fois, probablement un certain arrondi, sinon exactement 1.
  4. Pour l'espace disponible, la réduction pour les fichiers individuels est le seul endroit où je soupçonne une réelle différence, et c'est parce que l'interface utilisateur n'est pas cohérente quant à l'endroit où elle obtient ses données, et certains de ces endroits sont soumis à la mise en cache qui nécessite DBCC UPDATEUSAGE.

Permettez-moi de voir ce que ces différentes boîtes de dialogue exécutent pour ma copie locale d'AdventureWorks2012 (avec certains tableaux agrandis à partir de ce script ).

EXEC sp_spaceused;

Cela renvoie (premier jeu de résultats uniquement):

database_size    unallocated space
-------------    -----------------
   1545.81 MB          6.67 MB

Exécute essentiellement cela, qui - j'ai confirmé via trace - est à peu près la même requête exécutée à partir des propriétés de la base de données et des boîtes de dialogue de réduction de la base de données (j'ai découpé les parties non pertinentes de la procédure stockée et ajouté une requête externe pour représenter les mathématiques que SSMS fait pour l'affichage):

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;

Cela renvoie une correspondance:

database_size    unallocated space
-------------    -----------------
    1545.8125             6.671875

Ces boîtes de dialogue affichent toutes ces informations correctement. Boîte de dialogue Propriétés de la base de données:

Boîte de dialogue Propriétés de la base de données

Boîte de dialogue Réduire la base de données:

Boîte de dialogue Réduire la base de données

Les boîtes de dialogue de réduction du fichier , d'autre part, exécutent une requête légèrement différente (encore une fois, cela est sculpté / adapté pour plus de commodité):

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;

Notez également qu'en plus d'obtenir des données de taille à partir d'une fonction au lieu d'un DMV, les prédicats n'ont pas été mis à jour pour les nouveaux types de fichiers, comme filestream / hekaton.

Résultats:

        Currently allocated space    Available free space
----    -------------------------    --------------------
Data                         1517                  7.9375 -- wrong
Log                       28.8125               25.671875 -- wrong

Le problème est la FILEPROPERTY()fonction, qui n'est pas garantie d'être à jour (même après l' DBCC UPDATEUSAGE(0);exécution; plus ci-dessous). Cela se termine par ces informations trompeuses sur les boîtes de dialogue:

Lectures d'espace disponibles incorrectes

Notez, encore une fois, que 6,67 Mo n'ont jamais été vraiment précis, car cela ne mesure que la taille totale de la base de données - le nombre de pages allouées, sans tenir compte du journal.

En toute honnêteté, si vous voulez des rapports précis sur l'espace utilisé dans la base de données, arrêtez d'utiliser les interfaces utilisateur de mickey mouse qui exécutent toutes sortes de requêtes différentes pour comprendre cela, et arrêtez d'utiliser les boîtes de dialogue de réduction de fichier pour récupérer des informations. Ceux-ci sont clairement sujets à des problèmes de données périmées dans certains cas. Exécutez une requête réelle sur une source de confiance. Voici ce que je préfère:

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;

Cette requête renvoie trois nombres qui devraient sembler très familiers et un qui ne devrait pas:

file_type    size           available
---------    -----------    ----------
data         1517.000000     6.6718750
log            28.812500    17.9008512

Notez que DBCC SQLPERF est également légèrement sujet à des problèmes d'utilisation de l'espace, par exemple après l'exécution:

DBCC UPDATEUSAGE(0);

La requête ci-dessus donne ceci à la place:

file_type    size           available
---------    -----------    ----------
data         1517.000000     8.0781250
log            28.812500    17.8669481

sp_spaceusedmaintenant donne des numéros correspondant aussi bien ( 1545.81 MB / 8.08 MB), même si - encore une fois - qui est seulement l'espace disponible dans les données fichier (s) et les boîtes de dialogue de propriétés de base de données et rétrécir la base de données sont « exactes », ainsi (mais les boîtes de dialogue de fichier psy sont encore loin - FILEPROPERTY()ne semble pas du tout affecté par UPDATEUSAGE):

Boîte de dialogue Propriétés de la base de données après la mise à jour

Boîte de dialogue de réduction de la base de données après la mise à jour

Boîte de dialogue de réduction du fichier de données après la mise à jour

Boîte de dialogue de réduction du fichier journal après la mise à jour

Oh, et pourrait aussi bien montrer ce que Windows Explorer pense de ces fichiers, vous pouvez donc vous référer aux calculs effectués pour déterminer Mo:

Tailles de fichiers sous Windows

La précision de tout cela dépend, bien sûr, de ce que vous allez faire des informations.

Aaron Bertrand
la source