none
Plattenauslastung SQL Server RRS feed

  • Frage

  • Hallo,

    kann man auf SQL-Servern ab 2008 R2 im T-SQL die Plattenauslastung ermitteln?

    Ich meine nicht damit den noch frei verfügbaren Speicherplatz eines Volums sondern die derzeit prozentuale Auslastung.

    Gruß

    Bodo

    Donnerstag, 24. September 2015 10:18

Antworten

  • Hallo Bodo,
    das ist undokumentiert und gefällt bestimmt nicht jedem!

    Einmalig vorab:

    sp_configure 'Ole Automation Procedures', 1;
    GO
    RECONFIGURE;
    GO

    Danach geht es hierüber, wobei ich die ursprüngliche Quelle des Codes nicht mehr finde:

    SET NOCOUNT ON
    Declare        @CMD sysname
                 ,@hr int
                 ,@fso int
                 ,@drive char(1)
                 ,@odrive int
                 ,@TotalSize varchar(20)
                 ,@MB bigint ;
    
    SET @MB = 1048576;
    
    select @CMD = @@SERVERNAME + '.master.dbo.xp_fixeddrives';
    
    IF    EXISTS (SELECT * FROM sysobjects WHERE name = 'drives' AND type = 'U')
         DROP TABLE [dbo].[drives];
            CREATE TABLE drives (ServerName varchar(15),
         drive char(1) PRIMARY KEY,
         FreeSpace int NULL,
         TotalSize int NULL,
         FreespaceTimestamp DATETIME NULL);
    
    INSERT drives(drive,FreeSpace)
         EXEC @CMD;
    
    EXEC @hr=sp_OACreate 'Scripting.FileSystemObject',@fso OUT
         IF @hr <> 0
                 EXEC sp_OAGetErrorInfo @fso;
    
    DECLARE dcur CURSOR LOCAL FAST_FORWARD
         FOR SELECT drive from drives
         ORDER by drive;
    
    OPEN dcur;
    FETCH NEXT FROM dcur INTO @drive;
    WHILE @@FETCH_STATUS=0
         BEGIN
                 EXEC @hr = sp_OAMethod @fso,'GetDrive', @odrive OUT, @drive;
                 IF @hr <> 0
                         EXEC sp_OAGetErrorInfo @fso;
                 EXEC @hr = sp_OAGetProperty @odrive,'TotalSize', @TotalSize OUT;
                 IF @hr <> 0 EXEC sp_OAGetErrorInfo @odrive
                         UPDATE drives
                         SET TotalSize=@TotalSize/@MB, ServerName = replace( @CMD ,
    '.master.dbo.xp_fixeddrives',''), FreespaceTimestamp = (GETDATE())
                         WHERE drive=@drive;
                 FETCH NEXT FROM dcur INTO @drive;
         END;
    CLOSE dcur;
    DEALLOCATE dcur;
    
    Select * from drives;

     Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu

    • Als Antwort vorgeschlagen Stefan FalzModerator Dienstag, 29. September 2015 11:02
    • Als Antwort markiert Bo_Ro Dienstag, 29. September 2015 11:09
    Freitag, 25. September 2015 09:58
    Beantworter

Alle Antworten

  • Hallo Bodo,

    mir ist Deine Frage nicht so ganz klar. "Der" SQL Server ist eine Software und hat keine Platten, nur der Rechner, auf dem der SQL Server läuft.

    Und wie die Auslastung/der (prozentual) frei Platz aussieht, kannst Du wie bei jedem Rechner auf eben diesen Ermitteln. Das kann z.B. auch mit eine PowerShell Skript machen, dort kann man auch den prozentualen Anteil errechnen, siehe List the free space of all drives for several machines


    Olaf Helper

    [ Blog] [ Xing] [ MVP]

    Donnerstag, 24. September 2015 10:48
  • Hallo Bodo,

    meinst Du die prozentuale Speicherauslastung? Das lässt sich doch recht einfach über die ( Gesamtgröße abzgl. des freien Speicherplatzes ) / Gesamtgröße berechnen.

    Falls Du was anderes meintest, beschreib bitte genauer, was Du wie auslesen willst.


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Donnerstag, 24. September 2015 10:55
    Moderator
  • Hallo,

    genau, ich meine die prozentuale Speicherauslastung von einem oder mehreren Volums. Und diese Ermittlung möchte ich nach Möglichkeit im T-SQL machen, um ab einem bestimmten Wert eine Aktion (Mail…) auszulösen.

    Den derzeit verfügbaren Speicherplatz kann ich ermitteln, was fehlt, ist die Ermittlung der Gesamtgröße.

    Hat jemand da eine Idee?

    Gruß

    Bodo

    Donnerstag, 24. September 2015 11:06
  • Hallo Bodo,

    nun, mit T-SQL geht es so nicht. Das geht erst seit SQL Server 20012 über DMVs.

    Alternativ kann man das mit WMIC machen.

    Dort lassen sich Volume-Daten mit einer SQL-ähnliche Syntax wie zB so abfragen:

    SELECT * FROM Win32_LogicalDisk

    Das müsste man über den SQL Server Agent oder Powershell initiieren.

    Ein Beispiel, wie man das mit dem Agent diekt angehen kann, findet sich hier:

    https://www.mssqltips.com/sqlservertip/2929/monitoring-sql-server-disk-space/


    Andreas Wolter (Blog | Twitter)
    MCSM: Microsoft Certified Solutions Master Data Platform, MCM, MVP
    www.SarpedonQualityLab.com | www.SQL-Server-Master-Class.com

    Donnerstag, 24. September 2015 11:29
  • Warum per T-SQL? SQL Server ist zum Verwalten von Daten da, nicht von Systeminformationen. Nutzt PowerShell, das ist prädestiniert dafür.

    Olaf Helper

    [ Blog] [ Xing] [ MVP]

    Donnerstag, 24. September 2015 11:40
  • Hallo Bodo,
    das ist undokumentiert und gefällt bestimmt nicht jedem!

    Einmalig vorab:

    sp_configure 'Ole Automation Procedures', 1;
    GO
    RECONFIGURE;
    GO

    Danach geht es hierüber, wobei ich die ursprüngliche Quelle des Codes nicht mehr finde:

    SET NOCOUNT ON
    Declare        @CMD sysname
                 ,@hr int
                 ,@fso int
                 ,@drive char(1)
                 ,@odrive int
                 ,@TotalSize varchar(20)
                 ,@MB bigint ;
    
    SET @MB = 1048576;
    
    select @CMD = @@SERVERNAME + '.master.dbo.xp_fixeddrives';
    
    IF    EXISTS (SELECT * FROM sysobjects WHERE name = 'drives' AND type = 'U')
         DROP TABLE [dbo].[drives];
            CREATE TABLE drives (ServerName varchar(15),
         drive char(1) PRIMARY KEY,
         FreeSpace int NULL,
         TotalSize int NULL,
         FreespaceTimestamp DATETIME NULL);
    
    INSERT drives(drive,FreeSpace)
         EXEC @CMD;
    
    EXEC @hr=sp_OACreate 'Scripting.FileSystemObject',@fso OUT
         IF @hr <> 0
                 EXEC sp_OAGetErrorInfo @fso;
    
    DECLARE dcur CURSOR LOCAL FAST_FORWARD
         FOR SELECT drive from drives
         ORDER by drive;
    
    OPEN dcur;
    FETCH NEXT FROM dcur INTO @drive;
    WHILE @@FETCH_STATUS=0
         BEGIN
                 EXEC @hr = sp_OAMethod @fso,'GetDrive', @odrive OUT, @drive;
                 IF @hr <> 0
                         EXEC sp_OAGetErrorInfo @fso;
                 EXEC @hr = sp_OAGetProperty @odrive,'TotalSize', @TotalSize OUT;
                 IF @hr <> 0 EXEC sp_OAGetErrorInfo @odrive
                         UPDATE drives
                         SET TotalSize=@TotalSize/@MB, ServerName = replace( @CMD ,
    '.master.dbo.xp_fixeddrives',''), FreespaceTimestamp = (GETDATE())
                         WHERE drive=@drive;
                 FETCH NEXT FROM dcur INTO @drive;
         END;
    CLOSE dcur;
    DEALLOCATE dcur;
    
    Select * from drives;

     Einen schönen Tag noch,
    Christoph
    --
    Microsoft SQL Server MVP - http://www.insidesql.org/blogs/cmu

    • Als Antwort vorgeschlagen Stefan FalzModerator Dienstag, 29. September 2015 11:02
    • Als Antwort markiert Bo_Ro Dienstag, 29. September 2015 11:09
    Freitag, 25. September 2015 09:58
    Beantworter
  • Hallo,

    sowohl mit T-SQL als auch mit Power Shell funktioniert es nach den Beispielen. Habe damit einen guten Lösungsansatz.

    Besten Dank für die Unterstützung.

    Gruß

    Bodo

    Dienstag, 29. September 2015 08:11