列出SQL Server中所有数据库文件的信息

108

如何在SQL Server上列出所有数据库(MDF/LDF)文件的信息?

我想获取一个列表,显示哪个数据库正在使用本地磁盘上的哪些文件。

我的尝试:

  • exec sp_databases 显示所有数据库
  • select * from sys.databases 显示每个数据库的大量信息 - 但不幸的是它不显示每个数据库使用的文件。
  • select * from sys.database_files 显示master数据库的mdf/ldf文件- 但不包括其他数据库。

我发现如果你在select * from sys.database_files之前加上一个指向你感兴趣的数据库的use语句,它就能正常工作。所以,在SQL Server 2019中,use MyDb; select * from sys.database_files对我来说是有效的。 - undefined
15个回答

1
这个脚本列出了大部分你需要的内容,并希望能根据你的需求进行修改。请注意,它在其中创建了一个永久表 - 你可能需要更改它。它是一个较大脚本的子集,还总结了各种服务器上的备份和作业信息。
IF OBJECT_ID('tempdb..#DriveInfo') IS NOT NULL
 DROP TABLE #DriveInfo
CREATE TABLE #DriveInfo
 (
    Drive CHAR(1)
    ,MBFree INT
 ) 

INSERT  INTO #DriveInfo
      EXEC master..xp_fixeddrives


IF OBJECT_ID('[dbo].[Tmp_tblDatabaseInfo]', 'U') IS NOT NULL 
   DROP TABLE [dbo].[Tmp_tblDatabaseInfo]
CREATE TABLE [dbo].[Tmp_tblDatabaseInfo](
      [ServerName] [nvarchar](128) NULL
      ,[DBName] [nvarchar](128)  NULL
      ,[database_id] [int] NULL
      ,[create_date] datetime NULL
      ,[CompatibilityLevel] [int] NULL
      ,[collation_name] [nvarchar](128) NULL
      ,[state_desc] [nvarchar](60) NULL
      ,[recovery_model_desc] [nvarchar](60) NULL
      ,[DataFileLocations] [nvarchar](4000)
      ,[DataFilesMB] money null
      ,DataVolumeFreeSpaceMB INT NULL
      ,[LogFileLocations] [nvarchar](4000)
      ,[LogFilesMB] money null
      ,LogVolumeFreeSpaceMB INT NULL

) ON [PRIMARY]

INSERT INTO [dbo].[Tmp_tblDatabaseInfo] 
SELECT 
      @@SERVERNAME AS [ServerName] 
      ,d.name AS DBName 
      ,d.database_id
      ,d.create_date
      ,d.compatibility_level  
      ,CAST(d.collation_name AS [nvarchar](128)) AS collation_name
      ,d.[state_desc]
      ,d.recovery_model_desc
      ,(select physical_name + ' | ' AS [text()]
         from sys.master_files m
         WHERE m.type = 0 and m.database_id = d.database_id
         ORDER BY file_id
         FOR XML PATH ('')) AS DataFileLocations
      ,(select sum(size) from sys.master_files m WHERE m.type = 0 and m.database_id = d.database_id)  AS DataFilesMB
      ,NULL
      ,(select physical_name + ' | ' AS [text()]
         from sys.master_files m
         WHERE m.type = 1 and m.database_id = d.database_id
         ORDER BY file_id
         FOR XML PATH ('')) AS LogFileLocations
      ,(select sum(size) from sys.master_files m WHERE m.type = 1 and m.database_id = d.database_id)  AS LogFilesMB
      ,NULL
FROM  sys.databases d  

