如何监控可用磁盘空间

时间:2015-04-22 12:10:17

标签: sql sql-server automation

我们在可用空间方面存在问题,并且没有经济手段来升级它。因此,在监视数据库大小,增长和剩余可用空间时,我必须非常小心。每天早上,我都会手动运行查询以获得可用空间,并且我将结果复制到excel文件。你可以想象这是一个相当艰巨的过程,浪费了我很多时间,因为我必须分别为每个服务器做这件事。

我想知道是否有办法从生产环境中自动检索统计信息(特别是剩余的可用空间)并将其移动到同一个或另一个数据库/服务器中的特殊表。我想让桌子每天自动更新。它不一定是一张桌子。任何能让我每天节省时间的方式都将受到赞赏。

你可以建议吗?您的数据库中是否有类似的解决方案?请分享您的经验。

<!/ P>

3 个答案:

答案 0 :(得分:2)

这是一个开始使用SP的SP。我将假设您已经设置了数据库邮件并且它正常运行。您可以手动运行它以查看其工作原理。根据需要调整@FreeSpaceThresholdMB的默认值。 SP有一些限制:

  • 只能查看可用空间
  • 它不会检查使用的空间
  • 它不会根据百分比
  • 显示

CREATE PROCEDURE dbo.CheckFixedDriveFreeSpace
@FreeSpaceThresholdMB INT = 1024
AS
--Name     : dbo.CheckFixedDriveFreeSpace
--Purpose  : Performs a rudimentary check of free space on fixed drives,
--           sends an email as needed.
--Inputs   : @FreeSpaceThresholdMB - the threshold for checking free disk space.
--              If free space is greater, no action is taken.  If less, an
--              email is sent.
BEGIN
    CREATE TABLE #FixedDrives (
        Drive CHAR(1) PRIMARY KEY NONCLUSTERED,
        MBFree INT
    )

    INSERT INTO #FixedDrives EXEC xp_fixeddrives

    DECLARE @ErrMsg VARCHAR(MAX)
    SET @ErrMsg = ''

    SELECT @ErrMsg = @ErrMsg + fd.Drive + ':' + CHAR(9) + CAST(fd.MBFree AS VARCHAR) + ' MB' + CHAR(13) + CHAR(10)
    FROM #FixedDrives fd
    WHERE fd.MBFree < @FreeSpaceThresholdMB

    IF @@ROWCOUNT > 0
    BEGIN
        SET @ErrMsg = 'Warning: one or more disk drives is running out of free space:' + CHAR(13) + CHAR(10) + @ErrMsg
        DECLARE @Subj NVARCHAR(255) 
        SET @Subj = @@SERVERNAME + ' - Low Disk Space'
        EXEC msdb..sp_send_dbmail
            @recipients = 'Your email address', 
            @Subject = @Subj,
            @body = @ErrMsg
    END

    DROP TABLE #FixedDrives
END
GO

你可以&#34;挂钩&#34; SP到SQL代理作业,并根据需要安排它运行。这是&#34;每小时&#34;时间表:

IF NOT EXISTS (
    SELECT *
    FROM msdb.dbo.sysschedules s
    WHERE s.name = N'DBA-Hourly Schedule'
)
    EXEC msdb.dbo.sp_add_schedule 
        @schedule_name=N'DBA-Hourly Schedule', 
        @enabled=1, 
        @freq_type=4, 
        @freq_interval=1, 
        @freq_subday_type=8, 
        @freq_subday_interval=1,  
        @active_start_date=20140101, 
        @active_end_date=99991231, 
        @active_start_time=0, 
        @active_end_time=235959
GO

接下来,创建一个SQL代理作业:

IF NOT EXISTS (SELECT job_id FROM msdb.dbo.sysjobs_view WHERE name = N'DBA-Check Fixed Drive Free Space')
BEGIN
    EXEC msdb.dbo.sp_add_job 
        @job_name=N'DBA-Check Fixed Drive Free Space', 
        @enabled=1, 
        @notify_level_eventlog=0, 
        @notify_level_email=2, 
        @notify_level_netsend=0, 
        @notify_level_page=2, 
        @delete_level=0, 
        @description=N'Self-explanatory.', 
        @category_name=N'[Uncategorized (Local)]', 
        @owner_login_name=N'sa', 
        @notify_email_operator_name=N'Some Operator',
        @notify_page_operator_name=N'Some Operator',
        @start_step_id = 1

    EXEC msdb.dbo.sp_attach_schedule
        @job_name=N'DBA-Check Fixed Drive Free Space',
        @schedule_name=N'DBA-Hourly Schedule'

    EXEC msdb.dbo.sp_add_jobserver 
        @job_name=N'DBA-Check Fixed Drive Free Space', 
        @server_name = N'(local)'
END
GO

添加工作步骤:

