Monitorando o espaço livre nos arquivos de dados do SQL Server

9

Redimensionei manualmente os arquivos mdf / ndf para um tamanho grande para evitar operações de crescimento automático nos bancos de dados do SQL Server. Como os arquivos são maiores, há muito pouco espaço livre nas partições do disco e os administradores de sistemas continuam me alertando que estou ficando sem espaço.

Como eu os redimensionei, há muito espaço livre nos arquivos de dados, mas não dá para notar isso olhando para tamanhos de arquivo / espaço livre em disco.

Como posso monitorar o% real de uso de arquivos de dados? Eu preferiria usar contadores perfmon. Estou preocupado que, quando o arquivo realmente ficar sem espaço, o SQL Server não conseguirá alocar espaço suficiente e travará.

BuahahaXD
fonte

Respostas:

11

Não sei por que você deseja usar contadores de desempenho para isso quando é possível obtê-lo a partir de uma consulta simples. E, de fato, embora você possa obter essas informações sobre arquivos de log nos contadores de desempenho ( Log File(s) Size (KB)/ Log File(s) Used Size (KB)), não existe esse contador para quanto espaço é usado em um arquivo de dados.

;WITH f AS 
(
  SELECT name, size = size/128.0 FROM sys.database_files
),
s AS
(
  SELECT name, size, free = size-CONVERT(INT,FILEPROPERTY(name,'SpaceUsed'))/128.0
  FROM f
)
SELECT name, size, free, percent_free = free * 100.0 / size
FROM s;
Aaron Bertrand
fonte
Eu esperava que isso pudesse ser feito sem o uso do SQL Server. Claro que posso consultá-lo manualmente e ver o espaço livre, mas preciso de uma solução automatizada. Um contador perfmon seria perfeito porque os administradores de sistemas poderiam usá-lo com seu software de monitoramento. Eu poderia usar sua consulta e configurar um trabalho do SQL Agent + alerta de email. Além disso, tentarei a solução de Kin e verei qual funciona melhor.
BuahahaXD
11
Eu tenho um caso de uso semelhante. Se uma solução de monitoramento pronta para uso não for específica do SQL Server, mas souber sobre o Windows, um contador de desempenho seria mais fácil de implementar e monitorar.
Michael J Swart
7

Eu tenho outro método para monitorar proativamente o espaço no arquivo de dados e alertar se o espaço livre ficar abaixo de uma certa porcentagem usando o SQL Alert.

