Home
%3CLINGO-SUB%20id%3D%22lingo-sub-750751%22%20slang%3D%22en-US%22%3EHow%20to%20configure%20bi-directional%20transaction%20replication%20between%20SQL%20MI%20and%20SQL%20VM%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-750751%22%20slang%3D%22en-US%22%3E%3CP%3ERecently%20I%20got%20an%20advisory%20request%20on%20how%20to%20configure%20bi-directional%20replication%20in%20MI%20and%20I%20realize%20we%20don't%20have%20much%20documentation%20on%20this%20so%20hopefully%20following%20example%20script%20that%20I%20tested%20will%20be%20helpful%3A%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CSTRONG%3EGoal%3A%26nbsp%3B%3C%2FSTRONG%3EReplicate%20the%20same%20table%20from%20MI%20to%20SQL%20VM%20as%20well%20as%20from%20SQL%20VM%20to%20MI.%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CU%3E%3CSTRONG%3EOn%20SQL%20MI%20side%3A%3C%2FSTRONG%3E%3C%2FU%3E%3C%2FP%3E%0A%3CP%3EUSE%20%5Bmaster%5D%3C%2FP%3E%0A%3CP%3EGO%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EEXEC%20sp_adddistributor%20%40distributor%20%3D%20%40%40ServerName%3B%3C%2FP%3E%0A%3CP%3EEXEC%20sp_adddistributiondb%20%40database%20%3D%20N'distribution'%3B%3C%2FP%3E%0A%3CP%3EGO%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3Asetvar%20username%20xxxx%3C%2FP%3E%0A%3CP%3E%3Asetvar%20password%20xxxxxxxxx%3C%2FP%3E%0A%3CP%3E%3Asetvar%20file_storage%20%22%2F%2Fxxxxx.file.core.windows.net%2Fxxxxx%22%3C%2FP%3E%0A%3CP%3E%3Asetvar%20file_storage_key%20%22DefaultEndpointsProtocol%3Dhttps%3BAccountName%3Dxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx%3D%3D%3BEndpointSuffix%3Dcore.windows.net%22%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3EUSE%20%5Bmaster%5D%3C%2FP%3E%0A%3CP%3EEXEC%20sp_adddistpublisher%3C%2FP%3E%0A%3CP%3E%40publisher%20%3D%20%40%40ServerName%2C%3C%2FP%3E%0A%3CP%3E%40distribution_db%20%3D%20N'distribution'%2C%3C%2FP%3E%0A%3CP%3E%40security_mode%20%3D%200%2C%3C%2FP%3E%0A%3CP%3E%40login%20%3D%20N'%24(username)'%2C%3C%2FP%3E%0A%3CP%3E%40password%20%3D%20N'%24(password)'%2C%3C%2FP%3E%0A%3CP%3E%40working_directory%20%3D%20N'%24(file_storage)'%2C%3C%2FP%3E%0A%3CP%3E%40storage_connection_string%20%3D%20N'%24(file_storage_key)'%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%26nbsp%3B%20--%20Set%20variables%3C%2FP%3E%0A%3CP%3E%3Asetvar%20username%20xxxxx%3C%2FP%3E%0A%3CP%3E%3Asetvar%20password%20xxxxxxxxxxxxxxxxxx%3C%2FP%3E%0A%3CP%3E%3Asetvar%20source_db%20xxxxx%3C%2FP%3E%0A%3CP%3E%3Asetvar%20publication_name%20xxxxxx%3C%2FP%3E%0A%3CP%3E%3Asetvar%20object%20XXXXXX%3C%2FP%3E%0A%3CP%3E%3Asetvar%20schema%20dbo%3C%2FP%3E%0A%3CP%3E%3Asetvar%20target_server%20%22VM%20IP%22%3C%2FP%3E%0A%3CP%3E%3Asetvar%20target_username%20XXXX%3CEM%3E(I%20used%20sql%20account%20here)%3C%2FEM%3E%3C%2FP%3E%0A%3CP%3E%3Asetvar%20target_password%20xxxxxx%3C%2FP%3E%0A%3CP%3E%3Asetvar%20target_db%20xxxxxx%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E--%20Enable%20replication%20for%20your%20source%20database%3C%2FP%3E%0A%3CP%3EUSE%20%5B%24(source_db)%5D%3C%2FP%3E%0A%3CP%3EEXEC%20sp_replicationdboption%3C%2FP%3E%0A%3CP%3E%40dbname%20%3D%20N'%24(source_db)'%2C%3C%2FP%3E%0A%3CP%3E%40optname%20%3D%20N'publish'%2C%3C%2FP%3E%0A%3CP%3E%40value%20%3D%20N'true'%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E--%20Create%20your%20publication%3C%2FP%3E%0A%3CP%3EEXEC%20sp_addpublication%3C%2FP%3E%0A%3CP%3E%40publication%20%3D%20N'%24(publication_name)'%2C%3C%2FP%3E%0A%3CP%3E%40status%20%3D%20N'active'%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E--%20Configure%20your%20log%20reaer%20agent%3C%2FP%3E%0A%3CP%3EEXEC%20sp_changelogreader_agent%3C%2FP%3E%0A%3CP%3E%40publisher_security_mode%20%3D%200%2C%3C%2FP%3E%0A%3CP%3E%40publisher_login%20%3D%20N'%24(username)'%2C%3C%2FP%3E%0A%3CP%3E%40publisher_password%20%3D%20N'%24(password)'%2C%3C%2FP%3E%0A%3CP%3E%40job_login%20%3D%20N'%24(username)'%2C%3C%2FP%3E%0A%3CP%3E%40job_password%20%3D%20N'%24(password)'%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E--%20Add%20the%20publication%20snapshot%3C%2FP%3E%0A%3CP%3EEXEC%20sp_addpublication_snapshot%3C%2FP%3E%0A%3CP%3E%40publication%20%3D%20N'%24(publication_name)'%2C%3C%2FP%3E%0A%3CP%3E%40frequency_type%20%3D%201%2C%3C%2FP%3E%0A%3CP%3E%40publisher_security_mode%20%3D%200%2C%3C%2FP%3E%0A%3CP%3E%40publisher_login%20%3D%20N'%24(username)'%2C%3C%2FP%3E%0A%3CP%3E%40publisher_password%20%3D%20N'%24(password)'%2C%3C%2FP%3E%0A%3CP%3E%40job_login%20%3D%20N'%24(username)'%2C%3C%2FP%3E%0A%3CP%3E%40job_password%20%3D%20N'%24(password)'%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E--%20Add%20the%20ReplTest%20table%20to%20the%20publication%3C%2FP%3E%0A%3CP%3EEXEC%20sp_addarticle%3C%2FP%3E%0A%3CP%3E%40publication%20%3D%20N'%24(publication_name)'%2C%3C%2FP%3E%0A%3CP%3E%40type%20%3D%20N'logbased'%2C%3C%2FP%3E%0A%3CP%3E%40article%20%3D%20N'%24(object)'%2C%3C%2FP%3E%0A%3CP%3E%40source_object%20%3D%20N'%24(object)'%2C%3C%2FP%3E%0A%3CP%3E%40source_owner%20%3D%20N'%24(schema)'%2C%3C%2FP%3E%0A%3CP%3E%3CFONT%20color%3D%22%23ff0000%22%3E%40schema_option%20%3D%200x80030F3%3B%3C%2FFONT%3E%3CEM%3E%2F%2FI%20need%20to%20use%20this%20schema%20option%20otherwise%20the%20primary%20key%20got%20lost%20upon%20replication.%3C%2FEM%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E--%20Add%20the%20subscriber%3C%2FP%3E%0A%3CP%3EEXEC%20sp_addsubscription%3C%2FP%3E%0A%3CP%3E%40publication%20%3D%20N'%24(publication_name)'%2C%3C%2FP%3E%0A%3CP%3E%40subscriber%20%3D%20N'%24(target_server)'%2C%3C%2FP%3E%0A%3CP%3E%40destination_db%20%3D%20N'%24(target_db)'%2C%3C%2FP%3E%0A%3CP%3E%40subscription_type%20%3D%20N'Push'%2C%3C%2FP%3E%0A%3CP%3E%3CFONT%20color%3D%22%23ff0000%22%3E%40sync_type%20%3D%20N'replication%20support%20only'%3C%2FFONT%3E%2C%26nbsp%3B%20%3CEM%3E%2F%2FThis%20option%20is%20needed%20thus%20we%20don%E2%80%99t%20need%20to%20run%20snapshot.%20Snapshot%20will%20cause%20the%20replication%20fail%20with%20error%20%E2%80%9CCannot%20drop%20the%20table%20'dbo.ReplicateTable'%20because%20it%20is%20being%20used%20for%20replication%E2%80%9D.%20We%20will%20need%20to%20have%20the%20schema%20and%20data%20in%20sync%20on%20both%20sides%20before%20this%20replication.%3C%2FEM%3E%3C%2FP%3E%0A%3CP%3E%3CFONT%20color%3D%22%23ff0000%22%3E%40loopback_detection%20%3D'TRUE'%3B%3C%2FFONT%3E%3CEM%3E%2F%2FThis%20option%20is%20also%20needed%20for%20bidirectional%20replication%3C%2FEM%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E--%20Create%20the%20push%20subscription%20agent%3C%2FP%3E%0A%3CP%3EEXEC%20sp_addpushsubscription_agent%3C%2FP%3E%0A%3CP%3E%40publication%20%3D%20N'%24(publication_name)'%2C%3C%2FP%3E%0A%3CP%3E%40subscriber%20%3D%20N'%24(target_server)'%2C%3C%2FP%3E%0A%3CP%3E%40subscriber_db%20%3D%20N'%24(target_db)'%2C%3C%2FP%3E%0A%3CP%3E%40subscriber_security_mode%20%3D%200%2C%3C%2FP%3E%0A%3CP%3E%40subscriber_login%20%3D%20N'%24(target_username)'%2C%3C%2FP%3E%0A%3CP%3E%40subscriber_password%20%3D%20N'%24(target_password)'%2C%3C%2FP%3E%0A%3CP%3E%40job_login%20%3D%20N'%24(target_username)'%2C%3C%2FP%3E%0A%3CP%3E%40job_password%20%3D%20N'%24(target_password)'%3B%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3E%3CU%3E%3CSTRONG%3EOn%20SQL%20VM%20side%2C%3C%2FSTRONG%3E%3C%2FU%3E%3C%2FP%3E%0A%3COL%3E%0A%3CLI%3EI%20used%20the%20GUI%20to%20create%20the%20publication%20as%20I%20got%20login%20failed%20error%20for%20some%20reason%20when%20using%20the%20TSQL%20command.%3C%2FLI%3E%0A%3CLI%3EI%20used%20following%20script%20to%20add%20subscription%3C%2FLI%3E%0A%3C%2FOL%3E%0A%3CP%3Euse%20%5Bdbname%5D%3C%2FP%3E%0A%3CP%3Eexec%20sp_addsubscription%20%40publication%20%3D%20N'publicationname'%2C%20%40subscriber%20%3D%20N'mi.xxxxx.database.windows.net'%2C%20%40destination_db%20%3D%20N'targetdb'%2C%20%40subscription_type%20%3D%20N'Push'%2C%20%3CFONT%20color%3D%22%23ff0000%22%3E%40sync_type%20%3D%20N'replication%20support%20only'%2C%3C%2FFONT%3E%40article%20%3D%20N'all'%2C%20%40update_mode%20%3D%20N'read%20only'%2C%20%40subscriber_type%20%3D%200%2C%20%3CFONT%20color%3D%22%23ff0000%22%3E%40loopback_detection%20%3DN'TRUE'%3B%3C%2FFONT%3E%3C%2FP%3E%0A%3CP%3E%26nbsp%3B%3C%2FP%3E%0A%3CP%3Eexec%20sp_addpushsubscription_agent%20%40publication%20%3D%20N'publicationname'%2C%20%40subscriber%20%3D%20N'mi.xxxxxxx.database.windows.net'%2C%20%40subscriber_db%20%3D%20N'targetdb'%2C%20%40job_login%20%3D%20N'VM%5Cdanzhang'%2C%20%40job_password%20%3D%20'xxxxxxx'%2C%20%40subscriber_security_mode%20%3D%200%2C%20%40subscriber_login%20%3D%20N'xxxx'%2C%20%40subscriber_password%20%3D%20'xxxxx'%2C%20%40frequency_type%20%3D%2064%2C%20%40frequency_interval%20%3D%200%2C%20%40frequency_relative_interval%20%3D%200%2C%20%40frequency_recurrence_factor%20%3D%200%2C%20%40frequency_subday%20%3D%200%2C%20%40frequency_subday_interval%20%3D%200%2C%20%40active_start_time_of_day%20%3D%200%2C%20%40active_end_time_of_day%20%3D%20235959%2C%20%40active_start_date%20%3D%2020190528%2C%20%40active_end_date%20%3D%2099991231%2C%20%40enabled_for_syncmgr%20%3D%20N'False'%2C%20%40dts_package_location%20%3D%20N'Distributor'%3C%2FP%3E%0A%3CP%3EGO%3C%2FP%3E%3C%2FLINGO-BODY%3E
Microsoft

