Додайте статтю до транзакційного видання, не створюючи нового знімка


23

Використовуючи транзакційну реплікацію SQL 2008 R2 з підписниками, що додають, коли ми додаємо статтю, я хотів би уникати створення цілого знімка (db становить ~ 80 ГБ, тому це займає години).

З цієї статті я бачив, як це зробити за допомогою часткового знімка, встановивши вимкнено_синхронізацію, але це не спрацювало для нас.

В ідеалі я хотів би просто запустити це як частину нашого сценарію db, щоб створити таблицю, тому, якщо ми хочемо, щоб вона була повторена, ми робимо:

Create Table ...    
sp_addArticle ...    
sp_PushThisToOurSubscribersNow    

Відповіді:


13

Ви можете додати статтю через SSMS за допомогою GUI і навіть застосувати до неї фільтри. Поки ви не зміните жодних інших властивостей статті, вам не знадобиться генерувати повний знімок.

Коли ви натиснете кнопку OK в графічному інтерфейсі публікації (після додавання статті), він буде закритий без запиту переініціалізіровать - якщо він робить запит на повторну ініціалізацію, то ви змінили то , що вимагає повного знімка. Якщо це трапиться, натисніть Скасувати та спробуйте ще раз.

Після додавання статті ви можете просто почати роботу з знімком, і ви помітите, що вона створює лише знімок для нової статті (називається міні-знімок).

Потім перевірте свою роботу з розповсюдження та помітьте, що вона створила таблицю у передплатника та масово скопіювала ваші дані.

Удачі, і повідомте мене, якщо вам потрібна подальша допомога.


Я зробив усе, що було пояснено у цій відповіді, але все-таки я очікував синхронізувати всю реплікувану базу даних. Мені НЕ було запропоновано повторно ініціалізуватися після додавання нових статей, але це все ще зробило повну ініціалізацію. Будь обережний.
JzInqXc9Dg

7
  1. Додайте нові статті у вікно властивості публікації (зніміть прапорець Показувати лише відмічені статті у списку)
  2. клацніть правою кнопкою миші той самий вузол публікації та перейдіть до " Переглянути статус агента знімка "
  3. натисніть кнопку " Пуск" і просто відзначте журнал у тих же вікнах, де показано, що ця нова стаття синхронізована
  4. через короткий час нові статті будуть синхронізовані в підписниках, не збираючись ініціалізувати всі раніше синхронізовані

введіть тут опис зображення


3

У мене було те саме питання, і хоча я деякий час був DBA, я насправді не займався тиражуванням досить глибоко, щоб бути повністю комфортним з ним, тому я вважав, що наступні ресурси та посібники корисні:

  • Цей блог , який дав хороший контур процесу. Це також нагадує нам, що якщо у вас є велика вже наявна публікація, і вона встановлена ​​на "негайне_синхронізація", це спричинить підготовку абсолютно нового знімка щоразу, коли ви додаєте або змінюєте статтю. Тож у нього є корисна порада змінити цей варіант, використовуючиsp_changePublication @publication='MyPub', @property='immediate_sync', @value='false';

  • Повідомлення в блозі MSDN в "repltalk" (це загалом звучить як хороший ресурс!) - не "безпосередньо безпосередньо", але все-таки корисно

  • Це питання, де @ Брендон-Вільямс вказував, що якщо це підписка на Pull , ви також повинні оновити її, використовуючиsp_refreshSubscriptions @publication = 'MyPub'

  • Монітор реплікації SSMS - зручний спосіб зупинки та запуску агентів (знімок, зчитування журналів) при дотриманні керівництва.

