web-dev-qa-db-ja.com

レプリケーションを使用したSQL Serverデータベースの復元

これが怒り/怒りのように聞こえるかどうか私を許してください、しかしそれはちょっとです。

高レベルの概要:

5つのpub/subsを使用したトランザクションレプリケーションに関係するSQL DBを復元するにはどうすればよいですかなしでドロップ、作成、および再初期化(または再-snapshot)すべての潜水艦。または、少なくとも、再初期化/再スナップショットする必要はありません。私はpubs/subs自体のスクリプトを処理できますが、それは(ある程度)理解できます。しかし、私は既知の適切なバックアップを持っているか、サブスクリプションを作成するときに「バックアップからの初期化」機能を使用して、セカンダリサーバーと共有する「新しい」バックアップをプライマリサーバーで作成したいと考えています。うまく動かないようです。

Rant-yバージョン:

SQL Serverが、同じバックアップファイルから復元されるという性質上、パブリッシャーとサブスクライバーのDBが同期していることを "信頼できる"のではなく、レプリケーションをそのまま続行できるのはなぜですか。気の利いた再初期化やゼロからの再作成を必要としない陽気な方法!?


詳細:

データベースMyCoolDBがあります。サーバーOldFooにあります。 「古い」環境では、読み取り専用のレポート目的で、サーバーOldBarに複製されます。同様の名前のサーバーNewFooおよびNewBarを使用して、「新しい」環境への移行を準備しています。この説明では、Fooサーバーがパブリッシャーとなり、Barサーバーがサブスクライバー。物事を簡単にするために、パブリッシャーをディストリビューターとして兼務させます。つまり、OldFooOldBarにパブリッシュおよび配布します。NewFooからNewBarも同様です。

「新しい」環境で、MyCoolDBNewFoo(pub)とNewBar(sub)の両方に同じバックアップファイルを使用して復元したい[〜#〜] and [〜#〜]、これを複数回実行して、最終的なカットオーバーの前に上記の環境を更新しているので、[〜#〜]しない[〜#〜]pubs/subsを削除、再作成、再初期化または再スナップショットする必要がありますダンタイム

それだけ質問するのですか?レプリケーションに関与する可能性のあるSQL DBに関しては、より高い(Prod/Pre-Prod)環境からDev&QA環境を「更新」する方法が確実に必要です。

仮定/メモ:

  1. Replカテゴリー(Distribution&Log-Readerエージェント)の関連するエージェントジョブを停止することで、レプリケーションを効果的に「一時停止」できます。 これは悪い仮定かもしれません。
  2. ディスク上のネイティブバックアップファイルからMyCoolDBを迅速かつ効率的に復元でき、両方のサーバーインスタンスにアクセスできます。
  3. NewFooから生成されたスクリプトを経由して文字列置換を行うことにより、OldFooインスタンスのrepl pub/sub作成をスクリプトアウトしました。また、上記の作成スクリプトを使用して通常の方法で初期化すると、期待どおりに機能することを確認しました。
  4. 「バックアップからのサブスクリプションの初期化」プロセスをたどる 記事ブログ投稿 を確認しましたが、有効な解決策が見つかりませんでした。 私は近づきました;詳細は以下のとおりです。
  5. ここで問題になっている環境は決定的に本番環境ではありませんが、これはすべて同様の問題を伴う本番環境移行の準備と実践です(複製されたDB、再初期化によりパフォーマンスの問題が発生します)。

閉じるが葉巻はない:

試行後この方法...

  • パブ/サブスクライブを削除
  • パブリッシャーでDBを復元する
  • パブを作成する
  • dBを特別な場所にバックアップ
  • サブスクライバーのDBを特別な場所から復元する
  • 特別な場所にinit-from-backupを使用してSubsを作成する

Repl-Monitorでサブスクリプションを確認したところ、ログリーダーエージェントのステータスで次のエラーが表示されました。以下のエラーはwhy私がexec sp_replrestart、しかし私が言ったように、それも失敗しました。

The process could not execute 'sp_repldone/sp_replcounters' on 'NewFoo'. (Source: MSSQL_REPL, Error number: MSSQL_REPL20011)
Get help: http://help/MSSQL_REPL20011
The log scan number (267414:8865:55) passed to log scan in database 'Grading' is not valid. This error may indicate data corruption or that the log file (.ldf) does not match the data file (.mdf). If this error occurred during replication, re-create the publication. Otherwise, restore from backup if the problem results in a failure during startup. (Source: MSSQLServer, Error number: 9003)
Get help: http://help/9003
The process could not set the last distributed transaction. (Source: MSSQL_REPL, Error number: MSSQL_REPL22017)
Get help: http://help/MSSQL_REPL22017
The process could not execute 'sp_repldone/sp_replcounters' on 'NewFoo'. (Source: MSSQL_REPL, Error number: MSSQL_REPL22037)
Get help: http://help/MSSQL_REPL22037

テイカーはいますか?

TL; DR:私のprimary目標は、レプリケーションサブスクリプションをバックアップから初期化する方法を理解することです。これにより、re-init/re-snapshotが必要。私のsecondaryの目標は、pubs/subsを毎回ドロップして(スクリプトから)再作成する必要がないようにすることですが、この時点では、「持っているのはいい」です。 「要件」。

2
NateJ

まず、レプリケーションデータベースをdomain1からdomain2に復元することはお勧めしません。すべての複製をスクリプト化し、新しいドメインのエージェントのアカウントとパスワードを含むスクリプトを再適用する必要があります。

それが同じドメイン上にある場合、すべてのエージェントアカウントにはサーバー(パブリッシャー、ディストリビューター、サブスクライバー)に必要なすべての権限が既にあり、最初にスクリプトを作成し、後でスクリプトを適用することなく、複製されたデータベースを復元しています。

これが私がしたことです:

1)バックアップ

