一、目的
在做SQL Server數據庫維護的時候,當上司要求我們把幾十G的數據文件搬動到其它服務器,並且要求最小宕機時間的時候,我們有沒什麼方案可以做到這些要求呢?
在這裏我們假設這兩臺機器並不是在一個機房上,這樣看起來我們的解決方案才更有意義,如果你那麼好運這兩臺機器在同一個局域網,那麼恭喜你,你可以多很多的方案可以做到。
二、分析與設計思路
其實我們假設的環境有兩個特點:第一個是數據庫文件比較大;第二個就是我們的傳送文件的速度可能會比較慢。也許這傳送速度我們是沒有辦法了,但是我們可以就從文件的大小這個問題出發,結合SQL Server的特性,這樣就有了下面的解決方案了。
爲了使宕機時間最短,我們這裏使用了完整備份和差異備份來遷移數據庫,在白天的時候對需要遷移的數據庫進行一次完整備份(XXX_full.bak),並把備份文件拷貝(這裏可以使用FTP軟件進行斷點續傳)到目標服務器進行還原,等到下班時間之後再進行一次差異備份(XXX_diff.bak),再把這個差異備份拷貝到目標服務器,在完整還原的基礎上再進行差異還原。
這裏的宕機時間 = 差異備份時間 + 傳送差異備份文件時間 + 還原差異備份文件時間,這宕機時間是不是讓你感覺這時間很短呢?
三、參考腳本
注意修改下面腳本中數據庫的名稱,還有絕對路徑。
--1:完整備份 declare @dbname varchar(100) declare @sql nvarchar(max) set @dbname = 'DataBaseName' set @sql = ' --'+@dbname+'_full BACKUP DATABASE ['+@dbname+'] TO DISK = ''D:\DBBackup\'+@dbname+'_full.bak'' WITH NOFORMAT, NOINIT, NAME = '''+@dbname+'-完整數據庫備份'', SKIP, NOREWIND, NOUNLOAD, STATS = 10 GO' print @sql --生成的SQL --DataBaseName_full BACKUP DATABASE [DataBaseName] TO DISK = 'D:\DBBackup\DataBaseName_full.bak' WITH NOFORMAT, NOINIT, NAME = 'DataBaseName-完整數據庫備份', SKIP, NOREWIND, NOUNLOAD, STATS = 10 GO |
--2:完整備份還原 declare @dbname varchar(100) declare @sql nvarchar(max) set @dbname = 'DataBaseName' set @sql = ' --RESTORE '+@dbname+'_full RESTORE DATABASE ['+@dbname+'] FROM DISK = ''D:\DBBackup\'+@dbname+'_full.bak'' WITH FILE = 1, MOVE N''DataBase_Name'' TO N''D:\DataBase\'+@dbname+'.mdf'', MOVE N''DataBase_Name_log'' TO N''D:\DataBase\'+@dbname+'_log.ldf'', NORECOVERY, NOUNLOAD, REPLACE, STATS = 10 GO' print @sql --生成的SQL --RESTORE DataBaseName_full RESTORE DATABASE [DataBaseName] FROM DISK = 'D:\DBBackup\DataBaseName_full.bak' WITH FILE = 1, MOVE N'DataBase_Name' TO N'D:\DataBase\DataBaseName.mdf', MOVE N'DataBase_Name_log' TO N'D:\DataBase\DataBaseName_log.ldf', NORECOVERY, NOUNLOAD, REPLACE, STATS = 10 GO |
--3:差異備份 declare @dbname varchar(100) declare @sql nvarchar(max) set @dbname = 'DataBaseName' set @sql = ' --'+@dbname+'_diff BACKUP DATABASE ['+@dbname+'] TO DISK = N''D:\DBBackup\'+@dbname+'_diff.bak'' WITH DIFFERENTIAL , NOFORMAT, NOINIT, NAME = N'''+@dbname+'-差異數據庫備份'', SKIP, NOREWIND, NOUNLOAD, STATS = 10 GO ' print @sql --生成的SQL --DataBaseName_diff BACKUP DATABASE [DataBaseName] TO DISK = N'D:\DBBackup\DataBaseName_diff.bak' WITH DIFFERENTIAL , NOFORMAT, NOINIT, NAME = N'DataBaseName-差異數據庫備份', SKIP, NOREWIND, NOUNLOAD, STATS = 10 GO |
--4:差異備份還原 declare @dbname varchar(100) declare @sql nvarchar(max) set @dbname = 'DataBaseName' set @sql = ' --RESTORE '+@dbname+'_full RESTORE DATABASE ['+@dbname+'] FROM DISK = ''D:\DBBackup\'+@dbname+'_diff.bak'' WITH FILE = 1, NOUNLOAD, STATS = 10 GO' print @sql --生成的SQL --RESTORE DataBaseName_full RESTORE DATABASE [DataBaseName] FROM DISK = 'D:\DBBackup\DataBaseName_diff.bak' WITH FILE = 1, NOUNLOAD, STATS = 10 GO |
四、後記
也許到了這裏應該結束了,但是往往事與願違,有的時候我們的數據庫文件的大小並不是幾十G的,那麼我們應該如何做呢?是否還有其他的解決方案呢?
我之前就移動過700G的數據文件,不過給我移動的時間比較充足,我是通過數據庫的作業進行愚公移山的,搬數據到新的服務器上的,這樣的好處就是對之前的數據庫進行優化,比如進行數據庫參數的設置,比如表分區,在對之前數據庫影響儘量小的情況進行數據搬遷。詳細的過程下次再寫吧。
科網技術劉勇撰