SQL Server 經過備份文件初始化複製

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

  1. 本文所涉及的內容(Contents)
  2. 背景(Contexts)
  3. 搭建過程(Process)
  4. 注意事項(Attention)
  5. 疑問(Questions)
  6. 參考文獻(References)

二.背景(Contexts)

  MySQL在對有歷史數據的數據庫進行搭建複製(Master/Slave)的時候,能夠經過在Master服務器備份歷史數據,利用這個備份文件在Slave進行還原;這樣作的好處是能夠更加快速的搭建好環境,由於能夠對備份文件進行壓縮、分包,而且能夠使用FTP等工具保證傳輸過程的安全與快捷;詳情可參考:Windows下搭建MySQL Master Slavehtml

  當SQL Server遇到一樣須要對歷史數據庫搭建複製,一般的作法是在本地發佈快照,再由訂閱傳輸數據,那SQL Server應該如何實現備份歷史數據搭建複製(發佈/訂閱)呢?下圖是備份文件初始化訂閱的基本邏輯結構圖:sql

clip_image002

(Figure0:備份文件初始化訂閱邏輯結構圖)數據庫

三.搭建過程(Process)

(一) 環境信息編程

系統環境: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的錯誤信息;

clip_image004

(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'廣州')

clip_image005

(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) 在發佈服務器上建立一個發佈,具體步驟以下圖所示:

clip_image006

(Figure3:新建發佈)

clip_image007

(Figure4:選擇數據Barfoo.TestPublish)

clip_image008

(Figure5:選擇事務發佈)

clip_image009

(Figure6:選擇須要發佈的字段)

clip_image010

(Figure7:不勾選)

clip_image011

(Figure8:設置快照代理)

clip_image012

(Figure9:設置代理安全性)

clip_image013

(Figure10:設置日誌讀取器代理)

clip_image014

(Figure11:設置賬號密碼)

clip_image015

(Figure12:建立發佈)

clip_image016

(Figure13:發佈名稱)

clip_image017

(Figure14:建立成功)

clip_image018

(Figure15:建立的發佈)

 

4) 設置發佈屬性中的訂閱選項,把容許從備份文件初始化的默認值false設置爲true;也能夠使用下面的SQL腳本進行修改;

clip_image019

(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腳本執行成功,數據庫會返回下面的提示信息:

clip_image021

(Figure17:建立訂閱返回信息)

注意:若是備份文件以後相隔太長時間,執行上面的腳本有可能會出現下面的錯誤信息,若是遇到這個問題,能夠參考下面【疑問】的內容:

消息21397,級別16,狀態1,過程sp_MSaddautonosyncsubscription,第271 行

對從指定備份建立的非同步訂閱進行同步時須要一些事務,但這些事務在分發服務器上不可用。請使用更新的日誌以及差別或完整數據庫備份再試此操做。

 

9) 檢查新添加的訂閱屬性中的安全性->訂閱服務器鏈接,確認正確的賬號和密碼,默認是使用代理賬號;

clip_image022

(Figure18:訂閱服務器屬性)

clip_image024

(Figure19:設置安全性)

clip_image026

(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) 檢查發佈服務器和訂閱服務器的訂閱狀態;

clip_image027

(Figure21:啓動複製監視器)

clip_image029

(Figure22:訂閱狀態)

clip_image030

(Figure23:訂閱服務器的本地訂閱)

 

11) 查看訂閱服務器QuZhoushiwei106的數據庫Barfoo.TestSubscribe的UserInfo表的數據;

clip_image031

(Figure24:UserInfo表數據)

 

12) 使用下面的SQL腳本在發佈服務器上UserInfo表插入新數據,測試複製,分別查看發佈服務器與訂閱服務器的數據;

--測試訂閱數據
INSERT [dbo].[UserInfo] ([names],[address]) VALUES (N'viajar', N'北京')

clip_image032

(Figure25:發佈服務器上UserInfo表數據)

clip_image033

(Figure26:訂閱服務器上UserInfo表數據)

四.注意事項(Attention)

1. 在SQL SERVER下實現發佈服務器和訂閱服務器的通訊正常(便可以互訪),打開1433端口,在防火牆中設置入站規則;

2. 發佈服務器與訂閱服務器的SQL Server Agent代理賬號必須設置的同樣,不然不能互訪;

3. 後期添加新的表須要手動在訂閱服務器建立表結構,主要先在發佈屬性的項目中勾選新表,再經過表的右鍵菜單建立表結構腳本。

五.疑問(Questions)

(一) 怎麼確保在發佈服務器持續進數據的狀況下,如何保證在拷貝歷史數據備份以後還能知道訂閱從哪一個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;

clip_image034

(Figure27:數據庫只讀)

C. 最後一種方式最常使用,是建立好發佈以後立刻關掉distributor cleanup這個JOB,可參考:Implementing NoSync Initializations (and variations) on SQL Server 2005/8(CareySon),關掉這個JOB,建立訂閱以後數據會同步到訂閱服務器上,可是不會對訂閱執行dbo.sp_MSdistribution_cleanup,能夠使用CHECKPOINT 1進行測試;

clip_image035

(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

clip_image037

(Figure29:訂閱配置信息)

六.參考文獻(References)

初始化事務訂閱(不使用快照)

如何從備份初始化事務訂閱(複製 Transact-SQL 編程)

使用快照初始化訂閱

Replication Without Creating a Snapshot(CareySon)

Implementing NoSync Initializations (and variations) on SQL Server 2005/8(CareySon)

SQL Server事務複製經過備份文件進行訂閱初始化

SQL Server複製用備份文件初始化訂閱

ALTER AUTHORIZATION (Transact-SQL)

Server2008+SQL2008 日誌讀取代理器未運行 進程沒法在「WIN-XXX」上執行「sp_replcmds

SQLServer Replication 常見錯誤

sp_addsubscription (Transact-SQL)

sp_addpullsubscription_agent (Transact-SQL)

SQL Server數據庫事務日誌序列號(LSN)介紹(譯文)

Log sequence numbers(原文)

相關文章
相關標籤/搜索