Recently I got an advisory request on how to configure bi-directional replication in MI and I realize we don't have much documentation on this so hopefully following example script that I tested will be helpful:

 

Goal:  Replicate the same table from MI to SQL VM as well as from SQL VM to MI. 

 

On SQL MI side:

USE [master]

GO

 

EXEC sp_adddistributor @distributor = @@ServerName;

EXEC sp_adddistributiondb @database = N'distribution';

GO

 

:setvar username xxxx

:setvar password xxxxxxxxx

:setvar file_storage "//xxxxx.file.core.windows.net/xxxxx"

:setvar file_storage_key "DefaultEndpointsProtocol=https;AccountName=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx==;EndpointSuffix=core.windows.net"

 

USE [master]

EXEC sp_adddistpublisher

@publisher = @@ServerName,

@distribution_db = N'distribution',

@security_mode = 0,

@login = N'$(username)',

@password = N'$(password)',

@working_directory = N'$(file_storage)',

@storage_connection_string = N'$(file_storage_key)';

 

   -- Set variables

:setvar username xxxxx

:setvar password xxxxxxxxxxxxxxxxxx

:setvar source_db xxxxx

:setvar publication_name xxxxxx

:setvar object XXXXXX

:setvar schema dbo

:setvar target_server "VM IP"

