Pagine

martedì 17 luglio 2012

SQL Server 2012: Transactional replication e Always On

E' possibile configurare una Transactional Replication per un database coinvolto in Always on Availability Group e fare in modo che anche in caso di failover la replica continui a funzionare ? Si è possibile !
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