MySQL Multi-Source Replication

La funzionalita' di replica dati di MySQL e' semplice da configurare, richiede poca manutenzione, e' molto flessibile e non aggiunge carico al database Master: tutto questo ne spiega la forte diffusione.
Dalla versione 5.7 e' stata introdotta la possibilita' per uno Slave da accettare dati da piu' Master o, meglio, da piu' canali (Multi-Source).

La replica Multi-Source di MySQL puo' essere utile in molti casi: per consolidare database diversi, per centralizzare i backup, per disporre di un unico sistema di DR (Disaster Recovery), per creare un DWH aziendale, per unire gli shard (tecnica molto utilizzata per partizionare logicamente le tabelle e scalare le prestazioni in scrittura), ... e' una funzionalita' da tempo attesa dalla comunita' degli utenti MySQL.

Questa pagina riporta gli elementi principali sulla configurazione e gestione della replica Multi-Source di MySQL.

Nel seguito sono riportate alcune informazioni di interesse organizzate in paragrafi specifici: Introduzione, Configurazione, Amministrazione, ...

Un'introduzione generale sulla replica in MySQL si trova su questo documento.

Introduzione

Storicamente la replicazione su MySQL e' basata sugli statement ed asincrona. Il Master si occupa di registrare su file (bin-log file) tutti gli statement che vengono eseguiti sulla base dati e che operano una qualche modifica ai dati (DML e DDL). Le istruzioni registrate sono identificate mediante la loro posizione nei file bin-log.
Lo Slave si collega con un thread al Master, raccoglie il contenuto dei bin-log, lo trasferisce in locale e quindi si occupa di applicarlo alla base dati. Architettura MySQL Replication

E' possibile utilizzare uno Slave come Master a sua volta di una serie di Slave di secondo livello implementando cosi' la cascading replication. Il Master e lo Slave possono avere configurazioni diverse ed anche utilizzare Engine differenti. Anche le versioni possono essere diverse, pero' e' consentita la differenza di una sola major version e comunque e' consigliabile limitare le differenze presenti.

Ogni versione di MySQL ha introdotto nuove funzionalita' e dalla versione 5.7 sono stati introdotti i canali che consentono la replica Multi-Source.

