2012-03-09 7 views
61

È possibile elencare le informazioni sui file (MDF/LDF) di tutti i database su un server SQL?Elenco delle informazioni su tutti i file di database in SQL Server

Mi piacerebbe avere una lista che mostra quale database sta usando quali file sul disco locale.

Quello che ho cercato:

  • exec sp_databases tutti i database
  • select * from sys.databases mostra un sacco di informazioni su ogni database - ma purtroppo non mostra i file utilizzati da ogni database.
  • select * from sys.database_files mostra i file MDF/LDF del database master - ma non gli altri database

risposta

78

È possibile utilizzare sys.master_files.

Contiene una riga per file di un database come memorizzata nel database master . Questa è una singola vista a livello di sistema.

+3

Grazie, (unito a sys.databases) è quello che stavo cercando! – M4N

13

Sto usando script per ottenere lo spazio vuoto in ogni file:

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 

Size è espressa in KB.

51

Se si desidera ottenere la posizione del database è possibile controllare Get All DBs Location.
è possibile utilizzare sys.master_files per ottenere la posizione di db e sys.databse per ottenere db nominare

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 
+0

Grazie, quello che stavo cercando. – Davos

3

di esecuzione a seguito di sql (Funzionerà solo quando non si dispone di più/ldf mdf per lo stesso database)

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 

restituirà questo output

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

e resto dei database

Se i tuoi TempDB hanno più MDF (come il mio), questo script fallirà. Tuttavia, è possibile utilizzare

WHERE db.database_id > 4 

alla fine e tornerà tutti i database tranne database di sistema.

+0

Mi rendo conto che è un dataset di piccole dimensioni, ma non è un motivo per utilizzare sottoquery correlate. Potrebbero andare bene su Oracle ma sono degli assassini di prestazioni serie su SQL Server, perché causano l'elaborazione riga per riga. Lo script interrogherà la tabella sys.master_files due volte per ogni riga nella tabella sys.databases. – Davos

+2

Oltre al commento di Davos ... Questo script fallirà anche con errori se si hanno più file di dati o file di log per qualsiasi database. (ad esempio, la sottoquery ha restituito più di 1 valore.) – Arkaine55

+0

@Davos So cosa stai dicendo, ma dipende da quanto frequentemente stai eseguendo questa query, altrimenti è pre-ottimizzazione che probabilmente non ti serve. – adeel41

-2

È possibile utilizzare il sottostante:

SP_HELPDB [Master] 
GO 
+0

Questo fornisce solo informazioni per il singolo database specificato. La domanda è per TUTTI i database. – Thronk

2

Si può anche provare questo.

0

Questo script elenca la maggior parte di ciò che si sta cercando e si spera possa essere modificato in base alle proprie esigenze. Si noti che sta creando una tabella permanente lì - si potrebbe desiderare di cambiarlo. È un sottoinsieme di uno script più grande che riassume anche le informazioni di backup e lavoro su vari server.

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] 
Problemi correlati