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 Slave

  當SQL Server遇到同樣需要對歷史數據庫搭建復制,通常的做法是在本地發布快照,再由訂閱傳輸數據,那SQL Server應該如何實現備份歷史數據搭建復制(發布/訂閱)呢?下圖是備份文件初始化訂閱的基本邏輯結構圖:

clip_image002

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

三.搭建過程(Process)

(一) 環境信息

系統環境:Windows Server 2008 + SQL Server 2008

發布服務器:192.168.1.105,服務器名稱:QuZhoushiwei105

分發服務器:與發布服務器同一台機器

訂閱服務器:192.168.1.106,服務器名稱:QuZhoushiwei106

發布數據庫:Barfoo.TestPublish

訂閱數據庫:Barfoo.TestSubscribe

數據庫帳號: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(原文)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM