Liệt kê thông tin về tất cả các tệp cơ sở dữ liệu trong SQL Server


90

Có thể liệt kê thông tin về tệp (MDF / LDF) của tất cả cơ sở dữ liệu trên SQL Server không?

Tôi muốn nhận một danh sách hiển thị cơ sở dữ liệu nào đang sử dụng những tệp nào trên đĩa cục bộ.

Những gì tôi đã thử:

  • exec sp_databases tất cả cơ sở dữ liệu
  • select * from sys.databases hiển thị nhiều thông tin về mỗi cơ sở dữ liệu - nhưng tiếc là nó không hiển thị các tệp được sử dụng bởi mỗi cơ sở dữ liệu.
  • select * from sys.database_fileshiển thị các tệp mdf / ldf của mastercơ sở dữ liệu - nhưng không hiển thị các cơ sở dữ liệu khác

Câu trả lời:


123

Bạn có thể sử dụng sys.master_files .

Chứa một hàng trên mỗi tệp của cơ sở dữ liệu như được lưu trữ trong cơ sở dữ liệu chính. Đây là một chế độ xem duy nhất, toàn hệ thống.


4
Cảm ơn, đó (kết hợp với sys.databases) là những gì tôi đang tìm kiếm!
M4N

1
select * từ sys.master_files
Cosmin

2
@ M4N Nếu bạn chỉ muốn lấy tên cơ sở dữ liệu, bạn cũng có thể gọi DB_NAME(database_id)bằng cách kết hợp vớisys.databases
Cleptus

84

Nếu bạn muốn lấy vị trí của Cơ sở dữ liệu, bạn có thể chọn Lấy tất cả Vị trí của Cơ sở dữ liệu .
bạn có thể sử dụng sys.master_filesđể lấy vị trí của db và sys.databselấy tên db

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

18

Tôi đang sử dụng tập lệnh để lấy không gian trống trong mỗi tệp:

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

Kích thước được biểu thị bằng KB.


Phải Use [?]làm gì? Nó đưa ra một lỗi rằng nó không thể tìm thấy thủ tục được lưu trữ đó. Loại bỏ nó chỉ hiển thị nhiều lần cơ sở dữ liệu hệ thống.
Abel

4

Tôi đã tạo truy vấn này:

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

3

Bạn cũng có thể thử điều này.

 select db_name(dbid) dbname, filename from sys.sysaltfiles

3

Thực thi sau sql (Nó sẽ chỉ hoạt động khi bạn không có nhiều tệp mdf / ldf cho cùng một cơ sở dữ liệu)

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

sẽ trả lại đầu ra này

DBName       DataFile                     LogFile
--------------------------------------------------------------------------------
master       C:\....\master.mdf           C:\....\mastlog.ldf
tempdb       C:\....\tempdb.mdf           C:\....\templog.ldf
model        C:\....\model.mdf            C:\....\modellog.ldf

và phần còn lại của cơ sở dữ liệu

Nếu TempDB của bạn có nhiều MDF (như của tôi có), tập lệnh này sẽ không thành công. Tuy nhiên, bạn có thể sử dụng

WHERE db.database_id > 4

ở cuối và nó sẽ trả về tất cả cơ sở dữ liệu ngoại trừ cơ sở dữ liệu hệ thống.


Tôi nhận ra đó là một tập dữ liệu nhỏ, nhưng đó không phải là lý do để sử dụng các truy vấn con tương quan. Chúng có thể ổn trên Oracle nhưng chúng là những kẻ giết hiệu suất nghiêm trọng trên SQL Server, vì chúng gây ra quá trình xử lý từng hàng. Tập lệnh của bạn sẽ truy vấn bảng sys.master_files hai lần cho mỗi hàng trong bảng sys.databases.
Davos

2
Ngoài nhận xét của Davos ... Tập lệnh này cũng sẽ bị lỗi nếu bạn có nhiều tệp dữ liệu hoặc tệp nhật ký cho bất kỳ cơ sở dữ liệu nào. (ví dụ: Truy vấn con trả về nhiều hơn 1 giá trị.)
Arkaine55

@Davos Tôi biết bạn đang nói gì nhưng nó phụ thuộc vào tần suất bạn thực hiện truy vấn này, nếu không thì đó là tiền tối ưu hóa mà có thể bạn không cần.
adeel41

