Monte um MariaDB Galera Cluster com 3 nós no Ubuntu 24.04 ou Debian: configuração wsrep, SST com mariabackup, bootstrap, testes e recuperação.
O Galera Cluster transforma vários servidores MariaDB em um só banco lógico. A replicação é síncrona: uma transação só é confirmada depois que todos os nós a aceitam, e qualquer nó pode receber gravações. Se um servidor cai, os outros continuam atendendo sem perder dados.
Use pelo menos três nós. Com dois, quando um cai o outro não sabe se está sozinho ou isolado da rede e para de aceitar consultas para evitar divergência. Se só houver duas máquinas de banco, o terceiro voto pode vir do garbd (Galera Arbitrator), que roda em uma máquina pequena e não guarda dados.
Cenário e pré-requisitos
- Três servidores com o mesmo sistema e a mesma versão do MariaDB:
db1(10.0.0.21),db2(10.0.0.22) edb3(10.0.0.23), em rede privada. - Relógio sincronizado (o Ubuntu e o Debian já vêm com
systemd-timesyncdouchrony). - Portas liberadas entre os nós:
| Porta | Uso |
|---|---|
| 3306/tcp | Conexões de clientes |
| 4567/tcp e udp | Replicação do Galera entre os nós |
| 4568/tcp | IST: transferência incremental para um nó que ficou pouco tempo fora |
| 4444/tcp | SST: cópia completa para um nó novo ou muito atrasado |
Com ufw, em cada nó:
sudo ufw allow from 10.0.0.0/24 to any port 3306,4444,4567,4568 proto tcp
sudo ufw allow from 10.0.0.0/24 to any port 4567 proto udp
Passo 1: instale o MariaDB nos três nós
sudo apt update
sudo apt install -y mariadb-server mariadb-backup
mariadb --version
No Ubuntu 24.04 vem o MariaDB 10.11; no Debian 12, 10.11; no Debian 13, 11.8. O pacote do Galera (galera-4) entra como dependência. Para outra série, como a 11.4, use o repositório oficial do MariaDB nos três nós, sempre com a mesma versão.
Confira o caminho da biblioteca do Galera, que vai na configuração:
dpkg -L galera-4 | grep libgalera_smm.so
No Ubuntu e no Debian é /usr/lib/galera/libgalera_smm.so. No AlmaLinux, com os pacotes do repositório do MariaDB, confira com rpm -ql galera-4 | grep smm.
Passo 2: crie o usuário da cópia completa (SST) no db1
Quando um nó entra no cluster, ele recebe uma cópia completa de outro nó pelo mariabackup, sem travar o doador. Para isso é preciso um usuário local. Crie no db1, que ainda está rodando sozinho:
sudo mariadb -e "CREATE USER 'sst'@'localhost' IDENTIFIED BY 'Senha-SST-forte';
GRANT RELOAD, PROCESS, LOCK TABLES, BINLOG MONITOR ON *.* TO 'sst'@'localhost';"
Não precisa criar nos outros nós: eles recebem esse usuário junto com a primeira cópia. Depois pare o serviço nos três nós:
sudo systemctl stop mariadb
Passo 3: configure o Galera em cada nó
Crie o arquivo /etc/mysql/mariadb.conf.d/60-galera.cnf (se já existir, substitua o conteúdo). Exemplo do db1:
[galera]
wsrep_on = ON
wsrep_provider = /usr/lib/galera/libgalera_smm.so
wsrep_cluster_name = cluster_loja
wsrep_cluster_address = gcomm://10.0.0.21,10.0.0.22,10.0.0.23
wsrep_node_name = db1
wsrep_node_address = 10.0.0.21
wsrep_sst_method = mariabackup
wsrep_sst_auth = sst:Senha-SST-forte
binlog_format = ROW
default_storage_engine = InnoDB
innodb_autoinc_lock_mode = 2
bind-address = 10.0.0.21
No db2 e no db3, mude só wsrep_node_name, wsrep_node_address e bind-address. O nome do cluster e a lista de endereços são iguais nos três. Como o arquivo tem senha, restrinja a leitura:
sudo chown root:mysql /etc/mysql/mariadb.conf.d/60-galera.cnf
sudo chmod 640 /etc/mysql/mariadb.conf.d/60-galera.cnf
50-server.cnf do Ubuntu e do Debian traz bind-address = 127.0.0.1. Como o 60-galera.cnf é lido depois, o valor dele prevalece. Aplicações no próprio servidor continuam conectando por localhost, que usa o socket.Passo 4: inicie o cluster
- No db1, crie o cluster. Este comando é usado só para o primeiro nó, e só quando o cluster inteiro está parado:
Confira:sudo galera_new_clustersudo mariadb -e "SHOW STATUS LIKE 'wsrep_cluster_size'"deve mostrar1. - No db2, inicie normalmente:
sudo systemctl start mariadb. Ele recebe a cópia completa do db1 e entra. O tamanho do cluster passa para2. - No db3, faça o mesmo. O tamanho vai para
3.
Passo 5: teste e acompanhe o cluster
Crie um banco no db2 e veja se ele aparece no db3:
# no db2
sudo mariadb -e "CREATE DATABASE teste_galera;"
# no db3
sudo mariadb -e "SHOW DATABASES LIKE 'teste_galera';"
Para acompanhar a saúde, rode SHOW GLOBAL STATUS LIKE 'wsrep_%'; e olhe estes valores:
| Variável | Valor saudável |
|---|---|
wsrep_cluster_size | 3 (número de nós) |
wsrep_cluster_status | Primary |
wsrep_local_state_comment | Synced |
wsrep_ready e wsrep_connected | ON |
Como religar o cluster depois de desligar todos os nós
Se os três nós pararam (queda de energia, manutenção), o cluster precisa ser recriado a partir do nó com os dados mais recentes:
- Em cada nó, veja o arquivo de estado:
sudo cat /var/lib/mysql/grastate.dat. O nó com o maiorseqnoé o mais atualizado. Se todos mostramseqno: -1, rodesudo galera_recoveryem cada um para descobrir a posição real. - No nó escolhido, libere o bootstrap: edite o
grastate.date mudesafe_to_bootstrap: 0parasafe_to_bootstrap: 1. - Inicie esse nó com
sudo galera_new_clustere depois os outros comsudo systemctl start mariadb, um de cada vez.
Problemas comuns
It may not be safe to bootstrap the cluster from this node
O nó não foi o último a sair do cluster, então o MariaDB recusa criar o cluster a partir dele. Siga a seção de religar o cluster para escolher o nó certo. Forçar o bootstrap no nó errado perde as últimas transações.
O nó novo não entra e o log fala em SST
Veja sudo journalctl -u mariadb -n 100 no nó que está entrando e os arquivos mariabackup*.log em /var/lib/mysql do doador. As causas mais comuns: porta 4444 bloqueada, pacote mariadb-backup faltando em um dos nós, ou usuário e senha do wsrep_sst_auth diferentes do usuário criado.
Cada nó mostra wsrep_cluster_size = 1
Os três foram iniciados com galera_new_cluster e viraram três clusters separados. Pare o db2 e o db3, mantenha só o que tem os dados certos e inicie os outros com systemctl start mariadb.
ERROR 1213: Deadlock found when trying to get lock
Duas transações alteraram a mesma linha em nós diferentes ao mesmo tempo, e uma foi descartada. É o comportamento esperado do Galera. A aplicação deve repetir a transação; mandar todas as gravações para um único nó (com MaxScale, HAProxy ou ProxySQL na frente) reduz muito esses conflitos.
Uma tabela tem dados diferentes em cada nó
Provavelmente não é InnoDB. Liste as tabelas fora do padrão e converta com ALTER TABLE nome ENGINE=InnoDB;:
SELECT table_schema, table_name, engine FROM information_schema.tables
WHERE engine <> 'InnoDB'
AND table_schema NOT IN ('mysql','information_schema','performance_schema','sys');