新しいスナップショットを生成せずに記事をトランザクションパブリケーションに追加する


23

プルサブスクライバーでSQL 2008 R2トランザクションレプリケーションを使用して、記事を追加するときに、スナップショット全体を作成する必要がないようにしたいと思います(dbは最大80 GBであるため、これには数時間かかります)。

この記事から、immediate_syncをオフに設定することで部分スナップショットでこれを行う方法を見てきましたが、それはうまくいきませんでした。

理想的には、dbスクリプトの一部としてこれを実行してテーブルを作成したいので、複製する場合は次のようにします。

Create Table ...    
sp_addArticle ...    
sp_PushThisToOurSubscribersNow    

回答:


13

GUIを使用してSSMS経由で記事を追加し、フィルターを適用することもできます。記事の他のプロパティを変更しない限り、完全なスナップショットを生成する必要はありません。

あなたは(記事を追加した後)出版GUIでOKを押すと、それが再初期化するためにプロンプトを表示せず終了します-それは場合はありません再初期化するためのプロンプト、あなたはFULLスナップショットを必要とする何かを変更しました。その場合は、キャンセルを押して再試行してください。

記事を追加したら、スナップショットジョブを開始するだけで、新しい記事のスナップショット(ミニスナップショットと呼ばれる)のみが生成されることに気付くでしょう。

次に、配布ジョブを確認し、サブスクライバーでテーブルを作成し、データを一括コピーしたことを確認します。

幸運を祈ります。さらにサポートが必要な場合はお知らせください。


この回答で説明したことはすべて行いましたが、複製されたデータベース全体が同期するのを待っていました。新しい記事を追加した後、再初期化するように求められませんでしたが、それでも完全な初期化は行われました。注意してください。
JzInqXc9Dg

7
  1. [出版物] プロパティウィンドウに新しい記事を追加します(リスト内のチェックされた記事のみを表示するのチェックを外します)
  2. 同じパブリケーションノードを右クリックして、「スナップショットエージェントステータスの表示」に進みます。
  3. [ スタート ]をクリックし、同じウィンドウでこの新しい記事が同期されていることを示すログを確認します。
  4. しばらくすると、以前に同期されたすべてを初期化することなく、新しい記事がサブスクライバーで同期されます

ここに画像の説明を入力してください


3

同じ質問がありました。しばらくDBAを務めてきましたが、完全に使いこなすには十分なほど深くレプリケーションに対処していなかったので、次のリソースとガイドが役立つと思いました。

  • このブログでは、プロセスの概要を説明しています。また、大きな既存のパブリケーションがあり、そのオプションが「immediate_sync」に設定されている場合、記事を追加または変更するたびに完全に新しいスナップショットが準備されることを思い出させます。したがって、彼はそのオプションを変更するための便利なヒントを持っています。sp_changePublication @publication='MyPub', @property='immediate_sync', @value='false';

  • 「repltalk」のMSDNブログ投稿(一般的には良いリソースのように聞こえます!)-「直接」関連ではなく、まだ有用

  • @ Brandon-Williamsが指摘したこの質問、それが プルサブスクリプションの場合は、以下を使用して更新する必要があります。sp_refreshSubscriptions @publication = 'MyPub'

  • SSMSレプリケーションモニター-ガイドに従うときにエージェント(スナップショット、ログリーダー)を停止および開始する便利な方法。

私が従った実際の手順は次のとおりです。これはうまく機能し、私の監督DBAの承認を満たしました。

  1. レプリケーションモニターを開き、パブリケーションを選択して、[エージェント]に移動し、[ログリーダーエージェント]を右クリックして、[停止]をクリックします。
  2. 次を使用して、パブリケーションを許可しない匿名および即時同期ではないように設定します sp_changePublication@cody_koniorが指摘しているます-はい、これは文書化されていませんが、私の場合はうまくいきました。YMMV
  3. スクリプトを使用してサブスクライバでテーブルを手動で作成し、リンクサーバークエリを使用してデータを入力しました(小さいため)。SSIS、BCP、またはこれを行う他の手段を使用することもできます。そして、repl-snapshotがあなたのためにそれをしていても大丈夫なら、それは必要ではないかもしれません。初めて手動で準備したかっただけです。
  4. を使用して記事(テーブル)を追加します sp_addArticle
  5. を使用してテーブルのすべての列を追加します sp_articleColumn(指定されたパブリケーションと記事、列を指定しません->すべての列を意味します)
  6. 実行した sp_refreshSubscriptionsその出版物をして、を更新します
  7. レプリケーションモニターを再度開き、パブを選択し、[エージェント]に移動して、[スナップショットエージェント]を右クリックし、[開始]をクリックします。1回実行され、新しいスナップショットが作成されます。
  8. [ログリーダーエージェント]を右クリックし、[開始]をクリックします。通常どおり起動し、実行を継続します。複製が再び機能するようになります。