:setvar target_username XXXX(I used sql account here)

:setvar target_password xxxxxx

:setvar target_db xxxxxx

 

-- Enable replication for your source database

USE [$(source_db)]

EXEC sp_replicationdboption

@dbname = N'$(source_db)',

@optname = N'publish',

@value = N'true';

 

-- Create your publication

EXEC sp_addpublication

@publication = N'$(publication_name)',

@status = N'active';

 

 

-- Configure your log reaer agent

EXEC sp_changelogreader_agent

@publisher_security_mode = 0,

@publisher_login = N'$(username)',

@publisher_password = N'$(password)',

@job_login = N'$(username)',

@job_password = N'$(password)';

 

-- Add the publication snapshot

EXEC sp_addpublication_snapshot

@publication = N'$(publication_name)',

@frequency_type = 1,

@publisher_security_mode = 0,

@publisher_login = N'$(username)',

@publisher_password = N'$(password)',

@job_login = N'$(username)',

@job_password = N'$(password)';

 

 

-- Add the ReplTest table to the publication

EXEC sp_addarticle

@publication = N'$(publication_name)',

@type = N'logbased',

@article = N'$(object)',

@source_object = N'$(object)',

@source_owner = N'$(schema)',

@schema_option = 0x80030F3; //I need to use this schema option otherwise the primary key got lost upon replication.

 

