รายการข้อมูลเกี่ยวกับไฟล์ฐานข้อมูลทั้งหมดใน SQL Server


92

เป็นไปได้ไหมที่จะแสดงรายการข้อมูลเกี่ยวกับไฟล์ (MDF / LDF) ของฐานข้อมูลทั้งหมดบน SQL Server

ฉันต้องการรับรายการที่แสดงว่าฐานข้อมูลใดใช้ไฟล์ใดในดิสก์ภายในเครื่อง

สิ่งที่ฉันพยายาม:

  • exec sp_databases ฐานข้อมูลทั้งหมด
  • select * from sys.databases แสดงข้อมูลจำนวนมากเกี่ยวกับแต่ละฐานข้อมูล - แต่น่าเสียดายที่ไม่แสดงไฟล์ที่ใช้โดยแต่ละฐานข้อมูล
  • select * from sys.database_filesแสดงไฟล์ mdf / ldf ของmasterฐานข้อมูล - แต่ไม่ใช่ฐานข้อมูลอื่น

คำตอบ:


124

คุณสามารถใช้sys.master_files

มีแถวต่อไฟล์ของฐานข้อมูลที่เก็บไว้ในฐานข้อมูลหลัก นี่เป็นมุมมองเดียวทั้งระบบ


4
ขอบคุณที่ (เข้าร่วมกับ sys.databases) คือสิ่งที่ฉันกำลังมองหา!
M4N

1
เลือก * จาก sys.master_files
Cosmin

2
@ M4N หากคุณต้องการรับชื่อฐานข้อมูลคุณสามารถเรียกDB_NAME(database_id)แทนการเข้าร่วมด้วยsys.databases
Cleptus

84

ถ้าคุณต้องการที่จะได้รับตำแหน่งของฐานข้อมูลคุณสามารถตรวจสอบได้รับทั้งหมดที่ตั้งดีบีเอส
คุณสามารถใช้sys.master_filesเพื่อรับตำแหน่งของฐานข้อมูลและsys.databseเพื่อรับชื่อฐานข้อมูล

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

ฉันใช้สคริปต์เพื่อเพิ่มพื้นที่ว่างในแต่ละไฟล์:

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


สิ่งที่Use [?]ควรทำ? ทำให้เกิดข้อผิดพลาดที่ไม่พบกระบวนงานที่จัดเก็บนั้น การลบออกจะแสดงฐานข้อมูลระบบหลายครั้งเท่านั้น
Abel

4

ฉันได้สร้างแบบสอบถามนี้:

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

กำลังดำเนินการต่อไปนี้ 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

ในตอนท้ายและจะส่งคืนฐานข้อมูลทั้งหมดยกเว้นฐานข้อมูลระบบ


ฉันรู้ว่ามันเป็นชุดข้อมูลขนาดเล็ก แต่ก็ไม่มีเหตุผลที่จะใช้เคียวรีย่อยที่สัมพันธ์กัน อาจใช้ได้ดีใน Oracle แต่เป็นตัวทำลายประสิทธิภาพที่ร้ายแรงบน SQL Server เนื่องจากทำให้เกิดการประมวลผลทีละแถว สคริปต์ของคุณจะสืบค้นตาราง sys.master_files สองครั้งสำหรับทุกแถวในตาราง sys.databases
ดาวอส

2
นอกเหนือจากความคิดเห็นของ Davos ... สคริปต์นี้จะล้มเหลวด้วยข้อผิดพลาดหากคุณมีไฟล์ข้อมูลหรือไฟล์บันทึกหลายรายการสำหรับฐานข้อมูลใด ๆ (เช่น Subquery ส่งคืนมากกว่า 1 ค่า)
Arkaine55

@Davos ฉันรู้ว่าคุณกำลังพูดอะไร แต่ขึ้นอยู่กับความถี่ที่คุณเรียกใช้แบบสอบถามนี้มิฉะนั้นจะเป็นการเพิ่มประสิทธิภาพล่วงหน้าซึ่งคุณอาจไม่ต้องการ
adeel41

