SQL Server'daki tüm veritabanı dosyaları hakkındaki bilgileri listeleme


92

Bir SQL Sunucusundaki tüm veritabanlarının dosyaları (MDF / LDF) hakkındaki bilgileri listelemek mümkün müdür?

Hangi veritabanının yerel diskte hangi dosyaları kullandığını gösteren bir liste almak istiyorum.

Ne denedim:

  • exec sp_databases tüm veritabanları
  • select * from sys.databases her veritabanı hakkında pek çok bilgi gösterir - ancak ne yazık ki her veritabanı tarafından kullanılan dosyaları göstermez.
  • select * from sys.database_filesmasterveritabanının mdf / ldf dosyalarını gösterir - ancak diğer veritabanlarını göstermez

Yanıtlar:


124

Sys.master_files'ı kullanabilirsiniz .

Ana veritabanında depolandığı gibi, bir veritabanının dosyası başına bir satır içerir. Bu, sistem genelinde tek bir görünümdür.


4
Teşekkürler, aradığım şey (sys.databases ile birleştirildi)!
M4N 09

1
sys.master_files'dan * seçin
Cosmin

2
@ M4N Eğer sadece veritabanı adını almak istiyorsanız, DB_NAME(database_id)katılmak yerine arayabilirsinsys.databases
Cleptus

84

Veritabanının konumunu almak istiyorsanız Tüm Veritabanlarını Al Konumunu kontrol edebilirsiniz . db'nin yerini ve db adını almak için
kullanabilirsinizsys.master_filessys.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

Her dosyada boş alan elde etmek için komut dosyası kullanıyorum:

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

Boyut KB cinsinden ifade edilir.


Ne Use [?]yapmalı? Bu saklı yordamı bulamadığına dair bir hata verir. Kaldırıldığında, sistem veritabanları yalnızca birkaç kez gösterilir.
Abel

4

Bu sorguyu oluşturdum:

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

Bunu da deneyebilirsiniz.

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

3

Aşağıdaki sql'yi yürütme (Yalnızca aynı veritabanı için birden fazla mdf / ldf dosyanız olmadığında çalışır)

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

bu çıktıyı döndürecek

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

ve veri tabanlarının geri kalanı

TempDB'lerinizde birden fazla MDF varsa (benimki gibi), bu komut dosyası başarısız olacaktır. Ancak kullanabilirsiniz

WHERE db.database_id > 4

sonunda ve sistem veritabanları dışındaki tüm veritabanlarını döndürür.


Bunun küçük bir veri kümesi olduğunun farkındayım, ancak bu ilişkili alt sorgular kullanmak için bir neden değil. Oracle'da iyi olabilirler ancak SQL Server'da ciddi performans katilleridir, çünkü satır satır işlemeye neden olurlar. Komut dosyanız, sys.databases tablosundaki her satır için sys.master_files tablosunu iki kez sorgulayacaktır.
Davos

2
Davos'un yorumuna ek olarak ... Herhangi bir veritabanı için birden fazla veri dosyası veya günlük dosyanız varsa, bu komut dosyası da hatalarla başarısız olacaktır. (örneğin,
Alt sorgu 1'den

@Davos Ne dediğini biliyorum ama bu sorguyu ne sıklıkta çalıştırdığına bağlı, yoksa muhtemelen ihtiyacın olmayan ön optimizasyondur.
adeel41

2
Genel olarak erken optimizasyonun kötü olduğu konusunda hemfikirim, ancak söylüyorum, ilişkili alt sorgular sadece ilk etapta asla kullanılmaması gereken kötü bir kalıptır. Her zaman 'asla' kurallarının istisnaları vardır, ancak bu bu durumlardan biri değildir. Bunun önemsiz olduğunu biliyorum ve burada gerçekten önemli olmayabilir, ama konu bu değil. Bu, yeni başlayanların iyi uygulamaları öğrenmek için kullandıkları halka açık bir forumdur, bu nedenle rol model kodu sağlamanız gerekir.
Davos