はい、あなたがしながら可能性が SSMS GUIでの変更の大半を行う、私はそれがソース管理(変更管理)、およびB)の下のすべてのアウトそれができるように、A)が繰り返しまたは複数のインスタンスに配備スクリプトにそれが有用見つけます。残念ながら、エージェントの停止/開始をスクリプト化するのに時間を費やしませんでしたが、それらが単なるSQLエージェントジョブであることを考えると、それほど難しくないはずです。「Job-Nameを使用してJobIDを見つける」トリック全体を実行するだけです(クエリsysjobs-本当に、MS?)...

将来の読者に役立つことを願っています!


3

既存のパブリケーションへのアーティクルの追加とアーティクルのドロップ」で説明したように、パブリケーションの新しいスナップショットを作成する必要があります*。

新しい記事を追加するとき、すべての記事のスナップショットの発生を防ぐため、出版プロパティがimmediate_sync0のコールに設定する必要がありsp_addarticle、その後、sp_addsubscription。サブスクリプションがプルの場合は、を呼び出す必要もありますsp_refreshsubscriptions。次に、スナップショットを生成すると、新しく追加された記事のスナップショットのみが生成されます。

*これは、SQL Server Books Onlineで推奨されるアプローチです。アプローチの問題は、エラーが発生しやすいことです。


2

大規模な編集 これは、この回答を完全に書き直したものです(以前のバージョンはエラーが発生しやすく、問題を引き起こす可能性があるという有効な批判を受け入れました)

また、これを適用する方法のデモを投稿しました:Youtube-SQL Server Replication:スナップショットを取らずに記事を追加する方法

重要:これは、NOTあなたが、それは働い取得に関して、独自になりますので、マイクロソフトからの推奨アプローチはありません重要な孤立テストを行わずに本番環境に直接適用し、手順で自分が快適になって!

従うべき手順:

Planning steps:
    * Choose Publication that article will be added to
    * Gather information about the publication 
        exec sp_helppublication '[Name of Publication]'
        https://msdn.microsoft.com/en-us/library/ms189782(v=sql.105).aspx
        - replication frequency = 0 - this is Transactional replication (THIS IS A REQUIREMENT FOR THIS METHOD)
        - replicate_ddl = 1 - means ALTER TABLES will apply SQL Server generated repl procs
        - independent_agent = 1 - means that you will only affect tables in this publication when deploying
    * Identify which subscribers are going to be affected

Pre-deployment steps (can be done at any time)
    1. Create table on subscribers
    2. Create custom replication procs on subscribers
       (Customisation will ignore if the IUD has already been applied to subscriber - because you have manually sync'd the data)

Deployment/Potential impact:
    3. Stop Distribution Agents to all subscribers for this publication
    4. Add article to publication on publisher
    5. Sync data from publisher to subscriber
    6. Start Distribution Agents to all subscribers for this publication
    7. Monitor/Verify all data has arrived

Optional follow on:
    8. Apply standard repl procs (removing if not exists checks)
       This is optional as the generated repl scripts should be fine for the most part

Note:  When ALTER table scripts are applied on the Publisher (when replicate_ddl = 1) repl procs will automatically be recreated by the Distribution Agent (so any customisation will be lost)

検証します:

  • パブリッシャーで挿入を実行します-サブスクライバーで行が到着することを確認します
  • パブリッシャーで更新を実行します-サブスクライバーに変更が到着したことを確認します
  • パブリッシャーで削除を実行します-サブスクライバーで削除された行を確認します
  • 最後のn行が到着し、パブリッシャーとサブスクライバーの間で一致することを確認します

例のプロセス

A)パブリッシャーにテーブルを作成します。

