代码改变世界

sqlserver 2008 R2容灾方案:另一种思路-1

2012-04-19 10:40  java环境变量  阅读(404)  评论(1编辑  收藏  举报

自己的定义的容灾方案,可以根据自己的需要自己定义.

1.源数据库备份数据

 

说明:
使用方法:exec master.dbo.fullbackup1 's:\backup','suzhou','full'


0.备份类型只能是full、diff或log,数据库名不能为空

1.通过新建一个历史表记录每次备份内容

2.检查数据库版本是否为2005以上

3.检查当前用户是否有权限完成备份


4.会自动检查指定盘符是否存在

5.检查指定格式是否为s:\

6.如果指定的备份目录不存在proc将自动新建,根据备份类型为full、diff或log

7.检查备份数据库名suzhou是否存在并联机

8.检查备份数据库名suzhou不能是临时数据库

9.如果备份类型为差异备份则检查是否有完全备份存在并且备份的这个文件存在于指定的目录下,
如果备份历史表有记录但是该备份文件不存在将终止备份

10.如果备份类型为日志备份,先检查数据库恢复模式是否为完整,否则将停止备份;
将进一步检查备份历史表和备份文件,必须存在完全备份或差异备份,否则终止备份

 


USE [msdb]
GO
if OBJECT_ID('backuphistory')is not null
drop table backuphistory
go
CREATE TABLE [dbo].[backuphistory](
 [sid] [int] IDENTITY(1,1) NOT NULL primary key,
 [dbname] [sysname] NOT NULL,
 [backtype] [char](2) NOT NULL,
 [lastbackup] [datetime] NOT NULL,
 [backupdesc] [varchar](20) NOT NULL,
 [backupfilename] [nvarchar](max) NULL,
)
GO

use master
go
create PROCEDURE [dbo].[fullbackup1]
(
@backupPath varchar(500),
@dbname sysname,
@backuptype varchar(100)
)
with encryption
as

declare @currentuser sysname
declare @role varchar(30)
select   @currentuser=system_user

DECLARE @Version numeric(18,10)
DECLARE @Error int
declare @Directory nvarchar(100)
DECLARE @CheckDirectory nvarchar(4000)
DECLARE @DirectoryInfo TABLE (FileExists bit,
                                FileIsADirectory bit,
                                ParentDirectoryExists bit)
DECLARE @ErrorMessage nvarchar(max)
DECLARE @backupPath2 nvarchar(500)
DECLARE @DirTree TABLE (subdirectory nvarchar(255), depth INT)
DECLARE @FullPath varchar(1000)
declare @backupPath3 nvarchar(500)
declare @recovery_model_desc varchar(20)
declare @backtype varchar(100)
declare @backupdesc varchar(20)
declare @backupfilename varchar(max)

-----new
DECLARE @tmp TABLE (backupfilename varchar(3000),
                                backuptime datetime)
declare @fullbafile varchar(3000)
declare @result int
declare @log_start int


set nocount on

--检查用户权限
select @role=srvrole from
(
select SrvRole = g.name, MemberName = u.name
  from sys.server_principals u, sys.server_principals g, sys.server_role_members m
 where g.principal_id = m.role_principal_id
   and u.principal_id = m.member_principal_id
   and u.name=@currentuser
   ) c
  --order by 1, 2
if @role !='sysadmin' or @role is null or @role=''
begin
  RAISERROR('当前用户没有需要的权限完成备份!',16,1)
  print '你可能是越权操作或其它!'+char(13)+'请联系DBA!'
  SET @Error = @@ERROR
  return
end


--检查服务器版本
SET @Error = 0
SET @Version = CAST(LEFT(CAST(SERVERPROPERTY('ProductVersion') AS nvarchar(max)),
CHARINDEX('.',CAST(SERVERPROPERTY('ProductVersion') AS nvarchar(max))) - 1) + '.'
+ REPLACE(RIGHT(CAST(SERVERPROPERTY('ProductVersion') AS nvarchar(max)),
LEN(CAST(SERVERPROPERTY('ProductVersion') AS nvarchar(max))) - CHARINDEX('.',
CAST(SERVERPROPERTY('ProductVersion') AS nvarchar(max)))),'.','') AS numeric(18,10))
IF @Version < 9
BEGIN
  RAISERROR('该备份方案仅支持 SQL Server 2005, SQL Server 2008和SQL Server 2008 R2.',16,1)
  SET @Error = @@ERROR
  return
END

 

set @Directory=@backupPath

--判断路径格式
  IF NOT (@Directory LIKE '[a-z]:\%' )
  BEGIN
    SET @ErrorMessage = '输入的目录'+@Directory+'格式'+ '不支持!.'+' 参考类型如: s:\backup' + CHAR(13) + CHAR(10)
    RAISERROR(@ErrorMessage,16,1) WITH NOWAIT
    SET @Error = @@ERROR
    return
  END

--判断输入的数据库名是否存在

  IF @dbname not in(select name from sys.databases)
  BEGIN
    SET @ErrorMessage = '数据库名: '+@dbname+' 不存在!.' + CHAR(13) + CHAR(10)
    RAISERROR(@ErrorMessage,16,1) WITH NOWAIT
    SET @Error = @@ERROR
    return
  END


--判断输入的盘符是否存在和是否新建目录
--检查指定盘符是否存在

SET @CheckDirectory = substring(@Directory,1,3)
INSERT INTO @DirectoryInfo (FileExists, FileIsADirectory, ParentDirectoryExists)
EXECUTE [master].dbo.xp_fileexist @CheckDirectory
IF NOT EXISTS (SELECT * FROM @DirectoryInfo WHERE FileExists = 0 AND FileIsADirectory = 1 AND ParentDirectoryExists = 1)
  BEGIN
    SET @ErrorMessage = '服务器上不存在指定的盘符:'+upper(substring(@CheckDirectory,1,1)+ CHAR(13) + CHAR(10))
    RAISERROR(@ErrorMessage,16,1) WITH NOWAIT
    SET @Error = @@ERROR
    return
 END

 

--判断是否输入备份数据库名
IF @dbname IS NULL OR @dbname = ''
  BEGIN
    SET @ErrorMessage = '未输入任何备份数据库名.' + CHAR(13) + CHAR(10)+'备份进程已终止!'
    RAISERROR(@ErrorMessage,16,1) WITH NOWAIT
    SET @Error = @@ERROR
    return
  END

else if (@dbname='tempdb' or @dbname='TEMPDB')
 begin
 SET @ErrorMessage = '临时数据库不需要备份.' + CHAR(13) + CHAR(10)+'备份进程已终止!'
    RAISERROR(@ErrorMessage,16,1) WITH NOWAIT
    SET @Error = @@ERROR
    return
 end
else if (@dbname  in ( select name from sys.databases where state_desc='OFFLINE' or state_desc='offline'))
 begin
 SET @ErrorMessage = '脱机的数据库'+@dbname+'不需要备份.' + CHAR(13) + CHAR(10)+'备份进程已终止!'
    RAISERROR(@ErrorMessage,16,1) WITH NOWAIT
    SET @Error = @@ERROR
    return
 end

--判断输入类型
if  @backuptype not in ('full','diff','log')
begin
 print '#########################严重警告###############严重警告#################################'
 print '不支持类型'+@backuptype+'!   只能输入(full:完全备份; diff:差异备份; log:日志备份)                        '
 print '有问题请联系ocpyang!'
 print '#########################严重警告###############严重警告###################################'
 return
end

 

--判断目录是否存在
SET @backupPath2=@backupPath+'\'+@dbname
INSERT INTO @DirTree(subdirectory, depth)
EXEC master.sys.xp_dirtree @backupPath
IF NOT EXISTS (SELECT 1 FROM @DirTree WHERE subdirectory = @DBName)
begin
 print '系统将新建目录:'+@backupPath2+' ............' 
   EXEC master.dbo.xp_create_subdir @backupPath2
   print '目录:'+@backupPath2+'新建成功!'
   print '         '
   delete from  @DirTree
end
else
begin
 print '----------------------------------------------------------------------- '
 print '目录:'+@backupPath2+'已经存在!'
 print '                                                                        '+char(13)+'备份运行中$$$$$$$$$$$$$$$$$$$$$$$$$$$$$'
 print '----------------------------------------------------------------------- '
 delete from  @DirTree
end


--开始完全备份
if @backuptype='full'
begin
print '.............................................................................'
print '开始完全备份.....请稍等'
print '.............................................................................'
--隐藏检查目录
set @backupPath3=@backupPath2+'\'+'full'
INSERT INTO @DirTree(subdirectory, depth)
EXEC master.sys.xp_dirtree @backupPath3
IF NOT EXISTS (SELECT 1 FROM @DirTree WHERE subdirectory = @backupPath3)
EXEC master.dbo.xp_create_subdir @backupPath3
delete from @DirTree
set @FullPath = @backuppath3+'\'+@dbname+'_'+@backuptype+'_'+replace(replace(replace(convert(varchar,getdate(),20),'-',''),' ',''),':','')+ '.bak'
backup database @dbname to disk=@FullPath
WITH buffercount = 20, maxtransfersize = 2097152 ,
COMPRESSION,RETAINDAYS=15,NOFORMAT,NOINIT,
NAME=N'完整备份',SKIP,NOREWIND,
NOUNLOAD,STATS=10

set @backtype='D'
set @backupdesc='完全备份'
set @backupfilename=@FullPath
insert into msdb.dbo.backuphistory
(dbname,backtype,lastbackup,backupdesc,backupfilename)
values(@dbname, @backtype,GETDATE(), @backupdesc,@backupfilename)
    SET @Error = @@ERROR
    if @Error !=0
    begin
    SET @ErrorMessage = '数据库'+@dbname+'完全备份未顺利完成!: ' + CHAR(13) + CHAR(10)
    RAISERROR(@ErrorMessage,16,1) WITH NOWAIT
    return
    end
  
print '                                                                    '
print '----------------------------------------------------------------------- '
print @dbname+'完全备份 '+@FullPath+' 已经完成!'
print '----------------------------------------------------------------------- '
return
end

--开始差异备份
else if @backuptype='diff'
begin
 print '                                                                             '
 print '.............................................................................'
    print '开始差异备份.....请稍等'
    print '.............................................................................'
    --检查是否有完全备份并存在
 insert into @tmp                        
 select top 1  a.backupfilename,
 MAX(a.lastbackup)  as backuptime from msdb.dbo.backuphistory a
 where a.dbname=@dbname and a.backtype='D'
 group by backupfilename
 order by a.backupfilename desc
 if not exists (select top 1 1 from @tmp )
    begin
    SET @ErrorMessage = '数据库'+@dbname+'没有完全备份历史记录!!' + CHAR(13) + CHAR(10)
    RAISERROR(@ErrorMessage,16,1) WITH NOWAIT
    return
    end
 else
 begin 
     select @fullbafile=backupfilename from @tmp
     exec xp_fileexist @fullbafile, @result output
  if (@result=0 )
  begin
  SET @ErrorMessage = '数据库'+@dbname+'完全备份文件不存在!做差异备份无意义!' + CHAR(13) + CHAR(10)
  RAISERROR(@ErrorMessage,16,1) WITH NOWAIT
  return
  end
     end


    --隐藏检查目录
 set @backupPath3=@backupPath2+'\'+'diff'
 INSERT INTO @DirTree(subdirectory, depth)
 EXEC master.sys.xp_dirtree @backupPath3
 IF NOT EXISTS (SELECT 1 FROM @DirTree WHERE subdirectory = @backupPath3)
 EXEC master.dbo.xp_create_subdir @backupPath3
 delete from @DirTree
 set @FullPath = @backuppath3+'\'+@dbname+'_'+@backuptype+'_'+replace(replace(replace(convert(varchar,getdate(),20),'-',''),' ',''),':','')+ '.diff'
 backup database @dbname to disk=@FullPath
 WITH buffercount = 30, maxtransfersize = 2097152 ,
 COMPRESSION, DIFFERENTIAL,RETAINDAYS=8,NOFORMAT,NOINIT,
 NAME=N'差异备份',SKIP,NOREWIND,
 NOUNLOAD,STATS=10
 
 set @backtype='I'
 set @backupdesc='差异备份'
 set @backupfilename=@FullPath
 insert into msdb.dbo.backuphistory
 (dbname,backtype,lastbackup,backupdesc,backupfilename)
 values(@dbname, @backtype,GETDATE(), @backupdesc,@backupfilename)
    SET @Error = @@ERROR
    if @Error !=0
    begin
    SET @ErrorMessage = '数据库'+@dbname+'差异备份未顺利完成!: ' + CHAR(13) + CHAR(10)
    RAISERROR(@ErrorMessage,16,1) WITH NOWAIT
    return
    end
 
 
 print '                                                                    '
   print '----------------------------------------------------------------------- '
   print @dbname+'差异备份 '+@FullPath+' 已经完成!'
  print '----------------------------------------------------------------------- '
  return
end
 
 
--开始日志备份
else  if @backuptype='log'
begin
 print '                                                                        '
    print '检查环境.....请稍等..'
    print '                                                                        '
    --检查数据库恢复模式
 select @recovery_model_desc=recovery_model_desc from sys.databases
 where name=@dbname
 if @recovery_model_desc not in ('full')
 begin
 print '########错误信息######################################################'
 print '                                                                         '+char(13)+'请检查数据库'+@dbname+'的恢复模式!'+char(13)+ '使用命令ALTER DATABASE'+@dbname+' SET RECOVERY FULL WITH NO_WAIT修改!'
 print '                                                                         '
 print '########错误信息######################################################'
 print '                                                                         '+char(13)+'日志备份已终止!'
 return
 end
    print '.........................................................................'
 print '                                                                         '
    print '开始日志备份.....请稍等'
    print '                                                                         '
    print '.........................................................................'
   
    --检查是否有完全备份或差异备份
   -------------------------------------------------------------------------
   
        --检查是否有完全备份并存在
   

set  @log_start=0  
insert into @tmp                        
select top 1  a.backupfilename,
MAX(a.lastbackup)  as backuptime from msdb.dbo.backuphistory a
where a.dbname=@dbname and a.backtype='D'
group by backupfilename
order by a.backupfilename desc
if not exists (select top 1 1 from @tmp)
    begin
  set  @log_start=1
    end
else
 begin 
    select @fullbafile=backupfilename from @tmp
    exec xp_fileexist @fullbafile, @result output
  if (@result=0 )
  begin
   set  @log_start=2
  end

  end
 
  --检查是否有差异备份并存在
insert into @tmp                        
select top 1  a.backupfilename,
MAX(a.lastbackup)  as backuptime from msdb.dbo.backuphistory a
where a.dbname=@dbname and a.backtype='I'
group by backupfilename
order by a.backupfilename desc
if not exists (select top 1 1 from @tmp)
    begin
 set  @log_start=3
    end
else
 begin 
    select @fullbafile=backupfilename from @tmp
    exec xp_fileexist @fullbafile, @result output
  if (@result=0 )
  begin
   set  @log_start=4
  end
 end

if @log_start !=0
begin
    SET @ErrorMessage = '数据库'+@dbname+'没有完全备份或差异备份!: ' + CHAR(13) + CHAR(10)
    RAISERROR(@ErrorMessage,16,1) WITH NOWAIT
    return
end


   
   
   
   
   
    ------------------------------------------------------------------------------
   
    --隐藏检查目录
    set @backupPath3=@backupPath2+'\'+'log'
    INSERT INTO @DirTree(subdirectory, depth)
 EXEC master.sys.xp_dirtree @backupPath3
 IF NOT EXISTS (SELECT 1 FROM @DirTree WHERE subdirectory = @backupPath3)
 EXEC master.dbo.xp_create_subdir @backupPath3
 delete from @DirTree
 --开始备份
 set @FullPath = @backuppath3+'\'+@dbname+'_'+@backuptype+'_'+replace(replace(replace(convert(varchar,getdate(),20),'-',''),' ',''),':','')+ '.trn'
 backup log @dbname to disk=@FullPath WITH COMPRESSION,RETAINDAYS=3,NOFORMAT,NOINIT,
 NAME=N'日志备份',SKIP,NOREWIND,
 NOUNLOAD,STATS=10
 
 set @backtype='L'
 set @backupdesc='日志备份'
 set @backupfilename=@FullPath
 insert into msdb.dbo.backuphistory
 (dbname,backtype,lastbackup,backupdesc,backupfilename)
 values(@dbname, @backtype,GETDATE(), @backupdesc,@backupfilename)
    SET @Error = @@ERROR
    if @Error !=0
    begin
    SET @ErrorMessage = '数据库'+@dbname+'日志备份未顺利完成!: ' + CHAR(13) + CHAR(10)
    RAISERROR(@ErrorMessage,16,1) WITH NOWAIT
    return
    end
 
 
  print '                                                                    '
   print '-------------------------------------------------------------------------'
   print @dbname+'日志备份 '+@FullPath+' 已经完成!'
  print '---------------------------------------------------------------------------'
  return
end
set nocount off
GO