patternsqlMinor
Database reporting more space reserved than total size
Viewed 0 times
reportingtotalspacesizethanmoredatabasereserved
Problem
I have a database which has four data files and a log file. The data files are each around 5 GB, the log is about 1 GB. The database reports the total space reserved as around 21 GB, and of that 18 GB is in use. This information is corroborated by:
However, the Disk Usage Report and
This phantom reserved space certainly isn't on the hard drive, so it must be a case of incorrect data somewhere in SQL Server. Where is it and how do I restore normality?
- Disk Usage Report
- Database Properties dialog (in Management Studio)
sp_spaceused
sys.database_files
- The data files on disk
However, the Disk Usage Report and
sp_spaceused are both reporting that there is around 61 GB of data file space reserved, leaving around 43 GB as "unused" (i.e. not containing data). This should be impossible as the total space reserved is only 21 GB.This phantom reserved space certainly isn't on the hard drive, so it must be a case of incorrect data somewhere in SQL Server. Where is it and how do I restore normality?
Solution
Looking at the code behind
Once a table has (or some tables have) been identified, their statistics can be updated by running one of:
The report should now correctly report (or be closer to correctly reporting) the true reserved and used disk space for the database.
More information is available at MS Docs on DBCC UPDATEUSAGE and sp_spaceused.
sp_spaceused, it references a system table called sys.allocation_units which stores statistics about how big each object in the database is. In particular, the total_pages and used_pages columns relate to the reserved and used disk space reported by sp_spaceused. The following query can help to pinpoint which objects are reporting the excessive reserved space:SELECT
o.name,
a.total_pages * 8 / 1024. AS 'Reserved_MB',
a.used_pages * 8 / 1024. AS 'Used_MB'
FROM sys.allocation_units a
INNER JOIN sys.partitions p
ON p.partition_id = a.container_id
LEFT OUTER JOIN sys.all_objects o
ON o.object_id = p.object_id
ORDER BY a.total_pages - a.used_pages DESC;Once a table has (or some tables have) been identified, their statistics can be updated by running one of:
-- Update the whole current database
DBCC UPDATEUSAGE(0);
-- Update the whole database
DBCC UPDATEUSAGE(DATABASE_NAME);
-- Update a single table and its indexes
DBCC UPDATEUSAGE(DATABASE_NAME, 'TABLE_NAME');
-- Update a single index within a table
DBCC UPDATEUSAGE(DATABASE_NAME, 'TABLE_NAME', 'INDEX_NAME');
-- Update the whole current database and run sp_spaceused
EXEC sp_spaceused @updateusage = 'true'The report should now correctly report (or be closer to correctly reporting) the true reserved and used disk space for the database.
More information is available at MS Docs on DBCC UPDATEUSAGE and sp_spaceused.
Code Snippets
SELECT
o.name,
a.total_pages * 8 / 1024. AS 'Reserved_MB',
a.used_pages * 8 / 1024. AS 'Used_MB'
FROM sys.allocation_units a
INNER JOIN sys.partitions p
ON p.partition_id = a.container_id
LEFT OUTER JOIN sys.all_objects o
ON o.object_id = p.object_id
ORDER BY a.total_pages - a.used_pages DESC;-- Update the whole current database
DBCC UPDATEUSAGE(0);
-- Update the whole database
DBCC UPDATEUSAGE(DATABASE_NAME);
-- Update a single table and its indexes
DBCC UPDATEUSAGE(DATABASE_NAME, 'TABLE_NAME');
-- Update a single index within a table
DBCC UPDATEUSAGE(DATABASE_NAME, 'TABLE_NAME', 'INDEX_NAME');
-- Update the whole current database and run sp_spaceused
EXEC sp_spaceused @updateusage = 'true'Context
StackExchange Database Administrators Q#174692, answer score: 3
Revisions (0)
No revisions yet.