IT *_*her 9 sql-server-2008 sql-server ssms sql-server-2008-r2
In SSMS I saw file size related properties and found below details for one database. Here values does not match with other properties. Here size of the mdf, ldf and total size matches with other values under each window. But Available free space of mdf and ldf if added then it does not equal to Available free space shown in shrink database window and free space shown in database properties. This is true for any database. Why is it so? Please can anyone explain the logic behind this?
Under database properties:
Size: 91.31 MB
Space available:13.40 MBUnder database file properites:
mdf size: 17 MB
ldf size: 75 MBunder shrink database:
Currently allocated size: 91.31 MB
Available free space: 13.40 MBunder shrink file-for data file:
当前分配的大小:16.38 MB
可用空间:12.63 MB在收缩文件-for 日志文件下:
当前分配的大小:74.94 MB
可用空间:55.62 MB
Aar*_*and 11
这看起来并不是那么疯狂,但请注意,某些 UI 对话框可能没有完全最新的信息(这就是我们拥有DBCC UPDATEUSAGE 之类的内容的原因),并且其中一些还可能涉及四舍五入计算。最后,对话框显示整个数据库的总空间,但未分配的空间只计算数据文件,而不是日志。
让我们合并一些事情。
让我看看这些不同的对话框为我的 AdventureWorks2012 本地副本运行了什么(从这个脚本放大了某些表)。
EXEC sp_spaceused;
Run Code Online (Sandbox Code Playgroud)
这将返回(仅限第一个结果集):
database_size unallocated space
------------- -----------------
1545.81 MB 6.67 MB
Run Code Online (Sandbox Code Playgroud)
基本上运行这个 - 我已经通过跟踪确认 - 与从数据库属性和数据库收缩对话框执行的查询大致相同(我已经从存储过程中剔除了不相关的部分,并添加了一个外部查询来表示数学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;
Run Code Online (Sandbox Code Playgroud)
这将返回一个匹配项:
database_size unallocated space
------------- -----------------
1545.8125 6.671875
Run Code Online (Sandbox Code Playgroud)
这些对话框都正确显示了这些信息。数据库属性对话框:
收缩数据库对话框:
另一方面,收缩文件对话框运行一个略有不同的查询(为了方便起见,这也是雕刻/改编的):
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;
Run Code Online (Sandbox Code Playgroud)
还要注意,除了从函数而不是从 DMV 获取大小数据之外,还没有为新文件类型更新谓词,例如 filestream/hekaton。
结果:
Currently allocated space Available free space
---- ------------------------- --------------------
Data 1517 7.9375 -- wrong
Log 28.8125 25.671875 -- wrong
Run Code Online (Sandbox Code Playgroud)
问题在于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;
Run Code Online (Sandbox Code Playgroud)
此查询返回三个看起来应该很熟悉的数字,一个不应该:
file_type size available
--------- ----------- ----------
data 1517.000000 6.6718750
log 28.812500 17.9008512
Run Code Online (Sandbox Code Playgroud)
请注意,DBCC SQLPERF也稍微容易出现空间使用问题,例如在运行后:
DBCC UPDATEUSAGE(0);
Run Code Online (Sandbox Code Playgroud)
上面的查询产生了这个:
file_type size available
--------- ----------- ----------
data 1517.000000 8.0781250
log 28.812500 17.8669481
Run Code Online (Sandbox Code Playgroud)
sp_spaceused
现在也产生匹配的数字 ( 1545.81 MB / 8.08 MB
),即使 - 再次 - 这只是数据文件中的可用空间,并且数据库属性和数据库收缩对话框也是“准确的”(但收缩文件对话框仍然是离开 -FILEPROPERTY()
似乎根本不受其影响UPDATEUSAGE
):
哦,不妨展示一下 Windows 资源管理器对这些文件的看法,这样您就可以将确定 MB 的计算联系起来:
当然,这一切需要有多准确取决于您将如何处理这些信息。
归档时间: |
|
查看次数: |
6014 次 |
最近记录: |