Vediamo come.
Nel mio caso gli attori coinvolti nello scenario Always On/Transactional Replication saranno 3 e tutti con SQL 2012 installato:
1. Win2012Node1
2. Win2012Node2
3. Win2012Node3
Win2012Node1 e Win2012Node2 fanno parte di un Availability Group a cui è associato il database [MyTestDatabase] a cui fa riferimento anche un Listener denominato MyListener.
Al termine della configurazione lo scenario sarà il seguente :
1. Win2012Node1 = Primary Publisher
2. Win2012Node2 = Failover Publisher
3. Win2012Node3 = Distributor and Subscriber
Win2012Node3 non è compreso nell'Availability Group ed il suo ruolo in questo scenario sarà quello di Distributor e di Subscriber per la nostra Transactional Replication.

Passo 1: Verifica Prerequisito
Verificare se tutti gli attori coinvolti hanno la replication installata. Eseguiamo su tutti i server SQL coinvolti la seguente query:
USE master; GO DECLARE @installed int; EXEC @installed = sys.sp_MS_replication_installed; SELECT @installed; GO
Se 1 Replication presente, 0 non presente.
Passo 2: Configurare Win2012NODE3 come Distributor
Dal Management Studio mi connetto a WIN2012NODE3 ed eseguo gli script seguenti
Use [Master] Go --Configuro WIN2012NODE3 come distributor ed imposto una Pwd exec sp_adddistributor @distributor = N'WIN2012NODE3', @password = N'Pa$$w0rd' GO --Creo il database di gestione della distribuzione denominato MyDistributionDb exec sp_adddistributiondb @database = N'MyDistributionDb' , @data_folder = N'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Data' , @log_folder = N'C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\Data' , @log_file_size = 2, @security_mode = 1 GO
Ora devo configurare la snapshot folder che sarà utilizzata nella transactional replication. Deve essere un path accessibile da tutti gli attori coinvolti
use [MyDistributionDb] Go --Configuro la snapshot folder if (not exists (select * from sysobjects where name = 'UIProperties' and type = 'U ')) create table UIProperties(id int) if (exists (select * from ::fn_listextendedproperty('SnapshotFolder', 'user', 'dbo', 'table', 'UIProperties', null, null))) EXEC sp_updateextendedproperty N'SnapshotFolder', N'\\win2012dc\TempSharedFolder\Replication Snapshot', 'user', dbo, 'table', 'UIProperties' else EXEC sp_addextendedproperty N'SnapshotFolder', N'\\win2012dc\TempSharedFolder\Replication Snapshot', 'user', dbo, 'table', 'UIProperties' GO
Configuriamo quindi i Publisher di questo Distributor
--Aggiungo WIN2012NODE1 e WIN2012NODE2 come publisher al server Distributor --Aggiungo WIN2012NODE1 exec sp_adddistpublisher @publisher = N'WIN2012NODE1' , @distribution_db = N'MyDistributionDb' , @security_mode = 1 , @working_directory = N'\\win2012dc\TempSharedFolder\Replication Snapshot' , @publisher_type = N'MSSQLSERVER' GO --Aggiungo WIN2012NODE2 exec sp_adddistpublisher @publisher = N'WIN2012NODE2' , @distribution_db = N'MyDistributionDb' , @security_mode = 1 , @working_directory = N'\\win2012dc\TempSharedFolder\Replication Snapshot' , @publisher_type = N'MSSQLSERVER' GO
Passo 3: Configurare WIN2012NODE1 e WIN2012NODE2 come Publisher
Mi connetto con Management Studio a WIN2012NODE1 ed eseguo lo script seguente:
use master go --configuro WIN2012NODE3 come Distributor per il server WIN2012NODE1 exec sp_adddistributor @distributor = N'WIN2012NODE3', @password = N'Pa$$w0rd' GO --Abilito il db per la publicazione Transazionale use [MyTestDatabase] Go exec sp_replicationdboption @dbname = N'MyTestDatabase', @optname = N'publish', @value = N'true' Go
Applichiamo lo stesso script anche a WIN2012NODE2.
Passo 4: Reindirizziamo il Publisher sul listener [MyListener]
WIN2012NODE1 è attualmente il server Primary del nostro availability group mentre WIN2012NODE2 è il Secondary. WIN2012NODE1 è di conseguenza anche il publisher che replicherà il database MyTestDataBase ai Subscriber grazie al distributor WIN2012NODE3. Per far si che la Transactional replication che stiamo configurando benefici anch'essa dell'Always On Availability Group è necessario reindirizzare il publisher principale verso il Listener [MyListener]
Per ragioni d'autenticazione è necessario eseguire fisicamente lo script dalla macchina Distributor.
Connettiamoci quindi al Distributor WIN2012NODE3 ed eseguiamo lo script seguente :
USE MyDistributionDb; GO EXEC sys.sp_redirect_publisher @original_publisher = 'WIN2012NODE1', @publisher_db = 'MyTestDatabase', @redirected_publisher = 'MyListener'; Go DECLARE @redirected_publisher_out sysname; EXEC sys.sp_validate_replica_hosts_as_publishers @original_publisher = 'WIN2012NODE1', @publisher_db = 'MyTestDatabase', @redirected_publisher = @redirected_publisher_out output; Go
Passo 5: Pubblichiamo il database [MyTestDatabase]
Connettiamoci all'istanza WIN2012NODE1 che in questo momento è il server Primary dell'availability group e dunque colui che pubblicherà il DB fino a che non si verificherà un Failover.
Eseguiamo lo script seguente :
use [MyTestDatabase] Go --Aggiungo la pubblicazione del Database MyTestDatabase exec sp_addpublication @publication = N'MyAgGroupPubblication' , @description = 'MyAgGroupPubblication = Transactional Replication' , @sync_method = N'concurrent' , @retention = 0 , @allow_push = N'true' , @allow_pull = N'true' , @allow_anonymous = N'true' , @enabled_for_internet = N'false' , @snapshot_in_defaultfolder = N'true' , @compress_snapshot = N'false' , @ftp_port = 21 , @allow_subscription_copy = N'false' , @add_to_active_directory = N'false' , @repl_freq = N'continuous' , @status = N'active' , @independent_agent = N'true' , @immediate_sync = N'true' , @allow_sync_tran = N'false' , @allow_queued_tran = N'false' , @allow_dts = N'false' , @replicate_ddl = 1 , @allow_initialize_from_backup = N'false' , @enabled_for_p2p = N'false' , @enabled_for_het_sub = N'false' GO --Gestione iniziale dello snapshot exec sp_addpublication_snapshot @publication = N'MyAgGroupPubblication' , @frequency_type = 1 , @frequency_interval = 1 , @frequency_relative_interval = 1 , @frequency_recurrence_factor = 0 , @frequency_subday = 8 , @frequency_subday_interval = 1 , @active_start_time_of_day = 0 , @active_end_time_of_day = 235959 , @active_start_date = 0 , @active_end_date = 0 , @job_login = null , @job_password = null , @publisher_security_mode = 1 GO --Aggiungo gli articoli da replicare, la tabelle dbo.test exec sp_addarticle @publication = N'MyAgGroupPubblication' , @article = N'test' , @source_owner = N'dbo' , @source_object = N'test' , @type = N'logbased' , @description = null , @creation_script = null , @pre_creation_cmd = N'drop' , @identityrangemanagementoption = N'manual' , @destination_table = N'test' , @destination_owner = N'dbo' , @vertical_partition = N'false' , @ins_cmd = N'CALL sp_MSins_dbotest' , @del_cmd = N'CALL sp_MSdel_dbotest' , @upd_cmd = N'SCALL sp_MSupd_dbotest' GO --Creo lo snapshot iniziale della pubblicazione exec sp_startpublication_snapshot @publication = N'MyAgGroupPubblication' GO
La nostra pubblicazione ora è attiva su WIN2012NODE1.
Ma come potete vedere è già configurata anche su WIN2012NODE2 !!
Passo 6: Configurare un subscriber
Configuro ora WIN2012NODE3 anche come Subscriber della nostra publicazione MyAgGroupPubblication.
Preparo un DB vuoto denominato MyTestSubscription su WIN2012NODE3.
create database MyTestSubscription
La sottoscrizione che vado ad implementare è di tipo Push, cioè l'agent è sul server Publisher.
Mi connetto a WIN2012NODE1 ed eseguo lo script seguente:
use [MyTestDatabase] Go --Creo la sottoscrizione alla pubblicazione exec sp_addsubscription @publication = N'MyAgGroupPubblication' , @subscriber = N'WIN2012NODE3' , @destination_db = N'MyTestSubscription' , @subscription_type = N'Push' , @sync_type = N'automatic' , @article = N'all' , @update_mode = N'read only' , @subscriber_type = 0 Go --Ne definisco il tipo Push exec sp_addpushsubscription_agent @publication = N'MyAgGroupPubblication' , @subscriber = N'WIN2012NODE3' , @subscriber_db = N'MyTestSubscription' , @job_login = null , @job_password = null , @subscriber_security_mode = 1 , @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 = 20120717 , @active_end_date = 99991231 , @enabled_for_syncmgr = N'False' , @dts_package_location = N'Distributor' GO
A questo punto la configurazione è conclusa.
Vediamo se funziona.
Mi connetto all'istanza primary attraverso il listener [MyListener] ed implemento un inserimento nel database MyTestDatabase
use [MyTestDatabase] GO Insert into dbo.test values(@@SERVERNAME) GO
Verifichiamo se il database [MyTestSubscription] ha ricevuto l'aggiornamento eseguendo la select (potrebbe essere necessario attendere qualche secondo) :
use [MyTestDatabase] GO Select * from dbo.test GO
Ed ecco il risultato
Verifichiamo ora se in caso di failover la nostra transactional replication continua a funzionare.
Implemento un failover manuale e sempre da [MyListener] rieseguo il comando di insert precedente.
Dato che abbiamo effettuato un failover la prima esecuzione darà un errore di comunicazione, basta rieseguire il comando....
Proviamo con la select precedente a visualizzare il contenuto della tabella dbo.test del db [MyTestSubscription]. (Per visualizzare il contenuto aggiornato potrebbe essere necessario attendere qualche secondo)
Come potete vedere la replication ha continuato a funzionare nonostante il failover.
L'anello debole quindi nel nostro caso è il server distributor dato che non è possibile inserire il database MyDistributorDb, più in generale tutti i db di sistema, in un Availability Group. Per proteggere anche questo componente è necessario implementare un cluster.
(Grazie ad Alberto Gastaldo per la precisazione)
Ciao
Luca
Nessun commento:
Posta un commento