2
Tôi thường đồng ý rằng tối ưu hóa sớm là không tốt, nhưng những gì tôi đang nói là các truy vấn con tương quan chỉ là một mô hình xấu không bao giờ được sử dụng ngay từ đầu. Luôn có ngoại lệ cho các quy tắc 'không bao giờ', nhưng đây không phải là một trong những trường hợp đó. Tôi biết đó là điều nhỏ và nó thực sự có thể không quan trọng ở đây, nhưng đó không phải là vấn đề. Đây là một diễn đàn công khai mà người mới sử dụng để học cách thực hành tốt, vì vậy bạn cần cung cấp mã mô hình vai trò.
Davos,

1
Truy vấn sẽ lỗi nếu nhiều tệp dữ liệu được sử dụng trong một trong các cơ sở dữ liệu. Đây là phiên bản truy vấn của bạn sử dụng các phép nối thay thế. Chúc mừng! CHỌN 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 BẬT db.database_id = mfl.database_id VÀ mfl.type_desc = 'ĐĂNG NHẬP' ĐẶT HÀNG BẰNG db.database_id
Robert

2

Sử dụng tập lệnh này, bạn có thể hiển thị tất cả tên cơ sở dữ liệu và các tệp được sử dụng (ngoại trừ dbs hệ thống).

select name,physical_name from sys.master_files where database_id > 4

1

Tập lệnh này liệt kê hầu hết những gì bạn đang tìm kiếm và hy vọng có thể được sửa đổi theo nhu cầu của bạn. Lưu ý rằng nó đang tạo một bảng vĩnh viễn trong đó - bạn có thể muốn thay đổi nó. Nó là một tập hợp con từ một tập lệnh lớn hơn cũng tóm tắt thông tin sao lưu và công việc trên các máy chủ khác nhau.

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] 

Một tập lệnh tuyệt vời có thể được sao chép / dán và sử dụng nguyên trạng. Tuy nhiên, một câu hỏi đặt ra, tôi thấy rằng LogVolumeFreeSpaceMBnó luôn hiển thị cùng một số lượng cho tất cả các tệp, trong trường hợp của tôi là 44756. Có thể nhận được dung lượng trống thực tế không? Hay đó là số lượng không gian trống tối đa trên ổ đĩa có LDF?
Abel

Xin chào Abel - Đã một thời gian kể từ khi tôi viết và tôi không thực sự chắc chắn về vấn đề của bạn. Có một giải pháp thay thế cho XP_FIXEDDRIVES được gọi là sys.dm_os_volume_stats để bạn có thể thử sử dụng. Nếu vấn đề là kích thước tệp của cơ sở dữ liệu không thay đổi theo thời gian thì điều đó là bình thường vì SQL Server phân bổ một lượng lớn không gian đĩa trống để sử dụng và sau đó không mở rộng tệp đó cho đến khi nó được lấp đầy. Nó sẽ mở rộng một tệp theo bước nhảy với số lượng được xác định bởi cài đặt tệp cho cơ sở dữ liệu cụ thể đó
Gerard

0

Truy vấn sẽ lỗi nếu nhiều tệp dữ liệu (ví dụ: loại tệp ".ndf") được sử dụng trong một trong các cơ sở dữ liệu.

Đây là phiên bản truy vấn của bạn sử dụng các phép nối thay vì các truy vấn phụ.

Chúc mừng!

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

0

Tập lệnh dưới đây có thể được sử dụng để lấy thông tin sau: 1. Thông tin kích thước DB 2. FileSpaceInfo 3. AutoGrowth 4. Mô hình khôi phục 5. Thông tin log_reuse_backup

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

0

chỉ thêm 2 xu của tôi.

nếu đặc biệt muốn tìm tổng dung lượng trống chỉ trong Tệp dữ liệu hoặc chỉ trong tệp Nhật ký trong tất cả cơ sở dữ liệu, chúng tôi có thể sử dụng cột "data_space_id". 1 dành cho tệp dữ liệu và 0 dành cho tệp nhật ký.

MÃ:

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 


0

Nếu bạn đổi tên Cơ sở dữ liệu của mình, MS SQL Server sẽ không đổi tên các tệp bên dưới.

Truy vấn sau cung cấp cho bạn tên hiện tại của cơ sở dữ liệu và tên tệp logic (có thể là tên ban đầu của Cơ sở dữ liệu khi nó được tạo) và cả tên tệp vật lý tương ứng.

Lưu ý: Bỏ nhận xét dòng cuối cùng để chỉ xem các tệp dữ liệu thực tế

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'

Tài liệu tham khảo:

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

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


-3

Bạn có thể sử dụng bên dưới:

SP_HELPDB [Master]
GO

Điều này chỉ cung cấp thông tin cho cơ sở dữ liệu được chỉ định duy nhất. Câu hỏi dành cho TẤT CẢ các cơ sở dữ liệu.
Thronk
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.