• 使用作业自动清理数据库日志文件


           在上一篇文章中介绍了如何删除数据库日志文件,但是想想还是不是不方便需要手工操作,于是想结合作业实现自动清理日志文件,在清理日志文件时我加上了条件,当磁盘控空间不足多少M才会清理,下面介绍如何实现该功能。没有阅读上一篇文章的,可以通过传送门阅读(删除数据库日志文件的方法)

    SQL查询磁盘空间大小

       采用内置的存储过程,即可查看各个磁盘可用空间

       

    exec master..xp_fixeddrives

     

    存储过程添加作业

      

    GO
    IF EXISTS(SELECT 1 FROM sysobjects WHERE id=OBJECT_ID('usp_p_CreateJob'))
    BEGIN
        DROP PROC dbo.usp_p_CreateJob
    END
    GO
    CREATE PROCEDURE dbo.usp_p_CreateJob(
        @jobname varchar(100),         
        @sql VARCHAR(MAX),                      
        @freqtype varchar(6)='day',     
        @fsinterval int=1,                
        @time int=235959,                     
        @description VARCHAR(1000)=''           
    )
    AS
    /*
    功能:创建SQL作业
    参数:
        @jobname:作业名称
        @sql:要执行的命令
        @freqtype:时间周期,month 月,week 周,day 日
        @fsinterval:相对于每日的重复次数
        @time:开始执行时间,对于重复执行的作业,将从0点到23:59分
        @description:作业的描述
    */ 
    BEGIN
        DECLARE @dbname AS VARCHAR(500)
        SET @dbname=DB_NAME()
            
        BEGIN TRANSACTION
        DECLARE @ReturnCode INT
        SELECT @ReturnCode = 0
        
        --添加类别
        IF NOT EXISTS (SELECT name FROM msdb.dbo.syscategories WHERE name='添加作业' AND category_class=1)
        BEGIN
            EXEC @ReturnCode = msdb.dbo.sp_add_category @class=N'JOB', @type=N'LOCAL', @name=N'添加作业'
            IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
        END
        
        --删除作业  
        DECLARE @JobID BINARY(16)   
        DECLARE @ErrMsg NVARCHAR(500)      
        SELECT  @JobID = job_id  FROM msdb.dbo.sysjobs WHERE name = @JobName  
        IF ( @JobID IS NOT NULL )  
        BEGIN   
          -- 检查此作业是否为多重服务器作业  
          IF ( EXISTS ( SELECT * FROM msdb.dbo.sysjobservers WHERE ( job_id = @JobID ) AND ( server_id <> 0 ) ) )  
          BEGIN  
            --多重服务器作业不操作  
            SET @ErrMsg = '无法导入作业"' + @JobName + '",因为已经有相同名称的多重服务器作业。'  
            RAISERROR (@ErrMsg, 16, 1)   
            GOTO QuitWithRollback  
          END  
          ELSE  
           BEGIN  
            -- 删除[本地]作业   
            EXECUTE msdb.dbo.sp_delete_job @job_name = @JobName  
            SELECT @JobID = NULL  
           END  
         END  
    
        SET @JobID = NULL    
        EXEC @ReturnCode =  msdb.dbo.sp_add_job @job_name=@jobname, 
                @enabled=1, 
                @notify_level_eventlog=2, 
                @notify_level_email=0, 
                @notify_level_netsend=0, 
                @notify_level_page=0, 
                @delete_level=0, 
                @description=@description, 
                @category_name=N'添加作业', 
                @owner_login_name=N'sa', @job_id = @jobId OUTPUT
        IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
        /****** Object:  Step [数据同步]    Script Date: 01/25/2014 23:00:36 ******/
        EXEC @ReturnCode = msdb.dbo.sp_add_jobstep @job_id=@jobId, @step_name=@jobname, 
                @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=5, 
                @retry_interval=5, 
                @os_run_priority=0, @subsystem=N'TSQL', 
                @command= @sql, 
                @database_name=@dbname, 
                @flags=0
        IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
        EXEC @ReturnCode = msdb.dbo.sp_update_job @job_id = @jobId, @start_step_id = 1
        IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
        
        --创建调度
        declare @ftype int,@fstype int,@ffactor int
        select @ftype=case @freqtype when 'day' then 4
                                                when 'week' then 8
                                                when 'month' then 16 end
                ,@fstype=case @fsinterval when 1 then 0 else 8 end
        if @fsinterval<>1 set @time=0
        set @ffactor=case @freqtype when 'day' then 0 else 1 end
        
        EXEC msdb..sp_add_jobschedule @job_name=@jobname, 
            @name = @jobname,
            @freq_type=@ftype ,                                        
            @freq_interval=1,                                       
            @freq_subday_type=@fstype,                       
            @freq_subday_interval=@fsinterval,        
            @freq_recurrence_factor=@ffactor,
            @active_start_time=@time                         
            
        IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
        EXEC @ReturnCode = msdb.dbo.sp_add_jobserver @job_id = @jobId, @server_name = N'(local)'
        IF (@@ERROR <> 0 OR @ReturnCode <> 0) GOTO QuitWithRollback
        COMMIT TRANSACTION
        GOTO EndSave
        QuitWithRollback:
            IF (@@TRANCOUNT > 0) ROLLBACK TRANSACTION
        EndSave:
    END
    GO

           结合上一篇文章的usp_p_delDBLog,进行改造

      

    GO
    IF EXISTS(SELECT 1 FROM sysobjects WHERE id=OBJECT_ID('usp_p_delDBLog'))
    BEGIN
        DROP PROC dbo.usp_p_delDBLog
    END
    GO
    CREATE PROC usp_p_delDBLog(
        @DriveLimit AS BIGINT,
        @DBLogSise AS INT =0
    )
    /*
    *    功能:收缩当前数据库日志文件
    *    参数  @DriveLimit:当前数据库所在磁盘空间到达多少的时候进行收缩数据库  MB
    *          @DBLogSise:日志文件收缩至多少M 默认收缩到最小
    */
    AS 
    BEGIN
        IF @DBLogSise<0 OR @DriveLimit<0
        BEGIN
            RETURN
        END
        
        --当前数据库所在磁盘
        DECLARE @Drive AS VARCHAR(10)
        DECLARE @Available AS BIGINT
    
        SELECT TOP 1  @Drive=SUBSTRING(filename,1,1)  from   sysfiles
    
    
        CREATE TABLE #TempFile(
            Drive VARCHAR(10),--磁盘
            Available BIGINT --可用大小MB
        )
        INSERT INTO #TempFile(Drive,Available)
        exec master..xp_fixeddrives
    
        --查询当前数据库所在磁盘剩余空间大小
        SELECT @Available=Available FROM #TempFile
        WHERE Drive=@Drive
    
        --符合条件则进行收缩日志文件
        IF @Available<=@DriveLimit
        BEGIN
        
            --查询出数据库对应的日志文件名称
            DECLARE @strDBName AS NVARCHAR(500)
            DECLARE @strLogName AS NVARCHAR(500)
            DECLARE @strSQL AS VARCHAR(1000)
            
            SELECT 
                @strLogName=B.name,
                @strDBName=A.name
            FROM master.sys.databases AS A
            INNER JOIN sys.master_files AS B
            ON A.database_id = B.database_id
            WHERE A.database_id=DB_ID() 
                
            SET @strSQL='
            --设置数据库恢复模式为简单
            ALTER DATABASE ['+@strDBName+'] SET RECOVERY SIMPLE;
            --收缩日志文件
            DBCC SHRINKFILE ('''+@strLogName+''' , '+CONVERT(VARCHAR(20),@DBLogSise)+');
            --恢复数据库还原模式为完整
            ALTER DATABASE ['+@strDBName+'] SET RECOVERY FULL '
    
            exec(@strSQL)    
        END
        
        DROP TABLE #TempFile
    END
    GO


    这里主要添加了查询当前数据库所在磁盘空间剩余大小的功能

        --当前数据库所在磁盘
        DECLARE @Drive AS VARCHAR(10)
        DECLARE @Available AS BIGINT
    
        SELECT TOP 1  @Drive=SUBSTRING(filename,1,1)  from   sysfiles
    
    
        CREATE TABLE #TempFile(
            Drive VARCHAR(10),--磁盘
            Available BIGINT --可用大小MB
        )
        INSERT INTO #TempFile(Drive,Available)
        exec master..xp_fixeddrives
    
        --查询当前数据库所在磁盘剩余空间大小
        SELECT @Available=Available FROM #TempFile
        WHERE Drive=@Drive

    好了上面的准备工作做完以后可以通过以下SQL进行添加自动运行的作业

    --添加作业
    --作业每天间隔两小时执行一次
    --执行条件为磁盘空间不足 5000MB,即@DriveLimit=5000 可自行配置
    DECLARE @@jobname AS VARCHAR(1000)
    SELECT @@jobname=DB_NAME()+'_自动清理当前数据库日志文件'
    EXEC dbo.usp_p_CreateJob @jobname = @@jobname, -- varchar(100)
        @sql = 'EXEC usp_p_delDBLog @DriveLimit=5000,@DBLogSise=0', -- varchar(max)
        @freqtype = 'day', -- varchar(6)
        @fsinterval = 2, -- int
        @time = 235959, -- int
        @description = '自动清理当前数据库日志文件' -- varchar(1000)

    示例下载

             示例sql

      

       相关阅读:附加没有日志文件的数据库方法

                              删除数据库日志文件的方法

  • 相关阅读:
    圣杯布局,不太明白为什么后面的元素会飘上来
    CSS实现宽高成比例缩放
    javascript原生ajax;
    http-关于application/x-www-form-urlencoded等字符编码的解释说明
    jQuery判断滚动条滚到页面底部脚本
    下拉顶部刷新简单实现
    swig模板下拉框应用
    swig模板中文资料
    张宵 20200924-2 功能测试
    张宵 20200924-5 四则运算试题生成
  • 原文地址:https://www.cnblogs.com/yanweidie/p/3811035.html
Copyright © 2020-2023  润新知