爲了可以恢復數據,數據庫運維基礎就是備份,備份自動化也是運維自動化首要進行的。html
筆者的備份自動化,經過配置錶快速配置爲前提,同時記錄備份過程,儘量的減小人工操做。首先將SQL Server備份按用途分:sql
一、 業務數據庫備份--本文主要內容shell
SQL Server提供多種備份方式,爲業務數據庫備份選擇何種備份策略,可根據各自的數據量和業務狀況而定。數據庫
備份策略需求:服務器
備份策略制定:網絡
注:在執行完整或差別備份的同時,可同時執行日誌備份。架構
2、系統數據庫、配置數據庫、高可用配置、權限、Job、SSIS等備份;如下簡稱爲「災備」--後續文章介紹運維
災備的目的在於,發生重大服務器故障,可迅速經過災備恢復原有配置,權限用戶等等。ide
基礎備份架構如圖所示:加密
方案1、將數據先備份到所在服務器的本地磁盤,再上傳到遠程磁盤櫃(多份數據副本),最後針對磁盤櫃的備份進行歸檔處理。之因此先備份到本地,是考慮備份最好保存多份,以防止文件損壞。
方案2、若本地磁盤空間不足,或者io壓力較大,可直接備份到遠程。
指定兩張配置表,BackupRestoreSetting爲備份配置信息,備份路徑,上傳路徑,是否備份,是否上傳控制;BackupFileList記錄備份信息,備份文件名稱、大小、開始時間、結束時間等。
以下圖所示,插入該數據庫的備份還原配置信息,備份磁盤路徑,上傳路徑,是否備份是否上傳等信息。後續腳本封裝將讀取這些配置信息進行備份。
注:因爲還原是以備份信息爲基礎,因此配置信息須要放在一塊兒。此處暫時刻忽略還原內容。
--運維配置庫,收集本地服務器全部自動化信息;包括dmv,擴展事件,計數器,備份,平常維護腳本封裝等。 USE [Configdb] GO --備份還原配置表 CREATE TABLE [dbo].[BackupRestoreSetting]( [Servername] [sysname] NOT NULL,--服務器名稱 [DBname] [sysname] NOT NULL,--數據庫名稱 [V_DBname] [nvarchar](128) NULL,--還原數據庫名稱 [Backup_drive] [char](1) NULL,--備份磁盤 [Backup_path] [varchar](100) NULL,--備份路徑 [Restore_drive] [char](1) NULL,--還原磁盤 [Restore_path] [varchar](100) NULL,--還原路徑 [Copy_path] [varchar](100) NULL,--上傳路徑 [IsBackup] [char](1) NULL,--是否備份 [IsCopy] [char](1) NULL,--是否上傳 [IsRestore] [char](1) NULL,--是否還原 [RestoreStatus] [char](1) NULL,--還原狀態 [Priority] [smallint] NULL,--還原優先級 [Net_Ip] [varchar](100) NULL,--遠程磁盤櫃IP CONSTRAINT [PK_BackupRestoreSetting] PRIMARY KEY CLUSTERED ( [Servername] ASC, [DBname] ASC ) ) ON [PRIMARY]
記錄備份大小,開始時間,結束時間,上傳時間等等;以便統計和備份異常處理。
--備份信息記錄表 CREATE TABLE [dbo].[BackupFilelist]( [id] [int] IDENTITY(1,1) NOT NULL, [Servername] [varchar](50) NULL,--服務器名稱 [Dbname] [varchar](50) NULL,--數據庫名稱 [Backupset] [varchar](4) NULL,--備份模式,完整FULL 差別DIFF 日誌LOG [Filename] [varchar](100) NULL,--備份文件名稱 [Filesize] [varchar](20) NULL,--備份文件大小 [Backup_start_time] [datetime] NULL,--備份開始時間 [Backup_end_time] [datetime] NULL,--備份結束時間 [Copy_end_time] [datetime] NULL,--上傳開始時間 [Copy_status] [char](1) NULL,--上傳狀態 [ReCopyTimes] [int] NULL,--重複上傳次數 [Media_set_id] [int] NULL,--上傳文件meidaid [Error_Msg] [varchar](max) NULL,--錯誤信息 [Cmd] [varchar](max) NULL,--上傳命令 CONSTRAINT [PK_BackupFilelist] PRIMARY KEY CLUSTERED ( [id] ASC ) ) GO
若備份存放在本地,須要按期刪除本地備份,以防止本地磁盤不足;建議在執行完整FULL備份以前來刪除本地備份,以保證可快速還原完整備份以後的任意時間點。
刪除本地備份腳本spx_Backup_DelFile
USE [Configdb] GO /****************************** 功能描述:<本地備份文件刪除> * 建立者:<HuangCH〉 * 建立日期:<2015-12-03> * 備註說明:<@Retain_weeks 保留週數,默認所有刪除> ########## Change Log ########## Date Changer Description -------------------------------------------------- <2015-12-03> <HuangCH> <新建> -------------------------------------------------- ***************************/ CREATE PROCEDURE [dbo].[spx_Backup_DelFile] @servername [SYSNAME], @dbname [SYSNAME], @Retain_weeks INT=0 AS SET nocount on ----=============================== DECLARE @retcode INT DECLARE @cmd VARCHAR(2000) DECLARE @backup_drive CHAR(1)--本地備份磁盤 DECLARE @backup_path VARCHAR(200)--本地備份路徑' SELECT @backup_drive = backup_drive, @backup_path = backup_path FROM dbo.BackupRestoreSetting WITH (nolock) WHERE servername=@servername and dbname = @dbname IF @Retain_weeks=0 BEGIN --刪除備份 SET @cmd='del '+@backup_drive +':\'+@backup_path+'\'+ @dbname + '_??????????????_*_???.bak' EXEC master..Xp_cmdshell @cmd END ELSE IF @Retain_weeks>0 BEGIN DECLARE @delday Datetime SET @delday=CONVERT(VARCHAR,DATEADD(WEEK,-@Retain_weeks,GETDATE()),23) WHILE @delday>=DATEADD(WEEK,-@Retain_weeks-3,GETDATE()) BEGIN SET @delday=DATEADD(D,-1,@delday) SET @cmd='del '+@backup_drive +':\'+@backup_path+'\'+ @dbname + '_'+CONVERT(VARCHAR,@delday,112)+'*_*_???.bak' EXEC master..Xp_cmdshell @cmd END END
例如:刪除本地sqlmonitor服務器下configdb備份;插入配置信息,傳入@servername和@dbname 可刪除某個數據庫的本地備份
USE Configdb GO --插入配置信息 INSERT INTO [dbo].[BackupRestoreSetting](Servername,DBname,V_DBname,Backup_drive,Backup_path,Restore_drive,Restore_path,Copy_path,IsBackup,IsCopy) VALUES('sqlmonitor','configdb','configdb','d','backup','d','sqldasta','m:\dbbackup\sqlmonitor','T','F') GO --完整備份:確認d:\backup目錄是否存在 EXEC spx_Backup_DelFile @servername='sqlmonitor',@dbname='configdb',@Retain_weeks=0--默認爲0,若1值則多保留1周
USE [Configdb] GO GO /****************************** 功能描述:<備份數據庫> * 建立者:<HuangCH〉 * 建立日期:<2015-12-03> * 備註說明:< 一、備份類型只能是"FULL","DIFF","LOG"' > ########## Change Log ########## Date Changer Description -------------------------------------------------- <2015-12-03> <HuangCH> <新建> -------------------------------------------------- ***************************/ ALTER proc [dbo].[spx_Backup_DB] @servername [varchar](50), @dbname [sysname], @backupset [varchar](4) as ----肯定linkedserver是否正常 --DECLARE @servername [VARCHAR](50), -- @dbname [SYSNAME], -- @backupset [VARCHAR](4) /*確認參數信息是否正確*/ IF @backupset NOT IN ('full','log','diff') BEGIN PRINT '''' + Upper(@backupset) + ''' is not a valid value for argument @backupset.' RETURN -1000 END IF Db_id(@dbname) IS NULL BEGIN PRINT 'Database ''' + @dbname + ''' not found.' RETURN -2000 END IF NOT EXISTS(SELECT TOP 1 1 FROM dbo.BackupRestoreSetting WHERE servername = @servername AND dbname = @dbname) BEGIN RAISERROR ('備份還原配置表信息不存在,請確認',16,1) RETURN -4000 END DECLARE @version VARCHAR(4)--sql server版本 DECLARE @Backup_dirve CHAR(1)--備份磁盤 DECLARE @backup_path VARCHAR(1000)--備份路徑 DECLARE @copy_path VARCHAR(50)--上傳路徑 DECLARE @IsCopy CHAR(1)--是否已經上傳 DECLARE @filename VARCHAR(2000)--備份文件名稱 DECLARE @retcode INT DECLARE @errorMessage VARCHAR(2000) DECLARE @netdevice CHAR(1) DECLARE @net_ip VARCHAR(20) DECLARE @id INT DECLARE @cmd VARCHAR(4000) /*肯定數據庫版本*/ SET @version =CASE WHEN CONVERT(VARCHAR(20),Serverproperty('ProductVersion')) LIKE '9.0%' THEN '05' WHEN CONVERT(VARCHAR(20),Serverproperty('ProductVersion')) LIKE '10%' THEN '08' WHEN CONVERT(VARCHAR(20),Serverproperty('ProductVersion')) LIKE '11%' THEN '12' WHEN CONVERT(VARCHAR(20),Serverproperty('ProductVersion')) LIKE '12%' THEN '14' ELSE '16' END SELECT @Backup_dirve = backup_drive, @backup_path = backup_path, @copy_path = copy_path, @IsCopy = IsCopy, @net_ip = net_ip FROM dbo.BackupRestoreSetting WITH (NOLOCK) WHERE servername = @servername AND dbname = @dbname /*肯定備份文件名稱*/ SET @filename = @dbname + '_' + REPLACE(REPLACE(REPLACE(CONVERT(VARCHAR(19),Getdate(),21),'-',''),' ',''),':','') + '_' + Upper(@backupset) + '_P' + @version + '.bak' /*肯定本地備份路徑*/ SET @backup_path = @Backup_dirve + ':\' + @backup_path + '\' + @filename /*記錄備份文件基本信息,和備份開始時間*/ INSERT INTO dbo.BackupFilelist ( Servername, Dbname, Backupset, Filename, Filesize, Backup_start_time, Backup_end_time, Copy_end_time, Copy_status, ReCopyTimes, Media_set_id ) VALUES (@servername, @dbname, @backupset, @filename, NULL, Getdate(), NULL, NULL, NULL, NULL, NULL) /*取記錄id號*/ SET @ID=SCOPE_IDENTITY() /*開始備份(log,full),覆蓋現有備份集*/ BEGIN TRY IF @backupset='FULL' BEGIN SET @cmd='BACKUP DATABASE ['+@dbname+'] TO DISK='''+@backup_path+CASE WHEN CONVERT(VARCHAR(20),Serverproperty('ProductVersion')) LIKE '9.0%' THEN ''' WITH INIT' ELSE ''' WITH INIT,COMPRESSION' END END ELSE IF @backupset='DIFF' BEGIN SET @cmd='BACKUP DATABASE ['+@dbname+'] TO DISK='''+@backup_path+CASE WHEN CONVERT(VARCHAR(20),Serverproperty('ProductVersion')) LIKE '9.0%' THEN ''' WITH INIT,DIFFERENTIAL' ELSE ''' WITH INIT,COMPRESSION,DIFFERENTIAL' END END ELSE BEGIN SET @cmd='BACKUP LOG ['+@dbname+'] TO DISK='''+@backup_path+CASE WHEN CONVERT(VARCHAR(20),Serverproperty('ProductVersion')) LIKE '9.0%' THEN ''' WITH INIT' ELSE ''' WITH INIT,COMPRESSION' END END --PRINT @cmd EXEC (@cmd) END TRY BEGIN CATCH SELECT @retcode = @@ERROR, @errorMessage = Error_message() UPDATE dbo.BackupFilelist SET Error_Msg=@errorMessage, Cmd=@cmd WHERE id = @id RAISERROR (@errorMessage,16,1) RETURN @retcode END CATCH /*記錄備份結束時間*/ UPDATE dbo.BackupFilelist SET backup_end_time = Getdate(), media_set_id = (SELECT TOP 1 media_set_id FROM msdb.dbo.backupmediafamily WITH (nolock) ORDER BY media_set_id Desc), Cmd=@cmd WHERE id = @id /*記錄備份文件大小*/ DECLARE @filesize VARCHAR(20), @tempString VARCHAR(400) SET @cmd = 'DIR ' + @backup_path CREATE TABLE #tbl (line NVARCHAR(255)) INSERT INTO #tbl EXEC master.dbo.Xp_cmdshell @cmd SELECT @tempString = line FROM #tbl WHERE line LIKE '%' + @filename + '%' IF (@tempString LIKE '%:__ _M %') --like '%:__ AM %' OR @tempString like '%:__ PM %') SELECT @filesize = REPLACE(Rtrim(Ltrim(Substring(@tempString,Charindex(':',@tempString) + 6, Charindex(@filename,@tempString) - Charindex(':',@tempString) - 6))), ',','') ELSE SELECT @filesize = REPLACE(Rtrim(Ltrim(Substring(@tempString,Charindex(':',@tempString) + 3, Charindex(@filename,@tempString) - Charindex(':',@tempString) - 3))), ',','') UPDATE dbo.BackupFilelist SET filesize = @filesize WHERE id = @id /*開始上傳備份文件*/ DECLARE @ReCopyTimes INT SET @ReCopyTimes = 0 RECOPYFLAG: IF @IsCopy = 'T' BEGIN /*映射@netdevice遠程*/ SELECT @netdevice = Substring(Ltrim(@copy_path),1,1) BEGIN TRY EXEC spx_NetUse @drive = @netdevice output, @ip = @net_ip END TRY BEGIN CATCH SELECT @errorMessage = Error_message() RAISERROR (@errorMessage,16,1) RETURN -5000 END CATCH /*確認拷貝路徑是否存在*/ SELECT @cmd = 'DIR ' + @netdevice + Substring(@copy_path,2,Len(@copy_path)) EXEC @retcode = master..Xp_cmdshell @cmd IF @@ERROR = 0 AND @retcode <> 0 BEGIN SELECT @cmd = 'MD ' + @netdevice + Substring(@copy_path,2,Len(@copy_path)) EXEC @retcode = master..Xp_cmdshell @cmd END SET @cmd = 'copy ' + @backup_path + ' ' + @netdevice + Substring(@copy_path,2,Len(@copy_path)) EXEC @retcode = master..Xp_cmdshell @cmd IF @retcode <> 0 BEGIN SET @ReCopyTimes = @ReCopyTimes + 1 UPDATE dbo.BackupFilelist SET recopytimes = @reCopyTimes,Copy_status='F' WHERE id = @id PRINT '時間:' + CAST(Getdate() AS VARCHAR) + ' 從新copy次數:' + CAST(@reCopyTimes AS VARCHAR) --輸出重試次數 /*刪除@netdevice映射*/ SELECT @cmd = 'net use ' + @netdevice + ':' + ' /delete /y' EXEC master..Xp_cmdshell @cmd IF (@reCopyTimes < 5) --最多重試五次 GOTO recopyflag ELSE --大於5次即五次copy都失敗,則報錯 BEGIN SELECT @errorMessage = ' 自定義錯誤:' + @backup_path + ' 沒法拷貝到' + @netdevice + Substring(@copy_path,2,Len(@copy_path)) RAISERROR (@ErrorMessage,16,1) RETURN @retcode END END /*記錄上傳時間*/ UPDATE dbo.BackupFilelist SET Copy_end_time = Getdate(),Copy_status='T',ReCopyTimes=@ReCopyTimes WHERE id = @id END /*刪除@netdevice映射*/ SELECT @cmd = 'net use ' + @netdevice + ':' + ' /delete /y' EXEC master..Xp_cmdshell @cmd RETURN 0
以上備份存儲過程可執行三種類型備份FULL,LOG,DIFF;
一、在執行此存儲過程以前,須要確認以上兩個配置表是否已經創建。
二、存儲過程內部調用spx_netuse;進行遠程共享映射,具體原理以下章節(4.三、上傳遠程磁盤櫃)
例如:添加sqlmonitor下configdb的備份;只備份到本地,不上傳遠程
USE Configdb GO --插入配置信息 INSERT INTO [dbo].[BackupRestoreSetting](Servername,DBname,V_DBname,Backup_drive,Backup_path,Restore_drive,Restore_path,Copy_path,IsBackup,IsCopy) VALUES('sqlmonitor','configdb','configdb','d','backup','d','sqldasta','m:\dbbackup\sqlmonitor','T','F') GO --完整備份:確認d:\backup目錄是否存在 EXEC spx_Backup_DB @servername='sqlmonitor',@dbname='configdb',@backupset='FULL' --差別備份 EXEC spx_Backup_DB @servername='sqlmonitor',@dbname='configdb',@backupset='DIFF' --日誌備份 EXEC spx_Backup_DB @servername='sqlmonitor',@dbname='configdb',@backupset='LOG'
數據庫名稱_備份時間_備份模式_數據庫版本.BAK
例子:Configdb_20161009182755_LOG_P12.BAK
BACKUP DATABASE ['+@dbname+'] TO DISK ='''+@backup_path+ ''' WITH INIT,COMPRESSION
4.2.1、INIT
若已存在相同名稱備份文件,覆蓋該文件片;默認爲追加NOINIT
4.2.2、COMPRESSION
壓縮會消耗必定的io和cpu資源;相比壓縮帶來的好處,建議使用壓縮備份。
好處:備份文件減小10倍;備份效率提升4倍,帶寬壓力減小。--2005版本不包括
4.2.3、加密
加密備份是很是有必要,可是SQL Server2012並無提供備份加密,可用rar實行壓縮加密等。此處不作贅述。
遠程磁盤櫃的定義即爲:某個服務器磁盤的共享文件夾,將文件夾設置爲共享,語句某個帳號讀寫,利用netuse 命令完成腳本映射後,便可經過cmd命令來完成腳本拷貝刪除等命令。
4.3.1、共享文件夾設置
在磁盤櫃上配置共享文件夾,例如:DBADataSource文件夾共享配置,容許BackupRestoreUser讀寫。
4.3.2、經過net use 命令映射
--映射共享X: \\192.168.1.1\DBADataSource EXEC master.dbo.xp_cmdshell 'net use x: \\192.168.1.1\DBADataSource "pwd" /user:"BackupRestoreUser"' --查詢映射 EXEC master.dbo.xp_cmdshell 'net use'
經過net use 完成映射磁盤,可供備份使用,封裝成存儲過程spx_netuse
USE [Configdb] GO CREATE PROC [dbo].[spx_netuse] @drive CHAR(1) OUTPUT, @ip VARCHAR(20), @directory VARCHAR(1000) = '' WITH ENCRYPTION AS DECLARE @cmd VARCHAR(2000) DECLARE @retcode int DECLARE @netusetempdrives TABLE(drive CHAR(1),unused VARCHAR(100),status NVARCHAR(20)) DECLARE @netusetemp TABLE(strs VARCHAR(2000)) DECLARE @errormessges VARCHAR(MAX) DECLARE @unuseddrives TABLE(drive char(1)) DECLARE @FLAG INT SET @FLAG = 0 INSERT INTO @unuseddrives --排除ABCDEFG、Q SELECT 'I' UNION SELECT 'J' UNION SELECT 'K' UNION SELECT 'L' UNION SELECT 'M' UNION SELECT 'N' UNION SELECT 'O' UNION SELECT 'P' UNION SELECT 'R' UNION SELECT 'S' UNION SELECT 'T' UNION SELECT 'U' UNION SELECT 'V' UNION SELECT 'W' UNION SELECT 'X' UNION SELECT 'Y' UNION SELECT 'Z' IF @ip IS NULL OR @ip NOT LIKE '%.%.%.%' OR @ip LIKE '%[a-Z]%' BEGIN SET @retcode =1000 RAISERROR('NetUse IP IS Not Found',16,1) RETURN @retcode END IF @directory IS NOT NULL AND @directory<>'' AND Charindex(':\',@directory) > 1 BEGIN SET @drive = LEFT(Ltrim(Rtrim(@directory)),1) END --本地使用的磁盤 INSERT INTO @netusetempdrives (drive,unused) EXEC master.dbo.Xp_fixeddrives --已經映射的網絡磁盤 INSERT INTO @netusetemp(strs) EXEC master.dbo.Xp_cmdshell 'net use' --將全部已經被使用的磁盤彙總 INSERT INTO @netusetempdrives (drive,status) SELECT Ltrim(Rtrim(Substring(strs,Charindex(' ',strs),Charindex(':',strs) - Charindex(' ',strs)))), Ltrim(Rtrim(LEFT(strs,10))) + '-netuse' FROM @netusetemp WHERE strs LIKE '%[a-Z]:%' --若是存在已經斷開的映射,則刪除磁盤 IF EXISTS (SELECT TOP 1 1 FROM @netusetempdrives WHERE drive = LEFT(Ltrim(Rtrim(@drive)),1) AND status LIKE '%已斷開-netuse%' AND status LIKE '%不可用-netuse%') BEGIN SELECT @cmd = 'master..xp_cmdshell ''net use ' + LEFT(Ltrim(Rtrim(@directory)),1) + ': /del''' EXEC @cmd DELETE FROM @netusetempdrives WHERE drive = LEFT(Ltrim(Rtrim(@drive)),1) AND status LIKE '%已斷開-netuse%' AND status LIKE '%不可用-netuse%' END DELETE FROM @unuseddrives WHERE drive IN (SELECT drive from @netusetempdrives) IF EXISTS (SELECT TOP 1 1 FROM @netusetempdrives WHERE drive = LEFT(Ltrim(Rtrim(@drive)),1) AND status NOT LIKE '%已斷開-netuse%' and status NOT LIKE '%不可用-netuse%') --磁盤已經被映射 or @drive is null BEGIN IF NOT EXISTS (SELECT TOP 1 1 FROM @unuseddrives) BEGIN SET @retcode =3000 --RAISERROR('再也不有可映射磁盤!!!',16,1) RETURN @retcode END SELECT TOP 1 @drive = drive FROM @unuseddrives ORDER BY NEWID() DELETE FROM @unuseddrives WHERE drive =@drive END SELECT @cmd = 'net use ' + @drive + ': \\' + @ip + '\DBADataSource' + Substring(Ltrim(Rtrim(isnull(@directory,''))),3,Len(isnull(@directory,''))) + ' "pwd" /user:"BackupRestoreUser"' ReNetUse:--重複映射 BEGIN TRY EXEC @retcode = master..xp_cmdshell @cmd END TRY BEGIN CATCH SET @retcode = 4000 IF @FLAG = 0 BEGIN WAITFOR DELAY '00:00:10' SET @FLAG =1 GOTO ReNetUse END END CATCH RETURN @retcode
例如:
--默認路徑\\' + @ip + '\DBADataSource' --映射:映射x :\\192.168.1.1\DBADataSource exec [dbo].[spx_netuse] @drive='X',@ip='192.168.1.1' --映射:映射x :\\192.168.1.1\DBADataSource;若x盤已經映射,則自動分配,並output 到@drive declare @drive char(1)='X' exec [dbo].[spx_netuse] @drive=@drive output,@ip='192.168.1.1' --映射:映射x :\\192.168.1.1\DBADataSource\dbbackup;若x盤已經映射,則自動分配,並output 到@drive exec [dbo].[spx_netuse] @drive='X',@ip='192.168.1.1',@directory='x:\dbbackup'
默認狀況下,建議全部備份上傳到遠程磁盤櫃,而磁盤櫃定義如上章節(4.四、上傳遠程磁盤櫃)
與「本地備份刪除」相似,建議歸檔在每次完整備份執行以前歸檔掉。
歸檔策略:
一、dbbackup文件夾:存放當前備份文件;由配置表BackupRestoreSetting的copy_path字段決定。
二、dbbackuphistory\2016\201610文件夾:保留每一個數據庫當月最先完整備份和全部日誌備份
USE [Configdb] GO /****************************** 功能描述:<歸檔備份文件> * 建立者:<HuangCH〉 * 建立日期:<2015-12-03> * 備註說明:<> ########## Change Log ########## Date Changer Description -------------------------------------------------- <2015-12-03> <HuangCH> <新建> -------------------------------------------------- ***************************/ CREATE PROC [dbo].[spx_Backup_MoveFile] @servername [SYSNAME], @dbname [SYSNAME] AS SET NOCOUNT ON --/*確認參數傳遞是否正確*/ IF Db_id(@dbname) IS NULL BEGIN PRINT 'The database ' + @dbname + 'can not found' RETURN -1000 END /*確認配置表信息是否存在*/ IF NOT EXISTS (SELECT TOP 1 1 FROM dbo.BackupRestoreSetting WITH (nolock) WHERE servername = @servername AND dbname = @dbname) BEGIN RAISERROR ('backuprestoresetting配置表信息不存在,請確認',16,1) RETURN -2000 END DECLARE @retcode INT DECLARE @copy_path VARCHAR(2000) DECLARE @copy_pathTO VARCHAR(2000)--遷移路徑 DECLARE @redo int--遷移路徑 SET @redo=0 DECLARE @IsCopy CHAR(1) DECLARE @IsBackup CHAR(10) DECLARE @netdevice CHAR(1)--網絡磁盤映射 DECLARE @net_ip VARCHAR(20) DECLARE @cmd VARCHAR(2000) DECLARE @date VARCHAR(10) DECLARE @ErrorMsg VARCHAR(MAX) SET @ErrorMsg='' --配置信息 SELECT @copy_path = copy_path, @IsCopy = IsCopy, @IsBackup = IsBackup, @net_ip = net_ip FROM dbo.BackupRestoreSetting WITH (nolock) WHERE servername = @servername AND dbname = @dbname IF @IsCopy = 'T' BEGIN /*添加@netdevice映射*/ SET @netdevice = Substring(Ltrim(@copy_path),1,1) EXEC spx_NetUse @drive = @netdevice output, @ip = @net_ip SET @copy_path=@netdevice + Substring(@copy_path,2,Len(@copy_path)) SET @date=CONVERT(VARCHAR(6),GETDATE(),112) redo:--備份歸檔入口 SET @copy_pathTO=@netdevice + ':\dbbackuphistory\'+CONVERT(VARCHAR(4),@date,112)+'\'+ @date+'\'+@servername --當前路徑是否存在 SET @cmd = 'DIR ' + @copy_pathTO EXEC @retcode = master..Xp_cmdshell @cmd PRINT @cmd IF @@ERROR = 0 AND @retcode <> 0 BEGIN SELECT @cmd = 'MD ' + @copy_pathTO EXEC @retcode = master..Xp_cmdshell @cmd --PRINT @cmd END ELSE--存在路徑 BEGIN --FULL 是否存在 SET @cmd = 'DIR ' + @copy_pathTO+'\'+ @dbname + '_'+@date+'*_FULL_*.BAK' --PRINT @cmd EXEC @retcode = master.dbo.Xp_cmdshell @cmd IF @@ERROR = 0 AND @retcode = 0 BEGIN --刪除FULL SET @cmd = 'DEL ' + @copy_path+ '\' + @dbname + '_'+@date+'*_FULL_*.BAK' EXEC @retcode = master.dbo.Xp_cmdshell @cmd --PRINT @cmd END END --刪除DIFF SET @cmd = 'DEL ' + @copy_path+ '\' + @dbname + '_'+@date+'*_DIFF_*.BAK' EXEC @retcode = master.dbo.Xp_cmdshell @cmd --PRINT @cmd /*遷移備份文件數據*/ BEGIN TRY SET @cmd='MOVE '+ @copy_path+ '\' + @dbname + '_'+@date+'*.BAK '+@copy_pathTO EXEC @retcode = master.dbo.Xp_cmdshell @cmd --PRINT @cmd IF @redo=0--上個月的轉移 BEGIN SET @date=CONVERT(VARCHAR(6),dateadd(mm,-1,GETDATE()),112) SET @redo=1 GOTO redo END END TRY BEGIN CATCH /*刪除@netdevice映射*/ SET @ErrorMsg=@ErrorMsg+@dbname+'歸檔失敗:'+ERROR_MESSAGE() END CATCH /*刪除@netdevice映射*/ WAITFOR DELAY '00:00:10' SELECT @cmd = 'net use ' + @netdevice + ':' + ' /delete /y' EXEC master.dbo.Xp_cmdshell @cmd END IF @ErrorMsg <> '' BEGIN RAISERROR (@ErrorMsg,16,1) END
策略制定:
BackupRestoreSetting
BackupFilelist
若不上傳遠程,可排除遠程共享配置;配置信息寫入的時候設置isCopy=’F’便可
spx_netuse
spx_Backup_DelFile
spx_Backup_DB
spx_Backup_MoveFile
以上存儲過程爲單個數據庫的備份處理,自動化還需根據以上策略封裝一層,方便Job調用和管理員維護。具體以下存儲過程spb_Backup_DB
USE [Configdb] GO /****** Object: StoredProcedure [dbo].[spb_Backup_DB] Script Date: 2016/10/19 16:12:48 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO /****************************** 功能描述:<自動備份> * 建立者:<HuangCH〉 * 建立日期:<2015-12-03> * 備註說明:< 一、備份類型只能是"FULL OR DIFF","LOG"' 二、若須要單獨執行備份,須要調用spx_Backup_DB 三、默認每週一FULL 其餘時間爲DIFF > ########## Change Log ########## Date Changer Description -------------------------------------------------- <2015-12-03> <HuangCH> <新建> -------------------------------------------------- ***************************/ CREATE PROC [dbo].[spb_Backup_DB] @servername SYSNAME,--服務器名稱@@servername @backupset VARCHAR(10),--備份類型 @Retain_weeks INT =0 AS IF @backupset NOT IN ('FULL&DIFF','LOG') BEGIN PRINT '@backupset備份類型只能是"FULL&DIFF","LOG"' RETURN -1000 END -- IF @servername <> @@SERVERNAME -- BEGIN -- PRINT '@servername服務器與本機服務器名稱[' + @@SERVERNAME + ']不一樣' -- RETURN -2000 -- END DECLARE @dbname SYSNAME DECLARE @cmd VARCHAR(1000) DECLARE @errormessage VARCHAR(1000) SET @errormessage = '' IF EXISTS (SELECT TOP 1 1 FROM dbo.BackupRestoreSetting WITH (nolock) WHERE servername = @servername AND IsBackup<>'F') BEGIN IF (@backupset = 'LOG') BEGIN --if not exists( --select top 1 1 --from msdb.dbo.sysjobs a join msdb.dbo.sysjobactivity b on a.job_id = b.job_id --where a.name like '%完整備份%' and b.start_execution_date is not null and b.stop_execution_date is null) begin --定義遊標 DECLARE cur_autoback CURSOR FOR SELECT dbname FROM BackupRestoreSetting WITH (nolock) WHERE servername = @servername AND dbname IN (SELECT name FROM sys.databases WHERE recovery_model <> 3--篩選簡單恢復模式 AND state = 0) AND IsBackup<>'F' OPEN cur_autoback FETCH NEXT FROM cur_autoback INTO @dbname WHILE @@FETCH_STATUS = 0 BEGIN BEGIN TRY --備份 SET @cmd = 'dbo.spx_Backup_DB @servername=''' + @servername + ''',@dbname=''' + @dbname + ''',@backupset=''' + @backupset + '''' EXEC( @cmd) END TRY BEGIN CATCH SET @errormessage = @errormessage+'自動備份' + @backupset + '失敗: ' + Error_message() END CATCH FETCH NEXT FROM cur_autoback INTO @dbname END CLOSE cur_autoback DEALLOCATE cur_autoback end END IF (@backupset = 'FULL&DIFF') BEGIN --定義遊標 DECLARE cur_autoback CURSOR FOR SELECT dbname FROM dbo.BackupRestoreSetting WITH (nolock) WHERE servername = @servername AND dbname IN (SELECT name FROM sys.databases WHERE state = 0)--ONline數據庫的備份 AND IsBackup<>'F' OPEN cur_autoback FETCH NEXT FROM cur_autoback INTO @dbname WHILE @@FETCH_STATUS = 0 BEGIN BEGIN TRY SET DATEFIRST 7 IF datepart(WEEKDAY,getdate())= 2--週一完整備份 BEGIN --歸檔 SET @backupset='FULL' SET @cmd = 'dbo.spx_Backup_MoveFile @servername=''' + @servername + ''',@dbname=''' + @dbname + '''' EXEC( @cmd) --刪除本地備份 SET @cmd = 'dbo.spx_Backup_DelFile @servername=''' + @servername + ''',@dbname=''' + @dbname + ''',@Retain_weeks=' + CONVERT(VARCHAR(10),@Retain_weeks) EXEC( @cmd) --備份 SET @cmd = 'dbo.spx_Backup_DB @servername=''' + @servername + ''',@dbname=''' + @dbname + ''',@backupset=''' + @backupset + '''' EXEC( @cmd) END ELSE BEGIN SET @backupset='DIFF' --備份 SET @cmd = 'dbo.spx_Backup_DB @servername=''' + @servername + ''',@dbname=''' + @dbname + ''',@backupset=''' + @backupset + '''' EXEC( @cmd) END END TRY BEGIN CATCH SET @errormessage = @errormessage+'自動備份' + @backupset + '失敗: ' + Error_message() END CATCH FETCH NEXT FROM cur_autoback INTO @dbname END CLOSE cur_autoback DEALLOCATE cur_autoback END END IF @errormessage<>'' BEGIN RAISERROR (@errormessage,16,1) END RETURN 0
6.4.1 完整差別備份
步驟1、spb_Backup_DB @servername='sqlmonitor',@backupset='FULL&DIFF'
執行計劃、天天12點執行一次
6.4.2 日誌備份
步驟1、spb_Backup_DB @servername='sqlmonitor',@backupset='LOG'
執行計劃、每1小時執行一次
支持原創,轉載請註明出處! |