Überwachen des freien Speicherplatzes in SQL Server-Datendateien


9

Ich habe die Größe von MDF / NDF-Dateien manuell auf eine große Größe geändert, um Autogrow-Vorgänge in SQL Server-Datenbanken zu vermeiden. Da die Dateien größer sind, ist auf den Festplattenpartitionen nur sehr wenig freier Speicherplatz vorhanden, und die Systemadministratoren warnen mich immer wieder, dass mir der Speicherplatz ausgeht.

Da ich die Größe geändert habe, ist in den Datendateien viel freier Speicherplatz vorhanden, aber man kann es nicht bemerken, wenn man die Dateigrößen / den freien Speicherplatz der Festplatte betrachtet.

Wie kann ich die tatsächliche prozentuale Nutzung von Datendateien überwachen? Ich würde es vorziehen, Perfmon-Zähler zu verwenden. Ich bin besorgt, dass SQL Server nicht genügend Speicherplatz zuweisen kann und abstürzt, wenn der Datei wirklich der Speicherplatz ausgeht.

Antworten:


11

Sie sind sich nicht sicher, warum Sie hierfür Leistungsindikatoren verwenden möchten, wenn Sie diese aus einer einfachen Abfrage abrufen können. Während Sie diese Informationen zu Protokolldateien von Leistungsindikatoren ( Log File(s) Size (KB)/ Log File(s) Used Size (KB)) abrufen können , gibt es keinen solchen Zähler dafür, wie viel Speicherplatz in einer Datendatei verwendet wird.

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

Ich hatte gehofft, dass dies ohne SQL Server möglich ist. Natürlich kann ich es manuell abfragen und den freien Speicherplatz anzeigen, aber ich benötige eine automatisierte Lösung. Ein Perfmon-Zähler wäre perfekt, da Sysadmins ihn mit ihrer Überwachungssoftware verwenden könnten. Ich könnte Ihre Abfrage verwenden und einen SQL Agent-Job + eine E-Mail-Benachrichtigung einrichten. Außerdem werde ich Kins Lösung ausprobieren und herausfinden, welche am besten funktioniert.
BuahahaXD

1
Ich habe einen ähnlichen Anwendungsfall. Wenn eine Standardüberwachungslösung nicht SQL Server-spezifisch ist, aber Windows kennt, ist ein Leistungsindikator einfacher zu implementieren und zu überwachen.
Michael J Swart

7

Ich habe eine andere Methode, um den Speicherplatz von Datendateien proaktiv zu überwachen und zu warnen, wenn der freie Speicherplatz mithilfe von SQL Alert unter einen bestimmten Prozentsatz fällt.

Die Grundlagen sind

  • Erstellen Sie eine benutzerdefinierte Fehlermeldung in sys.messages. Dies wird von der SQL Agent-Warnung verwendet.

    -- 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.'
  • Erstellen Sie nun einen SQL Agent-Job. Stellen Sie sicher, dass Sie das set @threshold = 20 --->>>>>>>>>>>>>>>>> CHANGE HERE <<<<<<<<<<<<<<<<<<<<<---folgende Skript ändern . Ich habe seine als sehr niedrige Schwelle festgelegt, nur um den Alarm zu simulieren. Planen Sie die Ausführung des Jobs alle 30 Minuten (ändern Sie dies gemäß Ihren Anforderungen).

        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
  • Erstellen Sie nun eine Warnung, um auf die 911421Fehlernummer zu reagieren .

    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

    Geben Sie hier die Bildbeschreibung ein

    Geben Sie hier die Bildbeschreibung ein

Hinweis: Es gibt andere Arten von Verbesserungen, die Sie mit meiner obigen Idee vornehmen können.

  • Machen Sie den Agentenjob zu einer gespeicherten Prozedur, die den Schwellenwert als Eingabewert akzeptiert.
  • Protokollieren Sie die Werte in einer physischen Tabelle in der DBA-Datenbank, damit Sie eine Trendanalyse und Kapazitätsplanung durchführen können.
  • Alle anderen, die Sie denken können .... :-)

Es liegt ein Problem mit Ihrer Abfrage vor. Ich denke, irgendwo gibt es eine Endlosschleife. Ich habe die Warnungen konfiguriert, deaktiviert, um den Job durch die Warnung auszulösen, und ich
bekomme

1
Sie sollten die Einstellung für die Verzögerung zwischen den Antworten verwenden.
Kin Shah

5

Um auf den Antworten von Aaron und Kin aufzubauen, können Sie dies mit Perf-Zählern tun, aber einem der vom Benutzer einstellbaren Zähler .

Ich würde:

  • Erstellen Sie eine gespeicherte Prozedur, die Aarons Abfrage verwendet, um den freien Speicherplatz in einer einzelnen Datei oder Schleife durch alle Dateien abzurufen und den gewünschten Min / Max-Wert abzurufen
  • Erstellen Sie einen Job, der den gespeicherten Prozess regelmäßig ausführt

Falls Sie ordnungsgemäß benachrichtigt werden möchten:

  • Erstellen Sie einen Operator / verwenden Sie einen vorhandenen mit einer gültigen E-Mail-Adresse
  • Erstellen Sie basierend auf diesem Benutzerzähler eine Warnung, die den vorherigen Bediener benachrichtigt (stellen Sie sicher, dass Sie sich nicht mit E-Mails überfluten - stellen Sie eine Verzögerung zwischen den Antworten ein).

Die Vorbehalte sind:

  • Sie haben nur 10 einstellbare Zähler
  • Sie haben keinen aussagekräftigen Namen
  • Sie müssen den umständlichen Job + Proc + Alarm haben, um ein schönes Bild zu haben

Sie können jedoch in Perfmon oder einem anderen ähnlichen Tool verwendet werden.


3

Es gibt auch eine einfache Alarmeinstellung zum Überwachen der Datendateigröße:

Geben Sie hier die Bildbeschreibung ein

Der zusätzliche Alarm "Niedriger Protokollspeicherplatz" überwacht den freien Speicherplatz für die Transaktionsprotokolldatei (das automatische Wachstum ist deaktiviert):

Geben Sie hier die Bildbeschreibung ein

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.