查询 磁盘 磁盘上的数据和日志文件空间使用信息

需求背景:

有的时候磁盘空间吃紧,需要及时了解该磁盘的使用情况,以及该磁盘上的数据库数据文件和日志文件的使用情况

可以使用以下脚本获取相关信息

 

/*
editor:lynn
function: get disk, datafile and logfile used space info  
查看当前实例实际使用空间情况

*/


USE master
GO
SET NOCOUNT ON
--===================public variables
declare 
    @drive sysname
select 
    @drive    = N'D'              --input  (null: all disks)
;


--begin get disk info ##############################
if OBJECT_ID('tempdb.dbo.#Disk','u') is not null
    drop table #Disk

CREATE TABLE #Disk
( 
  driver char(1) 
 ,freespace nvarchar(255) 
 ,totalspace nvarchar(255) 
 ,freeprecent nvarchar(5) 
)     
DECLARE  @TotalDisk TABLE 
( 
     t nvarchar(100) 
)   

DECLARE 
    @driver nvarchar(5) 
    ,@totalsize nvarchar(50)
;  
INSERT INTO #Disk 
( 
     driver 
    ,freespace 
)        
EXEC master.sys.xp_fixeddrives
          
DECLARE disk_cur CURSOR 
FOR    
SELECT 
   driver 
FROM #Disk
         
OPEN disk_cur    
FETCH NEXT FROM disk_cur INTO @driver 
   
WHILE @@FETCH_STATUS=0     
BEGIN       
    INSERT INTO @TotalDisk         
    EXEC('xp_cmdshell ''wmic LogicalDisk WHERE "Caption='''''+@driver+':''''" GET FreeSpace ,SIZE /VALUE''' )       
    SELECT 
        @totalsize=t 
    FROM @TotalDisk 
    WHERE 
        t LIKE 'Size%'       

    if(@totalsize is not null and LEN(@totalsize)>4)       
    BEGIN        
        SET @totalsize=REPLACE(SUBSTRING(@totalsize,CHARINDEX('=',@totalsize)+1,LEN(@totalsize)-CHARINDEX('=',@totalsize)-1),' ','')        
        SET @totalsize=cast(cast(RTRIM(@totalsize) as bigint)/1024/1024 as nvarchar(50))        

        UPDATE #Disk 
        SET totalspace=@totalsize 
           ,freeprecent=CAST(CAST(freespace AS bigint)*1.0/CAST(@totalsize AS bigint)*100 AS decimal(5,2))   
        WHERE 
            driver=@driver       
    END       

    FETCH NEXT FROM disk_cur INTO @driver     
END    

close disk_cur    
deallocate disk_cur   

SELECT 
    GETDATE() datetime 
   ,driver 
   ,[freespace(GB)] = cast(freespace as decimal(10,2))/1024.
   ,[totalspace(GB)] = cast(totalspace as decimal(10,2))/1024.
   ,[freeprecent(%)]= freeprecent 
FROM #Disk     
WHERE driver = ISNULL(@drive,driver);

if OBJECT_ID('tempdb.dbo.#Disk','u') is not null
drop table #Disk
--end get disk info ##############################


--begin get dbfile info #################

if OBJECT_ID('tempdb.dbo.#dbfileinfo','U') is not null
    drop table #dbfileinfo
CREATE TABLE DBO.#dbfileinfo
(
    dbname    VARCHAR(100),
    files_name    VARCHAR(100),
    drive    CHAR(1),
    type INT,
    AllocateSize_MB DECIMAL(10,2),
    UsedSize_MB    DECIMAL(10,2),
    UnUsedSize_MB    DECIMAL(10,2),
    Used_Percent DECIMAL(10,2),    
    UnUsed_Percent DECIMAL(10,2),
    physical_name varchar(500)
)


declare @sql nvarchar(max),
    @exec_sql nvarchar(max),
    @database_name sysname;

if @drive is not null
    begin
        select @sql=N'
            INSERT INTO #dbfileinfo(dbname, files_name, drive, type, AllocateSize_MB, UsedSize_MB, UnUsedSize_MB, Used_Percent, UnUsed_Percent,physical_name)
            SELECT
                DB_NAME() AS  dbname,
                name AS files_name,
                LEFT(physical_name,1) AS drive,
                type ,
                CAST( size/128.0 AS DECIMAL(10,2) )AS AllocateSize_MB,
                CAST( FILEPROPERTY(name, ''SpaceUsed'')/128.0  AS DECIMAL(10,2) )AS UsedSize_MB,    
                CAST( (size - FILEPROPERTY(name, ''SpaceUsed''))/128.0 AS DECIMAL(10,2) ) AS UnUsedSize_MB,     
                CAST( FILEPROPERTY(name, ''SpaceUsed'')*100.0/size AS DECIMAL(10,2)) AS Used_Percent,
                CAST((size - FILEPROPERTY(name, ''SpaceUsed''))*100.0/size AS DECIMAL(10,2))  UnUsed_Percent,
                physical_name        
                FROM sys.database_files WITH(NOLOCK)
            where left(physical_name,1) = '''+@drive+'''
        '
    end
