it-swarm-eu.dev

Artikel zur Transaktionsveröffentlichung hinzufügen, ohne einen neuen Snapshot zu generieren

Wenn wir die Transaktionsreplikation von SQL 2008 R2 mit Pull-Abonnenten verwenden und einen Artikel hinzufügen, möchte ich vermeiden, dass ein vollständiger Snapshot erstellt werden muss (die Datenbank ist ~ 80 GB groß, dies dauert also Stunden).

Von dieser Artikel habe ich gesehen, wie dies mit einem Teilschnappschuss gemacht wird, indem sofort_sync deaktiviert wird, aber das hat bei uns nicht funktioniert.

Idealerweise möchte ich dies einfach als Teil unseres Datenbank-Skripts ausführen, um die Tabelle zu erstellen. Wenn wir also möchten, dass sie repliziert wird, tun wir Folgendes:

Create Table ...    
sp_addArticle ...    
sp_PushThisToOurSubscribersNow    
24
user175528

Sie können den Artikel über SSMS über die GUI hinzufügen und sogar Filter darauf anwenden. Solange Sie keine der anderen Eigenschaften des Artikels ändern, müssen Sie keinen vollständigen Schnappschuss erstellen.

Wenn Sie in der GUI der Veröffentlichung auf OK klicken (nachdem Sie den Artikel hinzugefügt haben), wird er geschlossen, ohne dass Sie zur erneuten Initialisierung aufgefordert werden. Wenn zur erneuten Initialisierung aufgefordert wird, werden Sie etwas geändert haben, das einen vollständigen Schnappschuss erfordert. In diesem Fall drücken Sie Abbrechen und versuchen Sie es erneut.

Nachdem Sie den Artikel hinzugefügt haben, können Sie einfach den Snapshot-Job starten. Sie werden feststellen, dass nur ein Snapshot für den neuen Artikel generiert wird (als Mini-Snapshot bezeichnet).

Überprüfen Sie dann Ihren Verteilungsjob und stellen Sie fest, dass er die Tabelle beim Abonnenten erstellt und Ihre Daten in großen Mengen kopiert hat.

Viel Glück und lassen Sie mich wissen, wenn Sie weitere Hilfe benötigen.

13
NTDLS
  1. Fügen Sie neue Artikel in Ihr Eigenschaftsfenster für Veröffentlichungen ein (deaktivieren Sie das Kontrollkästchen Nur geprüfte Artikel anzeigen in der Liste).
  2. klicken Sie mit der rechten Maustaste auf denselben Publikationsknoten und gehen Sie zu " Status des Snapshot-Agenten anzeigen ".
  3. klicken Sie auf Start und notieren Sie sich das Protokoll in denselben Fenstern, in dem angezeigt wird, dass dieser neue Artikel nur synchronisiert ist
  4. nach kurzer Zeit werden die neuen Artikel in Abonnenten synchronisiert, ohne dass alle zuvor synchronisierten Artikel initialisiert werden