Un canale individua una catena Master-Slave e tutti i thread coinvolti nella replica. Su uno Slave e' sempre presente un canale di default anonimo che non puo' essere disattivato ed un numero a piacere di canali [NdE non proprio a piacere: il limite e' 256] destinati alla replica Multi-Souce. Ogni canale e' indipendente e puo' essere definito/attivato/disattivato/cancellato in modo indipendente.

Questo documento fa riferimento alla versione MySQL 5.7.6 o successiva poiche' da tale versione sono state introdotte le funzionalita' relative al Multi-Source.

Configurazione

La configurazione della replica con Multi-Source e' simile a quella della replica tradizionale. La documentazione completa e' presente nel sito ufficiale, nel seguito riportiamo solo un semplice esempio di configurazione con due database Master ed uno Slave ma che copre tutti i punti fondamentali. MySQL Multi-Source Replication

Attivita' su Master1
 
Attivita' su Master2
 
Attivita' sullo Slave
 
Note
 
[mysqld]
server-id=10
log-bin=mysql-bin
relay_log_info_repository=table
master_info_repository=table
[mysqld]
server-id=20
log-bin=mysql-bin
relay_log_info_repository=table
master_info_repository=table
[mysqld]
server-id=30
read_only=ON
La configurazione di base per i Master e' semplice: oltre ai normali parametri di configurazione della replica vanno posti su TABLE i repository della topologia.

I server-id debbono essere differenti tra loro.

grant replication slave on *.* to 'repl'@'%' identified by 'xyz'; grant replication slave on *.* to 'repl'@'%' identified by 'xyz';  Non e' obbligatorio definire un nuovo utente ma e' consigliato sia per sicurezza che per semplicita' di configurazione e controllo
BackupBackup

Restore
Le modalita' backup/restore sono molteplici e dipendono da molti fattori. Nella maggioranza delle situazioni si effettua un backup/restore logico delle basi dati da replicare.
   change master to master_host='myMaster.MyDomain.it', master_user='repl', master_port=3306, master_password='xyz', master_auto_position=1 FOR CHANNEL 'master-1';

change master to master_host='myMaster.MyDomain.it', master_user='repl', master_port=3306, master_password='xyz', master_auto_position=1 FOR CHANNEL 'master-2';
Con questi comandi lo Slave sa come connettersi al Master e determina automaticamente da dove partire (perche' e' stata utilizzata la replica GTID).
  start slave FOR CHANNEL 'master-1';

start slave FOR CHANNEL 'master-2';
Per far partire i canali sullo Slave. Per ogni canale sono utilizzati un thread remoto (sul Master per inviare i bin-log) e due thread locali (IO_THREAD e SQL_THREAD per ricevere il bin-log ed applicarlo).

I passi riportati e le spiegazioni sono un po' semplificati ma... funzionano e rendono l'idea (spero ;-) E' ovvio che per far leggere i nuovi parametri del my.cnf e' necessario riavviare il server, che per lanciare uno statement SQL e' necessario collegarsi alla base dati...

Ulteriori parametri di configurazione

La configurazione vista nel paragrafo precedente e' gia' perfettamente funzionante. Ulteriori parametri relativi alla replica in generale sono riportati in questo documento.

I parametri di configurazione utilizzabili, come abbiamo visto, sono molteplici... Per riassumere riportiamo una possibile configurazione finale che contiene tutti i parametri di interesse per la replica (compresi quelli che hanno un impatto sulle prestazioni). La configurazione e' relativa ad una semplice architettura in cui sono presenti due master ed uno slave configurati in replicazione Multi-Source:

Parametri consigliati per la replica Multi-Source
[mysqld]
server-id=10
log-bin=mysql-bin
enforce-gtid-consistency=ON
gtid-mode=ON
innodb_flush_log_at_trx_commit=1
sync_binlog=1
relay_log_info_repository=table
master_info_repository=table
report-host=hostname
report-port=3306
# read_only=ON       ### Su tutti gli slave
# super_read_only=ON     ### Su tutti gli slave

Alcuni parametri sono specifici per Master/Slave, altri sono relativi alle performances, ... ma e' opportuno che le configurazioni siano allineate tra loro.

Amministrazione

L'amministrazione di una replica con Multi-Source e' analoga all'amministrazione della replica standard ed alla amministrazione della replica GTID (se e' utilizzata quest'ultima). C'e' solo l'ulteriore indicazione del canale!

Un esempio?

SELECT * FROM performance_schema.replication_connection_status; SELECT * FROM performance_schema.replication_connection_status WHERE channel_name='master-1';

In pratica ogni canale viene gestito in modo indipendente e, con la replica GTID, e' semplice controllare e recuperare in modo automatico le eventuali transazioni mancanti sullo Slave.

Duplicate entry

La configurazione riportata funziona se i server Master operano su database diversi oppure su tabelle diverse oppure su righe diverse...
Ma nel caso venga inserita la stessa chiave sui Master il secondo inserimento sullo Slave fallirebbe [NdA con il classico ERROR 1062: Duplicate entry] e si bloccherebbe la replica.

Nel caso in cui si debbano utilizzare gli stessi schemata e tabelle, oltre che una gestione applicativa delle chiavi, e' possibile sfruttare un trucco con il parametro auto_increment_increment. Ad esempio con due Master si imposta auto_increment_increment=2 sui server e si creano le tabelle rispettivamente con:

CREATE TABLE ...
  PRIMARY KEY (id)
  )
 ENGINE=InnoDB
 AUTO_INCREMENT=1000;
e con:
CREATE TABLE ...
  PRIMARY KEY (id)
  )
 ENGINE=InnoDB
 AUTO_INCREMENT=1001;

In questo modo le chiavi create sui database sono differenti e non si hanno errori sullo Slave.

Naturalmente questo non esaurisce tutte le possibili problematiche sui dati (eg. UNIQUE KEYS, constraints, ...) e puo' presentare alcuni problemi (eg. limite di chiavi) ma e' sicuramente molto utile.

Molto interessanti sono anche le possibilita' fornite dai filtri:

CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE = ('db1.%') FOR CHANNEL "master_1";
CHANGE REPLICATION FILTER REPLICATE_WILD_DO_TABLE = ('db2.%') FOR CHANNEL "master_2";

CHANGE REPLICATION FILTER REPLICATE_REWRITE_DB = ((db, db3)) FOR CHANNEL "master_1";
CHANGE REPLICATION FILTER REPLICATE_REWRITE_DB = ((db, db4)) FOR CHANNEL "master_2";

Nel primo caso viene preso il solo DB1 da un master ed il solo DB2 dal secondo master; nel secondo esempio dai due master viene preso un DB con lo stesso nome e rinominato in DB3 e DB4 a seconda della provenienza.

Varie ed eventuali

La replica Multi-Source su MariaDB, disponibile dalla versione 10.0, e' differente da quella MySQL (eg. utilizza i "connection name" al posto dei "channel"). La replica tra MySQL e MariaDB comunque non e' supportata ne consigliata.


Titolo: MySQL Multi-Source Replication
Livello: Avanzato (3/5)
Data: 14 Febbraio 2016 ❤️
Versione: 1.0.1 - 1 Aprile 2019 🐟
Autore: mail [AT] meo.bogliolo.name