2
โดยทั่วไปฉันยอมรับว่าการเพิ่มประสิทธิภาพในช่วงต้นนั้นไม่ดี แต่สิ่งที่ฉันกำลังพูดก็คือการสืบค้นย่อยที่สัมพันธ์กันเป็นเพียงรูปแบบที่ไม่ดีที่ไม่ควรนำมาใช้ตั้งแต่แรก มีข้อยกเว้นเสมอสำหรับกฎ 'ไม่เคย' แต่นี่ไม่ใช่หนึ่งในกรณีเหล่านั้น ฉันรู้ว่ามันเป็นเรื่องเล็กน้อยและมันอาจไม่สำคัญที่นี่ แต่นั่นไม่ใช่ประเด็น นี่คือฟอรัมสาธารณะที่มือใหม่ใช้เพื่อเรียนรู้แนวปฏิบัติที่ดีดังนั้นคุณต้องระบุรหัสแบบอย่าง
Davos

1
แบบสอบถามจะผิดพลาดหากมีการใช้ไฟล์ข้อมูลหลายไฟล์ในฐานข้อมูลใดฐานข้อมูลหนึ่ง นี่คือเวอร์ชันของข้อความค้นหาของคุณโดยใช้การรวมแทน ไชโย! เลือก db.name เป็น DBName, db.database_id, mfr.Physical_Name AS DataFile, mfl.Physical_Name เป็น LogFile จาก sys.databases db JOIN sys.master_files mfr บน db.database_id = mfr.database_id และ mfr.type_desc = 'ROWS' JOIN .master_files mfl บน db.database_id = mfl.database_id AND mfl.type_desc = 'LOG' ORDER BY db.database_id
Robert

2

การใช้สคริปต์นี้คุณสามารถแสดงชื่อฐานข้อมูลและไฟล์ทั้งหมดที่ใช้ (ยกเว้น dbs ระบบ)

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

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

สวัสดีอาเบล - ฉันเขียนมาได้สักพักแล้วและฉันไม่แน่ใจในปัญหาของคุณ มีทางเลือกอื่นสำหรับ XP_FIXEDDRIVES ที่เรียกว่า sys.dm_os_volume_stats เพื่อให้คุณสามารถลองใช้สิ่งนั้นได้ หากปัญหาคือขนาดไฟล์ของฐานข้อมูลไม่เปลี่ยนแปลงตลอดเวลานั่นเป็นเรื่องปกติเนื่องจาก SQL Server จัดสรรพื้นที่ว่างในดิสก์จำนวนมหาศาลสำหรับการใช้งานจากนั้นจะไม่ขยายไฟล์นั้นจนกว่าจะเต็ม มันจะขยายไฟล์แบบกระโดดตามจำนวนที่กำหนดโดยการตั้งค่าไฟล์สำหรับฐานข้อมูลนั้น
เจอราร์ด

1

สามารถใช้สคริปต์ด้านล่างเพื่อรับข้อมูลต่อไปนี้: 1. DB Size Info 2. FileSpaceInfo 3. AutoGrowth 4. Recovery Model 5. Log_reuse_backup information

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

แบบสอบถามจะผิดพลาดหากมีการใช้ไฟล์ข้อมูลหลายไฟล์ (เช่นไฟล์ประเภท ".ndf") ในฐานข้อมูลใดฐานข้อมูลหนึ่ง

นี่คือเวอร์ชันของข้อความค้นหาของคุณโดยใช้การรวมแทนการสืบค้นย่อย

ไชโย!

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

แค่เพิ่ม 2 เซ็นต์ของฉัน

หากต้องการค้นหาพื้นที่ว่างทั้งหมดเฉพาะในไฟล์ข้อมูลหรือเฉพาะในไฟล์บันทึกในฐานข้อมูลทั้งหมดเราสามารถใช้คอลัมน์ "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 


0

หากคุณเปลี่ยนชื่อฐานข้อมูล 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://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

คุณสามารถใช้ด้านล่าง:

SP_HELPDB [Master]
GO

สิ่งนี้ให้ข้อมูลสำหรับฐานข้อมูลเดียวที่ระบุ คำถามคือสำหรับฐานข้อมูลทั้งหมด
Thronk
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.