MySQL在對有歷史數據的數據庫進行搭建複製(Master/Slave)的時候,能夠經過在Master服務器備份歷史數據,利用這個備份文件在Slave進行還原;這樣作的好處是能夠更加快速的搭建好環境,由於能夠對備份文件進行壓縮、分包,而且能夠使用FTP等工具保證傳輸過程的安全與快捷;詳情可參考:Windows下搭建MySQL Master Slavehtml
當SQL Server遇到一樣須要對歷史數據庫搭建複製,一般的作法是在本地發佈快照,再由訂閱傳輸數據,那SQL Server應該如何實現備份歷史數據搭建複製(發佈/訂閱)呢?下圖是備份文件初始化訂閱的基本邏輯結構圖:sql
(Figure0:備份文件初始化訂閱邏輯結構圖)數據庫
(一) 環境信息編程
系統環境:Windows Server 2008 + SQL Server 2008安全
發佈服務器:192.168.1.105,服務器名稱:QuZhoushiwei105服務器
分發服務器:與發佈服務器同一臺機器工具
訂閱服務器:192.168.1.106,服務器名稱:QuZhoushiwei106測試
發佈數據庫:Barfoo.TestPublishspa
訂閱數據庫:Barfoo.TestSubscribe.net
數據庫賬號:ReplicationUser/ ReplicationPassword
說明:發佈服務器與訂閱服務器是在同一內網的機器,若是你的環境是跨網段(跨機房)的請參考:SQL Server 跨網段(跨機房)部署
(二) 搭建步驟
1) 在發佈服務器上以QuZhoushiwei105服務器名稱登錄發佈服務器,若是你以localhost或者IP形式登錄服務器,在建立發佈的時候會出現下圖Figure1的錯誤信息;
(Figure1:錯誤信息)
登錄服務器以後使用下面的SQL腳本建立一個測試數據庫:Barfoo.TestPublish,建立一個測試表:UserInfo,並插入一條數據,用於模擬歷史數據;
--建立測試數據庫 USE MASTER GO CREATE DATABASE [Barfoo.TestPublish] GO --建立測試表 USE [Barfoo.TestPublish] GO CREATE TABLE [dbo].[UserInfo]( [Id] [int] IDENTITY(1,1) NOT FOR REPLICATION NOT NULL, [names] [nvarchar](50) NULL, [address] [nvarchar](50) NULL, CONSTRAINT [PK_UserInfo] PRIMARY KEY CLUSTERED ( [Id] ASC ) ON [PRIMARY] ) ON [PRIMARY] GO --插入測試數據 INSERT [dbo].[UserInfo] ([names],[address]) VALUES (N'gaizai', N'廣州')
(Figure2:UserInfo表記錄)
2) 在發佈數據庫和訂閱服務器上分別執行下面的SQL腳本建立賬號和密碼(ReplicationUser/ ReplicationPassword);
--發佈服務器建立賬號密碼 USE [master] GO CREATE LOGIN [ReplicationUser] WITH PASSWORD=N'ReplicationPassword', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF GO EXEC master..sp_addsrvrolemember @loginame = N'ReplicationUser', @rolename = N'sysadmin' GO USE [Barfoo.TestPublish] GO CREATE USER [ReplicationUser] FOR LOGIN [ReplicationUser] GO USE [Barfoo.TestPublish] GO ALTER USER [ReplicationUser] WITH DEFAULT_SCHEMA=[dbo] GO --訂閱服務器建立賬號密碼 USE [master] GO CREATE LOGIN [ReplicationUser] WITH PASSWORD=N'ReplicationPassword', DEFAULT_DATABASE=[master], CHECK_EXPIRATION=OFF, CHECK_POLICY=OFF GO EXEC master..sp_addsrvrolemember @loginame = N'ReplicationUser', @rolename = N'sysadmin' GO
3) 在發佈服務器上建立一個發佈,具體步驟以下圖所示:
(Figure3:新建發佈)
(Figure4:選擇數據Barfoo.TestPublish)
(Figure5:選擇事務發佈)
(Figure6:選擇須要發佈的字段)
(Figure7:不勾選)
(Figure8:設置快照代理)
(Figure9:設置代理安全性)
(Figure10:設置日誌讀取器代理)
(Figure11:設置賬號密碼)
(Figure12:建立發佈)
(Figure13:發佈名稱)
(Figure14:建立成功)
(Figure15:建立的發佈)
4) 設置發佈屬性中的訂閱選項,把容許從備份文件初始化的默認值false設置爲true;也能夠使用下面的SQL腳本進行修改;
(Figure16:Allow initialization from backup files)
--修改發表容許從備份中初始化 USE [Barfoo.TestPublish] GO DECLARE @publication AS sysname SET @publication = N'testpub' EXEC sp_changepublication @publication = @publication, @property = N'allow_initialize_from_backup', @value = true GO
5) 使用下面的SQL腳本備份數據庫Barfoo.TestPublish,保留備份文件,在後面建立訂閱的時候須要用到;
--備份數據 BACKUP DATABASE [Barfoo.TestPublish] TO DISK = N'G:\DBBackup\Barfoo.TestPublish_20130822.bak' WITH NOFORMAT, NOINIT, NAME = N'Barfoo.TestPublish-完整數據庫備份', SKIP, NOREWIND, NOUNLOAD, STATS = 10 GO
6) 在訂閱服務器:192.168.1.106上使用下面的SQL腳本還原剛剛的備份文件;
--還原數據庫 RESTORE DATABASE [Barfoo.TestSubscribe] FROM DISK = N'G:\DBBackup\Barfoo.TestPublish_20130822.bak' WITH FILE = 1, MOVE N'Barfoo.TestPublish' TO N'G:\DataBase\Barfoo.TestSubscribe.mdf', MOVE N'Barfoo.TestPublish_log' TO N'G:\DataBase\Barfoo.TestSubscribe_log.ldf', NOUNLOAD, REPLACE, STATS = 10 GO
7) 在訂閱服務器行修改賬號ReplicationUser,SQL腳本以下:
--修改賬號ReplicationUser USE [Barfoo.TestSubscribe] GO ALTER USER [ReplicationUser] WITH DEFAULT_SCHEMA=[dbo] GO
8) 在發佈服務器上執行sp_addsubscription存儲過程添加訂閱,SQL腳本以下:
--在發佈服務器建立訂閱 EXEC sp_addsubscription @publication = N'testpub', @subscriber ='QuZhoushiwei106', @destination_db = N'Barfoo.TestSubscribe', @subscription_type = N'Push', @sync_type = N'initialize with backup', @backupdevicetype='disk', @backupdevicename='G:\DBBackup\Barfoo.TestPublish_20130822.bak'
若是上面的SQL腳本執行成功,數據庫會返回下面的提示信息:
(Figure17:建立訂閱返回信息)
注意:若是備份文件以後相隔太長時間,執行上面的腳本有可能會出現下面的錯誤信息,若是遇到這個問題,能夠參考下面【疑問】的內容:
消息21397,級別16,狀態1,過程sp_MSaddautonosyncsubscription,第271 行
對從指定備份建立的非同步訂閱進行同步時須要一些事務,但這些事務在分發服務器上不可用。請使用更新的日誌以及差別或完整數據庫備份再試此操做。
9) 檢查新添加的訂閱屬性中的安全性->訂閱服務器鏈接,確認正確的賬號和密碼,默認是使用代理賬號;
(Figure18:訂閱服務器屬性)
(Figure19:設置安全性)
(Figure20:設置登陸名密碼)
也能夠經過下面的SQL腳本設置訂閱服務器鏈接的賬號密碼:
--設置訂閱服務器賬號密碼 EXEC sp_addpushsubscription_agent @publication = N'testpub', @subscriber = N'QUZHOUSHIWEI106', @subscriber_db = N'Barfoo.TestSubscribe', @subscriber_security_mode = 0, @subscriber_login = N'ReplicationUser', @subscriber_password = N'ReplicationPassword'
10) 檢查發佈服務器和訂閱服務器的訂閱狀態;
(Figure21:啓動複製監視器)
(Figure22:訂閱狀態)
(Figure23:訂閱服務器的本地訂閱)
11) 查看訂閱服務器QuZhoushiwei106的數據庫Barfoo.TestSubscribe的UserInfo表的數據;
(Figure24:UserInfo表數據)
12) 使用下面的SQL腳本在發佈服務器上UserInfo表插入新數據,測試複製,分別查看發佈服務器與訂閱服務器的數據;
--測試訂閱數據 INSERT [dbo].[UserInfo] ([names],[address]) VALUES (N'viajar', N'北京')
(Figure25:發佈服務器上UserInfo表數據)
(Figure26:訂閱服務器上UserInfo表數據)
1. 在SQL SERVER下實現發佈服務器和訂閱服務器的通訊正常(便可以互訪),打開1433端口,在防火牆中設置入站規則;
2. 發佈服務器與訂閱服務器的SQL Server Agent代理賬號必須設置的同樣,不然不能互訪;
3. 後期添加新的表須要手動在訂閱服務器建立表結構,主要先在發佈屬性的項目中勾選新表,再經過表的右鍵菜單建立表結構腳本。
(一) 怎麼確保在發佈服務器持續進數據的狀況下,如何保證在拷貝歷史數據備份以後還能知道訂閱從哪一個LSN開始讀取?
解答:若是備份文件以後相隔太長時間,執行上面的腳本有可能會出現下面的錯誤信息:
消息21397,級別16,狀態1,過程sp_MSaddautonosyncsubscription,第271 行
對從指定備份建立的非同步訂閱進行同步時須要一些事務,但這些事務在分發服務器上不可用。請使用更新的日誌以及差別或完整數據庫備份再試此操做。
若是遇到這個問題,有3種解決辦法:
A. 按照上面的提示,對Barfoo.TestPublish數據庫作一個差別備份,再在Barfoo.TestSubscribe數據庫作差別還原,須要注意的是在使用sp_addsubscription的時候應該指定差別備份的文件;
--差別備份數據庫 BACKUP DATABASE [Barfoo.TestPublish] TO DISK = N'G:\DBBackup\Barfoo.TestPublish_Diff_20130822.bak' WITH NOFORMAT, NOINIT, DIFFERENTIAL, NAME = N'Barfoo.TestPublish-差別數據庫備份', SKIP, NOREWIND, NOUNLOAD, STATS = 10 GO --完整還原數據庫 RESTORE DATABASE [Barfoo.TestSubscribe] FROM DISK = N'G:\DBBackup\Barfoo.TestPublish_20130822.bak' WITH FILE = 1, MOVE N'Barfoo.TestPublish' TO N'G:\DataBase\Barfoo.TestSubscribe.mdf', MOVE N'Barfoo.TestPublish_log' TO N'G:\DataBase\Barfoo.TestSubscribe_log.ldf', NOUNLOAD, REPLACE, NORECOVERY, STATS = 10 GO --差別還原數據庫 RESTORE DATABASE [Barfoo.TestSubscribe] FROM DISK = N'G:\DBBackup\Barfoo.TestPublish_Diff_20130822.bak' WITH FILE = 1, MOVE N'Barfoo.TestPublish' TO N'G:\DataBase\Barfoo.TestSubscribe.mdf', MOVE N'Barfoo.TestPublish_log' TO N'G:\DataBase\Barfoo.TestSubscribe_log.ldf', NOUNLOAD, STATS = 10 GO --在發佈服務器建立訂閱 EXEC sp_addsubscription @publication = N'testpub', @subscriber ='QuZhoushiwei106', @destination_db = N'Barfoo.TestSubscribe', @subscription_type = N'Push', @sync_type = N'initialize with backup', @backupdevicetype='disk',
@backupdevicename='G:\DBBackup\Barfoo.TestPublish_Diff_20130822.bak'
B. 若是你的數據庫Barfoo.TestPublish能夠接受短期不寫入數據,能夠在作完整備份以前就先設置數據庫爲只讀狀態,在數據庫【屬性】-【選項】-【狀態】-【數據庫爲只讀】設置爲True;
(Figure27:數據庫只讀)
C. 最後一種方式最常使用,是建立好發佈以後立刻關掉distributor cleanup這個JOB,可參考:Implementing NoSync Initializations (and variations) on SQL Server 2005/8(CareySon),關掉這個JOB,建立訂閱以後數據會同步到訂閱服務器上,可是不會對訂閱執行dbo.sp_MSdistribution_cleanup,能夠使用CHECKPOINT 1進行測試;
(Figure28:分發清除)
(二) 若是是transactional的replication,建立完畢以後是會產生對應的三個Job,下面3個是複製做業中的Job,他們的做用分別是什麼呢?
A. QUZHOUSHIWEI105-Barfoo.TestPublish-12
B. QUZHOUSHIWEI105-Barfoo.TestPublish-testpub-12
C. QUZHOUSHIWEI105-Barfoo.TestPublish-testpub-QUZHOUSHIWEI106-22
QUZHOUSHIWEI105-Barfoo.TestPublish-12,這是REPL-LogReader類別的JOB,一個數據庫只會有一個日誌讀取器做業,命名的格式是:ServerName-DBName-Num;
QUZHOUSHIWEI105-Barfoo.TestPublish-testpub-12,這是REPL-Snapshot類別,的JOB,一個發佈(也叫作一條同步鏈)對應一個快照做業,命名的格式是:ServerName-DBName-PublishName-Num;
QUZHOUSHIWEI105-Barfoo.TestPublish-testpub-QUZHOUSHIWEI106-22,這是一個REPL-Distribution類別的JOB,一個訂閱對應一個分發做業,命名的格式是:ServerName-DBName-PublishName-ServerName-Num;
能夠經過下面的SQL腳本查詢訂閱JOB和訂閱屬性的相關信息:
--返回訂閱信息 SELECT * FROM msdb.dbo.sysjobs WHERE category_id=10 --返回訂閱屬性信息 SELECT [description] ,[name] ,[allow_initialize_from_backup] ,[min_autonosync_lsn] FROM [Barfoo.TestPublish].[dbo].[syspublications] GO
(Figure29:訂閱配置信息)
如何從備份初始化事務訂閱(複製 Transact-SQL 編程)
Replication Without Creating a Snapshot(CareySon)
Implementing NoSync Initializations (and variations) on SQL Server 2005/8(CareySon)
ALTER AUTHORIZATION (Transact-SQL)
Server2008+SQL2008 日誌讀取代理器未運行 進程沒法在「WIN-XXX」上執行「sp_replcmds」
sp_addsubscription (Transact-SQL)
sp_addpullsubscription_agent (Transact-SQL)