Supervisión de espacio libre en archivos de datos de SQL Server


9

He redimensionado manualmente los archivos mdf / ndf a un tamaño grande para evitar operaciones de crecimiento automático en las bases de datos de SQL Server. Como los archivos son más grandes, hay muy poco espacio libre en las particiones de disco y los administradores de sistemas me siguen alertando de que me estoy quedando sin espacio.

Debido a que los redimensioné, hay mucho espacio libre en los archivos de datos, pero uno no puede notarlo mirando los tamaños de archivo / espacio libre en disco.

¿Cómo puedo monitorear el% de uso real de los archivos de datos? Preferiría usar los contadores de perfmon. Me preocupa que cuando el archivo realmente se quede sin espacio, SQL Server no podrá asignar suficiente espacio y se bloqueará.

Respuestas:


11

No estoy seguro de por qué desea usar contadores de rendimiento para esto cuando puede obtenerlo de una consulta simple. Y, de hecho, si bien puede obtener esta información sobre los archivos de registro de los contadores de rendimiento ( Log File(s) Size (KB)/ Log File(s) Used Size (KB)), no existe dicho contador de cuánto espacio se utiliza en un archivo de datos.

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

Esperaba que se pudiera hacer sin usar SQL Server. Claro que puedo consultarlo manualmente y ver el espacio libre, pero necesito una solución automatizada. Un contador de rendimiento sería perfecto porque los administradores de sistemas podrían usarlo con su software de monitoreo. Podría usar su consulta y configurar un trabajo del Agente SQL + alerta por correo electrónico. También intentaré la solución de Kin y veré cuál funciona mejor.
BuahahaXD

1
Tengo un caso de uso similar. Si una solución de monitoreo estándar no es específica de SQL Server, pero conoce Windows, entonces un contador de rendimiento sería más fácil de implementar y monitorear.
Michael J Swart

7

Tengo otro método para monitorear proactivamente el espacio de archivos de datos y alertar si el espacio libre cae por debajo de un cierto porcentaje usando Alerta SQL.

Los fundamentos son

  • Cree un mensaje de error definido por el usuario en sys.messages. Esto será utilizado por la alerta del 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.'
  • Ahora cree un trabajo de Agente SQL. Asegúrese de cambiar set @threshold = 20 --->>>>>>>>>>>>>>>>> CHANGE HERE <<<<<<<<<<<<<<<<<<<<<---en el siguiente script. He puesto el suyo como un umbral muy bajo, solo para simular la alerta. Programe el trabajo para que se ejecute cada 30 minutos (cambie esto según sus necesidades).

        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
  • Ahora cree una alerta para responder al 911421número de error.

    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

    ingrese la descripción de la imagen aquí

    ingrese la descripción de la imagen aquí

Nota: Hay otros tipos de mejoras que puede hacer con mi idea anterior.

  • Haga que el agente funcione como un procedimiento almacenado aceptando el umbral como un valor de entrada.
  • Registre los valores en una tabla física en la base de datos DBA para que pueda hacer análisis de tendencias y planificación de capacidad.
  • Cualquier otro que puedas pensar .... :-)

Hay un problema con su consulta. Creo que hay un bucle infinito en alguna parte. Configuré las alertas, apagué la activación del trabajo por la alerta y sigo recibiendo toneladas de correos sobre archivos de datos :)
BuahahaXD

1
Debe usar la demora entre la configuración de respuestas.
Kin Shah

5

Solo para construir sobre las respuestas de Aaron y Kin, puede hacerlo con contadores de rendimiento, pero uno de los contadores configurables por el usuario .

Me gustaría:

  • cree un procedimiento almacenado que utilizará la consulta de Aaron para obtener el espacio libre en un solo archivo o recorrer todos los archivos y obtener el valor mínimo / máximo que sea de interés
  • crear un trabajo que ejecutará periódicamente el proceso almacenado

En caso de que desee recibir una notificación adecuada:

  • crear un operador / usar uno existente con una dirección de correo electrónico válida
  • cree una alerta basada en ese contador de usuario que notificará al operador anterior (asegúrese de no inundarse de correos electrónicos; establezca un retraso entre las respuestas).

Las advertencias son:

  • solo tienes 10 contadores configurables
  • no tienen un nombre significativo
  • necesitas tener el trabajo engorroso + proc + alerta para tener una buena foto

Pero pueden usarse en Perfmon u otra herramienta similar.


3

También hay una configuración de alerta simple para monitorear el tamaño del archivo de datos:

ingrese la descripción de la imagen aquí

La 'Alerta de espacio de registro bajo' adicional monitoreará el espacio libre para el archivo de registro de transacciones (el crecimiento automático está desactivado):

ingrese la descripción de la imagen aquí

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.