SQL Server Health Check

Removing Offline Databases And Orphaned Data Files From Your SQL Server

Updated April 8, 20263 min read

What are orphaned database data files?

Orphaned database files are not associated with any live database.

Sometimes when you drop a database from a SQL Server instance, the underlying files are not removed.

This can certainly occur if you manage many development and test environments.

Orphaned files usually appear when a database is taken offline and not put back online before it is removed.

Why should you care about them?

Offline databases and orphaned files may be using unnecessary space in your SQL Server storage.

How can I check them?

Offline databases

Run the script below to list all offline databases from your instance.

SELECT 'DB_NAME' = db.name
	,'FILE_NAME' = mf.name
	,'FILE_TYPE' = mf.type_desc
	,'FILE_PATH' = mf.physical_name
FROM sys.databases db
INNER JOIN sys.master_files mf ON db.database_id = mf.database_id
WHERE db.STATE = 6

Orphaned database files

You can run the script below and find the orphaned database from an instance.


DECLARE @DefaultDataPath VARCHAR(512)
	,@DefaultLogPath VARCHAR(512);

SET @DefaultDataPath = CAST(SERVERPROPERTY('InstanceDefaultDataPath') AS VARCHAR(512));
SET @DefaultLogPath = CAST(SERVERPROPERTY('InstanceDefaultLogPath') AS VARCHAR(512));

IF OBJECT_ID('tempdb..#OrphanedDataFiles') IS NOT NULL
	DROP TABLE #OrphanedDataFiles;

CREATE TABLE #OrphanedDataFiles (
	Id INT IDENTITY(1, 1)
	,[FileName] NVARCHAR(512)
	,Depth SMALLINT
	,FileFlag BIT
	,Directory VARCHAR(512) NULL
	,FullFilePath VARCHAR(512) NULL
	);

INSERT INTO #OrphanedDataFiles (
	[FileName]
	,Depth
	,FileFlag
	)
EXEC MASTER..xp_dirtree @DefaultDataPath
	,1
	,1;

UPDATE #OrphanedDataFiles
SET Directory = @DefaultDataPath
	,FullFilePath = @DefaultDataPath + [FileName]
WHERE Directory IS NULL;

INSERT INTO #OrphanedDataFiles (
	[FileName]
	,Depth
	,FileFlag
	)
EXEC MASTER..xp_dirtree @DefaultLogPath
	,1
	,1;

UPDATE #OrphanedDataFiles
SET Directory = @DefaultLogPath
	,FullFilePath = @DefaultLogPath + [FileName]
WHERE Directory IS NULL;

SELECT f.[FileName]
	,f.Directory
	,f.FullFilePath
FROM #OrphanedDataFiles f
LEFT JOIN sys.master_files mf ON f.FullFilePath = REPLACE(mf.physical_name, '\\', '\')
WHERE mf.physical_name IS NULL
	AND f.FileFlag = 1
ORDER BY f.[FileName]
	,f.Directory

DROP TABLE #OrphanedDataFiles;

Also, this task can be accomplished by using dbatools.io (PowerShell).

How to fix it?

Since they are still offline, they are probably not necessary.

Therefore:

  1. Consider removing the files.
  2. If there is a potential need for something from them, ensure to back up first.

More information:

Discover More

Discover what clients are saying about Red9

Red9 has incredible expertise both in SQL migration and performance tuning.

The single biggest benefit has been performance gains and tuning associated with migrating to AWS and a newer version of SQL Server with Always On clustering. Red9 was an integral part of this process.… The deep level of knowledge of MSSQL is incredible and the combined experience and expertise has been a huge asset.… Red9 was able to find a number of inefficient indexes and performance bottlenecks that resulted in over 400% improvement in latency.

Rich StaatsRich StaatsCloud EngineerMetalToad
See more testimonials