Ось фактичні кроки, які я виконував, які добре працювали та відповідали схваленню мого наглядового DBA:

  1. Відкрийте Монітор реплікації, виберіть публікацію, перейдіть до Агенти, клацніть правою кнопкою миші Агент читання журналів і натисніть Зупинити.
  2. Встановіть публікацію не дозволяти-анонімно та не негайно синхронізувати, використовуючи sp_changePublication- так, як вказує @cody_konior, це недодокументовано, але в моєму випадку воно спрацювало нормально. YMMV
  3. Створив таблицю у абонента вручну за допомогою скрипту, заповнившись даними за допомогою запиту на зв’язаний сервер (оскільки він був невеликим). Ви також можете використовувати SSIS, BCP або якісь інші засоби для цього. І це може не бути необхідним, якщо ви все в порядку, коли репл-знімок робить це за вас. Я просто хотів підготувати його вручну вперше.
  4. Додайте статтю (таблицю) за допомогою sp_addArticle
  5. Додайте всі стовпці таблиці за допомогою sp_articleColumn(вказана публікація та стаття; DIDN'T уточнюйте стовпці -> має на увазі ВСІ стовпці)
  6. Exec'd sp_refreshSubscriptionsдля цієї публікації, щоб оновити потяг
  7. Знову відкрийте Монітор реплікації, виберіть паб, перейдіть до Агенти, клацніть правою кнопкою миші Агент зйомки, натисніть «Пуск». Вона запуститься один раз, створивши новий знімок.
  8. Клацніть правою кнопкою миші Агент з читання журналів, натисніть «Пуск». Він запуститься і продовжить працювати як звичайно, і ваша реплікація повинна працювати знову.

І хоча так, ви можете зробити більшість змін за допомогою графічного інтерфейсу SSMS, я вважаю корисним все це зафіксувати, щоб він міг бути A) під контролем джерела (управління зміною) та B) повторно розгорнуто або в декілька примірників . На жаль, я не витратив час на розробку сценаріїв, коли Агент зупиняється / запускається, але це не повинно бути занадто важким, враховуючи, що вони просто SQL Agent Jobs. Вам просто потрібно виконати цілий трюк "знайти JobID за допомогою Job-Name" (запит sysjobs- справді, MS?) ...

Сподіваємось, що допоможе майбутнім читачам!


3

Як зазначено у Додаванні статей до та видаленню статей із існуючих публікацій , ви повинні * створити новий знімок для публікації.

Щоб уникнути створення знімків для всіх статей при додаванні нової статті, властивість публікації immediate_syncповинна бути встановлена ​​на 0. sp_addarticleПотім виклик sp_addsubscription. Якщо підписки витягнуті, потрібно також зателефонувати sp_refreshsubscriptions. Потім створіть знімок, і буде створено лише знімок для щойно доданої статті.

* Це рекомендований підхід у Інтернет-книжках SQL Server. Проблема вашого підходу полягає в тому, що він схильний до помилок.


2

Основна редакція Це повне перезапис цієї відповіді (приймаючи до уваги справедливу критику, що попередня версія була схильною до помилок і спричинила б проблеми)

Також розміщено демонстрацію того, як це застосувати до: Youtube - Реплікація SQL Server: Як додати статтю без зйомки .

ВАЖЛИВО: Це НЕ рекомендований підхід від Microsoft, тому ви будете самостійно щодо того, щоб працювати, НЕ застосовуйте безпосередньо до свого виробничого середовища без значних ізольованих тестувань і не будете комфортно виконувати дії!

Кроки для виконання:

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) Створіть собі завдання / proc / скрипт, щоб зробити кілька вставок / оновлень / видалень на [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:

  • Вручну (будьте обережні, оскільки помилитися дуже легко!)
  • Додайте статтю за допомогою методу MS Snapshot на машині Dev та відключіть скрипт із програмами repl (готові додати налаштування)
  • Створити / знайти якийсь генератор

Зміни, які потрібно застосувати:

  • sp_MSins_ [Схема] [Таблиця] - Додати, IF NOT EXISTS (SELECT 'row already exists' FROM [Schema].[TableName] dest WITH (NOLOCK) WHERE dest.Id = @c1)щоб не вставити, якщо вона вже є
  • sp_MSupd_ [Схема] [Таблиця] - прокоментуйте IF @@rowcount = 0 ... exec sp_MSreplraiserror ...ігноруйте оновлення, яке не застосовується (оскільки запис може бути видалено видавцем до синхронізації даних)
  • sp_MSdel_ [Схема] [Таблиця] - Прокоментуйте 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'використовується для того, щоб сказати Distributer, що йому не потрібно створювати новий знімок, він може просто встановити чергу команд 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 "Генерувати заяви про вставку ..."

Точний метод, який ви використовуєте, я залишаю до читача, він також буде залежати від того, на який термін ви готові зупинити вашого дистриб'юторського агента.

ДОПОМОГА: Як додатковий крок у ваших тестах, ось гарне місце для запуску вашого сценарію (від кроку (B)) для створення дій IUD на [TableNotUsingSnap], щоб ви могли отримати впевненість у цьому методі.

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!
*/
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.