WHERE d.database_id > 4 --Exclude basic system databases
UPDATE [dbo].[Tmp_tblDatabaseInfo] 
   SET DataFileLocations = 
      CASE WHEN LEN(DataFileLocations) > 4 THEN  LEFT(DataFileLocations,LEN(DataFileLocations)-2) ELSE NULL END
   ,LogFileLocations =
      CASE WHEN LEN(LogFileLocations) > 4 THEN  LEFT(LogFileLocations,LEN(LogFileLocations)-2) ELSE NULL END
   ,DataFilesMB = 
      CASE WHEN DataFilesMB > 0 THEN  DataFilesMB * 8 / 1024.0   ELSE NULL END
   ,LogFilesMB = 
      CASE WHEN LogFilesMB > 0 THEN  LogFilesMB * 8 / 1024.0  ELSE NULL END
   ,DataVolumeFreeSpaceMB = 
      (SELECT MBFree FROM #DriveInfo WHERE Drive = LEFT( DataFileLocations,1))
   ,LogVolumeFreeSpaceMB = 
      (SELECT MBFree FROM #DriveInfo WHERE Drive = LEFT( LogFileLocations,1))

select * from [dbo].[Tmp_tblDatabaseInfo] 

一个优秀的脚本,可以直接复制/粘贴并使用。不过我有一个问题,我发现对于“LogVolumeFreeSpaceMB”,它始终显示相同的所有文件的数量,在我的情况下是44756。是否可以获取实际空闲空间?或者这是LDF所在驱动器上的最大可用空间数量? - Abel
嗨,Abel - 我已经有一段时间没有写信了,我不太确定你的问题。有一个替代XP_FIXEDDRIVES的方法叫做sys.dm_os_volume_stats,你可以尝试使用它。如果问题是数据库文件大小随时间不变,则这是正常的,因为SQL Server为其使用分配了一大块空磁盘空间,然后直到填满该文件才会扩展该文件。它将按跳跃方式扩展文件,所扩展的数量由该特定数据库的文件设置确定。 - Gerard

1
如果您重命名数据库,MS SQL Server不会重命名底层文件。
以下查询将为您提供数据库的当前名称和逻辑文件名(可能是创建数据库时的原始名称),以及相应的物理文件名。
注意:取消注释最后一行,仅查看实际数据文件。
select  db.database_id, 
        db.name "Database Name", 
        files.name "Logical File Name",
        files.physical_name
from    sys.master_files files 
        join sys.databases db on db.database_id = files.database_id 
--                           and files.type_desc = 'ROWS'

参考资料:

https://learn.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-master-files-transact-sql?view=sql-server-ver15

https://learn.microsoft.com/en-us/sql/relational-databases/system-catalog-views/sys-databases-transact-sql?view=sql-server-ver15


1
使用sp_MSForEachDB存储过程是一种选择。
EXEC sp_MSForEachDB 'use ? select * from sys.database_files'

此外,还可以查看完整路径名称和大小信息。
EXEC sp_MSForEachDB '
USE [?];
SELECT DB_NAME() AS DbName, 
    physical_name AS FullPath,
    name AS FileName, 
    type_desc,
    size/128.0 AS CurrentSizeMB,  
    size/128.0 - CAST(FILEPROPERTY(name, ''SpaceUsed'') AS INT)/128.0 AS FreeSpaceMB
FROM sys.database_files
WHERE type IN (0,1);
'

0

只是添砖加瓦。

如果特别想要在所有数据库中仅查找数据文件或日志文件的总可用空间,可以使用"data_space_id"列。1表示数据文件,0表示日志文件。

代码:

Create Table ##temp
(
    DatabaseName sysname,
    Name sysname,
    spacetype sysname,
    physical_name nvarchar(500),
    size decimal (18,2),
    FreeSpace decimal (18,2)
)   
Exec sp_msforeachdb '
Use [?];

Insert Into ##temp (DatabaseName, Name,spacetype, physical_name, Size, FreeSpace)
    Select DB_NAME() AS [DatabaseName], Name,   ***data_space_id*** , physical_name,
    Cast(Cast(Round(cast(size as decimal) * 8.0/1024.0,2) as decimal(18,2))/1024 as nvarchar) SizeGB,
    Cast(Cast(Round(cast(size as decimal) * 8.0/1024.0,2)/1024 as decimal(18,2)) -
        Cast(FILEPROPERTY(name, ''SpaceUsed'') * 8.0/1024.0 as decimal(18,2))/1024 as nvarchar) As FreeSpaceGB
    From sys.database_files'


select  
    databasename
    , sum(##temp.FreeSpace) 
from 
    ##temp 
where 
    ##temp.spacetype = 1  
group by 
    DatabaseName

drop table ##temp 


-3

您可以使用以下内容:

SP_HELPDB [Master]
GO

这仅提供单个指定数据库的信息。问题是针对所有数据库的。 - Thronk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接