El espacio libre de mdf y ldf no coincide con el espacio libre de la base de datos

9

En SSMS, vi propiedades relacionadas con el tamaño del archivo y encontré los siguientes detalles para una base de datos. Aquí los valores no coinciden con otras propiedades. Aquí el tamaño de mdf, ldf y el tamaño total coinciden con otros valores debajo de cada ventana. Pero el espacio libre disponible de mdf y ldf si se agrega no es igual al espacio libre disponible que se muestra en la ventana de la base de datos de reducción y el espacio libre que se muestra en las propiedades de la base de datos. Esto es cierto para cualquier base de datos. ¿Por que es esto entonces? ¿Alguien puede explicar la lógica detrás de esto?

En propiedades de la base de datos:

Tamaño: 91,31 MB
Espacio disponible: 13,40 MB

En las propiedades del archivo de la base de datos:

Tamaño de mdf: 17 MB
Tamaño de ldf: 75 MB

bajo base de datos retráctil:

Tamaño asignado actualmente: 91.31 MB
Espacio libre disponible: 13.40 MB

bajo archivo de contracción para archivo de datos:

tamaño asignado actualmente: 16.38 MB
Espacio libre disponible: 12.63 MB

bajo reducir archivo para archivo de registro:

tamaño asignado actualmente: 74.94 MB
Espacio libre disponible: 55.62 MB

Investigador de TI
fuente

Respuestas:

11

Esto realmente no parece tan loco, pero tenga en cuenta que algunos de los cuadros de diálogo de la interfaz de usuario pueden no tener información completamente actualizada (es por eso que tenemos cosas como DBCC UPDATEUSAGE ), y el redondeo también puede estar involucrado en algunos de esos cálculos Finalmente, los cuadros de diálogo muestran el espacio total para toda la base de datos , pero el espacio no asignado solo se calcula para los archivos de datos , no para el registro.

Unamos algunas cosas.

  1. Las propiedades de la base de datos y la base de datos retráctil muestran lo mismo (¡de todas formas, no debería estar en la IU de la base de datos retráctil!).
  2. Las propiedades del archivo de la base de datos muestran 17 + 75 = 92 que, con redondeo antes de la adición, es probablemente el mismo 91.31 en 1.
  3. Para el espacio asignado, la reducción para archivos individuales muestra 16.38 + 74.94 = 91.32 - nuevamente, probablemente algo de redondeo allí, de lo contrario coincide exactamente con 1.
  4. Para el espacio disponible, la reducción de archivos individuales es el único lugar donde sospecho que existe una discrepancia real, y esto se debe a que la interfaz de usuario es inconsistente sobre dónde obtiene sus datos, y algunos de estos lugares están sujetos al almacenamiento en caché que requiere el USO ACTUALIZADO DBCC.

Permítanme echar un vistazo a lo que estos diálogos diferentes ejecutan para mi copia local de AdventureWorks2012 (con ciertas tablas ampliadas de este script ).

EXEC sp_spaceused;

Esto devuelve (solo el primer conjunto de resultados):

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

Esencialmente ejecuta esto, lo cual, he confirmado a través del rastreo, es aproximadamente la misma consulta ejecutada desde las propiedades de la base de datos y los cuadros de diálogo de reducción de la base de datos (he tallado las partes irrelevantes del procedimiento almacenado y agregué una consulta externa para representar las matemáticas que SSMS hace para mostrar):

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;

Esto devuelve una coincidencia:

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

Todos estos cuadros de diálogo muestran esta información correctamente. Cuadro de diálogo Propiedades de la base de datos:

Diálogo de propiedades de la base de datos

Cuadro de diálogo Reducir base de datos:

Cuadro de diálogo Reducir base de datos

Los cuadros de diálogo de reducción de archivos , por otro lado, ejecutan una consulta ligeramente diferente (de nuevo, esto está tallado / adaptado para mayor comodidad):

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;

Tenga en cuenta también que, además de obtener datos de tamaño de una función en lugar de un DMV, los predicados no se han actualizado para nuevos tipos de archivos, como filestream / hekaton.

Resultados:

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

El problema es la FILEPROPERTY()función, que no se garantiza que esté actualizada (incluso después de DBCC UPDATEUSAGE(0);ejecutarse; más abajo). Esto termina con esta información engañosa en los cuadros de diálogo:

Espacio incorrecto lecturas disponibles

Tenga en cuenta, de nuevo, que 6.67 MB nunca fue realmente preciso, ya que esto solo mide el tamaño total de la base de datos: la cantidad de páginas asignadas, sin tener en cuenta el registro.

Honestamente, si desea un informe preciso del espacio utilizado en la base de datos, deje de usar las interfaces de usuario de mickey mouse que ejecutan todo tipo de consultas diferentes para resolver esto, y deje de usar los diálogos de archivo de reducción para recuperar información. Estos están claramente sujetos a problemas de datos obsoletos en ciertos casos. Ejecute una consulta real en una fuente en la que pueda confiar. Esto es lo que prefiero:

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;

Esta consulta devuelve tres números que deberían parecer muy familiares, y uno que no debería:

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

Tenga en cuenta que DBCC SQLPERF también es ligeramente propenso a problemas con el uso del espacio, por ejemplo, después de ejecutar:

DBCC UPDATEUSAGE(0);

La consulta anterior produce esto en su lugar:

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

sp_spaceusedahora también produce números coincidentes ( 1545.81 MB / 8.08 MB), aunque, nuevamente, ese es solo el espacio disponible en los archivos de datos , y la propiedad de la base de datos y los cuadros de diálogo de reducción de la base de datos también son "precisos" (pero los cuadros de diálogo del archivo de reducción todavía son lejos - FILEPROPERTY()no parece verse afectado UPDATEUSAGEen absoluto):

Cuadro de diálogo Propiedades de la base de datos después del uso de la actualización

Diálogo de reducción de la base de datos después del uso de la actualización

Cuadro de diálogo de reducción de archivos de datos después de la actualización

Diálogo de reducción del archivo de registro después del uso de actualización

Ah, y también podría mostrar lo que Windows Explorer piensa de estos archivos, para que pueda relacionarse con los cálculos realizados para determinar MB:

Tamaños de archivo en Windows

La precisión de todo esto debe ser, por supuesto, depende de lo que va a hacer con la información.

Aaron Bertrand
fuente