-- Add the subscriber

EXEC sp_addsubscription

@publication = N'$(publication_name)',

@subscriber = N'$(target_server)',

@destination_db = N'$(target_db)',

@subscription_type = N'Push',

@sync_type = N'replication support only'//This option is needed thus we don’t need to run snapshot. Snapshot will cause the replication fail with error “Cannot drop the table 'dbo.ReplicateTable' because it is being used for replication”. We will need to have the schema and data in sync on both sides before this replication.

@loopback_detection ='TRUE'; //This option is also needed for bidirectional replication

 

-- Create the push subscription agent

EXEC sp_addpushsubscription_agent

@publication = N'$(publication_name)',

@subscriber = N'$(target_server)',

@subscriber_db = N'$(target_db)',

@subscriber_security_mode = 0,

@subscriber_login = N'$(target_username)',

@subscriber_password = N'$(target_password)',

@job_login = N'$(target_username)',

@job_password = N'$(target_password)';

 

On SQL VM side,

  1. I used the GUI to create the publication as I got login failed error for some reason when using the TSQL command.
  2. I used following script to add subscription

use [dbname]

exec sp_addsubscription @publication = N'publicationname', @subscriber = N'mi.xxxxx.database.windows.net', @destination_db = N'targetdb', @subscription_type = N'Push', @sync_type = N'replication support only', @article = N'all', @update_mode = N'read only', @subscriber_type = 0, @loopback_detection =N'TRUE';

 

exec sp_addpushsubscription_agent @publication = N'publicationname', @subscriber = N'mi.xxxxxxx.database.windows.net', @subscriber_db = N'targetdb', @job_login = N'VM\danzhang', @job_password = 'xxxxxxx', @subscriber_security_mode = 0, @subscriber_login = N'xxxx', @subscriber_password = 'xxxxx', @frequency_type = 64, @frequency_interval = 0, @frequency_relative_interval = 0, @frequency_recurrence_factor = 0, @frequency_subday = 0, @frequency_subday_interval = 0, @active_start_time_of_day = 0, @active_end_time_of_day = 235959, @active_start_date = 20190528, @active_end_date = 99991231, @enabled_for_syncmgr = N'False', @dts_package_location = N'Distributor'

GO