AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 29543
Accepted
MacGyver
MacGyver
Asked: 2012-11-30 11:07:42 +0800 CST2012-11-30 11:07:42 +0800 CST 2012-11-30 11:07:42 +0800 CST

Consulta para relatar alocação de espaço em disco e espaço usado

  • 772

Estamos usando 6 bancos de dados no total para um aplicativo e só podemos compartilhar 4 TB de espaço entre todos os 6 bancos de dados de crescimento automático (via armazenamento SAN).

Gostaria de escrever uma consulta (relatório) para um único banco de dados indicando os atributos "Espaço alocado atualmente" e "Espaço livre disponível" na opção Tarefas > Reduzir > Banco de dados no SQL Server Management Studio.

Em seguida, gostaria de converter esses números em TB e totalizar cada banco de dados para obter uma estimativa aproximada de quanto espaço resta. Esses campos podem ser acessados ​​por meio de uma consulta T-SQL? Se sim, como seria a consulta?

Diálogo de Reduzir Banco de Dados

sql-server sql-server-2008
  • 6 6 respostas
  • 139920 Views

6 respostas

  • Voted
  1. Best Answer
    Aaron Bertrand
    2012-11-30T11:22:46+08:002012-11-30T11:22:46+08:00

    Aqui está a consulta que o Management Studio usa para preencher esses números:

    SELECT
    (SELECT SUM(CAST(df.size as float)) FROM sys.database_files AS df 
       WHERE df.type in ( 0, 2, 4 ) ) AS [DbSize],
    SUM(a.total_pages) AS [SpaceUsed],
    (SELECT SUM(CAST(df.size as float)) FROM sys.database_files AS df 
       WHERE df.type in (1, 3)) AS [LogSize]
    FROM
    sys.partitions p join sys.allocation_units a 
      on p.partition_id = a.container_id 
    left join sys.internal_tables it 
      on p.object_id = it.object_id
    

    Você precisa realizar matemática aqui, assim como o Management Studio faz para obter os mesmos números. Além disso, a junção à esquerda sys.internal_tablesparece supérflua na melhor das hipóteses. Então, ajustando essa consulta para corresponder à sua saída ideal:

    SELECT
    (SELECT CONVERT(DECIMAL(18,2), SUM(CAST(df.size as float))*8/1024.0)
       FROM sys.database_files AS df 
       WHERE df.type in ( 0, 2, 4 ) ) AS [DbSize],
    CONVERT(DECIMAL(18,2), SUM(a.total_pages)*8/1024.0) AS [SpaceUsed],
    (SELECT CONVERT(DECIMAL(18,2), SUM(CAST(df.size as float))*8/1024.0)
       FROM sys.database_files AS df 
       WHERE df.type in (1, 3)) AS [LogSize]
    FROM sys.partitions p join sys.allocation_units a 
      on p.partition_id = a.container_id;
    

    Com esta atualização, supondo que seu banco de dados não mude nesse meio tempo, ele deve render:

    753475.94    744030.07    2900.00
    

    Fazendo algumas contas simples e isolando apenas os três números que você deseja:

    ;WITH t(s) AS
    (
      SELECT CONVERT(DECIMAL(18,2), SUM(size)*8/1024.0)
       FROM sys.database_files
       WHERE [type] % 2 = 0
    ), 
    d(s) AS
    (
      SELECT CONVERT(DECIMAL(18,2), SUM(total_pages)*8/1024.0)
       FROM sys.partitions AS p
       INNER JOIN sys.allocation_units AS a 
       ON p.[partition_id] = a.container_id
    )
    SELECT 
      Allocated_Space = t.s, 
      Available_Space = t.s - d.s,
      [Available_%] = CONVERT(DECIMAL(5,2), (t.s - d.s)*100.0/t.s)
    FROM t CROSS APPLY d;
    
    • 43
  2. Mike Fal
    2012-11-30T12:56:00+08:002012-11-30T12:56:00+08:00

    A consulta de Aaron é boa, mas como alternativa, uso esta consulta das consultas DMV
    de Glenn Berry (você precisaria alterar a matemática para TBs):

    -- Individual File Sizes and space available for current database
    -- (Query 36) (File Sizes and Space)
    SELECT f.name AS [File Name] , f.physical_name AS [Physical Name], 
    CAST((f.size/128.0) AS DECIMAL(15,2)) AS [Total Size in MB],
    CAST(f.size/128.0 - CAST(FILEPROPERTY(f.name, 'SpaceUsed') AS int)/128.0 AS DECIMAL(15,2)) 
    AS [Available Space In MB], [file_id], fg.name AS [Filegroup Name]
    FROM sys.database_files AS f WITH (NOLOCK) 
    LEFT OUTER JOIN sys.data_spaces AS fg WITH (NOLOCK) 
    ON f.data_space_id = fg.data_space_id OPTION (RECOMPILE);
    
    • 25
  3. Bruce
    2012-11-30T11:31:07+08:002012-11-30T11:31:07+08:00

    Aqui está algum SQL que pode funcionar para você.

    
    Create Table #dbInfo (dId smallint, dbName sysname, gId smallint NULL, segName varchar(256) NULL, 
           filName varchar(520) NULL, sizeMg decimal(10,2) null, 
           usedMg decimal(10,2) null, freeMg decimal(10,2) null, 
           pcntUsed decimal(10,2) null, pcntFree decimal(10,2) null)
    Declare @sSql varchar(1000)
    Set @sSql = 'Use [?];
    Insert #dbInfo (dId, dbName, gid, segName, filName, sizeMg, usedMg)
    Select db_id(), db_name(), groupid, rtrim(name), filename, Cast(size/128.0 As Decimal(10,2)), 
    Cast(Fileproperty(name, ''SpaceUsed'')/128.0 As Decimal(10,2))
    From dbo.sysfiles Order By groupId Desc;'
    Exec sp_MSforeachdb @sSql
    Update #dbInfo Set
    freeMg = sizeMg - usedMg,
    pcntUsed = (usedMg/sizeMg)*100,
    pcntFree = ((sizeMg-usedMg)/sizeMg)*100
    
    select * from #dbInfo compute sum(sizeMG),  sum(FreeMg) 
    drop table #dbInfo
    

    É SQL antigo, mas ainda funciona. Um dia desses vou reescrevê-lo para usar o sys.database_files como a resposta de Aaron.

    • 9
  4. John
    2016-06-28T08:19:40+08:002016-06-28T08:19:40+08:00

    Depois de trabalhar em uma pergunta semelhante ( Querying True Physical Database File Sizes ), acho que uma consulta que exibe os diferentes tamanhos de arquivo, separados, por exemplo, por log e banco de dados, e o tamanho do arquivo no disco seria mais útil para a maioria dos usuários.

    Isso inclui o tamanho do arquivo do sistema e quanto espaço está ocupando no disco, bem como o tamanho do arquivo SQL, o espaço SQL usado e, por extensão, o espaço livre do SQL. Inclui o caminho completo do arquivo que está sendo avaliado. Um usuário precisaria alterar o cálculo para 'Size_On_Disk_Bytes' se o disco for formatado usando um tamanho de alocação diferente do padrão (4096 bytes).

    SELECT fg.data_space_id AS FGID,
       (f.file_id) AS File_Id,
       -- As provided by OP, size on disk in bytes.
       REPLACE(CONVERT(VARCHAR,CONVERT(MONEY, CAST(f.size AS FLOAT) * 8.00 * 1024), 1), '.00','') AS Size_On_Disk_Bytes,
       ROUND((CAST(f.size AS FLOAT) * 8.00/1024)/1024,3) AS Actual_File_Size,
       ROUND(CAST((f.size) AS FLOAT)/128,2) AS Reserved_MB,
       ROUND(CAST((FILEPROPERTY(f.name,'SpaceUsed')) AS FLOAT)/128,2) AS Used_MB,
       ROUND((CAST((f.size) AS FLOAT)/128)-(CAST((FILEPROPERTY(f.name,'SpaceUsed'))AS FLOAT)/128),2) AS Free_MB,
       f.name,
       f.physical_name
    FROM sys.database_files f 
        LEFT JOIN sys.filegroups fg
        ON f.data_space_id = fg.data_space_id
    

    Além disso, essa consulta retornará informações sobre o espaço na unidade de volume que hospeda os arquivos. O usuário precisará ter acesso a sys.master_files.

    SELECT DISTINCT dovs.logical_volume_name AS LogicalName,
    dovs.volume_mount_point AS Drive,
    CONVERT(INT,dovs.available_bytes/1048576.0) AS FreeSpaceInMB
    FROM sys.master_files mf
    CROSS APPLY sys.dm_os_volume_stats(mf.database_id, mf.FILE_ID) dovs
    ORDER BY FreeSpaceInMB ASC
    
    • 8
  5. Alen
    2018-06-30T08:32:29+08:002018-06-30T08:32:29+08:00

    Algo que eu montei. Você PRECISA DO POWERSHELL em seu SQL Server para executar isso. Não tenho certeza da versão. Isso levará os tamanhos das unidades e relatará os tamanhos dos arquivos e o espaço livre, bem como o espaço livre em disco.

    Não é 100% original e partes dele eu encontrei em outros lugares na internet e coloquei tudo junto. Foi um PITA para encaixar nas margens certas, então você pode ter que brincar com os parênteses

    --drop table ##DB_FILE_INFO
     --alter procedure super_drive_info3 
    
     --as
    
      if exists ( select * from tempdb.dbo.sysobjects o
        where o.xtype in ('U') and o.name in ('##DB_FILE_INFO' ))
    drop table ##DB_FILE_INFO
    
    if exists ( select * from tempdb.dbo.sysobjects o
        where o.xtype in ('U') and o.name in ('##output'))
    drop table ##output
    
     create table ##DB_FILE_INFO (
    [server_Name] varchar(255) not null,
    [database_name] varchar(255) not null,
    [File_ID]           int     not null,
    [File_Type]     int     not null ,
    [Drive]     varchar(255)    not null ,
    [Logical_Name]      varchar(255)    not null ,
    [Physical_Name]     varchar(255)    not null ,
    [FILE_SIZE_MB]      int     not null ,
    [SPace_USED_MB] int     not null ,
    [Free_space]    int     not null ,
    [Max_SIZE]      int     not null ,
    [Percent_Log_growth_enabled]    int     not null ,
    [growth_rate]   int     not null ,
    [current_date]      datetime        not null
    )
    --go
    declare @sql    nvarchar(4000)
    set @sql =
    'use ['+'?'+']
     --if db_name() <> N''?'' goto Error_Exit
     insert into ##DB_FILE_INFO
    (
        [server_Name],
        [database_name],
        [File_ID],
    [File_Type],
    [Drive],
    [Logical_Name],
    [Physical_Name],
    [FILE_SIZE_MB],
    [SPace_USED_MB],
    [Free_space],
    [Max_SIZE],
    [Percent_Log_growth_enabled],
    [growth_rate],
    [current_date]
    )
    SELECT 
    @@servername as [Server_Name],
    db_name() as database_name,
    [file_id] AS [File_ID],
    [type] AS [File_Type],
    substring([physical_name],1,1) AS [Drive],
    [name] AS [Logical_Name],
    [physical_name] AS [Physical_Name],
    CAST([size] as DECIMAL(38,0))/128. AS [File Size MB], 
    CAST(FILEPROPERTY([name],''SpaceUsed'') AS DECIMAL(38,0))/128. AS 
    [Space_Used_MB], 
    (CAST([size] AS DECIMAL(38,0))/128) - 
    (CAST(FILEPROPERTY([name],''SpaceUsed'') AS DECIMAL(38,0))/128.) AS [Free 
     Space],
    [max_size] AS [Max_Size],
    [is_percent_growth] AS [Percent_Growth_Enabled],
    [growth] AS [Growth Rate],
    getdate() AS [Current_Date]
    FROM sys.database_files'
     exec sp_msforeachdb @sql
     declare @svrName varchar(255)
    declare @sql2 varchar(400)
    --by default it will take the current server name, we can the set the server 
    name as well
    set @svrName = @@SERVERNAME
    set @sql2 = 'powershell.exe -c "Get-WmiObject -ComputerName ' + 
    QUOTENAME(@svrName,'''') + ' -Class Win32_Volume -Filter ''DriveType = 3'' | 
    select name,capacity,freespace | 
    
    foreach{$_.name+''|
     ''+$_.capacity/1048576+''%''+$_.freespace/1048576+''*''}"'
     --creating a temporary table
     CREATE TABLE ##output
     (line varchar(255))
     --inserting  in to temporary table
     insert ##output
     EXEC xp_cmdshell @sql2;
    
     with Output2 
     --(drivename, capacity(gb),freespace(gb), always_on_status)
     as
     (
     select @@servername as server_name, 
    rtrim(ltrim(SUBSTRING(line,1,CHARINDEX(':',line) -1))) as drivename
     ,round(cast(rtrim(ltrim(SUBSTRING(line,CHARINDEX('|',line)+1,
     (CHARINDEX('%',line) -1)-CHARINDEX('|',line)) )) as float)/1024,2) as 
     'capacityGB'
     ,round(cast(rtrim(ltrim(SUBSTRING(line,CHARINDEX('%',line)+1,
     (CHARINDEX('*',line) -1)-CHARINDEX('%',line)) )) as float) /1024 ,2)as 
     'freespaceGB'
     ,CASE WHEN (SERVERPROPERTY ('IsHadrEnabled')=1) THEN 'YES' WHEN 
     (SERVERPROPERTY ('IsHadrEnabled')=0) THEN 'NO'ELSE 'NOT AVAILABLE' END AS 
     ALWAYS_ON_STATUS
      --into #output2
     from ##output
       where line like '[A-Z][:]%'
       --order by drivename
      ),
      DB_FILE_INFO2 as
     (
     select server_Name,
        database_name,
        File_ID,
    File_Type,
    Drive,
    Logical_Name,
    Physical_Name,
    FILE_SIZE_MB,
    SPace_USED_MB,
    Free_space,
    Max_SIZE,
    Percent_Log_growth_enabled,
    growth_rate
    --current_date 
    from ##DB_FILE_INFO 
    --inner join #output b on a.drive = b.drivename and a.server_Name = 
    b.server_name
    )
    select  
    getdate() as Today_Date,
    a.server_Name,
    a.database_name,
    a.Drive,
    a.Logical_Name,
    a.Physical_Name,
    a.FILE_SIZE_MB,
    a.Space_Used_MB,
    --sum(a.SPace_USED_MB) as hg,
    a.Free_space as Free_Space_in_File,
     --Percentage_file_free = (a.Space_Used_MB/a.FILE_SIZE_MB),
    b.capacitygb as Total_Drive_capacity,
    b.freespacegb as Total_Free_Space,
    c.total_log_size_mb,
    c.active_log_size_mb
    --,Percentage_free_space = ((cast(Free_space as decimal))/(cast(FILE_SIZE_MB 
    as decimal)) * 100)
    
    from DB_FILE_INFO2 a
    inner join output2 b on a.server_Name = b.server_name and a.Drive = 
     b.drivename
    cross apply sys.dm_db_log_stats (db_id(a.database_name)) c
    order by a.Drive, a.database_name
    
    --drop table ##DB_FILE_INFO
    --drop table #output
    
    • 0
  6. Vinod Narwal
    2019-05-27T22:07:18+08:002019-05-27T22:07:18+08:00

    O script abaixo pode ser usado para obter as seguintes informações: 1. Informações de tamanho do banco de dados 2. FileSpaceInfo 3. AutoGrowth 4. Modelo de recuperação 5. Informações de 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

relate perguntas

  • Quais são as principais causas de deadlocks e podem ser evitadas?

  • Quanto "Padding" coloco em meus índices?

  • Existe um processo do tipo "práticas recomendadas" para os desenvolvedores seguirem para alterações no banco de dados?

  • Como determinar se um Índice é necessário ou necessário

  • Downgrade do SQL Server 2008 para 2005

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como ver a lista de bancos de dados no Oracle?

    • 8 respostas
  • Marko Smith

    Quão grande deve ser o mysql innodb_buffer_pool_size?

    • 4 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    restaurar a tabela do arquivo .frm e .ibd?

    • 10 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Como selecionar a primeira linha de cada grupo?

    • 6 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    bernd_k Quando devo usar uma restrição exclusiva em vez de um índice exclusivo? 2011-01-05 02:32:27 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve