Attivare un nodo Galera Arbitrator in un Cluster Galera

Nei precedenti post Galera Cluster per MySQL e Automatizzare l’avvio di Galera Cluster ci siamo concentrati sull’installazione del cluster Galera su 2 nodi e sull’avvio automatico tramite script di job nel crontab. Qui voglio parlare invece del modulo Galera Arbitrator.

Galera Arbitrator

Abbiamo già sottolineato il fatto che è raccomandato configurare un cluster Galera usando un minimo di 3 nodi, e questo per evitare situazioni di split-brain in caso di problemi di connettività tra i nodi. Galera Arbitrator serve proprio a questo, rappresenta il terzo nodo del cluster ma non ospita dati, quindi non è coinvolto nelle operazioni di replica. Partecipa invece alle operazioni di voting ed in caso di perdita di connettività tra i nodi può nominare chi sarà il primario, evitando quindi il verificarsi di condizioni di split-brain.

Riprendendo i dati del cluster già installato, nel mio caso l’architettura sarà la seguente:

  • galera-node-1 172.31.81.55
  • galera-node-2 172.31.80.162
  • galera-arbitrator 172.31.6.110

I server 172.31.81.55 e 172.31.80.162 sono i 2 nodi Galera con installato MySQL, mentre il terzo nodo ospiterà il solo Arbitrator per il quale non occorrono risorse particolari, neppure in ambiente di produzione.

Setup

Per l’installazione procediamo allo stesso modo di un qualsiasi nodo di un cluster Galera. Quello che cambia infatti riguarda solo la configurazione ed il demone da avviare, che nel caso Arbitrator non sarà l’engine DB mysqld, ma il demone chiamato garbd. Pertanto, dobbiamo solo prevedere un repo file per accedere al repository di Galera Cluster ed installare il tutto yum install galera-4 mysql-wsrep-8.0. Completata l’installazione con yum assicuriamoci che l’avvio di MySQL sia disabilitato systemctl disable mysqld.

Il demone garbd può essere avviato da shell, oppure come servizio tramite systemctl. Supponendo di scegliere questa seconda opzione dobbiamo configurare il sistema modificando il file /etc/sysconfig/garb, andando a specificare il cluster name ed i nodi appartenenti al nostro cluster.

	# Copyright (C) 2012 Codership Oy
	# This config file is to be sourced by garb service script.

	# A comma-separated list of node addresses (address[:port]) in the cluster
	GALERA_NODES="172.31.81.55:4567,172.31.80.162:4567"

	# Galera cluster name, should be the same as on the rest of the nodes.
	GALERA_GROUP="galera-clusterdb"

	# Optional Galera internal options string (e.g. SSL settings)
	# see http://galeracluster.com/documentation-webpages/galeraparameters.html
	# GALERA_OPTIONS=""

	# Log file for garbd. Optional, by default logs to syslog
	# LOG_FILE="/var/log/garbd.log"

A questo punto possiamo avviare garbd tramite systemctl start garb.

Il passo successivo è quello di dire ai due nodi che ora esiste anche un terzo nodo, sebbene solo per le operazioni di voting. La modifica da fare alla configurazione riguarda il parametro wsrep_cluster_address, all’interno del file /etc/my.cnf, sul quale andremo ad aggiungere l’IP del nodo Arbitrator.

wsrep_cluster_address="gcomm://172.31.81.55,172.31.80.162,172.31.6.110"

Controllando la dimensione del cluster con SHOW STATUS LIKE 'wsrep_cluster_size'; possiamo verificare che ora la size del cluster è 3.

+--------------------+-------+
| Variable_name      | Value |
+--------------------+-------+
| wsrep_cluster_size | 3     |
+--------------------+-------+

Volendo fare qualche prova di funzionamento possiamo agire tramite iptables bloccando la comunicazione tra il nodo 2 del Cluster e gli altri nodi (nodo 1 ed Arbitrator).

	iptables -A INPUT -s 172.31.6.110 -j DROP; iptables -A OUTPUT -d 172.31.6.110 -j DROP
	iptables -A INPUT -s 172.31.81.55 -j DROP; iptables -A OUTPUT -d 172.31.81.55 -j DROP

L’Arbitrator si accorge che il nodo non è più raggiungibile.

	INFO: (1940e1d4-8259, 'tcp://0.0.0.0:4567') connection to peer 339f8f1d-a4ea with addr tcp://172.31.80.162:4567 timed out, no messages seen in PT3S, socket stats: rtt: 14992 rttvar: 19552 rto: 1720000 lost: 1 last_data_recv: 3381 cwnd: 1 last_queued_since: 381820935 last_delivered_since: 3381574527 send_queue_length: 0 send_queue_bytes: 0 segment: 0 messages: 0
	INFO: (1940e1d4-8259, 'tcp://0.0.0.0:4567') turning message relay requesting on, nonlive peers: tcp://172.31.80.162:4567
	INFO: (1940e1d4-8259, 'tcp://0.0.0.0:4567') reconnecting to 339f8f1d-a4ea (tcp://172.31.80.162:4567), attempt 0
	INFO: (1940e1d4-8259, 'tcp://0.0.0.0:4567') connection to peer 00000000-0000 with addr tcp://172.31.80.162:4567 timed out, no messages seen in PT3S, socket stats: rtt: 0 rttvar: 250000 rto: 2000000 lost: 1 last_data_recv: 2709114 cwnd: 1 last_queued_since: 3009114578953 last_delivered_since: 3009114578953 send_queue_length: 0 send_queue_bytes: 0

La size del cluster è ora ridotta a 2 l’Arbitrator ha bloccato le operazioni sul database ospitato dal nodo 2, infatti possiamo accedere a mysql sul nodo 2, ma non sono consentite operazioni.

Riattivando la connettività tra i nodi con iptables --flush, l’Arbitrator si accorge che il nodo è tornato raggiungibile e ristabilisce la size originale del cluster.

	INFO: STATE_EXCHANGE: sent state UUID: 664cf725-d87b-11ed-bfec-c212275b2001
	INFO: STATE EXCHANGE: sent state msg: 664cf725-d87b-11ed-bfec-c212275b2001
	INFO: STATE EXCHANGE: got state msg: 664cf725-d87b-11ed-bfec-c212275b2001 from 0 (garb)
	INFO: STATE EXCHANGE: got state msg: 664cf725-d87b-11ed-bfec-c212275b2001 from 1 (galera-node-2)
	INFO: STATE EXCHANGE: got state msg: 664cf725-d87b-11ed-bfec-c212275b2001 from 2 (galera-node-1)

E tutte le operazioni che erano state effettuate sul MySQL del nodo 1 sono sincronizzate sul nodo 2.