Configurare la replica in MySQL è facile, ma gestirla in produzione non è mai stato un compito facile. Anche con il nuovo posizionamento automatico GTID, può comunque andare storto se non sai cosa stai facendo. Dopo aver impostato la replica, qualsiasi cosa può andare storta. Gli errori possono essere facilmente commessi e possono avere una fine disastrosa per i tuoi dati.
Questo post evidenzierà alcuni degli errori più comuni commessi con la replica di MySQL e come puoi prevenirli.
Configurazione della replica
Quando si imposta la replica MySQL, è necessario eseguire il primer dei nodi slave con il set di dati del master. Con soluzioni come il cluster Galera, questo viene gestito automaticamente per te con il metodo che preferisci. Per la replica di MySQL, devi farlo tu stesso, quindi naturalmente prendi il tuo strumento di backup standard.
Per MySQL è disponibile un'enorme varietà di strumenti di backup, ma il più comunemente usato è mysqldump. Mysqldump emette un backup logico del set di dati del tuo master. Ciò significa che la copia dei dati non sarà una copia binaria, ma un file di grandi dimensioni contenente query per ricreare il set di dati. Nella maggior parte dei casi questo dovrebbe fornirti una copia (quasi) identica dei tuoi dati, ma ci sono casi in cui non lo farà, poiché il dump è per oggetto. Ciò significa che anche prima di iniziare a replicare i dati, il tuo set di dati non è lo stesso di quello sul master.
Ci sono un paio di modifiche che puoi fare per rendere mysqldump più affidabile come il dump come una singola transazione, e inoltre non dimenticare di includere routine e trigger:
mysqldump -uuser -ppass --single-transaction --routines --triggers --all-databases > dumpfile.sql
Una buona pratica è verificare se il tuo nodo slave è uguale al 100%, utilizzando pt-table-checksum dopo aver impostato la replica:
pt-table-checksum --replicate=test.checksums --ignore-databases mysql h=localhost,u=user,p=pass
Questo strumento calcolerà un checksum per ogni tabella sul master, replicherà il comando allo slave e quindi il nodo slave eseguirà la stessa operazione di checksum. Se una delle tabelle non è la stessa, dovrebbe essere chiaramente visibile nella tabella del checksum.
Utilizzo del metodo di replica errato
Il metodo di replica predefinito di MySQL era la cosiddetta replica basata su istruzioni. Questo metodo è esattamente quello che è:un flusso di replica di ogni istruzione eseguita sul master che verrà riprodotta sul nodo slave. Poiché MySQL stesso è multi-thread ma la sua replica (tradizionale) non lo è, l'ordine delle istruzioni nel flusso di replica potrebbe non essere lo stesso al 100%. Anche la riproduzione di un'istruzione può dare risultati diversi quando non viene eseguita esattamente nello stesso momento.
Ciò può comportare set di dati diversi tra il master e lo slave, a causa della deriva dei dati. Questo non è stato un problema per molti anni, poiché non molti hanno eseguito MySQL con molti thread simultanei, ma con le moderne architetture multi-CPU, questo è diventato molto probabile su un normale carico di lavoro quotidiano.
La risposta di MySQL è stata la cosiddetta replica basata su righe. La replica basata su riga replicherà i dati quando possibile, ma in alcuni casi eccezionali utilizza ancora le istruzioni. Un buon esempio potrebbe essere la modifica della DLL di una tabella, in cui la replica dovrebbe quindi copiare ogni riga della tabella tramite la replica. Poiché questo è inefficiente, tale affermazione verrà replicata in modo tradizionale. Quando la replica basata su riga rileva la deriva dei dati, interrompe il thread slave per evitare di peggiorare le cose.
Poi c'è un metodo tra questi due:la replica in modalità mista. Questo tipo di replica replica sempre le istruzioni, tranne quando la query contiene la funzione UUID(), vengono utilizzati trigger, stored procedure, UDF e poche altre eccezioni. La modalità mista non risolverà il problema della deriva dei dati e, insieme alla replica basata su istruzioni, dovrebbe essere evitata.
Replica circolare
L'esecuzione della replica MySQL con multi-master è spesso necessaria se si dispone di un ambiente multi-datacenter. Poiché l'applicazione non può attendere che il master nell'altro datacenter riconosca la tua scrittura, è preferibile un master locale. Normalmente l'offset di incremento automatico viene utilizzato per evitare conflitti di dati tra i master. Avere due master che si scrivono l'un l'altro in questo modo è una soluzione ampiamente accettata.
Replica MySQL Master-MasterTuttavia, se devi scrivere in più data center nello stesso database, ti ritroverai con più master che devono scrivere i propri dati l'uno con l'altro. Prima di MySQL 5.7.6 non esisteva un metodo per eseguire una replica di tipo mesh, quindi l'alternativa sarebbe utilizzare invece una replica ad anello circolare.
Topologia di replica ad anello MySQLLa replica ad anello in MySQL è problematica per i seguenti motivi:latenza, disponibilità elevata e deriva dei dati. Scrivendo alcuni dati sul server A, ci vorrebbero tre salti per finire sul server D (tramite il server B e C). Poiché la replica (tradizionale) di MySQL è a thread singolo, qualsiasi query di lunga durata nella replica potrebbe bloccare l'intero anello. Inoltre, se uno qualsiasi dei server si interrompesse, l'anello si guasterebbe e attualmente non esiste un software di failover in grado di riparare le strutture dell'anello. Quindi può verificarsi una deriva dei dati quando i dati vengono scritti sul server A e contemporaneamente modificati sul server C o D.
Replica anello rottoIn generale, la replica circolare non è adatta a MySQL e dovrebbe essere evitata a tutti i costi. Galera sarebbe una buona alternativa per le scritture multi-datacenter, poiché è stata progettata tenendo conto di questo.
Blocco della replica con aggiornamenti di grandi dimensioni
Spesso vari lavori batch di pulizia eseguiranno varie attività, che vanno dalla pulizia dei vecchi dati al calcolo della media dei "Mi piace" recuperati da un'altra fonte. Ciò significa che a intervalli prestabiliti, un lavoro creerà molta attività nel database e, molto probabilmente, riscriverà molti dati nel database. Naturalmente ciò significa che l'attività all'interno del flusso di replica aumenterà in egual modo.
La replica basata su istruzioni replicherà le query esatte utilizzate nei processi batch, quindi se la query ha richiesto mezz'ora per l'elaborazione sul master, il thread slave verrà bloccato almeno per lo stesso periodo di tempo. Ciò significa che nessun altro dato può essere replicato e i nodi slave inizieranno a rimanere indietro rispetto al master. Se questo supera la soglia del tuo strumento di failover o proxy, potrebbe eliminare questi nodi slave dai nodi disponibili nel cluster. Se utilizzi la replica basata su istruzioni, puoi evitarlo sgretolando i dati per il tuo lavoro in batch più piccoli.
Ora potresti pensare che la replica basata su riga non sia influenzata da ciò, poiché replicherà le informazioni sulla riga anziché la query. Ciò è in parte vero, poiché per le modifiche DDL, la replica torna al formato basato su istruzioni. Anche un numero elevato di operazioni CRUD influenzerà il flusso di replica:nella maggior parte dei casi si tratta ancora di un'operazione a thread singolo e quindi ogni transazione attenderà che la precedente venga riprodotta tramite replica. Ciò significa che se hai un'elevata concorrenza sul master, lo slave potrebbe bloccarsi per il sovraccarico delle transazioni durante la replica.
Per aggirare questo problema, sia MariaDB che MySQL offrono la replica parallela. L'implementazione può variare in base al fornitore e alla versione. MySQL 5.6 offre la replica parallela purché le query siano separate dallo schema. MariaDB 10.0 e MySQL 5.7 possono entrambi gestire la replica parallela tra schemi, ma hanno altri limiti. L'esecuzione di query tramite thread slave paralleli può accelerare il flusso di replica se la scrittura è pesante. Tuttavia, in caso contrario, sarebbe meglio attenersi alla tradizionale replica a thread singolo.
Modifiche allo schema
L'esecuzione di modifiche allo schema su una configurazione di produzione in esecuzione è sempre una seccatura. Ciò ha a che fare con il fatto che una modifica DDL nella maggior parte dei casi bloccherà una tabella e rilascerà questo blocco solo una volta applicata la modifica DDL. Peggiora anche quando inizi a replicare queste modifiche DDL tramite la replica MySQL, dove inoltre bloccherà il flusso di replica.
Una soluzione alternativa utilizzata di frequente consiste nell'applicare prima la modifica dello schema ai nodi slave. Per la replica basata su istruzioni funziona bene, ma per la replica basata su riga può funzionare fino a un certo punto. La replica basata su riga consente l'esistenza di colonne aggiuntive alla fine della tabella, quindi finché è in grado di scrivere le prime colonne andrà bene. Applicare prima la modifica a tutti gli slave, quindi eseguire il failover su uno degli slave, quindi applicare la modifica al master e collegarlo come slave. Se la modifica comporta l'inserimento di una colonna al centro o la rimozione di una colonna, funzionerà con la replica basata su riga.
Esistono strumenti in grado di eseguire modifiche allo schema online in modo più affidabile. Il Percona Online Schema Change (noto come pt-osc) creerà una tabella shadow con la nuova struttura della tabella, inserirà nuovi dati tramite trigger e riempirà i dati in background. Una volta terminata la creazione della nuova tabella, scambierà semplicemente la vecchia con la nuova tabella all'interno di una transazione. Questo non funziona in tutti i casi, specialmente se la tua tabella esistente ha già dei trigger.
Un'alternativa è il nuovo strumento Gh-ost di Github. Questo strumento di modifica dello schema online creerà prima una copia del layout della tabella esistente, modificherà la tabella nel nuovo layout e quindi collegherà il processo come una replica MySQL. Utilizzerà il flusso di replica per trovare nuove righe che sono state inserite nella tabella originale e allo stesso tempo riempie nuovamente la tabella. Una volta terminato il riempimento, le tabelle originali e nuove cambieranno. Naturalmente anche tutte le operazioni sulla nuova tabella finiranno nel flusso di replica, quindi su ogni replica la migrazione avviene contemporaneamente.
Tabelle di memoria e replica
Mentre siamo in tema di DDL, un problema comune è la creazione di tabelle di memoria. Le tabelle di memoria sono tabelle non persistenti, la loro struttura della tabella rimane ma perdono i dati dopo un riavvio di MySQL. Quando si crea una nuova tabella di memoria sia su un master che su uno slave, entrambi avranno una tabella vuota e funzionerà perfettamente. Una volta riavviato uno dei due, la tabella verrà svuotata e si verificheranno errori di replica.
La replica basata su riga si interromperà quando i dati nel nodo slave restituiscono risultati diversi e la replica basata su istruzioni si interromperà quando tenterà di inserire dati già esistenti. Per le tabelle di memoria questo è un frequente interruttore di replica. La soluzione è semplice:fai semplicemente una nuova copia dei dati, cambia il motore in InnoDB e ora dovrebbe essere sicuro per la replica.
Impostazione della variabile di sola lettura su True
Come descritto in precedenza, non avere gli stessi dati nei nodi slave può interrompere la replica. Spesso questo è stato causato da qualcosa (o qualcuno) che ha alterato i dati sul nodo slave, ma non sul nodo master. Una volta che i dati del nodo master vengono alterati, questi verranno replicati sullo slave dove non può applicare la modifica e questo provoca l'interruzione della replica.
C'è una facile prevenzione per questo:impostare la variabile read_only su true. Ciò impedirà a chiunque di apportare modifiche ai dati, ad eccezione della replica e degli utenti root. La maggior parte dei gestori di failover imposta automaticamente questo flag per impedire agli utenti di scrivere sul master utilizzato durante il failover. Alcuni di loro lo conservano anche dopo il failover.
Ciò lascia comunque all'utente root l'esecuzione di una query CRUD errata sul nodo slave. Per evitare che ciò accada, esiste una variabile super_read_only da MySQL 5.7.8 che impedisce anche all'utente root di aggiornare i dati.
Abilitazione GTID
Nella replica MySQL, è essenziale avviare lo slave dalla posizione corretta nei log binari. È possibile ottenere questa posizione quando si esegue un backup (xtrabackup e mysqldump lo supportano) o quando si è smesso di eseguire lo slave su un nodo di cui si sta eseguendo una copia. L'avvio della replica con il comando CHANGE MASTER TO sarebbe simile al seguente:
mysql> CHANGE MASTER TO MASTER_HOST='x.x.x.x',MASTER_USER='replication_user', MASTER_PASSWORD='password', MASTER_LOG_FILE='master-bin.0001', MASTER_LOG_POS= 04;
Avviare la replica nel punto sbagliato può avere conseguenze disastrose:i dati possono essere scritti due volte o non aggiornati. Ciò provoca la deriva dei dati tra il nodo master e quello slave.
Anche quando il failover di un master su uno slave implica trovare la posizione corretta e cambiare il master nell'host appropriato. MySQL non conserva i log binari e le posizioni del suo master, ma crea i propri log e posizioni binari. Per riallineare un nodo slave al nuovo master questo potrebbe diventare un problema serio:la posizione esatta del master in fase di failover deve essere trovata sul nuovo master, quindi tutti gli slave possono essere riallineati.
Per risolvere questo problema, il Global Transaction Identifier (GTID) è stato implementato sia da Oracle che da MariaDB. I GTID consentono l'allineamento automatico degli slave e sia in MySQL che in MariaDB il server calcola da solo qual è la posizione corretta. Tuttavia entrambi hanno implementato il GTID in modo diverso e sono quindi incompatibili. Se è necessario impostare la replica dall'uno all'altro, la replica deve essere impostata con il tradizionale posizionamento del log binario. Inoltre, il tuo software di failover dovrebbe essere informato di non utilizzare GTID.
Conclusione
Speriamo di averti dato abbastanza consigli per stare fuori dai guai. Queste sono tutte pratiche comuni degli esperti di MySQL. Hanno dovuto impararlo nel modo più duro e con questi suggerimenti ci assicuriamo che non sia necessario.
Abbiamo alcuni white paper aggiuntivi che potrebbero essere utili se desideri saperne di più sulla replica di MySQL.
Whitepaper correlati MySQL Replication BlueprintIl whitepaper MySQL Replication Blueprint include tutti gli aspetti di una topologia di replica con i dettagli della distribuzione, la configurazione della replica, il monitoraggio, gli aggiornamenti, l'esecuzione di backup e la gestione dell'elevata disponibilità tramite proxy.Scarica replica MySQL per l'elevata disponibilitàQuesto tutorial copre le informazioni su MySQL Replication, con informazioni sulle ultime funzionalità introdotte in 5.6 e 5.7. C'è anche una sezione più pratica e pratica su come distribuire e gestire rapidamente una configurazione di replica utilizzando ClusterControl.Download