Removing offline databases and orphaned datafiles from your SQL Server

What are orphaned datafiles?

Orphaned database files are files not associated with any attached database (live database).

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

If you manage a lot of development and test environments, this can certainly occur.

Usually, when you take a database offline and forget to put it back online before remove.

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, you can do this using dba tools (PowerShell).

How to fix it?

Since they are still offline, they probably not necessary.

  1. Consider removing the files.
  2. If there is a potential, you may need something from them, backup first.

More information

Multi-server Script to Find Orphaned Data Files using PowerShell, Prashanth Jayaram- SQLShack.
Microsoft – ALTER DATABASE SET options.

Share this post

Share on facebook
Share on google
Share on twitter
Share on linkedin
Share on pinterest
Share on print
Share on email

Leave a Comment

Your email address will not be published. Required fields are marked *

4.8/5

42

TESTIMONIALS

FREE Scripts to Instantly
Improve SQL Server Performance

3 FREE Scripts to Instantly
Improve SQL Server Performance

Learn how to increase Performance of SQL Server INSTANTLY with 3 free scripts.