O básico é

  • Crie uma mensagem de erro definida pelo usuário em sys.messages. Isso será usado pelo alerta do agente sql.

    -- User-defined error messages can be an integer between 50001 and 2147483647. 
    EXEC sp_addmessage 
      @msgnum=911421, -- 911DBA
      @severity=1,    -- Informational message not generated by DB Engine       
      @msgtext=N'Data files are %d percent full in database %s.'
    
  • Agora crie um trabalho do SQL Agent. Certifique-se de alterar o set @threshold = 20 --->>>>>>>>>>>>>>>>> CHANGE HERE <<<<<<<<<<<<<<<<<<<<<---script abaixo. Coloquei o dele como um limite muito baixo, apenas para simular o alerta. Agende a execução da tarefa a cada 30 minutos (altere-a conforme suas necessidades).

        if object_id('tempdb..#dbserversize') is not null
        DROP TABLE #dbserversize;
    
        create table dbo.#dbserversize (
         [id] int identity (1,1)
         ,[databaseName] sysname
        ,[Drive]    varchar(3)
        ,[Logical Name] sysname
        ,[Physical Name]    varchar(max)
        ,[File Size MB] decimal(38, 2)
        ,[Space Used MB]    decimal(38, 2)
        ,[Free Space]   decimal(38, 2)
        ,[%Free Space]  decimal(38, 2)
        ,[Max Size] varchar(max)
        ,[Growth Rate]  varchar(max)
        )
    
        declare @id int
        declare @threshold int
        declare @dbname sysname
    
        declare @sqltext nvarchar(max)
    
        declare @freespacePct int
    
        set @threshold = 20   --->>>>>>>>>>>>>>>>> CHANGE HERE <<<<<<<<<<<<<<<<<<<<<---
    
        select @dbname = min(name) from sys.databases where database_id > 4 and [state] = 0 
    
        while @dbname is not NULL
    
        begin
            select @dbname = name from sys.databases where name = @dbname and database_id > 4 and [state] = 0 
                --- Modified from Erin's blog : Proactive SQL Server Health Checks, Part 1 : Disk Space
                --- source http://sqlperformance.com/2014/12/io-subsystem/proactive-sql-server-health-checks-1
            set @sqltext =  ' use '+@dbname+';'+' 
                insert into dbo.#dbserversize
                select '''+@dbname+''' as [databaseName]
                    ,substring([physical_name], 1, 3) as [Drive]
                    ,[name] as [Logical Name]
                    ,[physical_name] as [Physical Name]
                    ,cast(CAST([size] as decimal(38, 2)) / 128.0 as decimal(38, 2)) as [File Size MB]
                    ,cast(CAST(FILEPROPERTY([name], ''SpaceUsed'') as decimal(38, 2)) / 128.0 as decimal(38, 2)) as [Space Used MB]
                    ,cast((CAST([size] as decimal(38, 0)) / 128) - (CAST(FILEPROPERTY([name], ''SpaceUsed'') as decimal(38, 0)) / 128.) as decimal(38, 2)) as [Free Space]
                    ,cast(((CAST([size] as decimal(38, 2)) / 128) - (CAST(FILEPROPERTY([name], ''SpaceUsed'') as decimal(38, 2)) / 128.0)) * 100.0 / (CAST([size] as decimal(38, 2)) / 128) as decimal(38, 2)) as [%Free Space]
                    ,case 
                        when cast([max_size] as varchar(max)) = - 1
                            then ''UNLIMITED''
                        else cast([max_size] as varchar(max))
                        end as [Max Size]
                    ,case 
                        when is_percent_growth = 1
                            then cast([growth] as varchar(20)) + ''%''
                        else cast([growth] as varchar(20)) + ''MB''
                        end as [Growth Rate]
                    from sys.database_files
                    where type = 0 -- for Rows , 1 = LOG'
                --print @sqltext
                exec (@sqltext)
    
    
                select @dbname = min(name) from sys.databases where name > @dbname and database_id > 4 and [state] = 0 
        end
    
    
        --- delete the entries that do not meet the threshold 
    
        delete from dbo.#dbserversize
        where [%Free Space] < @threshold;
    
    
        --select * from dbo.#dbserversize
    
        --- NOW Raise errors for the databases that we got flagged up
    
        while exists (select null from dbo.#dbserversize)
        begin
    
            select top 1 @id = id,
                        @dbname = databaseName,
                        @freespacePct = [%Free Space]
                    from dbo.#dbserversize;
    
    
                RAISERROR(911421, 10,1,@freespacePct, @dbname) with LOG;
    
                delete from dbo.#dbserversize where id = @id;
    
        end
    
  • Agora crie um alerta para responder ao 911421número do erro.

    USE [msdb]
    GO
    EXEC msdb.dbo.sp_add_alert @name=N'MDF file alert', 
            @message_id=911421, 
            @severity=0, 
            @enabled=1, 
            @delay_between_responses=1800, 
            @include_event_description_in=0, 
            @job_id=N'019c4770-865b-406b-894e-72a1ff34f732'
    GO
    EXEC msdb.dbo.sp_add_notification @alert_name=N'MDF file alert', @operator_name=N'Notify 911 DBA for MDF files getting full', @notification_method = 1
    GO
    

    insira a descrição da imagem aqui

    insira a descrição da imagem aqui

Nota: Existem outros tipos de aprimoramentos que você pode fazer com a minha ideia acima.

  • Faça o trabalho do agente como um procedimento armazenado, aceitando o limite como um valor de entrada.
  • Registre os valores em uma tabela física no banco de dados do DBA para poder fazer análise de tendências e planejamento de capacidade.
  • Qualquer outro que você possa pensar .... :-)
Kin Shah
fonte
Há um problema com sua consulta. Eu acho que há um loop infinito em algum lugar. Eu configurei os alertas desligados desencadeando o trabalho pelo alerta e eu continuo recebendo toneladas de mails sobre arquivos de dados :)
BuahahaXD
11
Você deve usar o atraso entre a configuração de respostas.
Kin Shah
5

Apenas para aproveitar as respostas de Aaron e Kin, você pode fazer isso com contadores de desempenho, mas um dos contadores configuráveis pelo usuário .

Eu gostaria:

  • crie um procedimento armazenado que usará a consulta de Aaron para obter o espaço livre em um único arquivo ou percorrer todos os arquivos e obter o valor mínimo / máximo de seu interesse
  • crie um trabalho que executará periodicamente o processo armazenado

Caso você queira ser notificado adequadamente:

  • crie um operador / use um operador existente com um endereço de email válido
  • crie um alerta com base nesse contador de usuários que notificará o operador anterior (verifique se não se enche de emails - defina um atraso entre as respostas).

As advertências são:

  • você tem apenas 10 contadores configuráveis
  • eles não têm um nome significativo
  • você precisa ter o trabalho pesado + proc + alerta para ter uma boa foto

Mas eles podem ser usados ​​no Perfmon ou outra ferramenta similar.

Marian
fonte
3

Além disso, existem configurações simples de alerta para monitorar o tamanho do arquivo de dados:

insira a descrição da imagem aqui

O 'Alerta de pouco espaço no log' adicional irá monitorar o espaço livre para o arquivo de log de transações (o crescimento automático está desativado):

insira a descrição da imagem aqui

Vladislav
fonte