SQL सर्वर में सभी डेटाबेस फ़ाइलों के बारे में जानकारी सूचीबद्ध करना


90

SQL सर्वर पर सभी डेटाबेस की फ़ाइलों (MDF / LDF) के बारे में जानकारी सूचीबद्ध करना संभव है?

मैं एक सूची दिखाना चाहूंगा कि कौन सा डेटाबेस स्थानीय डिस्क पर कौन सी फ़ाइलों का उपयोग कर रहा है।

मैंने क्या कोशिश की:

  • exec sp_databases सभी डेटाबेस
  • select * from sys.databases प्रत्येक डेटाबेस के बारे में बहुत सारी जानकारी दिखाता है - लेकिन दुर्भाग्य से यह प्रत्येक डेटाबेस द्वारा उपयोग की गई फ़ाइलों को नहीं दिखाता है।
  • select * from sys.database_filesmasterडेटाबेस की mdf / ldf फ़ाइलें दिखाता है - लेकिन अन्य डेटाबेस नहीं

जवाबों:


123

आप sys.master_files का उपयोग कर सकते हैं ।

मास्टर डेटाबेस में संग्रहीत डेटाबेस की फ़ाइल के अनुसार एक पंक्ति होती है। यह एकल, सिस्टम-व्यापी दृश्य है।


4
धन्यवाद, कि (sys.dat डेटाबेस के साथ शामिल) वह है जो मैं देख रहा था!
M4N

1
चयन करें * sys.master_files से
Cosmin

2
@ M4N यदि आप केवल डेटाबेस नाम प्राप्त करना चाहते हैं, तो आप DB_NAME(database_id)इसके साथ जुड़ने के बजाय कॉल भी कर सकते हैंsys.databases
क्लेप्टस

84

यदि आप डेटाबेस का स्थान प्राप्त करना चाहते हैं, तो आप सभी डीबी स्थान प्राप्त कर सकते हैं ।
आप sys.master_filesdb का स्थान पाने के लिए और sys.databsedb नाम प्राप्त करने के लिए उपयोग कर सकते हैं

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 [?]चाहिए? यह एक त्रुटि देता है कि यह उस संग्रहीत कार्यविधि को नहीं खोज सकता है। इसे हटाने से कई बार सिस्टम डेटाबेस से ही पता चलता है।
हाबिल

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

अंत में और यह सिस्टम डेटाबेस को छोड़कर सभी डेटाबेस को लौटा देगा।


मुझे एहसास हुआ कि यह एक छोटा डेटासेट है, लेकिन यह सहसंबद्ध उपश्रेणियों का उपयोग करने का कोई कारण नहीं है। वे ओरेकल पर ठीक हो सकते हैं लेकिन वे SQL सर्वर पर गंभीर प्रदर्शन हत्यारे हैं, क्योंकि वे पंक्ति-दर-पंक्ति प्रसंस्करण का कारण बनते हैं। आपकी स्क्रिप्ट sys.master_files तालिका को sys.dat डेटाबेस तालिका में प्रत्येक पंक्ति के लिए दो बार क्वेरी करेगी।
दावोस

2
दावोस की टिप्पणी के अलावा ... यह स्क्रिप्ट त्रुटियों के साथ भी विफल हो जाएगी यदि आपके पास किसी भी डेटाबेस के लिए कई डेटाफाइल्स या लॉगफाइल्स हैं। (उदा।
उपकरी

@Davos मुझे पता है कि आप क्या कह रहे हैं, लेकिन यह निर्भर करता है कि आप इस क्वेरी को कितनी बार निष्पादित कर रहे हैं अन्यथा यह पूर्व-अनुकूलन है जिसकी शायद आपको आवश्यकता नहीं है।
adeel41

2
मैं आमतौर पर मानता हूं कि शुरुआती अनुकूलन खराब है, लेकिन मैं जो कह रहा हूं वह यह है कि सहसंबद्ध उपश्रेणी केवल एक बुरा पैटर्न है जिसे कभी भी पहले स्थान पर उपयोग नहीं किया जाना चाहिए। हमेशा 'कभी नहीं' नियमों के अपवाद हैं, लेकिन यह उन मामलों में से एक नहीं है। मुझे पता है कि यह मामूली है और यह वास्तव में यहाँ मायने नहीं रखता, लेकिन यह बात नहीं है। यह एक सार्वजनिक मंच है जिसका उपयोग अच्छे अभ्यास सीखने के लिए newbies करते हैं, इसलिए आपको रोल मॉडल कोड प्रदान करने की आवश्यकता है।
दावोस

1
यदि डेटाबेस में से कई में डेटा फ़ाइलों का उपयोग किया जाता है, तो क्वेरी त्रुटि होगी। इसके बजाय अपनी क्वेरी का एक संस्करण यहां का उपयोग करके जुड़ता है। चीयर्स! चयन करें db.name AS DBName, db.database_id, mfr.Physical_Name AS DataFile, mfl.Physical_Name AS LogFile Fys sys.dat डेटाबेस से db JOIN sys .master_files mfr पर db.database_id = mfr.database_id और mfr। .master_files mb ON db.database_id = mfl.database_id और mfl.type_desc = 'लॉग' ORDER BY db.database_id
रॉबर्ट

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 स्थित ड्राइव पर अधिकतम मुक्त स्थान की संख्या कितनी है?
हाबिल

हाय एबेल - जब से मैंने लिखा है तब से यह एक समय हो गया है और मुझे आपके मुद्दे पर यकीन नहीं है। XP_FIXEDDRIVES के लिए एक विकल्प है जिसे sysinos_os_volume_stats कहा जाता है ताकि आप उसका उपयोग करने का प्रयास कर सकें। यदि समस्या यह है कि डेटाबेस का फ़ाइल आकार समय के साथ नहीं बदल रहा है, तो यह सामान्य है क्योंकि SQL सर्वर इसके उपयोग के लिए खाली डिस्क स्थान का एक बड़ा ब्लॉब आवंटित करता है और तब तक उस फ़ाइल का विस्तार नहीं करता है जब तक कि इसे भरा नहीं गया है। यह उस विशेष डेटाबेस के लिए फाइल सेटिंग्स द्वारा निर्धारित राशि के साथ जंप में एक फाइल का विस्तार करेगा
गेरार्ड

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

निम्न स्क्रिप्ट का उपयोग निम्न जानकारी प्राप्त करने के लिए किया जा सकता है: 1. DB आकार की जानकारी 2. FileSpaceInfo 3. AutoGrowth 4. पुनर्प्राप्ति मॉडल 5. 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

बस मेरे 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 सर्वर अंतर्निहित फ़ाइलों का नाम नहीं बदलता है।

निम्नलिखित क्वेरी आपको डेटाबेस का वर्तमान नाम और लॉजिकल फ़ाइल नाम (जो डेटाबेस का मूल नाम हो सकता है जब इसे बनाया गया था) और इसी भौतिक फ़ाइल नाम भी देता है।

नोट: केवल वास्तविक डेटा फ़ाइलों को देखने के लिए अंतिम पंक्ति पर टिप्पणी न करें

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

यह केवल एकल निर्दिष्ट डेटाबेस के लिए जानकारी प्रदान करता है। प्रश्न सभी डेटाबेस के लिए है।
थ्रोन्क
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.