SQL Server Health Check

Removing Offline Databases And Orphaned Data Files From Your SQL Server

Updated April 8, 20263 min read

Written byMark Varnas

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 removingthe 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 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 integral to this process. The deep knowledge of MSSQL and combined experience of Red9 have been a huge asset during a difficult migration. Red9 found inefficient indexes and performance bottlenecks that improved latency by over 400%.

Rich StaatsRich StaatsCloud EngineerMetalToad
See more testimonials