Monitoraggio dello spazio libero nei file di dati di SQL Server


9

Ho ridimensionato manualmente i file mdf / ndf di grandi dimensioni per evitare operazioni di aumento automatico dei database di SQL Server. Dato che i file sono più grandi, c'è molto poco spazio libero sulle partizioni del disco e gli amministratori di sistema continuano ad avvisarmi che sto esaurendo lo spazio.

Dato che li ho ridimensionati, c'è molto spazio libero nei file di dati, ma non si può notare che guardando alle dimensioni dei file / spazio libero su disco.

Come posso monitorare il reale utilizzo% dei file di dati? Preferirei usare i contatori di perfoni. Sono preoccupato che quando il file esaurisce veramente lo spazio SQL Server non sarà in grado di allocare spazio sufficiente e andrà in crash.

Risposte:


11

Non so perché desideri utilizzare i contatori delle prestazioni per questo quando puoi ottenerlo da una semplice query. Infatti, mentre è possibile ottenere queste informazioni sui file di registro dai contatori delle prestazioni ( Log File(s) Size (KB)/ Log File(s) Used Size (KB)), non esiste un contatore di questo tipo per quanto spazio viene utilizzato in un file di dati.

;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;

Speravo che potesse essere fatto senza usare SQL Server. Sicuramente posso interrogarlo manualmente e vedere lo spazio libero ma ho bisogno di una soluzione automatizzata. Un contatore perfmon sarebbe perfetto perché gli amministratori di sistema potrebbero usarlo con il loro software di monitoraggio. Potrei usare la tua query e impostare un lavoro di SQL Agent + avviso e-mail. Inoltre proverò la soluzione di Kin e vedrò quale funziona meglio.
BuahahaXD

1
Ho un caso d'uso simile. Se una soluzione di monitoraggio standard non è specifica di SQL Server, ma conosce Windows, un contatore delle prestazioni sarebbe più facile da implementare e monitorare.
Michael J Swart,

7

Ho un altro metodo per monitorare proattivamente lo spazio dei file di dati e avvisare se lo spazio libero scende al di sotto di una certa percentuale utilizzando SQL Alert.

Le basi sono

  • Creare un messaggio di errore definito dall'utente in sys.messages. Questo verrà utilizzato dall'avviso sql agent.

    -- 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.'
    
  • Ora crea un processo di SQL Agent. Assicurati di cambiare set @threshold = 20 --->>>>>>>>>>>>>>>>> CHANGE HERE <<<<<<<<<<<<<<<<<<<<<---nello script seguente. L'ho messo come soglia molto bassa, solo per simulare l'avviso. Pianifica l'esecuzione del lavoro ogni 30 minuti (modificalo in base alle tue esigenze).

        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
    
  • Ora crea un avviso per rispondere al 911421numero di errore.

    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
    

    inserisci qui la descrizione dell'immagine

    inserisci qui la descrizione dell'immagine

Nota: ci sono altri tipi di miglioramenti che puoi fare con la mia idea sopra.

  • Rendere il lavoro dell'agente come procedura memorizzata accettando la soglia come valore di input.
  • Registra i valori in una tabella fisica nel database DBA in modo da poter eseguire l'analisi delle tendenze e la pianificazione della capacità.
  • Qualsiasi altro che tu possa pensare .... :-)

Si è verificato un problema con la query. Penso che ci sia un ciclo infinito da qualche parte. Ho configurato gli avvisi, disattivato l'attivazione del lavoro dall'avviso e continuo a ricevere tonnellate di messaggi di posta elettronica sui file di dati :)
BuahahaXD

1
È necessario utilizzare il ritardo tra l'impostazione delle risposte.
Kin Shah,

5

Solo per basare sulle risposte di Aaron e Kin, puoi farlo con i contatori perf, ma uno dei contatori impostabili dall'utente .

Vorrei:

  • creare una procedura memorizzata che utilizzerà la query di Aaron per ottenere lo spazio libero in un singolo file o scorrere tutti i file e ottenere il valore min / max di interesse
  • creare un lavoro che eseguirà periodicamente il proc memorizzato

Nel caso in cui si desideri ricevere una notifica adeguata:

  • crea un operatore / usa uno esistente con un indirizzo email valido
  • crea un avviso basato sul contatore utente che avviserà l'operatore precedente (assicurati di non inondarti di e-mail - imposta un ritardo tra le risposte).

Le avvertenze sono:

  • hai solo 10 segnalini impostabili
  • non hanno un nome significativo
  • devi avere un lavoro ingombrante + proc + alert per avere una bella foto

Ma possono essere utilizzati in Perfmon o in un altro strumento simile.


3

Inoltre c'è una semplice impostazione di avviso per monitorare la dimensione del file di dati:

inserisci qui la descrizione dell'immagine

L'allerta aggiuntiva per lo spazio di log insufficiente monitorerà lo spazio libero per il file di log delle transazioni (la crescita automatica è disattivata):

inserisci qui la descrizione dell'immagine

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.