IF EXISTS (SELECT job_id FROM msdb.dbo.sysjobs_view WHERE name = N'DBA-Check Fixed Drive Free Space')
BEGIN
    --Calling sp_delete_jobstep with a step_id value of zero deletes all job steps for the job.
    EXEC msdb.dbo.sp_delete_jobstep
        @job_name=N'DBA-Check Fixed Drive Free Space', 
        @step_id=0

    DECLARE @Cmd NVARCHAR(MAX)
    SET @Cmd = N'EXEC dbo.CheckFixedDriveFreeSpace
    @FreeSpaceThresholdMB = 1024    --Or Whatever number you want
GO'
    EXEC msdb.dbo.sp_add_jobstep 
        @job_name=N'DBA-Check Fixed Drive Free Space', 
        @step_name=N'Check Fixed Drive Free Space', 
        --@step_id=1, 
        @cmdexec_success_code=0, 
        @on_success_action=1, 
        @on_success_step_id=0, 
        @on_fail_action=2, 
        @on_fail_step_id=0, 
        @retry_attempts=0, 
        @retry_interval=0, 
        @os_run_priority=0, 
        @subsystem=N'TSQL', 
        @command=@Cmd, 
        --Name Of The DB Where You Created [dbo].[CheckFixedDriveFreeSpace]
        @database_name=N'ReplaceMe', 
        @flags=0
END
ELSE
    RAISERROR('SQL Server job "DBA-Check Fixed Drive Free Space" does not exist.', 16, 1);
GO

现在让我们花点时间思考一下我们创造了什么...... 我们已经在每小时的最高时间运行一次SQL代理作业&#34;#34;它执行在可用磁盘空间不足时发送电子邮件的SP。这是一个良好的开端,但它有一些缺点。最大的缺点是我们的工作只是由时间表触发。如果存在快速消耗磁盘空间的事件,则在作业运行之前,一个或多个磁盘可能会耗尽空间 - 我们不会知道,直到它为时已晚。如果您想进一步追求这一点,我们可以通过事件通知增强迄今为止创建的内容。注意:我相信您将需要SQL Server 2008或更高版本。

有DATA_FILE_AUTO_GROW和LOG_FILE_AUTO_GROW的事件。让我们进入&#34;这些事件,以便每次数据或日志文件增长时,我们都会自动检查我们的磁盘。

--Create a queue just for file autogrowth events.
CREATE QUEUE queFileAutoGrowthNotification
GO

--Create a service just for file autogrowth events.
CREATE SERVICE svcFileAutoGrowthNotification
ON QUEUE queFileAutoGrowthNotification ([http://schemas.microsoft.com/SQL/Notifications/PostEventNotification])
GO

-- Create the event notification for file autogrowth events on the service.
CREATE EVENT NOTIFICATION enFileAutoGrowthEvents
ON SERVER
WITH FAN_IN
FOR DATA_FILE_AUTO_GROW, LOG_FILE_AUTO_GROW
TO SERVICE 'svcFileAutoGrowthNotification', 'current database';
GO


CREATE PROCEDURE dbo.ReceiveFileAutoGrowthEvent
AS
BEGIN
    SET NOCOUNT ON
    DECLARE @MsgBody XML

    WHILE (1 = 1)
    BEGIN
        BEGIN TRANSACTION

        -- Receive the next available message FROM the queue
        WAITFOR (
            RECEIVE TOP(1) -- just handle one message at a time
                @MsgBody = CAST(message_body AS XML)
                FROM queFileAutoGrowthNotification
        ), TIMEOUT 1000  -- if the queue is empty for one second, give UPDATE and go away
        -- If we didn't get anything, bail out
        IF (@@ROWCOUNT = 0)
        BEGIN
            ROLLBACK TRANSACTION
            BREAK
        END 
        ELSE
        BEGIN
            --Although we've captured the message body, we're not using any of the event data.

            --Run this SP when the event is triggered.
            EXEC [ReplaceMe].dbo.CheckFixedDriveFreeSpace
                @FreeSpaceThresholdMB = 1024    --Or Whatever number you want.

            /*
                Alternatively, you could start a SQL Agent job when the event is triggered.
                (You won't be able to do this with SQLExpress versions.)

                EXEC msdb.dbo.sp_start_job 
                    @job_name = 'DBA-Check Fixed Drive Free Space'
            */

            /*
                Commit the transaction.  At any point before this, we 
                could roll back -- the received message would be back 
                on the queue AND the response wouldn't be sent.
            */
            COMMIT TRANSACTION
        END
    END
END
GO

ALTER QUEUE dbo.queFileAutoGrowthNotification 
WITH 
STATUS = ON, 
ACTIVATION ( 
    PROCEDURE_NAME = dbo.ReceiveFileAutoGrowthEvent, 
    STATUS = ON, 
    --STATUS = OFF, 
    MAX_QUEUE_READERS = 1, 
    EXECUTE AS OWNER) 
GO

答案 1 :(得分:0)

您是否考虑过SQL Server代理作业?在Microsoft SQL Management Studio中,展开Object Explorer中的SQL Server代理节点,右键单击Jobs节点并选择New Job ...

答案 2 :(得分:0)

我认为你应该考虑使用powershell脚本来完成这项工作。请阅读此topic,它会谈到您想要的内容。