如何在SQL Server上列出所有数据库(MDF/LDF)文件的信息?
我想获取一个列表,显示哪个数据库正在使用本地磁盘上的哪些文件。
我的尝试:
exec sp_databases
显示所有数据库select * from sys.databases
显示每个数据库的大量信息 - 但不幸的是它不显示每个数据库使用的文件。select * from sys.database_files
显示master
数据库的mdf/ldf文件- 但不包括其他数据库。
如何在SQL Server上列出所有数据库(MDF/LDF)文件的信息?
我想获取一个列表,显示哪个数据库正在使用本地磁盘上的哪些文件。
我的尝试:
exec sp_databases
显示所有数据库select * from sys.databases
显示每个数据库的大量信息 - 但不幸的是它不显示每个数据库使用的文件。select * from sys.database_files
显示master
数据库的mdf/ldf文件- 但不包括其他数据库。它包含数据库中每个文件的行,这些行在主数据库中存储。这是一个单一的、系统范围内的视图。
DB_NAME(database_id)
而不是连接sys.databases
。 - Cleptus如果您想获取数据库的位置,可以查看获取所有数据库位置。
您可以使用sys.master_files
获取数据库的位置,并使用sys.database
获取数据库名称。
SELECT
db.name AS DBName,
type_desc AS FileType,
Physical_Name AS Location
FROM
sys.master_files mf
INNER JOIN
sys.databases db ON db.database_id = mf.database_id
我正在使用脚本获取每个文件中的空白空间:
Create Table ##temp
(
DatabaseName sysname,
Name sysname,
physical_name nvarchar(500),
size decimal (18,2),
FreeSpace decimal (18,2)
)
Exec sp_msforeachdb '
Use [?];
Insert Into ##temp (DatabaseName, Name, physical_name, Size, FreeSpace)
Select DB_NAME() AS [DatabaseName], Name, physical_name,
Cast(Cast(Round(cast(size as decimal) * 8.0/1024.0,2) as decimal(18,2)) as nvarchar) Size,
Cast(Cast(Round(cast(size as decimal) * 8.0/1024.0,2) as decimal(18,2)) -
Cast(FILEPROPERTY(name, ''SpaceUsed'') * 8.0/1024.0 as decimal(18,2)) as nvarchar) As FreeSpace
From sys.database_files
'
Select * From ##temp
drop table ##temp
大小以KB为单位表示。
我创建了这个查询:
SELECT
db.name AS [Database Name],
mf.name AS [Logical Name],
mf.type_desc AS [File Type],
mf.physical_name AS [Path],
CAST(
(mf.Size * 8
) / 1024.0 AS DECIMAL(18, 1)) AS [Initial Size (MB)],
'By '+IIF(
mf.is_percent_growth = 1, CAST(mf.growth AS VARCHAR(10))+'%', CONVERT(VARCHAR(30), CAST(
(mf.growth * 8
) / 1024.0 AS DECIMAL(18, 1)))+' MB') AS [Autogrowth],
IIF(mf.max_size = 0, 'No growth is allowed', IIF(mf.max_size = -1, 'Unlimited', CAST(
(
CAST(mf.max_size AS BIGINT) * 8
) / 1024 AS VARCHAR(30))+' MB')) AS [MaximumSize]
FROM
sys.master_files AS mf
INNER JOIN sys.databases AS db ON
db.database_id = mf.database_id
执行以下 SQL(仅适用于同一数据库没有多个 MDF/LDF 文件的情况)
SELECT
db.name AS DBName,
(select mf.Physical_Name FROM sys.master_files mf where mf.type_desc = 'ROWS' and db.database_id = mf.database_id ) as DataFile,
(select mf.Physical_Name FROM sys.master_files mf where mf.type_desc = 'LOG' and db.database_id = mf.database_id ) as LogFile
FROM sys.databases db
将返回此输出
DBName DataFile LogFile
--------------------------------------------------------------------------------
master C:\....\master.mdf C:\....\mastlog.ldf
tempdb C:\....\tempdb.mdf C:\....\templog.ldf
model C:\....\model.mdf C:\....\modellog.ldf
和其他数据库
如果您的TempDB有多个MDF文件(像我的一样),这个脚本将失败。 但是,您可以使用
WHERE db.database_id > 4
select name,physical_name from sys.master_files where database_id > 4
CREATE TABLE #tempFileInformation
(
DBNAME NVARCHAR(256),
[FILENAME] NVARCHAR(256),
[TYPE] NVARCHAR(120),
FILEGROUPNAME NVARCHAR(120),
FILE_LOCATION NVARCHAR(500),
FILESIZE_MB DECIMAL(10,2),
USEDSPACE_MB DECIMAL(10,2),
FREESPACE_MB DECIMAL(10,2),
AUTOGROW_STATUS NVARCHAR(100)
)
GO
DECLARE @SQL VARCHAR(2000)
SELECT @SQL = '
USE [?]
INSERT INTO #tempFileInformation
SELECT
DBNAME =DB_NAME(),
[FILENAME] =A.NAME,
[TYPE] = A.TYPE_DESC,
FILEGROUPNAME = fg.name,
FILE_LOCATION =a.PHYSICAL_NAME,
FILESIZE_MB = CONVERT(DECIMAL(10,2),A.SIZE/128.0),
USEDSPACE_MB = CONVERT(DECIMAL(10,2),(A.SIZE/128.0 - ((A.SIZE - CAST(FILEPROPERTY(A.NAME,''SPACEUSED'') AS INT))/128.0))),
FREESPACE_MB = CONVERT(DECIMAL(10,2),(A.SIZE/128.0 - CAST(FILEPROPERTY(A.NAME,''SPACEUSED'') AS INT)/128.0)),
AUTOGROW_STATUS = ''BY '' +CASE is_percent_growth when 0 then cast (growth/128 as varchar(10))+ '' MB - ''
when 1 then cast (growth as varchar(10)) + ''% - '' ELSE '''' END
+ CASE MAX_SIZE WHEN 0 THEN '' DISABLED ''
WHEN -1 THEN '' UNRESTRICTED''
ELSE '' RESTRICTED TO '' + CAST(MAX_SIZE/(128*1024) AS VARCHAR(10)) + '' GB '' END
+ CASE IS_PERCENT_GROWTH WHEn 1 then '' [autogrowth by percent]'' else '''' end
from sys.database_files A
left join sys.filegroups fg on a.data_space_id = fg.data_space_id
order by A.type desc,A.name
;
'
--print @sql
EXEC sp_MSforeachdb @SQL
go
SELECT dbSize.*,fg.*,d.log_reuse_wait_desc,d.recovery_model_desc
FROM #tempFileInformation fg
LEFT JOIN sys.databases d on fg.DBNAME = d.name
CROSS APPLY
(
select dbname,
sum(FILESIZE_MB) as [totalDBSize_MB],
sum(FREESPACE_MB) as [DB_Free_Space_Size_MB],
sum(USEDSPACE_MB) as [DB_Used_Space_Size_MB]
from #tempFileInformation
where dbname = fg.dbname
group by dbname
)dbSize
go
DROP TABLE #tempFileInformation
select db_name(dbid) dbname, filename from sys.sysaltfiles
SELECT
db.name AS DBName,
db.database_id,
mfr.physical_name AS DataFile,
mfl.physical_name AS LogFile
FROM sys.databases db
JOIN sys.master_files mfr ON db.database_id=mfr.database_id AND mfr.type_desc='ROWS'
JOIN sys.master_files mfl ON db.database_id=mfl.database_id AND mfl.type_desc='LOG'
ORDER BY db.database_id
示例结果: (请注意,每个单一的日志文件都与每个MDF和NDF配对,用于单一数据库)
你也可以使用以下 SQL 查询来检索文件列表:
SELECT d.name AS DatabaseName,
m.name AS LogicalName,
m.physical_name AS PhysicalName,
size AS FileSize
FROM sys.master_files m
INNER JOIN sys.databases d ON(m.database_id = d.database_id)
where d.name = '<Database Name>'
ORDER BY physical_name ;
select * from sys.database_files
之前加上一个指向你感兴趣的数据库的use
语句,它就能正常工作。所以,在SQL Server 2019中,use MyDb; select * from sys.database_files
对我来说是有效的。 - undefined