/* Deliberately applying IDENTITY, DEFAULT & INDEX to demonstrate usage on subscriber */
CREATE TABLE [dbo].[TableNotUsingSnap](
    [Id] [int] NOT NULL IDENTITY(1,1),
    [Note_Text] [varchar](4096) NOT NULL,
    [CreatedDate] [datetime] NULL,
    [LoggedDate] [datetime] NOT NULL CONSTRAINT DF_TableNotUsingSnap_LoggedDate DEFAUlT GETUTCDATE(),
 CONSTRAINT [PK_TableNotUsingSnap] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
GO 

CREATE NONCLUSTERED INDEX [IDX_NC_TableNotUsingSnap_LoggedDate]  ON [dbo].[TableNotUsingSnap]
(
    [LoggedDate] ASC
) INCLUDE ([Note_Text])
GO

B)自分でジョブ/プロシージャ/スクリプトを作成して、[TableNotUsingSnap]で挿入/更新/削除を実行します(これを使用して、このメソッドを使用してサブスクライバーが正しく同期される方法を検証できます。

事前手順:

1.サブスクライバーでテーブルを作成します

/* example script to add a table to a publication without running the snapshot agent 
Steps: 
    Pre steps: 
    1. Create table on subscribers
    2. Create replication procs on subscribers

    Deployment/Potential impact:
    3. Stop Distribution Agents to all subscribers for this publication
    4. Add article to publication on publisher
    5. DTS data from publisher to subscriber
    6. Start Distribution Agents to all subscribers for this publication
    7. Monitor/Verify all data has arrived

=========================================================
Notes:
    * Drop unnecessary FK's, Indexes
    * Do NOT have IDENTITY(1,1), DEFAULTS
    * Do have a Clustered PK
    * Create appropriate indexes for your subscribers use case */ 

-- RUN ON SUBSCRIBER
IF OBJECT_ID('dbo.TableNotUsingSnap') IS NOT NULL
    exec sp_rename 'dbo.TableNotUsingSnap', 'TableNotUsingSnap_20170127'
GO

SET ANSI_NULLS ON
GO

SET QUOTED_IDENTIFIER ON
GO

CREATE TABLE [dbo].[TableNotUsingSnap](
    [Id] [int] NOT NULL,
    [Note_Text] [varchar](4096) NOT NULL,
    [CreatedDate] [datetime] NULL,
    [LoggedDate] [datetime] NOT NULL,
 CONSTRAINT [PK_TableNotUsingSnap] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO

2.レプリケーションストアドプロシージャの作成(更新/挿入/削除)-サブスクライバーで

replプロシージャを作成できます。

  • 手動(間違いを犯しやすいので注意してください!)
  • DevマシンでMS Snapshotメソッドを使用して記事を追加し、replプロシージャからスクリプトを作成します(微調整を追加する準備ができています)
  • ある種のジェネレータを作成/検索する

適用する必要がある変更:

  • sp_MSins_ [Schema] [TableName]- IF NOT EXISTS (SELECT 'row already exists' FROM [Schema].[TableName] dest WITH (NOLOCK) WHERE dest.Id = @c1)既に存在する場合は挿入しないように追加
  • sp_MSupd_ [Schema] [TableName]- IF @@rowcount = 0 ... exec sp_MSreplraiserror ...適用されない更新を無視するようにコメントアウトします(データを同期する前にパブリッシャーでレコードが削除された可能性があるため)
  • sp_MSdel_ [Schema] [TableName]- IF @@rowcount = 0 ... exec sp_MSreplraiserror ...適用されない削除を無視するためにコメントアウトします(データを同期する前にパブリッシャーでレコードが削除された可能性があるため)

sp_MSins_dboTableNotUsingSnap:

/* Customised Replication insert proc utilized to support adding to replication without a snapshot. */
create procedure [dbo].[sp_MSins_dboTableNotUsingSnap]     
    @c1 int,     
    @c2 varchar(4096),     
    @c3 datetime
AS 
BEGIN
    IF NOT EXISTS (SELECT 'row already exists' FROM [dbo].[TableNotUsingSnap] dest WITH (NOLOCK) WHERE dest.Id = @c1)
    BEGIN
        insert into [dbo].[TableNotUsingSnap]
            ([Id],
            [Note_Text],
            [Repl_Upsert_UTC]) 
        values 
            (@c1,
            @c2,
            @c3)  
    END
END
GO

sp_MSupd_dboTableNotUsingSnap:

/* Customised Replication insert proc utilized to support adding to replication without a snapshot. */
create procedure [dbo].[sp_MSupd_dboTableNotUsingSnap]     
    @c1 int = NULL,     
    @c2 varchar(4096) = NULL,     
    @c3 datetime = NULL, 
    @pkc1 int = NULL, 
    @bitmap binary(1)
AS 
BEGIN
    declare @primarykey_text nvarchar(100) = '' 

    if (substring(@bitmap,1,1) & 1 = 1)
    begin 
        update [dbo].[TableNotUsingSnap]
        set [Id] = case substring(@bitmap,1,1) & 1 when 1 then @c1 else [Id] end, 
            [Note_Text] = case substring(@bitmap,1,1) & 2 when 2 then @c2 else [Note_Text] end,
            [Repl_Upsert_UTC] = case substring(@bitmap,1,1) & 4 when 4 then @c3 else [Repl_Upsert_UTC] END
        WHERE [Id] = @pkc1

        /*  Commented out while adding to publication
        if @@rowcount = 0
            if @@microsoftversion>0x07320000
            Begin
                set @primarykey_text = @primarykey_text + '[id] = ' + convert(nvarchar(100),@pkc1,1)
                exec sp_MSreplraiserror @errorid=20598, @param1=N'[dbo].[TableNotUsingSnap]', @param2=@primarykey_text, @param3=13233
            End */
    END
    ELSE
    BEGIN
        update [dbo].[TableNotUsingSnap]
        set [Note_Text] = case substring(@bitmap,1,1) & 2 when 2 then @c2 else [Note_Text] end,
            [Repl_Upsert_UTC] = case substring(@bitmap,1,1) & 4 when 4 then @c3 else [Repl_Upsert_UTC] END
        WHERE [Id] = @pkc1

        /*  Commented out while adding to publication
        if @@rowcount = 0
            if @@microsoftversion>0x07320000
            Begin
                set @primarykey_text = @primarykey_text + '[id] = ' + convert(nvarchar(100),@pkc1,1)
                exec sp_MSreplraiserror @errorid=20598, @param1=N'[dbo].[TableNotUsingSnap]', @param2=@primarykey_text, @param3=13233
            End */
    end
END
GO

sp_MSdel_dboTableNotUsingSnap:

/* Customised Replication insert proc utilized to support adding to replication without a snapshot. */
create procedure [dbo].[sp_MSdel_dboTableNotUsingSnap]
    @pkc1 int
as
begin  
    declare @primarykey_text nvarchar(100) = ''

    delete [dbo].[TableNotUsingSnap]
    where [Id] = @pkc1

    /* ignore if the record doesn't exist when deleting it 
    if @@rowcount = 0
        if @@microsoftversion>0x07320000
        Begin
            set @primarykey_text = @primarykey_text + '[Id] = ' + convert(nvarchar(100),@pkc1,1)
            exec sp_MSreplraiserror @errorid=20598, @param1=N'[dbo].[TableNotUsingSnap]', @param2=@primarykey_text, @param3=13234
        End */
end
GO

導入手順

3.ディストリビューションエージェントを停止します-ディストリビューター(プッシュ)またはサブスクライバー(プル)

/*  example script to add a table to a publication without running the snapshot agent
    Steps:
        Pre steps:
        1. Create table on subscribers
        2. Create replication procs on subscribers

        Deployment/Potential impact:
    **  3. Stop Distribution Agents to all subscribers for this publication
        4. Add article to publication on publisher
        5. DTS data from publisher to subscriber
        6. Start Distribution Agents to all subscribers for this publication
        7. Monitor/Verify all data has arrived

    =========================================================
    Note: check your publication settings:
          if @independent_agent = N'false'
            you will need to stop the distribution agent which will affect ALL
            publications going to that subscriber

          if @independent_agent = N'true'
            you will need to stop the publication specific distribution agent 
            (to each subscriber)

          Plan your live release around that knowledge!
*/

-- IF PUSH REPLICATION: RUN ON DISTRIBUTION SERVER
-- IF PULL REPLICATION: RUN ON SUBSCRIBER SERVER

/* disable the Job first */
exec msdb..sp_update_job @job_name = '[Distribution agent job]', @enabled = 0
GO

/* wait for 10 seconds - precaution ONLY */
WAITFOR DELAY '00:00:10.000'
GO

/* now stop the job */
exec msdb..sp_stop_job @job_name = '[Distribution agent job]'
GO

/* 
    NOTE: You might recieve an error about stopping a job that is already stopped.  You can ignore that error.
                It is up to you to verify that the job has been stopped correctly!
*/

4.ここで、パブリケーションに記事を追加します-パブリッシャーで

主なパラメーター:

  • sp_addarticle- @pre_creation_cmd = N'none'独自のオブジェクトを削除および生成しないようにディストリビューションエージェントに指示するために使用
  • sp_addsubscription- @sync_type = N'none'新しいスナップショットを作成する必要がないことをディストリビューターに伝えるために使用されます。IUDコマンドをキューに入れるだけです。

sp_addarticle:

exec sp_addarticle 
    @publication = N'Publication Name',
    @article = N'TableNotUsingSnap',
    @source_owner = N'dbo',
    @source_object = N'TableNotUsingSnap',
    @type = N'logbased',
    @description = N'',
    @creation_script = N'',
    @pre_creation_cmd = N'none',        /* this is a critical flag - tells SQL Server to not drop/recreate the repl procs/object on the subscriber */
    @schema_option = 0x0000000008004093,
    @identityrangemanagementoption = N'none',
    @destination_table = N'TableNotUsingSnap',
    @destination_owner = N'dbo',
    @status = 16,
    @vertical_partition = N'false',
    @ins_cmd = N'CALL [sp_MSins_dboTableNotUsingSnap]',
    @del_cmd = N'CALL [sp_MSdel_dboTableNotUsingSnap]',
    @upd_cmd = N'SCALL [sp_MSupd_dboTableNotUsingSnap]'
GO

-- Adding the transactional subscriptions
exec sp_addsubscription @publication = N'Publication Name',
    @subscriber = N'Subscriber Server',
    @destination_db = N'Subscriber DB',
    @subscription_type = N'Push',
    @sync_type = N'none',               /* tell SQL Server not to sync/snapshot this change to the publication */
    @article = N'all',
    @update_mode = N'read only',
    @subscriber_type = 0
GO

5.データを同期します

次に、サブスクライバーにデータをコピーする必要があります:

  • リンクサーバーを作成し、コピーします
  • エクスポート/インポートウィザードを使用する
  • バックアップを復元して差分を適用する
  • SSMS Toolpack「Generate Insert Statements ...」を使用してテーブルを抽出します

使用する正確な方法は読者にお任せします。また、ディストリビューションエージェントを停止する時間に依存します。

追加テストの追加ステップとして、ここでスクリプトを実行して(ステップ(B)から)、[TableNotUsingSnap]でIUDアクションを作成して、この方法に自信を持たせることができます。

6.ディストリビューションエージェントを再起動します-ディストリビューター(プッシュ)またはサブスクライバー(プル)

/*  example script to add a table to a publication without running the snapshot agent
    Steps:
        Pre steps:
        1. Create table on subscribers
        2. Create replication procs on subscribers

        Deployment/Potential impact:
        3. Stop Distribution Agents to all subscribers for this publication
        4. Add article to publication on publisher
        5. DTS data from publisher to subscriber
    **  6. Start Distribution Agents to all subscribers for this publication
        7. Monitor/Verify all data has arrived

    =========================================================
    Note: check your publication settings:
          if @independent_agent = N'false'
            you will need to stop the distribution agent which will affect ALL
            publications going to that subscriber

          if @independent_agent = N'true'
            you will need to stop the publication specific distribution agent 
            (to each subscriber)

          Plan your live release around that knowledge!
*/

-- IF PUSH REPLICATION: RUN ON DISTRIBUTION SERVER
-- IF PULL REPLICATION: RUN ON SUBSCRIBER SERVER

/* disable the Job first */
exec msdb..sp_update_job @job_name = 'Distribution agent job', @enabled = 1
GO

/* wait for 10 seconds - precaution ONLY */
WAITFOR DELAY '00:00:10.000'
GO

/* now stop the job */
exec msdb..sp_start_job @job_name = 'Distribution agent job'
GO

/* 
    Now go and make sure everything is working ok!
*/
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.