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


    焰尾迭 的基础上修改

    他的代码有一些缺陷,没法做到批量清理多个数据库日志,只能删除master日志,或者存储过程所在的数据库。

     可以把两个存储过程都建在master数据库,使用sa账户执行。

    1.先建立清理日志存储过程(此处代码做了修改,正式使用时也注意结合自己的数据库服务器)

    USE [master]
    GO
    /****** Object:  StoredProcedure [dbo].[usp_p_delDBLog]    Script Date: 02/14/2019 09:35:01 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER PROC [dbo].[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
    
        --查询当前数据库所在磁盘剩余空间大小,
    --此处查询的master所在的磁盘,(可能是C盘)
    --可能跟使用的数据库不在一个盘符,传参数时注意@DriveLimit的值
    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) --使用游标,批量清理类型为log的文件 declare B_Cursor cursor FOR SELECT B.name, A.name FROM master.sys.databases AS A INNER JOIN sys.master_files AS B ON A.database_id = B.database_id WHERE B.[type]=1 -- [type]=1为日志文件 open B_Cursor; fetch next from B_Cursor into @strLogName ,@strDBName while @@FETCH_STATUS =0 begin SET @strSQL=' use ['+@strDBName+']; -- 不适用use报错 --设置数据库恢复模式为简单 ALTER DATABASE ['+@strDBName+'] SET RECOVERY SIMPLE; --收缩日志文件 DBCC SHRINKFILE ('''+@strLogName+''' , '+CONVERT(VARCHAR(20),@DBLogSise)+'); --恢复数据库还原模式为完整 ALTER DATABASE ['+@strDBName+'] SET RECOVERY FULL ' --print @strDBName --print @strDBName --print @strSQL exec(@strSQL) fetch next from B_Cursor into @strLogName ,@strDBName end close B_Cursor; deallocate B_Cursor; END DROP TABLE #TempFile END

    2.创建SQL作业的存储过程(创建作业代码没有修改)

    USE [master]
    GO
    /****** Object:  StoredProcedure [dbo].[usp_p_CreateJob]    Script Date: 02/14/2019 11:36:13 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER 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

    3.在SQL中执行作业添加

    --添加作业
    --作业每天间隔两小时执行一次
    --执行条件为磁盘空间不足 50000MB,即@DriveLimit=50000 可自行配置
    DECLARE @@jobname AS VARCHAR(1000)
    SELECT @@jobname=DB_NAME()+'_自动清理当前数据库日志文件'
    EXEC dbo.usp_p_CreateJob @jobname = @@jobname, -- varchar(100)
        @sql = 'EXEC usp_p_delDBLog @DriveLimit=50000,@DBLogSise=0', -- varchar(max)
        @freqtype = 'day', -- varchar(6)
        @fsinterval = 2, -- int
        @time = 235959, -- int
        @description = '自动清理当前数据库日志文件' -- varchar(1000)
  • 相关阅读:
    C++学习9 this指针详解
    福建省第八届 Triangles
    UVA 11584 Partitioning by Palindromes
    POJ 2752 Seek the Name, Seek the Fame
    UVA 11437 Triangle Fun
    UVA 11488 Hyper Prefix Sets (字典树)
    HDU 2988 Dark roads(kruskal模板题)
    HDU 1385 Minimum Transport Cost
    HDU 2112 HDU Today
    HDU 1548 A strange lift(最短路&&bfs)
  • 原文地址:https://www.cnblogs.com/AlexLeeLi/p/10373849.html
Copyright © 2020-2023  润新知