it-swarm.asia

أضف مقالة إلى منشور المعاملات دون إنشاء لقطة جديدة

باستخدام النسخ المتماثل للمعاملات في SQL 2008 R2 مع المشتركين في السحب ، عندما نضيف مقالة ، أود أن أتجنب الاضطرار إلى إنشاء لقطة كاملة (db ~ 80 GB ، لذا يستغرق ذلك ساعات).

من هذه المقالة ، رأيت كيفية القيام بذلك من خلال لقطة جزئية عن طريق إيقاف فوري للمزامنة ، ولكن ذلك لم يفلح بالنسبة لنا.

من الناحية المثالية ، أود فقط تشغيل هذا كجزء من برنامج db النصي لإنشاء الجدول ، لذلك إذا أردنا تكراره نقوم بذلك:

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

يمكنك إضافة المقالة من خلال SSMS باستخدام واجهة المستخدم الرسومية وحتى تطبيق المرشحات عليها. طالما أنك لا تغير أيًا من الخصائص الأخرى للمقالة ، فلن تحتاج إلى إنشاء لقطة كاملة.

عندما تضغط على OK في المنشور GUI (بعد إضافة المقال) ، سيتم إغلاقه دون المطالبة بإعادة التهيئة - إذا كان يطالب بإعادة التهيئة ، غيرت شيئًا يتطلب لقطة كاملة. إذا حدث ذلك ، اضغط إلغاء وحاول مرة أخرى.

بعد إضافة المقال ، يمكنك ببساطة بدء مهمة اللقطة وستلاحظ أنها تنشئ لقطة للمقال الجديد فقط (تسمى لقطة مصغرة).

ثم تحقق من وظيفة التوزيع الخاصة بك ، ولاحظ أنها أنشأت الجدول لدى المشترك ونسخ بياناتك بشكل مجمّع.

حظا سعيدا ، واسمحوا لي أن أعرف إذا كنت بحاجة إلى مزيد من المساعدة.

13
NTDLS
  1. إضافة مقالات جديدة في نافذة الخاصية الخاصة بك (قم بإلغاء تحديد إظهار المقالات المحددة فقط في القائمة)
  2. انقر بزر الماوس الأيمن على نفس عقدة المنشور وانتقل إلى " عرض حالة وكيل اللقطة "
  3. انقر ابدأ ولاحظ فقط تسجيل الدخول في نفس النوافذ التي تظهر أن هذه المقالة الجديدة تتم مزامنتها فقط
  4. بعد وقت قصير ، ستتم مزامنة المقالات الجديدة في المشتركين دون الانتقال إلى تهيئة جميع المتزامنة سابقًا

enter image description here

8
Iman Abidi

كان لدي نفس السؤال ، وعلى الرغم من أنني كنت DBA لفترة من الوقت ، لم أتعامل حقًا مع النسخ المتماثل بدرجة كافية لأكون مرتاحًا تمامًا له ، لذلك اعتقدت أن الموارد والأدلة التالية مفيدة:

  • هذه المدونة ، والتي قدمت مخططًا جيدًا للعملية. ويذكرنا أيضًا أنه إذا كان لديك منشور كبير موجود ، وتم تعيين خياره على "Instant_sync" ، فسيؤدي ذلك إلى إعداد لقطة جديدة تمامًا في كل مرة تضيف فيها مقالًا أو تغيره. لذلك لديه نصيحة مفيدة لتغيير هذا الخيار ، باستخدام sp_changePublication @publication='MyPub', @property='immediate_sync', @value='false';

  • منشور مدونة MSDN في "repltalk" (يبدو كمورد جيد بشكل عام!) - ليست ذات صلة "مباشرة" ولكنها لا تزال مفيدة

  • هذا السؤال ، حيث أشار @ براندون ويليامز إلى أنه إذا كان اشتراكًا سحب ، فيجب عليك أيضًا تحديثه باستخدام sp_refreshSubscriptions @publication = 'MyPub'

  • مراقب النسخ المتماثل SSMS - طريقة ملائمة لإيقاف وبدء الوكلاء (لقطة ، قارئ سجل) عند اتباع الدليل.

فيما يلي الخطوات الفعلية التي اتبعتها ، والتي عملت بشكل جيد وحققت موافقة DBA المشرفة:

  1. افتح "مراقبة النسخ المتماثل" ، حدد المنشور ، وانتقل إلى "وكلاء" ، وانقر بزر الماوس الأيمن فوق "عامل قارئ السجل" ، وانقر فوق "إيقاف".
  2. اضبط المنشور على عدم السماح بالمجهول وعدم المزامنة الفورية ، باستخدام sp_changePublication - نعم ، كما يشيرCody_konior ، هذا غير موثق بشكل جيد ، لكنه عمل بشكل جيد في حالتي. YMMV
  3. إنشاء الجدول عند المشترك يدويًا باستخدام برنامج نصي ، مليء بالبيانات باستخدام استعلام خادم مرتبط (نظرًا لأنه صغير). يمكنك أيضًا استخدام SSIS أو BCP أو بعض الوسائل الأخرى للقيام بذلك. وقد لا يكون ذلك ضروريًا ، إذا كنت على ما يرام مع اللقطة البديلة التي تقوم بذلك من أجلك. أردت فقط إعداده يدويًا في المرة الأولى.
  4. تضاف المادة (الجدول) باستخدام sp_addArticle
  5. أضف جميع أعمدة الجدول باستخدام sp_articleColumn (منشورات ومقالات محددة ، لم تحدد الأعمدة -> تتضمن جميع الأعمدة)
  6. Exec'd sp_refreshSubscriptions لهذا المنشور لتحديث السحب
  7. افتح "مراقبة النسخ المتماثل" مرة أخرى ، وحدد الحانة ، وانتقل إلى "وكلاء" ، وانقر بزر الماوس الأيمن فوق "عامل اللقطات" ، وانقر فوق "ابدأ". سيتم تشغيله مرة واحدة ، مما يؤدي إلى إنشاء لقطة جديدة.
  8. انقر بزر الماوس الأيمن على عامل قارئ السجل ، وانقر على "ابدأ". سيبدأ ويستمر في العمل كالمعتاد ، ويجب أن يعمل النسخ المتماثل الآن مرة أخرى.