2)すべてのユーザーと権限をスクリプト化する

3)ドロップのスクリプトを作成し、すべてのレプリケーション(just in case you need to come to this

4)復元、トラブルシューティング、テスト

---------------------------------------

-- 5.1 --> if the database is involved in replication 
       -- check if it is Sync With backup

--At the Distributor, use the DATABASEPROPERTYEX (Transact-SQL) function to return the IsSyncWithBackup property of the distribution database. 


--IsSyncWithBackup
--The database is either a published database or a distribution database, 
--and can be restored without disrupting transactional replication.

--1 = TRUE
--0 = FALSE
--NULL = Input not valid

-- if that is false, then enable it
-- How to: Enable Coordinated Backups for Transactional Replication (Replication Transact-SQL Programming)
-- http://msdn.Microsoft.com/en-us/library/ms147311(v=sql.105).aspx

-- get the distributor
EXEC sp_get_distributor
GO
-- get the distributor server and distributor database too
EXEC sp_helpdistributor
GO
--SQLDISTLON1
-- distribution

use product
go
-- at the product database
declare @db sysname
select @db = 'Product'
SELECT DATABASEPROPERTYEX ( @db, 'IsSyncWithBackup' )
--0

--change the value to TRUE
sp_replicationdboption @dbname= 'Product',
                       @optname= 'sync with backup',
                       @value='true'

---------------------------------------

--Script to Enable/Disable Database for Replication
--I DID NOT DO THIS
--use master
--exec sp_replicationdboption @dbname = 'Product',
--@optname = 'publish',
--@value = 'false'
--go


--=====================================================================================
-- THE RESTORE
-- note the backup of the tail of the transaction log alongside the restore.
-- note also the KEEP_REPLICATION option
--=====================================================================================


USE [master]
ALTER DATABASE [Product] SET SINGLE_USER WITH ROLLBACK IMMEDIATE
BACKUP LOG [Product] TO  DISK = N'F:\SQLBackups\UserDB\Product\SQLAPPLON1_the_tail_log.trn' WITH NOFORMAT, NOINIT,  NAME = N'tail log backup', NOSKIP, NOREWIND, NOUNLOAD,  STATS = 1
RESTORE DATABASE [Product] FROM  DISK = N'F:\SQLBackups\UserDB\Product\SQLAPPLON1_Product_FULL_20140909_222917.bak' 
WITH  FILE = 1,  MOVE N'Product' TO N'E:\SQLData\Product.mdf', 
 MOVE N'Product_log' TO N'E:\SQLLogs\Product_log.ldf',  
 KEEP_REPLICATION,  
 NOUNLOAD,  
 REPLACE,  STATS = 1
 go
 ALTER DATABASE [Product] SET MULTI_USER

