日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

SQL Server 大数据搬迁之文件组备份还原实战

發布時間:2024/4/15 数据库 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL Server 大数据搬迁之文件组备份还原实战 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
SQL Server 大數據搬遷之文件組備份還原實戰 原文:SQL Server 大數據搬遷之文件組備份還原實戰

一.本文所涉及的內容(Contents)

  • 本文所涉及的內容(Contents)
  • 背景(Contexts)
  • 解決方案(Solution)
  • 搬遷步驟(Procedure)
  • 搬遷腳本(SQL Codes)
  • 注意事項(Attention)
  • 疑問(Questions)
  • 參考文獻(References)
  • 二.背景(Contexts)

      有一個數據庫大概在700G左右,需要從服務器A搬遷到服務器B,兩臺服務器網絡傳輸速度可以達到8MB/s,怎么做才能更快的搬遷并且宕機時間最短呢?

      數據庫業務邏輯概述:這個數據庫只會插入數據,每天大概有300W條數據,不會對數據進行修改,只有一個表比較大,并且這個表是以自增ID作為分區依據列的,文件組會被重用,數據庫為簡單恢復模式,我定時會對表數據進行交換分區刪除數據;

    三.解決方案(Solution)

    之前我也寫過關于搬遷數據庫的一些文章:

      1. SQL Server 數據庫最小宕機遷移方案,這篇文章是通過完全備份+差異備份的方式遷移數據庫的,這種方式比較合適數據庫只有20G左右的數據庫,宕機時間=差異備份時間+傳輸差異備份時間+還原差異備份時間,一般來說這個時間都比較短,因為差異備份都不會太大;

      2. SQL Server 數據庫遷移偏方,這篇文章是通過作業的方式遷移數據庫的,一個事務中轉移N條(大約2W條)數據,N值可以通過測試進行調整(需要看網絡情況而定),這種方式比較適合數據庫比較大,比如幾百G的數據庫,而且網絡環境比較差的情況下,宕機時間≈0(當轉移最后一部分數據足夠小),缺點就是遷移的時間會比較長;

      3. 那么這篇文章我們再來講講其它方式的遷移,在上面提到的背景下,可以通過對分區文件組進行備份的方式遷移數據庫,這種方式比較適合大數據庫的遷移,宕機時間=最后一個文件組備份時間+傳輸備份時間+還原最后一個文件組時間,缺點是宕機時間會比較大,但是整體遷移的時間會比較小;下面是邏輯結構圖:

    (Figure1:文件組搬遷邏輯圖)

    四.搬遷步驟(Procedure)

      在講述搬遷步驟之前,我們首先來看看文件組的大體情況,通過下面的SQL語句可以查看文件組的相關信息,見Figure2、Figure3;

    --查看文件組信息 SELECT df.[name], df.physical_name, df.[size], df.growth, fg.[name] [filegroup], fg.is_default FROM sys.database_files df JOIN sys.filegroups fg ON df.data_space_id = fg.data_space_id

    (Figure2:文件組列表)

    (Figure3:文件組列表)

    下面就講講搬遷的步驟:

    1. 首先我們先清理下數據,把不必要的數據通過交換分區的方式交換出去;

    2. 查看這張大表當前的自增ID值,通過修改分區方案讓新插入的數據存入到一個空的文件組(因為空的文件組在最后備份會更小一點),很多情況下,文件組是會重用的,所以要注意這個文件組是空的;

    3. 設置數據庫為完整恢復模式;

    4. 備份除了上面提到的文件組,如果條件允許可以進行備份的壓縮;(動態生成SQL)

    5. 通過FTP傳輸備份文件到新的服務器;

    6. 備份主分區,需要確保這個時候不會對主分區的數據進行修改,并傳輸主分區備份文件;

    7. 先還原主分區的備份,再還原上面的文件組備份;(動態生成SQL)

    8. 對最后一個文件組進行備份,對日志進行備份,對沒有做分區對齊的索引文件組進行備份,把這3個備份傳輸到新服務器;

    9. 還原文件組,還原日志;

    五.搬遷腳本(SQL Codes)

    搬遷腳本包括兩個部分,一個備份使用的腳本,一個是還原使用的腳本:

    1. 備份腳本,根據分區情況來自動生成對應的備份腳本;

    2. 還原腳本,根據分區情況和備份文件的規則來生成對應的還原腳本,也就是說還原腳本是依據備份腳本的;

    ?

    (一) 下面是用于生成備份SQL的代碼,這個代碼需要提供兩個變量值:

    1. @DataBaseName指定需要進行備份的數據庫名,值為'Barefoot.Archives';

    2. @BackupPath在舊服務器本地備份文件組存放的地址,值為:'E:\DBBackup\';

    在舊數據庫Barefoot.Archives中執行下面的SQL腳本:

    -- ============================================= -- Author: <聽風吹雨> -- Blog: <http://gaizai.cnblogs.com/> -- Create date: <2014/02/26> -- Description: <生成分區備份腳本> -- ============================================= DECLARE @DataBaseName SYSNAME--數據庫名稱 DECLARE @BackupPath SYSNAME--保存分區備份的路徑 DECLARE @FilegroupName SYSNAME--分區文件組名稱 DECLARE @sql NVARCHAR(MAX)--sql字符串--設置下面變量 SET @DataBaseName = 'DataBaseName' SET @BackupPath = 'D:\DBBackup\'--1.設置完整模式 PRINT '--設置完整模式' SET @sql = 'USE [master] GO ALTER DATABASE ['+@DataBaseName +'] SET RECOVERY FULL WITH NO_WAIT GO' PRINT @sql + CHAR(13)--2.備份分區 DECLARE @itemCur CURSOR SET @itemCur = CURSOR FORSELECT [name] FROM sys.filegroups ORDER BY is_defaultOPEN @itemCur FETCH NEXT FROM @itemCur INTO @FilegroupName WHILE @@FETCH_STATUS=0 BEGIN--邏輯處理PRINT '--備份分區- ' + @FilegroupNameSET @sql = 'BACKUP DATABASE [' + @DataBaseName + '] FILEGROUP = ''' + @FilegroupName + ''' TO DISK = ''' + @BackupPath+@FilegroupName + '.bak'' WITH FORMAT GO'PRINT @sql + CHAR(13)FETCH NEXT FROM @itemCur INTO @FilegroupName END CLOSE @itemCur DEALLOCATE @itemCur--3.備份日志 PRINT '--備份日志' SET @sql = 'BACKUP LOG [' + @DataBaseName + '] TO DISK = ''' + @BackupPath+@DataBaseName + '_Log.bak'' WITH FORMAT GO' PRINT @sql + CHAR(13)

    上面SQL腳本的邏輯是:

    1. 首先設置數據庫的恢復模式為完整恢復模式,這是為了后面對數據庫的日志進行備份;

    2. 通過當前數據庫的系統表sys.filegroups拿到文件組的名稱,這里把默認文件排在最后面,這是因為有可能會對配置表進行的操作,所以把這個文件組放到最后備份;

    3. 使用游標的方式來循環文件組,生成文件組對應的備份SQL語句;

    4. 最后備份數據庫的日志,對文件組的還原是需要通過日志備份才能還原的;

    ?

      在舊數據庫執行上面的SQL腳本,將會產生生成下面的SQL(只保留了部分SQL):

    --設置完整模式 USE [master] GO ALTER DATABASE [DataBaseName] SET RECOVERY FULL WITH NO_WAIT GO--備份分區- FG_Archive_Id_01 BACKUP DATABASE [DataBaseName] FILEGROUP = 'FG_Archive_Id_01' TO DISK = 'D:\DBBackup\FG_Archive_Id_01.bak' WITH FORMAT GO--備份分區- FG_Archive_Id_02 BACKUP DATABASE [DataBaseName] FILEGROUP = 'FG_Archive_Id_02' TO DISK = 'D:\DBBackup\FG_Archive_Id_02.bak' WITH FORMAT GO--備份分區- FG_Archive_Index BACKUP DATABASE [DataBaseName] FILEGROUP = 'FG_Archive_Index' TO DISK = 'D:\DBBackup\FG_Archive_Index.bak' WITH FORMAT GO--備份分區- PRIMARY BACKUP DATABASE [DataBaseName] FILEGROUP = 'PRIMARY' TO DISK = 'D:\DBBackup\PRIMARY.bak' WITH FORMAT GO--備份日志 BACKUP LOG [DataBaseName] TO DISK = 'D:\DBBackup\Barefoot.Archives_Log.bak' WITH FORMAT GO

    執行完上面的腳本,會生成下圖所示的備份文件:

    (Figure4:備份文件列表)

    ?

    (二) 下面是用于生成還原SQL的代碼,這個代碼需要提供幾個變量值:

    1. @DataBaseName指定需要進行備份的數據庫名,值為'Barefoot.Archives';

    2. @BackupPath在新服務器文件組備份的地址,值為:'E:\DBBackup\';

    3. @SavePath_Drive存在數據文件的盤符,值為:'F:\';

    4. @SavePath_FolderName存放數據文件的文件夾,值為:'DataBase\';

    5. @SavePath_SubFolderName存放ndf文件的文件夾,值為:'FG_Archive\';

    6. @IsSamePath表示是否延續之前的physical_name值,值為1表示延續,這樣會使用@SavePath_Drive替換physical_name的盤符,這樣@SavePath_FolderName和@SavePath_SubFolderName就不會起作用了,值為0表示不延續,這樣physical_name的值=@SavePath_Drive+@SavePath_FolderName+@SavePath_SubFolderName;

    在舊數據庫Barefoot.Archives中執行下面的SQL腳本:

    -- ============================================= -- Author: <聽風吹雨> -- Blog: <http://gaizai.cnblogs.com/> -- Create date: <2014/02/26> -- Description: <生成分區還原腳本> -- ============================================= DECLARE @DataBaseName SYSNAME--數據庫名稱 DECLARE @BackupPath SYSNAME--保存備份文件的路徑 DECLARE @SavePath_Drive SYSNAME--保存數據庫文件的盤符 DECLARE @SavePath_FolderName SYSNAME--保存數據庫的文件夾 DECLARE @SavePath_SubFolderName SYSNAME--保存分區的文件夾 DECLARE @FilegroupName SYSNAME--分區文件組名稱 DECLARE @FileName SYSNAME--分區文件名稱 DECLARE @PhysicalName SYSNAME--物理路徑 DECLARE @IsSamePath INT--是否跟遠路徑一樣1,0 DECLARE @sql NVARCHAR(MAX)--sql字符串--設置下面變量 SET @DataBaseName = 'DataBaseName' SET @BackupPath = 'E:\DBBackup\' SET @SavePath_Drive = 'F:\' SET @SavePath_FolderName = 'DataBase\' SET @SavePath_SubFolderName = 'FG_Archive\' SET @IsSamePath = 1--1.還原主分區 SELECT @FilegroupName = [name] FROM sys.filegroups WHERE is_default = 1 PRINT '--還原主分區' SET @sql = 'RESTORE DATABASE [' + @DataBaseName + '] FILEGROUP = ''' + @FilegroupName + ''' FROM DISK = ''' + @BackupPath + @FilegroupName + '.bak'' WITH FILE = 1, MOVE N''' + @DataBaseName + ''' TO N''' + @SavePath_Drive + @SavePath_FolderName + @DataBaseName + '.mdf'', MOVE N''' + @DataBaseName + '_log'' TO N''' + @SavePath_Drive + @SavePath_FolderName + @DataBaseName + '_log.ldf'', NORECOVERY,REPLACE,STATS = 10 GO' PRINT @sql + CHAR(13)--2.還原分區 DECLARE @itemCur CURSOR SET @itemCur = CURSOR FORSELECT df.[name] AS FileName, df.physical_name, fg.[name] AS FilegroupNameFROM sys.database_files dfJOIN sys.filegroups fgON df.data_space_id = fg.data_space_idWHERE fg.is_default = 0OPEN @itemCur FETCH NEXT FROM @itemCur INTO @FileName,@PhysicalName,@FilegroupName WHILE @@FETCH_STATUS=0 BEGIN--邏輯處理PRINT '--還原分區- ' + @FilegroupNameIF @IsSamePath = 0SET @PhysicalName = @SavePath_Drive + @SavePath_FolderName + @SavePath_SubFolderName + '\' + @FileName + '.ndf'ELSESET @PhysicalName = @SavePath_Drive + SUBSTRING(@PhysicalName,CHARINDEX('\',@PhysicalName)+1,LEN(@PhysicalName))SET @sql = 'RESTORE DATABASE [' + @DataBaseName + '] FILEGROUP = ''' + @FilegroupName + ''' FROM DISK = ''' + @BackupPath+@FilegroupName + '.bak'' WITH FILE = 1, MOVE N''' + @FileName + ''' TO N''' + @PhysicalName + ''', NORECOVERY GO'PRINT @sql + CHAR(13)FETCH NEXT FROM @itemCur INTO @FileName,@PhysicalName,@FilegroupName END CLOSE @itemCur DEALLOCATE @itemCur--3.還原日志 PRINT '--還原日志' SET @sql = 'RESTORE LOG [' + @DataBaseName + '] FROM DISK = ''' + @BackupPath + @DataBaseName + '_Log.bak'' WITH NORECOVERY GO' PRINT @sql + CHAR(13)--4.還原在線 PRINT '--還原在線' SET @sql = 'RESTORE DATABASE [' + @DataBaseName + '] WITH RECOVERY GO' PRINT @sql + CHAR(13)

    上面SQL腳本的邏輯是:

    1. 通過系統表sys.filegroups找到默認文件組,先還原這個主文件;

    2. 使用游標的方式來循環系統表sys.filegroups,拿到文件組名稱,生成文件組對應的還原SQL語句;

    3. 接著還原數據庫的日志;

    4. 最后還原在線,讓數據庫在線;

    ?

    執行上面的SQL腳本,將會產生生成下面的SQL(只保留了部分SQL):

    --還原主分區 RESTORE DATABASE [DataBaseName] FILEGROUP = 'PRIMARY' FROM DISK = 'E:\DBBackup\PRIMARY.bak' WITH FILE = 1, MOVE N'Barefoot.Archives' TO N'F:\DataBase\Barefoot.Archives.mdf', MOVE N'Barefoot.Archives_log' TO N'F:\DataBase\Barefoot.Archives_log.ldf', NORECOVERY,REPLACE,STATS = 10 GO--還原分區- FG_Archive_Id_01 RESTORE DATABASE [DataBaseName] FILEGROUP = 'FG_Archive_Id_01' FROM DISK = 'E:\DBBackup\FG_Archive_Id_01.bak' WITH FILE = 1, MOVE N'FG_Archive_Id_01_data' TO N'F:\DataBase\FG_Archive\FG_Archive_Id_01_data.ndf', NORECOVERY GO--還原分區- FG_Archive_Id_02 RESTORE DATABASE [DataBaseName] FILEGROUP = 'FG_Archive_Id_02' FROM DISK = 'E:\DBBackup\FG_Archive_Id_02.bak' WITH FILE = 1, MOVE N'FG_Archive_Id_02_data' TO N'F:\DataBase\FG_Archive\FG_Archive_Id_02_data.ndf', NORECOVERY GO--還原分區- FG_Archive_Index RESTORE DATABASE [DataBaseName] FILEGROUP = 'FG_Archive_Index' FROM DISK = 'E:\DBBackup\FG_Archive_Index.bak' WITH FILE = 1, MOVE N'FG_Archive_Index_data' TO N'F:\DataBase\Barefoot.Archives\FG_Archive_Index_data.ndf', NORECOVERY GO--還原日志 RESTORE LOG [DataBaseName] FROM DISK = 'E:\DBBackup\Barefoot.Archives_Log.bak' WITH NORECOVERY GO--還原在線 RESTORE DATABASE [DataBaseName] WITH RECOVERY GO

    在新服務器上執行上面的SQL腳本還原數據庫,需要注意的是:在還原在線之前數據庫都是一直處于:正在還原的狀態的;

    六.注意事項(Attention)

    1. 在實際運用中,可以結合本文和SQL Server 數據庫遷移偏方進行靈活結合運用,當通過本文件組備份后,舊庫繼續進數據,在花銷時間最大的網絡傳輸過程和還原過程繼續對老庫進數據,這樣當還原好數據庫之后使用SQL Server 數據庫遷移偏方來轉移最新的數據,這樣宕機的時間會趨向于0;

    2. 其實為了確保某些文件組不被修改,可以設置文件組的只讀屬性,這樣可以確保只有某個文件組在進新數據,可惜的是設置了只讀也無法拷貝這些文件組文件通過FTP傳輸,提示:操作無法完成,因為文件已在SQL Server(MSSQLSERVER)中打開。

    3. 上面腳本的每個文件組中只包含了一個文件,如果一個文件組包含多個文件,那就需要修改下腳本了;

    4. 高文佳曾經說過,可以先刪除索引,再壓縮備份,還原之后再創建索引,是的,這不防是一個好方法,不過需要考慮兩點,一個是在還原之后創建索引的速度與時間,如果磁盤速度不算快,那你就要考慮刪除索引是否適合了;另外一點是你的數據庫是否能停機讓你刪除索引,這個跟具體的業務有關;

    七.疑問(Questions)

      1. 對primary進行完整文件組備份(作為基備份),對FG1進行完整文件組備份(作為基備份)這些描述有問題吧?對primary進行完整文件組備份應該不會生成基線的吧? SQL文件組備份和還原

      2. 如果在同一個文件組中有兩個以上的分區值,就是把兩個段的分區方案中同指向同一個分區文件組,那在備份和還原有什么需要注意的呢?能成功備份還原嘛?

    --備份分區 DECLARE @FileName VARCHAR(200) SET @FileName = 'G:\DBBackup\FG_Archive_Id_05_null.bak' BACKUP DATABASE [DataBaseName] FILEGROUP='FG_Archive_Id_05' TO DISK=@FileName WITH FORMAT GO--還原分區 RESTORE DATABASE [DataBaseName] FILEGROUP='FG_Archive_Id_05' FROM DISK='E:\DBBackup\FG_Archive_Id_05_null.bak' WITH FILE = 1, MOVE N'FG_Archive_Id_05_data' TO N'E:\DataBase\FG_Archive\FG_Archive_Id_05_data.ndf', NORECOVERY GO

      解答:從備份和還原的代碼可以看出只是把FILEGROUP與bak對應,與ndf文件對應,所以是不需要理會這個文件組中包含了多少個邏輯分區;

    八.參考文獻(References)

    SQL文件組備份和還原

    Sql Server 系統表分析(1) - 備份表

    如何還原到故障點 (Transact-SQL)

    backupset (Transact-SQL)

    posted on 2018-02-01 15:49 NET未來之路 閱讀(...) 評論(...) 編輯 收藏

    轉載于:https://www.cnblogs.com/lonelyxmas/p/8399416.html

    總結

    以上是生活随笔為你收集整理的SQL Server 大数据搬迁之文件组备份还原实战的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。