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
これはそれほど奇妙に思われるわけではありませんが、一部の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
_
これらのダイアログはすべて、この情報を正しく表示します。データベースのプロパティダイアログ:
[データベースの縮小]ダイアログ:
一方、shrinkfileダイアログは、少し異なるクエリを実行します(これも、便宜上、切り分け/適応されています)。
_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
_)。ただし、これもdataファイル、およびデータベースプロパティとデータベースの縮小ダイアログも「正確」です(ただし、縮小ファイルのダイアログはまだずれています-FILEPROPERTY()
はUPDATEUSAGE
の影響をまったく受けていないようです):
ああ、また、Windowsエクスプローラーがこれらのファイルをどのように考えているかも示しているので、MBを決定するために行われた計算に関連付けることができます。
もちろん、これがどれほど正確である必要があるかは、情報をどのように処理するかによって異なります。