在上一篇文章中介绍了如何删除数据库日志文件,但是想想还是不是不方便需要手工操作,于是想结合作业实现自动清理日志文件,在清理日志文件时我加上了条件,当磁盘控空间不足多少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

  

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

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

posted on 2014-06-26 23:29  焰尾迭  阅读(4301)  评论(0编辑  收藏  举报