(enter image description here

8
Iman Abidi

Ich hatte die gleiche Frage, und obwohl ich eine Weile DBA war, habe ich mich nicht tief genug mit der Replikation befasst, um mich damit vollständig vertraut zu machen. Daher fand ich die folgenden Ressourcen und Anleitungen hilfreich:

  • Dieser Blog , der einen guten Überblick über den Prozess gab. Es erinnert uns auch daran, dass, wenn Sie eine große vorhandene Publikation haben und die Option auf "instant_sync" gesetzt ist, jedes Mal, wenn Sie einen Artikel hinzufügen oder ändern, ein völlig neuer Snapshot erstellt wird. Er hat also einen praktischen Tipp, um diese Option mit sp_changePublication @publication='MyPub', @property='immediate_sync', @value='false'; Zu ändern.

  • MSDN-Blogbeitrag in "repltalk" (klingt im Allgemeinen nach einer guten Ressource!) - nicht "direkt direkt" verwandt, aber dennoch hilfreich

  • Diese Frage, in der @ Brandon-Williams darauf hinwies, dass wenn es sich um ein Pull Abonnement handelt, Sie es auch mit sp_refreshSubscriptions @publication = 'MyPub' Aktualisieren sollten.

  • SSMS Replication Monitor - bequeme Möglichkeit zum Stoppen und Starten der Agenten (Snapshot, Protokollleser), wenn Sie die Anleitung befolgen.

Hier sind die tatsächlichen Schritte, die ich befolgt habe, die gut funktioniert haben und die Zustimmung meines betreuenden DBA erhalten haben:

  1. Öffnen Sie den Replikationsmonitor, wählen Sie die Publikation aus, gehen Sie zu Agenten, klicken Sie mit der rechten Maustaste auf Log Reader Agent, und klicken Sie auf Stop.
  2. Stellen Sie die Veröffentlichung mit sp_changePublication Auf "Nicht anonym und nicht sofort synchronisieren" ein. Ja, wie @cody_konior hervorhebt, ist dies nicht dokumentiert, aber in meinem Fall hat es einwandfrei funktioniert. YMMV
  3. Erstellt die Tabelle beim Abonnenten manuell mithilfe eines Skripts, das mithilfe einer Verbindungsserverabfrage mit Daten gefüllt wird (da diese klein war). Sie können dazu auch SSIS, BCP oder andere Mittel verwenden. Und es ist möglicherweise nicht erforderlich, wenn Sie mit dem Repl-Snapshot einverstanden sind, der dies für Sie erledigt. Ich wollte es nur beim ersten Mal manuell vorbereiten.
  4. Fügen Sie den Artikel (Tabelle) mit sp_addArticle Hinzu.
  5. Fügen Sie alle Spalten der Tabelle mit sp_articleColumn Hinzu (angegebene Veröffentlichung und Artikel, KEINE Spalten angegeben -> impliziert ALLE Spalten)
  6. Führen Sie sp_refreshSubscriptions Für diese Veröffentlichung aus, um den Pull-Er zu aktualisieren
  7. Öffnen Sie den Replikationsmonitor erneut, wählen Sie die Kneipe aus, gehen Sie zu Agenten, klicken Sie mit der rechten Maustaste auf Snapshot-Agent und klicken Sie auf "Start". Es wird einmal ausgeführt und erstellt den neuen Schnappschuss.
  8. Klicken Sie mit der rechten Maustaste auf Log Reader Agent und klicken Sie auf "Start". Es wird wie gewohnt gestartet und weiter ausgeführt, und Ihre Replikation sollte jetzt wieder funktionieren.

Und obwohl ja, Sie könnten die meisten Änderungen mit der SSMS-GUI vornehmen, finde ich es hilfreich, alles zu skripten, damit es A) unter Quellcodeverwaltung (Änderungssteuerung) sein kann, und B) wiederholt oder auf mehreren Instanzen bereitgestellt. Leider habe ich nicht die Zeit damit verbracht, die Stopps/Starts des Agenten zu skripten, aber das sollte nicht zu schwierig sein, da es sich nur um SQL Agent-Jobs handelt. Sie müssen nur den ganzen Trick "Finden der Job-ID mit dem Job-Namen" ausführen (Abfrage sysjobs - wirklich, MS?) ...

Hoffe das hilft zukünftigen Lesern!

3
NateJ

Wie in Hinzufügen von Artikeln zu und Löschen von Artikeln aus vorhandenen Veröffentlichungen angegeben, müssen Sie * einen neuen Snapshot für die Veröffentlichung erstellen.

Um zu vermeiden, dass beim Hinzufügen eines neuen Artikels ein Snapshot für alle Artikel erstellt wird, muss die Veröffentlichungseigenschaft immediate_sync Auf 0 gesetzt werden. Rufen Sie sp_addarticle Und dann sp_addsubscription Auf. Wenn Abonnements gezogen werden, müssen Sie auch sp_refreshsubscriptions Aufrufen. Generieren Sie dann einen Schnappschuss und es wird nur ein Schnappschuss für den neu hinzugefügten Artikel generiert.

* Dies ist der empfohlene Ansatz in SQL Server Books Online. Das Problem bei Ihrem Ansatz ist, dass er fehleranfällig ist.

3

Hauptbearbeitung Dies ist eine vollständige Überarbeitung dieser Antwort (unter Berücksichtigung der gültigen Kritik, dass die vorherige Version fehleranfällig war und Probleme verursachen würde)

Außerdem wurde eine Demo veröffentlicht, in der beschrieben wird, wie dies angewendet wird: Youtube - SQL Server-Replikation: Hinzufügen eines Artikels ohne Schnappschuss .

WICHTIG: Dies ist [~ # ~] nicht [~ # ~] Ein empfohlener Ansatz von Microsoft, damit Sie selbstständig sind, um ihn zum Laufen zu bringen. Tun Sie [~ # ~] nicht [~ # ~] direkt auf Ihre Produktionsumgebung anwenden, ohne wesentliche isolierte Tests durchzuführen und sich mit den Schritten vertraut zu machen!

Folgende Schritte:

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)

Verifizieren:

  • einfügen am Herausgeber durchführen - Überprüfen Sie, ob die Zeile beim Abonnenten eintrifft
  • update für Publisher durchführen - Überprüfen Sie, ob die Änderung beim Abonnenten eingeht
  • löschen beim Herausgeber durchführen - Überprüfen Sie, ob die Zeile beim Abonnenten gelöscht wurde
  • stellen Sie sicher, dass die letzten n Zeilen angekommen sind und zwischen Herausgeber und Abonnent übereinstimmen

BEISPIEL Prozess

A) Erstellen Sie eine Tabelle in Ihrem Verlag:

/* 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) Erstellen Sie sich einen Job/Proc/Skript, um einige Einfügungen/Aktualisierungen/Löschungen in [TableNotUsingSnap] durchzuführen (Sie können dies dann verwenden, um zu überprüfen, wie der Abonnent mit dieser Methode korrekt synchronisiert wird.

Vorschritte:

1. Erstellen Sie Ihre Tabelle auf dem Abonnenten

/* 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. Erstellen Sie Ihre gespeicherten Replikationsprozeduren (Aktualisieren/Einfügen/Löschen) - auf dem Abonnenten

Sie können die Repl-Prozesse erstellen:

  • Manuell (seien Sie vorsichtig, da es sehr leicht ist, einen Fehler zu machen!)
  • Fügen Sie den Artikel mithilfe der MS Snapshot-Methode auf einem Dev-Computer hinzu und schreiben Sie die Repl-Prozesse ab (bereit, dass Sie Ihre Optimierungen hinzufügen können).
  • Erstellen/Finden Sie eine Art Generator

Die Änderung, die Sie anwenden müssen:

  • sp_MSinsIF NOT EXISTS (SELECT 'row already exists' FROM [Schema].[TableName] dest WITH (NOLOCK) WHERE dest.Id = @c1) hinzu, um es nicht einzufügen, wenn es bereits vorhanden ist
  • sp_MSupd_ [Schema] [Tabellenname] - Kommentieren Sie IF @@rowcount = 0 ... exec sp_MSreplraiserror ... aus, um ein Update zu ignorieren, das nicht angewendet wird (da der Datensatz möglicherweise auf dem Herausgeber gelöscht wurde, bevor Sie die Daten synchronisiert haben).
  • sp_MSdel_ [Schema] [TableName] - Kommentieren Sie IF @@rowcount = 0 ... exec sp_MSreplraiserror ... aus, um einen Löschvorgang zu ignorieren, der nicht angewendet wird (da der Datensatz möglicherweise auf dem Herausgeber gelöscht wurde, bevor Sie die Daten synchronisiert haben).

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]', @[email protected]_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]', @[email protected]_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]', @[email protected]_text, @param3=13234
        End */
end
GO

ENTWICKLUNGSSCHRITTE

3. Stoppen Sie den Verteilungsagenten - Auf dem Verteiler (Push) oder Abonnenten (Pull)

/*  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. Fügen Sie nun den Artikel zur Publikation hinzu - On the Publisher

Schlüsselparameter:

  • sp_addarticle - @pre_creation_cmd = N'none' Wird verwendet, um den Verteilungsagenten anzuweisen, keine eigenen Objekte zu löschen und zu generieren
  • sp_addsubscription - @sync_type = N'none' Wird verwendet, um Distributer mitzuteilen, dass kein neuer Snapshot erstellt werden muss, sondern nur die IUP-Befehle in die Warteschlange gestellt werden können

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. Synchronisieren Sie Ihre Daten über

Jetzt müssen Sie Ihre Daten auf Ihren Abonnenten kopieren. Sie können:

  • Erstellen Sie einen Verbindungsserver und kopieren Sie ihn über
  • Verwenden Sie den Export/Import-Assistenten
  • Stellen Sie eine Sicherung wieder her und wenden Sie Unterschiede an
  • Extrahieren Sie die Tabelle mit dem SSMS Toolpack 'Generate Insert Statements ...'.

Die genaue Methode, die Sie verwenden, überlasse ich dem Leser. Dies hängt auch davon ab, wie lange Sie bereit sind, Ihren Distributionsagenten anzuhalten.

EXTRA: Als zusätzlichen Schritt in Ihren Tests ist hier ein guter Ort, um Ihr Skript auszuführen (ab Schritt (B)), um IUP-Aktionen für [zu erstellen TableNotUsingSnap], damit Sie Vertrauen in diese Methode gewinnen können.

6. Starten Sie den Verteilungsagenten neu - Auf dem Verteiler (Push) oder Abonnenten (Pull)

/*  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!
*/
2