else 
        select @sql=N'
            INSERT INTO #dbfileinfo(dbname, files_name, drive, type, AllocateSize_MB, UsedSize_MB, UnUsedSize_MB, Used_Percent, UnUsed_Percent,physical_name)
            SELECT
                DB_NAME() AS  dbname,
                name AS files_name,
                LEFT(physical_name,1) AS drive,
                type ,
                CAST( size/128.0 AS DECIMAL(10,2) )AS AllocateSize_MB,
                CAST( FILEPROPERTY(name, ''SpaceUsed'')/128.0  AS DECIMAL(10,2) )AS UsedSize_MB,    
                CAST( (size - FILEPROPERTY(name, ''SpaceUsed''))/128.0 AS DECIMAL(10,2) ) AS UnUsedSize_MB,     
                CAST( FILEPROPERTY(name, ''SpaceUsed'')*100.0/size AS DECIMAL(10,2)) AS Used_Percent,
                CAST((size - FILEPROPERTY(name, ''SpaceUsed''))*100.0/size AS DECIMAL(10,2))  UnUsed_Percent,
                physical_name        
                FROM sys.database_files WITH(NOLOCK)
        '

declare cur_database cursor local static forward_only read_only
for
select name
from sys.databases with(nolock)
WHERE state<>6   --OFFLINE
--==============you can filter the system database or not
--where name not in(
--'master'
--,'tempdb'
--,'model'
--,'msdb'
--,'distribution'
--);
open cur_database
fetch next from cur_database into @database_name
while(@@FETCH_STATUS = 0)
begin
    
    SET 
        @exec_sql = N'USE ' + QUOTENAME(@database_name) + ';'
        + @sql;
    exec sys.sp_executesql @exec_sql

    fetch next from cur_database into @database_name
end;

close cur_database
deallocate cur_database

--select * from #dbfileinfo

SELECT 
    N'包含日志文件'  '描述',
    drive,
    SUM(AllocateSize_MB) as 'AllocateSize_MB数据库文件分配空间', 
    SUM(UsedSize_MB) as 'UsedSize_MB数据库文件使用空间',
    SUM(UnUsedSize_MB)  as 'UnUsedSize_MB数据库文件可用空间'
FROM #dbfileinfo
group by drive

--##start  datafile#############################

;with datassum
as
(
    select 
        drive,dbname,
        SUM(AllocateSize_MB) Data_AllocateSize_MB,
        SUM(UsedSize_MB) Data_UsedSize_MB,
        SUM(UnUsedSize_MB) Data_UnUsedSize_MB 
    from #dbfileinfo
    where physical_name not like '%.ldf'
    group by drive,dbname
    
)
select 'datafile info'=
    'Sum_Data_AllocateSize_MB: '+CAST(SUM(Data_AllocateSize_MB) AS VARCHAR(100)) 
    +'  Sum_Data_UsedSize_MB: '+CAST(SUM(Data_UsedSize_MB) AS VARCHAR(100))
    +'  Sum_Data_UnUsedSize_MB: ' +CAST(SUM(Data_UnUsedSize_MB) AS VARCHAR(100))
from datassum 
;with datas
as
(
    select 
        drive,dbname,
        SUM(AllocateSize_MB) Data_AllocateSize_MB,
        SUM(UsedSize_MB) Data_UsedSize_MB,
        SUM(UnUsedSize_MB) Data_UnUsedSize_MB 
    from #dbfileinfo
    where physical_name not like '%.ldf'
    group by drive,dbname
    
)
select *
from datas order by Data_AllocateSize_MB desc,Data_UnUsedSize_MB desc




--##end  datafile#############################


--##start  logfile#############################
;with logsSum
as(
    select 
        drive,dbname,
        SUM(AllocateSize_MB) logs_AllocateSize_MB,
        SUM(UsedSize_MB) logs_UsedSize_MB,
        SUM(UnUsedSize_MB) logs_UnUsedSize_MB 
    from #dbfileinfo
    where physical_name  like '%.ldf'
    group by drive,dbname
    
)select  'logfile info'=
    'Sum_logs_AllocateSize_MB: '+CAST(SUM(logs_AllocateSize_MB) AS VARCHAR(100)) 
    +'  Sum_logs_UsedSize_MB: '+ CAST(SUM(logs_UsedSize_MB) AS VARCHAR(100))
    +'  Sum_logs_UnUsedSize_MB: '+CAST(SUM(logs_UnUsedSize_MB)  AS VARCHAR(100))
from logsSum 

;with logs
as(
    select 
        drive,dbname,
        SUM(AllocateSize_MB) logs_AllocateSize_MB,
        SUM(UsedSize_MB) logs_UsedSize_MB,
        SUM(UnUsedSize_MB) logs_UnUsedSize_MB 
    from #dbfileinfo
    where physical_name  like '%.ldf'
    group by drive,dbname
    
)select * --,SUM(logs_AllocateSize_MB),SUM(logs_UsedSize_MB),SUM(logs_UnUsedSize_MB)
from logs order by logs_UnUsedSize_MB desc
--##end  logfile#############################    

--end begin get dbfile info #################
if OBJECT_ID('tempdb.dbo.#dbfileinfo','U') is not null
    drop table #dbfileinfo
View Code

 

结果如下图:

 

 

posted @ 2016-08-17 17:55  simplelg17  阅读(536)  评论(0编辑  收藏  举报