一、目的
在做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 = '
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:DBBackupDataBaseName_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:DBBackupDataBaseName_full.bak' WITH FILE = 1,
MOVE N'DataBase_Name' TO N'D:DataBaseDataBaseName.mdf',
MOVE N'DataBase_Name_log' TO N'D:DataBaseDataBaseName_log.ldf',
NORECOVERY, NOUNLOAD, REPLACE, STATS = 10
GO
--3:差異備份
declare @dbname varchar(100)
declare @sql nvarchar(max)
set @dbname = 'DataBaseName'
set @sql = '
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:DBBackupDataBaseName_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:DBBackupDataBaseName_diff.bak' WITH FILE = 1,
NOUNLOAD, STATS = 10
GO
四、後記
也許到了這裡應該結束了,但是往往事與願違,有的時候我們的資料庫檔案的大小並不是幾十G的,那我們該如何做呢?是否還有其他的解決方案?
我之前就移動過700G的資料文件,不過給我移動的時間比較充足,我是透過資料庫的作業進行愚公移山的,搬資料到新的伺服器上的,這樣的好處就是對之前的資料庫進行最佳化,例如進行資料庫參數的設置,例如表格分區,在對先前資料庫影響盡量小的情況進行資料搬遷。詳細的過程下次再寫。
(作者:聽風吹雨出處:http: //gaizai.cnblogs.com/ )