mdfおよびldfの空き容量がデータベースの空き容量と一致しません


9

SSMSで、ファイルサイズに関連するプロパティを確認し、1つのデータベースの詳細を以下に示しました。ここで、値は他のプロパティと一致しません。ここで、mdf、ldf、および合計サイズのサイズは、各ウィンドウの下の他の値と一致します。ただし、追加された場合のmdfおよびldfの使用可能な空き領域は、データベースの縮小ウィンドウに表示される使用可能な空き領域およびデータベースのプロパティに表示される空き領域とは異なります。これは、どのデータベースにも当てはまります。なぜそうなのですか?誰かがこの背後にある論理を説明できますか?

データベースのプロパティ:

サイズ:91.31 MB
利用可能なスペース:13.40 MB

データベースファイルのプロパティ:

mdfサイズ:17 MB
ldfサイズ:75 MB

縮小データベース:

現在割り当てられているサイズ:91.31 MB
利用可能な空き容量:13.40 MB

縮小ファイルの下-データファイル:

現在割り当てられているサイズ:16.38 MB
利用可能な空き容量:12.63 MB

縮小ファイル-ログファイル用:

現在割り当てられているサイズ
:74.94 MB利用可能な空き容量:55.62 MB

回答:


11

これはそれほど奇妙に思われるわけではありませんが、UIダイアログの一部は完全に最新の情報を持たない可能性があることに注意してください(これがDBCC UPDATEUSAGEのようなものがある理由です)。計算。最後に、ダイアログにはデータベース全体の合計スペースが表示されますが、未割り当てスペースはログではなくデータファイルに対してのみ計算されます。

いくつかを合体させましょう。

  1. データベースプロパティと縮小データベースは同じことを示しています(とにかく縮小データベースUIにいる必要はありません!)。
  2. データベースファイルのプロパティは、17 + 75 = 92を示しています。これは、追加前の丸めにより、おそらく1の91.31と同じです。
  3. 割り当てられたスペースの場合、個々のファイルのシュリンクは、16.38 + 74.94 = 91.32と表示されます。ここでも、おそらく多少の丸めが行われます。
  4. 使用可能なスペースについては、個々のファイルの縮小が唯一の不一致が疑われる唯一の場所です。これは、UIがデータを取得する場所についてUIに一貫性がなく、これらの場所の一部がDBCC UPDATEUSAGEを必要とするキャッシュの対象となるためです。

ローカルコピーのAdventureWorks2012でこれらのさまざまなダイアログがどのように実行されるかを見てみましょう(このスクリプトから特定の表を拡大しています)。

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ではなく関数からサイズデータを取得することに加えて、filestream / hekatonなどの新しいファイルタイプの述語は更新されていません。

結果:

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

問題はFILEPROPERTY()関数であり、最新の状態であることが保証されていません(DBCC UPDATEUSAGE(0);実行後でも、以下を参照)。これは、ダイアログに関する誤解を招く情報で終わります:

利用可能な読み取り値が間違っています

ここでも、6.67 MBは実際には正確ではなかったことに注意してください。これは、データベースの合計サイズ(割り当てられたページ数)のみを測定しているため、ログを完全に無視しているためです。

正直なところ、データベースで使用されているスペースの正確なレポートが必要な場合は、さまざまな種類のクエリを実行するミッキーマウスUIの使用を停止してこれを把握し、情報を取得するための縮小ファイルダイアログの使用を停止します。これらは特定のケースで明らかに古いデータの問題の影響を受けます。信頼できるソースに対して実際のクエリを実行します。これが私が好むものです:

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;

このクエリは、見慣れたはずの3つの数値と、見慣れないはずの1つの数値を返します。

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):

更新後のデータベースプロパティダイアログ

アップデート後のデータベース縮小ダイアログ

アップデート後のデータファイル圧縮ダイアログ

アップデート後のログファイル圧縮ダイアログ

ああ、また、Windowsエクスプローラーがこれらのファイルをどのように考えているかも示しているので、MBを決定するために行われた計算に関連付けることができます。

Windowsのファイルサイズ

もちろん、これがどれほど正確である必要があるかは、情報をどのように処理するかによって異なります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.