GO
--=====================================================================================
-- THE RESTORE - FINISH
--=====================================================================================



---------------------------------------
-- set sync with backup to false (unless decided otherwise)
-- problem with this is that it slows the log reader a bit

use product
go
-- at the product database
declare @db sysname
select @db = 'Product'
SELECT DATABASEPROPERTYEX ( @db, 'IsSyncWithBackup' )
--0

--change the value to TRUE
sp_replicationdboption @dbname= 'Product',
                       @optname= 'sync with backup',
                       @value='FALSE'

-- at the product database
declare @db sysname
select @db = 'Product'
SELECT DATABASEPROPERTYEX ( @db, 'IsSyncWithBackup' )
--0

---------------------------------------
--Script to Enable/Disable Database for Replication
use master
exec sp_replicationdboption @dbname = 'Product',
@optname = 'publish',
@value = 'True'
go



---------------------------------------
-- There were some problems
-- the backup that I needed to use to restore the DB was much older and from a different server


-- I used these two commands
-- from inside the Product database (in the publisher)

use Product
go

DBCC OPENTRAN 
sp_replrestart

-- http://msdn.Microsoft.com/en-us/library/ms174390.aspx

--sp_replrestart is an internal replication stored procedure and s
--hould only be used when restoring a database published in a transactional replication 
--topology as directed in the topic Strategies for 
--Backing Up and Restoring Snapshot and Transactional Replication.

--Used by transactional replication during backup and restore so that 
--the replicated data at the Distributor is synchronized with data at the Publisher. 
--This stored procedure is executed at the Publisher on the publication database.

--How if works? 
--sp_replrestart will fill NO-OP (No-Operation) transaction which will cause the 
--LSN's to increase until the log LSN matches the LSN as per Distribution database. 
--So from there-on, Logreader agent will be able to read the LSN, it is expecting.

--Note: Depending on how old the backup of the Published database which was restored, 
--it may take hours for this operation and may make the transaction log to grow big.
--and grow by gigs, until they match.



--=====================================================================================
-- THE TEST
-- I add the folowing table to the published database
-- then I add the article to the publication
-- start a snapshot
-- and check if the article is in the subscription
--=====================================================================================

use product
go
--DROP TABLE dbo.marcelo_test

create table dbo.marcelo_test(
i int not null identity(1,1) not for replication
,the_name varchar(40) not null )

insert into marcelo_test values ('belluno')
insert into marcelo_test values ('rovigo')
insert into marcelo_test values ('feltre')
insert into marcelo_test values ('cremona')
insert into marcelo_test values ('padova')
insert into marcelo_test values ('vicenza')
insert into marcelo_test values ('venezia')


select * from dbo.marcelo_test

alter table dbo.marcelo_test
add constraint pk_marcelo primary key clustered (i)

さて、これは完全な解決策ではなく、複製されたデータベースを復元する際の私のメモ、私が行ったトラブルシューティング、起こり得る問題を回避するいくつかの方法、そして最後に小さなテストです。 。

それが役に立てば幸い

1

実際、@ NateJ、もうすぐです。しかし、create subs in init-from-backup with special locationの代わりに、次のように@ sync_type = 'replication support only'でサブスクリプションを追加する必要があります

EXEC sp_addsubscription @publication = N'Test',  
                        @subscriber = N'subscriber',  
                        @destination_db = N'SubDB',  
                        @subscription_type = N'Push',  
                        @sync_type = N'replication support only',  
                        @article = N'all'

これを行う簡単な方法は、sp_addsubscriptionを探して以前にスクリプト化したレプリケーションスクリプトを変更し、@ sync_type値を変更することです。

私は以前これを非常に頻繁に行いました。 (私はあなたのレプリケーションがPushトランザクションパブリケーションのサブスクリプションであると想定しています)

1
jyao