一、SQL Server自動化運維 - 備份(一)業務數據庫

爲了可以恢復數據,數據庫運維基礎就是備份,備份自動化也是運維自動化首要進行的。html

筆者的備份自動化,經過配置錶快速配置爲前提同時記錄備份過程,儘量的減小人工操做。首先將SQL Server備份按用途分:sql

一、 業務數據庫備份--本文主要內容shell

SQL Server提供多種備份方式,爲業務數據庫備份選擇何種備份策略,可根據各自的數據量和業務狀況而定。數據庫

備份策略需求:服務器

  • 可恢復到備份以前的任意時間點,儘可能減小數據丟失
  • 單個備份數據庫已達TB
  • 考慮還原效率、不可追加過多的日誌

備份策略制定:網絡

  • 完整備份:每週一執行一次
  • 差別備份:天天執行一次,週一不執行
  • 日誌備份:每1小時一次
  • 備份副本:保存多份備份副本;上傳一份副本到遠程磁盤dbbackup文件夾
  • 備份歸檔:歸檔遠程磁盤備份到dbbackuphistory文件夾,只保留當月最先完整備份和全部日誌備份,刪除差別備份
  • 經過配置表控制是否備份,備份路徑等;並記錄備份信息,備份大小,開始時間,結束時間等

注:在執行完整或差別備份的同時,可同時執行日誌備份。架構

2、系統數據庫、配置數據庫、高可用配置、權限、Job、SSIS等備份;如下簡稱爲「災備」--後續文章介紹運維

   災備的目的在於,發生重大服務器故障,可迅速經過災備恢復原有配置,權限用戶等等。ide

1、備份架構

基礎備份架構如圖所示:加密

方案1、將數據先備份到所在服務器的本地磁盤,再上傳到遠程磁盤櫃(多份數據副本),最後針對磁盤櫃的備份進行歸檔處理。之因此先備份到本地,是考慮備份最好保存多份,以防止文件損壞。

方案2、若本地磁盤空間不足,或者io壓力較大,可直接備份到遠程。

2、配置表

指定兩張配置表,BackupRestoreSetting爲備份配置信息,備份路徑,上傳路徑,是否備份,是否上傳控制;BackupFileList記錄備份信息,備份文件名稱、大小、開始時間、結束時間等。

2.一、BackupRestoreSetting備份還原配置信息表

以下圖所示,插入該數據庫的備份還原配置信息,備份磁盤路徑,上傳路徑,是否備份是否上傳等信息。後續腳本封裝將讀取這些配置信息進行備份。

注:因爲還原是以備份信息爲基礎,因此配置信息須要放在一塊兒。此處暫時刻忽略還原內容。

--運維配置庫,收集本地服務器全部自動化信息;包括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]

2.二、BackupFilelist備份信息記錄表

記錄備份大小,開始時間,結束時間,上傳時間等等;以便統計和備份異常處理。

--備份信息記錄表
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

3、spx_Backup_DelFile刪除本地備份

若備份存放在本地,須要按期刪除本地備份,以防止本地磁盤不足;建議在執行完整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
spx_Backup_DelFile

 

例如:刪除本地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周

4、spx_Backup_DB備份數據庫

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
spx_Backup_DB

以上備份存儲過程可執行三種類型備份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'

4.一、備份文件命名格式

數據庫名稱_備份時間_備份模式_數據庫版本.BAK

例子:Configdb_20161009182755_LOG_P12.BAK

4.二、備份腳本解釋

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實行壓縮加密等。此處不作贅述。

4.三、遠程磁盤櫃共享配置

遠程磁盤櫃的定義即爲:某個服務器磁盤的共享文件夾,將文件夾設置爲共享,語句某個帳號讀寫,利用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
spx_netuse

例如:

--默認路徑\\' + @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'

5、spx_Backup_MoveFile歸檔歷史備份

 默認狀況下,建議全部備份上傳到遠程磁盤櫃,而磁盤櫃定義如上章節(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
spx_Backup_MoveFile

6、自動化部署

策略制定:

  • 完整備份:每週一執行一次
  • 差別備份:天天執行一次,週一不執行
  • 日誌備份:每1小時一次

6.1、新建配置表

BackupRestoreSetting

BackupFilelist

6.二、配置磁盤櫃共享

若不上傳遠程,可排除遠程共享配置;配置信息寫入的時候設置isCopy=’F’便可

spx_netuse

6.三、新建存儲過程

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
spb_Backup_DB

6.四、新建做業

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小時執行一次

支持原創,轉載請註明出處!
http://www.cnblogs.com/chhuang/p/5977312.html

相關文章
相關標籤/搜索