Мониторинг свободного места в файлах данных SQL Server


9

Я вручную изменил размер файлов mdf / ndf до большого размера, чтобы избежать автоматических операций над базами данных SQL Server. Поскольку файлы больше, на дисковых разделах остается очень мало свободного места, и системные администраторы постоянно предупреждают меня о том, что у меня заканчивается свободное место.

Поскольку я изменил их размер, в файлах данных много свободного места, но этого не замечаешь, глядя на размеры файлов / свободное место на диске.

Как я могу отслеживать реальный процент использования файлов данных? Я бы предпочел использовать счетчики perfmon. Я обеспокоен тем, что, когда файлу действительно не хватит места, SQL Server не сможет выделить достаточно места и будет зависать.

Ответы:


11

Не уверен, почему вы хотите использовать счетчики производительности для этого, когда вы можете получить его из простого запроса. И на самом деле, хотя вы можете получить эту информацию о файлах журнала из счетчиков производительности ( Log File(s) Size (KB)/ Log File(s) Used Size (KB)), такого счетчика для того, сколько места используется в файле данных, нет.

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

Я надеялся, что это можно сделать без использования SQL Server. Конечно, я могу сделать запрос вручную и увидеть свободное место, но мне нужно автоматизированное решение. Счетчик perfmon был бы идеальным, потому что системные администраторы могли бы использовать его со своим программным обеспечением для мониторинга. Я мог бы использовать ваш запрос и настроить работу агента SQL + оповещение по электронной почте. Также я попробую решение Кина и посмотрю, какое из них работает лучше всего.
BuahahaXD

1
У меня есть похожий вариант использования. Если готовое решение для мониторинга не является специфичным для SQL Server, но знает о окнах, то счетчик производительности будет проще внедрить и отслеживать.
Майкл Дж Сварт

7

У меня есть другой метод для активного мониторинга файлового пространства данных и предупреждения, если свободное пространство падает ниже определенного процента с помощью SQL Alert.

Основы

  • Создайте пользовательское сообщение об ошибке в sys.messages. Это будет использовано оповещением агента 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.'
    
  • Теперь создайте задание агента SQL. Убедитесь, что вы изменили set @threshold = 20 --->>>>>>>>>>>>>>>>> CHANGE HERE <<<<<<<<<<<<<<<<<<<<<---в сценарии ниже. Я поставил его как очень низкий порог, только чтобы имитировать предупреждение. Запланируйте выполнение задания каждые 30 минут (измените его в соответствии с вашими потребностями).

        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
    
  • Теперь создайте оповещение, чтобы ответить на 911421номер ошибки.

    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
    

    введите описание изображения здесь

    введите описание изображения здесь

Примечание: есть и другие виды улучшений, которые вы можете сделать с моей идеей выше.

  • Сделайте задание агента хранимой процедурой, принимая порог в качестве входного значения.
  • Зарегистрируйте значения в физической таблице в базе данных DBA, чтобы можно было проводить анализ тенденций и планирование емкости.
  • Любое другое, что вы можете думать .... :-)

Возникла проблема с вашим запросом. Я думаю, что где-то есть бесконечный цикл. Я настроил оповещения, отключил запуск задания по оповещению, и я продолжаю получать тонны писем о файлах данных :)
BuahahaXD

1
Вы должны использовать задержку между настройками ответов.
Кин Шах

5

Просто основываясь на ответах Аарона и Кина, вы можете сделать это с помощью счетчиков перфорации, но с одним из настраиваемых пользователем счетчиков .

Я мог бы:

  • создайте хранимую процедуру, которая будет использовать запрос Аарона, чтобы получить свободное место в одном файле или перебрать все файлы и получить интересующее минимальное / максимальное значение
  • создать задание, которое будет периодически запускать сохраненный процесс

В случае, если вы хотите быть надлежащим образом уведомлены:

  • создать оператора / использовать существующего с действующим адресом электронной почты
  • на основе этого счетчика пользователей создайте оповещение, которое будет уведомлять предыдущего оператора (убедитесь, что вы не залили себя письмами - установите задержку между ответами).

Предостережения:

  • у вас есть только 10 настраиваемых счетчиков
  • у них нет значимого имени
  • вам нужно иметь громоздкую работу + proc + alert, чтобы иметь красивую картинку

Но они могут быть использованы в Perfmon или другом подобном инструменте.


3

Также есть простые настройки предупреждений для мониторинга размера файла данных:

введите описание изображения здесь

Дополнительное «Low Log Space Alert» будет следить за свободным местом для файла журнала транзакций (автоматический рост отключен):

введите описание изображения здесь

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.