Removing Databases and Orphaned Datafiles from your SQL Server

Learn all about Removing Databases and Orphaned Datafiles from your SQL S…. Detailed information, code examples, and best practices.

February 16, 2022

Removing Databases and Orphaned Datafiles from your SQL Server

What are Orphaned Datafiles?

Orphaned database files are files that are 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 large number of development and test environments, this can certainly happen.

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

Why should you care about them?

Offline databases and Orphaned database may be using unnecessary space on your SQL Server storage.

How can we control them?
Offline databases

Run the following script to list all offline databases in your installation.

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 following script and find an example of an Orphaned database.

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;

You can also do this using dba tools (PowerShell).

How to fix them?

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

  • Consider removing the files.
  • If there is a potential you might need something from them, back them up first.