1
Veritabanlarından birinde birden çok veri dosyası kullanılırsa sorgu hata verecektir. İşte bunun yerine birleştirme kullanan sorgunuzun bir versiyonu. Şerefe! Db.name olarak DBName, db.database_id, mfr.Physical_Name AS DataFile, mfl. .master_files mfl ÜZERİNE db.database_id = mfl.database_id VE mfl.type_desc = 'GÜNLÜK' db.database_id TARAFINDAN SİPARİŞ EDİN
Robert

2

Bu komut dosyasını kullanarak, kullanılan tüm veritabanlarının adını ve dosyalarını gösterebilirsiniz (sistem veritabanları hariç).

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

1

Bu komut dosyası aradıklarınızın çoğunu listeler ve umarız ihtiyaçlarınıza göre değiştirilebilir. Orada kalıcı bir tablo oluşturduğunu unutmayın - onu değiştirmek isteyebilirsiniz. Çeşitli sunuculardaki yedekleme ve iş bilgilerini de özetleyen daha büyük bir komut dosyasının bir alt kümesidir.

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] 

Kopyalanabilen / yapıştırılabilen ve olduğu gibi kullanılabilen mükemmel bir komut dosyası. Yine de bir soru, LogVolumeFreeSpaceMBbenim durumumda 44756, tüm dosyalar için her zaman aynı miktarı gösterdiğini görüyorum . Gerçek boş alanı elde etmek mümkün mü? Veya LDF'nin bulunduğu sürücüdeki maksimum boş alan sayısı mı?
Abel

Merhaba Abel - Yazmayalı epey oldu ve sorununuzdan pek emin değilim. XP_FIXEDDRIVES'e sys.dm_os_volume_stats adında bir alternatifi var, böylece onu kullanmayı deneyebilirsiniz. Sorun, veritabanının dosya boyutlarının zamanla değişmemesi ise, bu normaldir çünkü SQL Server, kullanımı için büyük bir boş disk alanı ayırır ve sonra bu dosyayı doldurulana kadar genişletmez. Bir dosyayı, belirli bir veritabanı için dosya ayarları tarafından belirlenen miktarda atlayarak genişletecektir
Gerard

1

Aşağıdaki komut dosyası aşağıdaki bilgileri almak için kullanılabilir: 1. DB Boyut Bilgisi 2. FileSpaceInfo 3. AutoGrowth 4. Kurtarma Modeli 5. Log_reuse_backup bilgisi

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

Veritabanlarından birinde birden çok veri dosyası (örn. ".Ndf" dosya türü) kullanılırsa sorgu hata verecektir.

Aşağıda, alt sorgular yerine birleştirmeler kullanan sorgunuzun bir sürümü bulunmaktadır.

Şerefe!

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

sadece 2 sentimi ekledim.

yalnızca Veri dosyalarında veya yalnızca tüm veritabanlarında yalnızca Günlük dosyalarında toplam boş alan bulmak istiyorsanız, "data_space_id" sütununu kullanabiliriz. 1 veri dosyaları için ve 0 günlük dosyaları içindir.

KOD:

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

Veritabanınızı yeniden adlandırırsanız, MS SQL Server temeldeki dosyaları yeniden adlandırmaz.

Aşağıdaki sorgu size veritabanının mevcut adını ve Mantıksal dosya adını (bu, oluşturulduğunda Veritabanının orijinal adı olabilir) ve ayrıca ilgili fiziksel dosya adlarını verir.

Not: Yalnızca gerçek veri dosyalarını görmek için son satırın açıklamasını kaldırın

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'

Referans:

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

Aşağıdakileri kullanabilirsiniz:

SP_HELPDB [Master]
GO

Bu yalnızca belirtilen tek veritabanı için bilgi sağlar. Soru TÜM veritabanları içindir.
Thronk
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.