backup(full,diff,log)备份并清理过时备份

需求说明:每天备份数据库,但是备份文件长期积累不删除,极大的浪费磁盘空间,

针对该情况做了2个sp来解决


 

备份sp: dbo.dba_db_backup

可以做全备,差备,日志备

备份的目录格式 YYYYMMDD_FULL/DF/LOG

/*
editor:Lynn
function desc: 
    backup full/diff database   backup log 
    backupdir @bakpath\YYYYMMDD_FULL/DF/LOG
exec demo:
EXEC DBO.dba_db_backup 
EXEC DBO.dba_db_backup  N'lynntest,SSB3',N'D:\DbBak',N'FULL'
*/
create PROC DBO.dba_db_backup
 @db_list nvarchar(2000)=NUll    -- NULL:all db except system db,  N'lynntest,SSB3'
    ,@bakpath nvarchar(1000)=N'D:\BackupDB'    --N'D:\bak'
    ,@backupType nvarchar(4)=N'FULL'    --DEFAULT: FULL   --FULL全备份  DF差异备份 LOG日志备份
AS
BEGIN 
set nocount on;
/*
    select @db_list=N'lynntest,SSB3'
            ,@bakpath =N'D:\bak'
            ,@backupType=N'LOG'  --DB全备份  DF差异备份 LOG日志备份
*/

    declare  @dblist table (id int identity(1,1), db  sysname)
    IF @db_list IS NOT NULL
    BEGIN
        insert into @dblist(db)
        select  T.name
        from(

            SELECT
                        name = PARSENAME(
                                        LTRIM(RTRIM(T.c.value('.[1]', 'sysname'))),
                                        1
                                )
                    FROM(
                        SELECT
                            database_name_list = CONVERT(xml,
                                                        N'<c><![CDATA[' 
                                                        + REPLACE(
                                                            REPLACE(
                                                                REPLACE(
                                                                    @db_list,
                                                                    CHAR(13),
                                                                    CHAR(10)
                                                                ),
                                                                CHAR(10),
                                                                N','
                                                            ),
                                                            N',',
                                                            N']]></c><c><![CDATA['
                                                        )
                                                        + N']]></c>'
                                                    )
        
                    )REQ
                        CROSS APPLY REQ.database_name_list.nodes('/c/text()') T(c) 
                ) T
                inner join sys.databases d
                    on T.name=d.name  and d.state=0
                WHERE T.name > N''
        END
    ELSE
    BEGIN
        insert into @dblist(db)
        select name
        from sys.databases with(nolock)
        WHERE state in ( 0 )  --OFFLINE
        --==============you can filter the system database or not
        and name not in( 'master', 'tempdb', 'model', 'msdb','distribution' );
    END
    
        declare @currnpath NVARCHAR(520)
            ,@subpath  nvarchar(200)

        select @subpath=LTRIM( RTRIM(convert(  char(8) ,getdate() ,112)+'_'+@backupType))
            ,@currnpath=  @bakpath+'\'+@subpath+'\'  --RTRIM( @bakpath+'\'+@subpath+'\')


        DECLARE @temp table(subdirectory varchar(500),depth int)
        INSERT @temp
        exec xp_dirtree @bakpath
        --select * from @temp

        IF NOT EXISTS(
            SELECT *
            FROM @temp where LTRIM( RTRIM(subdirectory))=@subpath
        )
        --创建目录
        EXEC master.sys.xp_create_subdir @currnpath

        DECLARE @tunid  int,@db sysname,@sql nvarchar(max)
        while exists(select * from @dblist)
        BEGIN
            select @tunid=0,@db=null,@sql=null
            select top(1) @tunid =id,@db=db from @dblist 
            select @sql='BACKUP '+ CASE @backupType 
                                        WHEN N'log ' THEN N'LOG '
                                        ELSE N'DATABASE '
                                    END+ @db +char(10)+'TO DISK =N'''+@currnpath+@db
                                    +CASE @backupType 
                                        WHEN N'log' THEN N'.trn'' '
                                        ELSE N'.bak'' '
                                    END+CHAR(10)
                                    +CASE @backupType 
                                        WHEN N'DF' THEN N'  WITH DIFFERENTIAL, COMPRESSION '
                                        ELSE N'  WITH COMPRESSION '
                                    END
            --PRINT @sql
            EXEC(@sql)
            DELETE TOP(1)  @dblist
            WHERE ID=@tunid
        END


END
View Code

 

删除文件目录sp:dbo.dba_db_backup_delDir

删除以上sp生成的格式化目录 ,

/*
editor:Lynn
function dec:
    delete expired backup dirs
exec demo:
  exec dba_db_backup_delDir N'D:\DbBak'    ,N'FULL',1    

*/
alter proc dbo.dba_db_backup_delDir
    @bakpath nvarchar(1000)=N'D:\BackupDB'    --N'D:\bak'
    ,@backupType varchar(10)=N'FULL'    --DEFAULT: FULL   --FULL全备份  DF差异备份 LOG日志备份
    ,@n int=2                     --保留最近n次相关备份
AS
BEGIN
    SET NOCOUNT ON
    if object_id('tempdb.dbo.#temp','U') IS NOT NULL
        DROP TABLE #temp
    CREATE table #temp (id int identity(1,1),subdirectory varchar(500),depth int,backupType  varchar(10),backupdate date,isdel int)
    INSERT #temp(subdirectory,depth)
    exec xp_dirtree @bakpath


    update #temp
    set subdirectory=rtrim(ltrim(subdirectory))

    update #temp
    set 
        backupType=right(subdirectory,len(subdirectory)-9)
        ,backupdate=cast(left(subdirectory,8) as date)

    delete  #temp
    where backupType<>@backupType

    declare @sql nvarchar(max)
    select @sql=N'update  a 
        set isdel=0
    from #temp a
    inner join 
    (
        select top (@top) id  from #temp 
        where 
            backupdate<=getdate()  and backupType=@backupType1 
        order by backupdate desc
    )b
    on b.id=a.id'
    exec sp_executesql @sql,N'@top int,@backupType1 varchar(10)', @top=@n,@backupType1=@backupType
    --select * from #temp
    declare @errortb table(id int identity(1,1),errorinfo nvarchar(200))
    declare @turnid int,@subdirectory varchar(500)
    while exists (select * from #temp where isdel is null)
    begin
        select @turnid=null,@subdirectory=null
        select top(1) @turnid=id ,@subdirectory=subdirectory  from #temp where isdel is null

        --print @bakpath +'\'+ @subdirectory
        insert into @errortb(errorinfo)
        EXEC('xp_cmdshell ''rd /s/q  ' + @bakpath +'\'+ @subdirectory + '''')
        delete #temp where id=@turnid    
    end
    --select * from @errortb order by id

END
View Code

note:

1 创建JOb定时备份和清理目录,可以采用 dbo.dba_db_backup调用dbo.dba_db_backup_delDir简化job创建

2 sp中有创建和删除目录,所以需要开启高级选项

 

-- 允许配置高级选项
EXEC sp_configure 'show advanced options', 1
GO
-- 重新配置
RECONFIGURE
GO
-- 启用xp_cmdshell
EXEC sp_configure 'xp_cmdshell', 1
GO
--重新配置
RECONFIGURE
GO
View Code

 

posted @ 2016-08-17 17:26  simplelg17  阅读(621)  评论(0编辑  收藏  举报