وبينما نعم ، يمكنك can إجراء معظم التغييرات باستخدام واجهة المستخدم الرسومية لـ SSMS ، أجد أنه من المفيد كتابة النص برمته بالكامل حتى يمكن أن يكون A) تحت التحكم بالمصدر (التحكم في التغيير) ، و ب) نشر بشكل متكرر أو في حالات متعددة. لسوء الحظ ، لم أقضي الوقت في كتابة أوامر توقف/تشغيل Agent ، ولكن لا ينبغي أن يكون ذلك صعبًا للغاية نظرًا لأنها وظائف SQL Agent فقط. عليك فقط القيام بذلك كله "العثور على JobID باستخدام اسم الوظيفة" (الاستعلام sysjobs - حقا ، MS؟) ...

نأمل أن يساعد القراء في المستقبل!

3
NateJ

كما هو موضح في إضافة مقالات إلى المقالات وإسقاطها من المنشورات الموجودة ، يجب عليك * إنشاء لقطة جديدة للمنشور.

لتجنب إنشاء لقطة لجميع المقالات عند إضافة مقال جديد ، يجب تعيين خاصية النشر immediate_sync على 0. اتصل بـ sp_addarticle ، ثم sp_addsubscription. إذا تم سحب الاشتراكات ، يجب عليك أيضًا الاتصال بـ sp_refreshsubscriptions. ثم قم بإنشاء لقطة ولن يتم إنشاء سوى لقطة للمقالة المضافة حديثًا.

* هذا هو الأسلوب الموصى به في كتب SQL Server Online. المشكلة في أسلوبك هي أنه عرضة للأخطاء.

3
Brandon Williams

تعديل رئيسي هذه إعادة كتابة كاملة لهذه الإجابة (مع الأخذ في الاعتبار النقد الصادق بأن الإصدار السابق كان عرضة للخطأ وسيسبب مشاكل)

نشر أيضًا عرضًا توضيحيًا لكيفية تطبيق ذلك على: Youtube - SQL Server Replication: كيفية إضافة مقال بدون أخذ لقطة .

هام: هذا [~ # ~] ليس [~ # ~] نهج موصى به من 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)

للتحقق:

  • تنفيذ إدراج على الناشر - تحقق من وصول الصف إلى المشترك
  • إجراء التحديث على الناشر - التحقق من وصول التغيير إلى المشترك
  • تنفيذ الحذف على الناشر - التحقق من حذف الصف عند المشترك
  • تحقق من وصول آخر عدد من الصفوف ومطابقتها بين الناشر والمشترك

مثال العملية

أ) اصنع لنفسك طاولة على ناشرك:

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

ب) قم بإنشاء وظيفة/proc/script لنفسك للقيام ببعض الإدخالات/التحديث/الحذف على [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. قم بإنشاء الإجراءات المخزنة للنسخ المتماثل (التحديث/الإدراج/الحذف) - على المشترك

يمكنك إنشاء عمليات الاستبدال:

  • يدويًا (كن حذرًا لأنه من السهل جدًا ارتكاب خطأ!)
  • أضف المقالة باستخدام طريقة MS Snapshot على جهاز Dev وكتابة برنامج نصي من procs البديلة (جاهزة لإضافة تعديلاتك)
  • إنشاء/البحث عن نوع من المولد

التغيير الذي ستحتاجه للتطبيق:

  • sp_MSinsIF NOT EXISTS (SELECT 'row already exists' FROM [Schema].[TableName] dest WITH (NOLOCK) WHERE dest.Id = @c1) لعدم الإدراج إذا كان موجودًا بالفعل
  • sp_MSupd_ [مخطط] [TableName] - علّق على IF @@rowcount = 0 ... exec sp_MSreplraiserror ... لتجاهل تحديث لم يتم تطبيقه (حيث ربما تم حذف السجل على الناشر قبل مزامنة البيانات)
  • sp_MSdel_ [مخطط] [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]', @[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

خطوات النشر

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 "إنشاء بيانات الإدراج ..."

الطريقة الدقيقة التي تستخدمها أترك للقارئ ، ستعتمد أيضًا على المدة التي تريد أن يتوقف فيها وكيل التوزيع لديك.

EXTRA: كخطوة إضافية في اختباراتك ، إليك مكان جيد لتشغيل النص البرمجي (من الخطوة (ب)) لإنشاء إجراءات اللولب على [ 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!
*/
2
Andrew Bickerton