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