{"id":672,"date":"2026-09-06T12:40:06","date_gmt":"2026-09-06T15:40:06","guid":{"rendered":"https:\/\/www.linuxpro.com.br\/2026\/09\/mariadb-galera-cluster-mariabackup-ubuntu\/"},"modified":"2026-09-23T09:14:46","modified_gmt":"2026-09-23T12:14:46","slug":"mariadb-galera-cluster-mariabackup-ubuntu","status":"publish","type":"post","link":"https:\/\/www.linuxpro.com.br\/en\/2026\/09\/mariadb-galera-cluster-mariabackup-ubuntu\/","title":{"rendered":"MariaDB Galera cluster with mariabackup on Ubuntu"},"content":{"rendered":"<p><img loading=\"lazy\" decoding=\"async\" alt=\"Mascote do LinuxPro conectando o cabo de um n\u00f3 do cluster MariaDB Galera, com o anel de replica\u00e7\u00e3o entre os tr\u00eas racks e o c\u00e3o caramelo sentado ao lado\" src=\"\/wp-content\/uploads\/2026\/09\/mariadb-galera-v7.webp\" width=\"1486\" height=\"856\" \/><\/p>\n<p>Tr\u00eas Ubuntu, um Galera, SST com <strong>mariabackup<\/strong>. N\u00e3o \u00e9 r\u00e9plica ass\u00edncrona: todo n\u00f3 aceita escrita e a maioria decide quem continua no ar. Dois n\u00f3s n\u00e3o bastam \u2014 cai um e o outro fica sozinho, sem maioria. Abaixo, o cluster de tr\u00eas do pacote ao <code>galera_new_cluster<\/code>, no Ubuntu 24.04 e no 26.04, com backup a quente e a recupera\u00e7\u00e3o de quando tudo cai.<\/p>\n<p><!-- more --><\/p>\n<h2>Tr\u00eas n\u00f3s, um quorum<\/h2>\n<p>O Galera, da finlandesa Codership, entra no MariaDB como a biblioteca <code>libgalera_smm.so<\/code> (pacote <code>galera-4<\/code>, API wsrep 26.4.x). Cada commit vira um <em>writeset<\/em>: os outros n\u00f3s o recebem e certificam antes de o commit retornar ao cliente, e aplicam logo em seguida. S\u00f3 InnoDB; MyISAM no cluster \u00e9 dor.<\/p>\n<p>Quando um n\u00f3 entra ou volta, ele precisa dos dados. Se ficou pouco tempo fora, recebe s\u00f3 o que perdeu (<strong>IST<\/strong>, a partir do cache <code>gcache<\/code> de um vizinho). Se \u00e9 novo ou ficou muito tempo fora, recebe a base inteira (<strong>SST<\/strong>). O SST por <code>rsync<\/code> trava o doador durante a c\u00f3pia; o <code>mysqldump<\/code> \u00e9 lento. O <code>mariabackup<\/code> copia a quente, manda o fluxo por <code>socat<\/code> na porta 4444 e o doador continua atendendo. Por isso tr\u00eas servidores e esse SST.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"Diagrama do cluster MariaDB Galera: aplica\u00e7\u00e3o acessando db1, db2 e db3 pela porta 3306, replica\u00e7\u00e3o entre os n\u00f3s na 4567, SST na 4444 e IST na 4568\" src=\"\/wp-content\/uploads\/2026\/09\/mariadb-galera-topologia.webp\" width=\"1200\" height=\"720\" \/><\/p>\n<p>Os IPs deste howto \u2014 troque pelos seus:<\/p>\n<pre><code class=\"language-text\">db1  10.0.0.11\ndb2  10.0.0.12\ndb3  10.0.0.13\n<\/code><\/pre>\n<p>Mesma vers\u00e3o de MariaDB nos tr\u00eas, mesmo <code>wsrep_cluster_name<\/code>, rel\u00f3gio sincronizado (chrony) e disco local \u2014 datadir em NFS, n\u00e3o.<\/p>\n<h2>O mapa em setembro de 2026<\/h2>\n<ul>\n<li><strong>Ubuntu 24.04<\/strong> (noble): MariaDB <strong>10.11.14<\/strong> em <code>noble-updates<\/code> e <code>galera-4<\/code> 26.4.16 no <code>universe<\/code>. Em maio de 2026 a MariaDB soltou corre\u00e7\u00f5es de seguran\u00e7a do Galera (<a href=\"https:\/\/mariadb.org\/mariadb-community-server-corrective-releases\/\">10.6.27, 10.11.18, 11.4.12 e 11.8.8<\/a>). At\u00e9 o fechamento deste post a atualiza\u00e7\u00e3o do noble para a 10.11.18 ainda n\u00e3o tinha sa\u00eddo (<a href=\"https:\/\/bugs.launchpad.net\/ubuntu\/+source\/mariadb\/+bug\/2158958\">LP #2158958<\/a>). Para cluster em produ\u00e7\u00e3o no 24.04, use o reposit\u00f3rio da MariaDB.<\/li>\n<li><strong>Ubuntu 26.04<\/strong> (resolute): MariaDB <strong>11.8.6<\/strong> e <code>galera-4<\/code> 26.4.25, os dois no <code>main<\/code>. O pacote <code>11.8.6-5ubuntu0.1<\/code> j\u00e1 traz as corre\u00e7\u00f5es de maio. A 11.8 \u00e9 LTS, com suporte da comunidade at\u00e9 junho de 2028.<\/li>\n<li>O reposit\u00f3rio da MariaDB tamb\u00e9m publica pacotes para o 26.04, mas s\u00f3 da 11.8 em diante; o script de instala\u00e7\u00e3o recusa a 10.11 no resolute.<\/li>\n<li>Bin\u00e1rio de backup: <code>mariadb-backup<\/code>. O valor de <code>wsrep_sst_method<\/code> continua <code>mariabackup<\/code> \u2014 o nome antigo. N\u00e3o misture.<\/li>\n<\/ul>\n<p>Quem vai colocar PHP na frente do banco: <a href=\"\/2026\/09\/nginx-varias-versoes-php-debian-ubuntu\/\">Nginx e v\u00e1rias vers\u00f5es de PHP<\/a>. O <a href=\"\/2026\/09\/a-historia-do-glpi\/\">GLPI<\/a> \u00e9 um dos clientes t\u00edpicos deste cluster.<\/p>\n<h2>Pacotes<\/h2>\n<p>Nos tr\u00eas n\u00f3s. Ubuntu 26.04, direto da distro:<\/p>\n<pre><code class=\"language-bash\">sudo apt update\nsudo apt install -y mariadb-server mariadb-backup galera-4 socat\n<\/code><\/pre>\n<p>Ubuntu 24.04 com a 11.8 do reposit\u00f3rio da MariaDB (recomendado, pelo patch de seguran\u00e7a):<\/p>\n<pre><code class=\"language-bash\">sudo apt install -y curl ca-certificates\ncurl -LsS https:\/\/r.mariadb.com\/downloads\/mariadb_repo_setup \\\n  | sudo bash -s -- --mariadb-server-version=\"11.8\"\nsudo apt update\nsudo apt install -y mariadb-server mariadb-backup galera-4 socat\n<\/code><\/pre>\n<p>A biblioteca fica em <code>\/usr\/lib\/libgalera_smm.so<\/code>, com um link em <code>\/usr\/lib\/galera\/libgalera_smm.so<\/code>, tanto no pacote do Ubuntu quanto no da MariaDB. Qualquer um dos dois serve no <code>wsrep_provider<\/code>. Confira na sua m\u00e1quina:<\/p>\n<pre><code class=\"language-bash\">dpkg -L galera-4 | grep libgalera_smm.so\n<\/code><\/pre>\n<p>A instala\u00e7\u00e3o j\u00e1 deixou um MariaDB sozinho no ar. Pare antes de configurar:<\/p>\n<pre><code class=\"language-bash\">sudo systemctl stop mariadb\nsudo systemctl enable mariadb\n<\/code><\/pre>\n<p>O datadir mudou no 26.04: instala\u00e7\u00e3o nova usa <code>\/var\/lib\/mariadb<\/code>; quem atualizou de uma vers\u00e3o anterior continua em <code>\/var\/lib\/mysql<\/code> (via <code>99-legacy-datadir.cnf<\/code>). No 24.04 \u00e9 <code>\/var\/lib\/mysql<\/code>. Confira com <code>mariadbd --help --verbose | grep ^datadir<\/code>.<\/p>\n<h2>Rede, firewall e AppArmor<\/h2>\n<p>O Galera usa quatro portas. Abra s\u00f3 entre os tr\u00eas IPs, nunca para o mundo:<\/p>\n<ul>\n<li><code>3306\/tcp<\/code> \u2014 cliente SQL<\/li>\n<li><code>4567\/tcp<\/code> \u2014 replica\u00e7\u00e3o (e UDP, s\u00f3 se usar multicast)<\/li>\n<li><code>4568\/tcp<\/code> \u2014 IST<\/li>\n<li><code>4444\/tcp<\/code> \u2014 SST do mariabackup\/socat<\/li>\n<\/ul>\n<pre><code class=\"language-bash\">NET=10.0.0.0\/24\nfor p in 3306 4567 4568 4444; do\n  sudo ufw allow proto tcp from \"$NET\" to any port \"$p\"\ndone\nsudo ufw reload\n<\/code><\/pre>\n<p>No <code>\/etc\/hosts<\/code> dos tr\u00eas:<\/p>\n<pre><code class=\"language-text\">10.0.0.11  db1\n10.0.0.12  db2\n10.0.0.13  db3\n<\/code><\/pre>\n<p><strong>AppArmor no 26.04.<\/strong> O pacote passou a trazer o perfil <code>\/etc\/apparmor.d\/mariadbd<\/code> em modo <em>enforce<\/em>, e ele n\u00e3o tem regras para os scripts de SST (<code>wsrep_sst_mariabackup<\/code>, <code>socat<\/code>, <code>mariadb-backup<\/code>). Se o joiner falhar e o <code>dmesg<\/code> mostrar <code>apparmor=\"DENIED\"<\/code>, ponha o perfil em modo de reclama\u00e7\u00e3o:<\/p>\n<pre><code class=\"language-bash\">sudo apt install -y apparmor-utils\nsudo aa-complain \/etc\/apparmor.d\/mariadbd\nsudo dmesg -T | grep -i apparmor | tail\n<\/code><\/pre>\n<p>No 24.04 o perfil do pacote vem vazio, sem confinamento; nada a fazer.<\/p>\n<p>O timeout do systemd n\u00e3o atrapalha: o <code>mariadb.service<\/code> j\u00e1 traz <code>TimeoutStartSec=900<\/code>, e durante o SST o pr\u00f3prio servidor avisa o systemd a cada 60 s para estender o prazo. N\u00e3o precisa de drop-in.<\/p>\n<h2>60-galera.cnf<\/h2>\n<p>O Ubuntu j\u00e1 traz <code>\/etc\/mysql\/mariadb.conf.d\/60-galera.cnf<\/code>, todo comentado. Substitua o conte\u00fado por este. Entre os n\u00f3s s\u00f3 mudam <code>wsrep_node_name<\/code> e <code>wsrep_node_address<\/code>.<\/p>\n<p>Em <strong>db1<\/strong>:<\/p>\n<pre><code class=\"language-ini\">[galera]\nwsrep_on=ON\nwsrep_provider=\/usr\/lib\/galera\/libgalera_smm.so\nwsrep_cluster_name=\"linuxpro\"\nwsrep_cluster_address=\"gcomm:\/\/10.0.0.11,10.0.0.12,10.0.0.13\"\nwsrep_node_name=db1\nwsrep_node_address=10.0.0.11\nwsrep_sst_method=mariabackup\nwsrep_sst_auth=mariabackup:troque-esta-senha\nwsrep_provider_options=\"gcache.size=1G;gcache.recover=yes\"\n\nbinlog_format=ROW\ndefault_storage_engine=InnoDB\ninnodb_autoinc_lock_mode=2\nbind-address=0.0.0.0\n<\/code><\/pre>\n<p>Em db2 e db3, copie o arquivo e troque s\u00f3 o nome e o IP. O <code>gcomm:\/\/<\/code> lista os tr\u00eas em todos \u2014 o Galera ignora o pr\u00f3prio endere\u00e7o. Nunca deixe <code>gcomm:\/\/<\/code> vazio no arquivo: isso cria um cluster novo a cada start.<\/p>\n<p>O <code>gcache.size<\/code> define quanto hist\u00f3rico cada n\u00f3 guarda para IST. Quanto maior, mais tempo um n\u00f3 pode ficar fora e ainda voltar s\u00f3 com o que perdeu, em vez de um SST completo.<\/p>\n<p>No <code>50-server.cnf<\/code>, comente o <code>bind-address = 127.0.0.1<\/code>. O 60 \u00e9 lido depois e ganha, mas n\u00e3o dependa da ordem.<\/p>\n<h2>Usu\u00e1rio do SST<\/h2>\n<p>O doador roda o <code>mariadb-backup<\/code> localmente e precisa de um usu\u00e1rio com estes privil\u00e9gios:<\/p>\n<pre><code class=\"language-sql\">CREATE USER 'mariabackup'@'localhost' IDENTIFIED BY 'troque-esta-senha';\nGRANT RELOAD, PROCESS, LOCK TABLES, BINLOG MONITOR ON *.* TO 'mariabackup'@'localhost';\n<\/code><\/pre>\n<p><code>BINLOG MONITOR<\/code> \u00e9 o nome desde a 10.5; <code>REPLICATION CLIENT<\/code> continua valendo como apelido. O usu\u00e1rio s\u00f3 conecta em localhost \u2014 n\u00e3o o abra na rede.<\/p>\n<p>Na <strong>11.8<\/strong> (26.04, ou 24.04 com o reposit\u00f3rio da MariaDB) h\u00e1 um atalho: sem <code>wsrep_sst_auth<\/code> no cnf, o servidor cria e apaga sozinho um usu\u00e1rio tempor\u00e1rio para cada SST (<a href=\"https:\/\/jira.mariadb.org\/browse\/MDEV-31809\">MDEV-31809<\/a>, desde a 11.6). Nesse caso, apague a linha <code>wsrep_sst_auth<\/code> dos tr\u00eas arquivos e pule o <code>CREATE USER<\/code>. Na <strong>10.11<\/strong> o usu\u00e1rio \u00e9 obrigat\u00f3rio.<\/p>\n<h2>Bootstrap e os dois joiners<\/h2>\n<p>Os tr\u00eas est\u00e3o parados, com o cnf no disco. S\u00f3 o primeiro n\u00f3 cria o cluster:<\/p>\n<pre><code class=\"language-bash\"># em db1\nsudo galera_new_cluster\n<\/code><\/pre>\n<p>\u00c9 um wrapper que sobe o <code>mariadbd<\/code> com <code>--wsrep-new-cluster<\/code>. Confira:<\/p>\n<pre><code class=\"language-sql\">SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size';\nSHOW GLOBAL STATUS LIKE 'wsrep_local_state_comment';\nSHOW GLOBAL STATUS LIKE 'wsrep_ready';\n<\/code><\/pre>\n<p>Esperado: size 1, <code>Synced<\/code>, <code>ON<\/code>. Crie agora o usu\u00e1rio do SST no db1 (se\u00e7\u00e3o anterior) \u2014 ele replica para os outros quando entrarem. Depois:<\/p>\n<pre><code class=\"language-bash\"># em db2; quando ele estiver Synced, em db3\nsudo systemctl start mariadb\n<\/code><\/pre>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"Mascote LinuxPro ajoelhado conectando o novo n\u00f3 (joiner) ao doador durante o SST do MariaDB Galera, com blocos de dados passando por um tubo e o c\u00e3o caramelo deitado ao lado\" src=\"\/wp-content\/uploads\/2026\/09\/mariadb-galera-sst-ubuntu-v5.webp\" width=\"1200\" height=\"675\" \/><\/p>\n<p>O joiner pede o SST ao doador. Acompanhe com <code>journalctl -u mariadb -f<\/code>. Durante a transfer\u00eancia, o datadir recebe <code>mariabackup.backup.log<\/code> (no doador) e <code>mariabackup.prepare.log<\/code> \/ <code>mariabackup.move.log<\/code> (no joiner) \u2014 \u00e9 ali que est\u00e1 o motivo quando o SST falha. Os arquivos mant\u00eam o nome antigo, embora o bin\u00e1rio seja <code>mariadb-backup<\/code>, e os de transfer\u00eancias anteriores v\u00e3o compactados para <code>\/tmp\/sst_log_archive<\/code>. No laborat\u00f3rio deste post, com a base pequena, cada joiner ficou <code>Synced<\/code> em cerca de 20 segundos.<\/p>\n<p>Com os tr\u00eas dentro:<\/p>\n<pre><code class=\"language-sql\">SHOW GLOBAL STATUS LIKE 'wsrep_cluster_size';      -- 3\nSHOW GLOBAL STATUS LIKE 'wsrep_cluster_status';    -- Primary\nSHOW GLOBAL STATUS LIKE 'wsrep_incoming_addresses';\n<\/code><\/pre>\n<p>Teste de verdade: <code>CREATE DATABASE teste_galera;<\/code> no db1 e <code>SHOW DATABASES;<\/code> no db3. Se apareceu, o writeset passou.<\/p>\n<h2>HAProxy na frente do cluster<\/h2>\n<p>Com tr\u00eas n\u00f3s, a aplica\u00e7\u00e3o precisa de um endere\u00e7o s\u00f3, que continue funcionando quando um n\u00f3 cai. O HAProxy faz isso em TCP. E h\u00e1 um motivo para n\u00e3o espalhar as escritas: o Galera aceita escrita em qualquer n\u00f3, mas duas transa\u00e7\u00f5es mexendo na mesma linha em n\u00f3s diferentes geram conflito de certifica\u00e7\u00e3o, e uma delas volta com erro de deadlock no <code>COMMIT<\/code>. O arranjo mais seguro \u00e9 <strong>escrever em um n\u00f3 por vez e ler dos tr\u00eas<\/strong>.<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" alt=\"Diagrama do MariaDB Galera com HAProxy: aplica\u00e7\u00f5es no IP virtual do keepalived, dois HAProxy, escrita na porta 3306 para um n\u00f3 com os outros dois de reserva e leitura na 3307 distribu\u00edda entre os tr\u00eas\" src=\"\/wp-content\/uploads\/2026\/09\/mariadb-galera-haproxy.webp\" width=\"1200\" height=\"780\" \/><\/p>\n<p>O HAProxy exp\u00f5e duas portas: <strong>3306<\/strong> para escrita, que manda tudo para o db1 e usa db2 e db3 s\u00f3 se ele cair, e <strong>3307<\/strong> para leitura, distribu\u00edda entre os tr\u00eas. Se a aplica\u00e7\u00e3o n\u00e3o separa leitura de escrita, use s\u00f3 a 3306.<\/p>\n<h3>Health check: TCP n\u00e3o basta<\/h3>\n<p>Um n\u00f3 em <code>Donor\/Desynced<\/code>, ainda sincronizando ou fora do quorum aceita conex\u00e3o TCP normalmente \u2014 s\u00f3 n\u00e3o serve dados confi\u00e1veis. O check precisa perguntar ao Galera. Este script responde HTTP 200 quando <code>wsrep_local_state<\/code> \u00e9 4 (<code>Synced<\/code>) e 503 em qualquer outro caso. Nos tr\u00eas n\u00f3s:<\/p>\n<pre><code class=\"language-bash\">sudo tee \/usr\/local\/bin\/galera-check &gt;\/dev\/null &lt;&lt;'EOF'\n#!\/bin\/bash\n# Responde HTTP 200 s\u00f3 quando o n\u00f3 est\u00e1 Synced (wsrep_local_state = 4).\n# L\u00ea o pedido at\u00e9 a linha em branco; fechar sem ler faz o kernel mandar RST.\nwhile read -r -t 2 line; do [ -z \"${line%$'\\r'}\" ] &amp;&amp; break; done\nstate=$(mariadb -N -s -e \"SHOW GLOBAL STATUS LIKE 'wsrep_local_state'\" 2&gt;\/dev\/null | cut -f2)\nif [ \"$state\" = \"4\" ]; then\n  printf 'HTTP\/1.1 200 OK\\r\\nContent-Type: text\/plain\\r\\nConnection: close\\r\\n\\r\\nSynced\\r\\n'\nelse\n  printf 'HTTP\/1.1 503 Service Unavailable\\r\\nContent-Type: text\/plain\\r\\nConnection: close\\r\\n\\r\\nNot synced (%s)\\r\\n' \"${state:-down}\"\nfi\nEOF\nsudo chmod 755 \/usr\/local\/bin\/galera-check\nsudo useradd -r -s \/usr\/sbin\/nologin galera-check\n<\/code><\/pre>\n<p>O script conecta sem senha: o usu\u00e1rio do MariaDB autentica pelo usu\u00e1rio do sistema (<code>unix_socket<\/code>) e n\u00e3o precisa de privil\u00e9gio nenhum para ler o status. Crie uma vez, em qualquer n\u00f3 \u2014 ele replica:<\/p>\n<pre><code class=\"language-sql\">CREATE USER 'galera-check'@'localhost' IDENTIFIED VIA unix_socket;\n<\/code><\/pre>\n<p>O systemd escuta a porta 9200 e roda o script a cada conex\u00e3o. Nos tr\u00eas n\u00f3s, <code>\/etc\/systemd\/system\/galera-check.socket<\/code>:<\/p>\n<pre><code class=\"language-ini\">[Unit]\nDescription=Health check HTTP do Galera (porta 9200)\n\n[Socket]\nListenStream=9200\nAccept=yes\n\n[Install]\nWantedBy=sockets.target\n<\/code><\/pre>\n<p>e <code>\/etc\/systemd\/system\/galera-check@.service<\/code>:<\/p>\n<pre><code class=\"language-ini\">[Unit]\nDescription=Health check HTTP do Galera\n\n[Service]\nUser=galera-check\nExecStart=\/usr\/local\/bin\/galera-check\nStandardInput=socket\nStandardOutput=socket\nStandardError=journal\n<\/code><\/pre>\n<pre><code class=\"language-bash\">sudo systemctl daemon-reload\nsudo systemctl enable --now galera-check.socket\ncurl -s http:\/\/127.0.0.1:9200\/      # Synced\n<\/code><\/pre>\n<p>Libere a 9200 s\u00f3 para os IPs dos HAProxy (<code>sudo ufw allow proto tcp from 10.0.0.21 to any port 9200<\/code>, e o mesmo para o .22).<\/p>\n<h3>O haproxy.cfg<\/h3>\n<p>Nas m\u00e1quinas do HAProxy (fora dos n\u00f3s do banco):<\/p>\n<pre><code class=\"language-bash\">sudo apt install -y haproxy\n<\/code><\/pre>\n<p>Acrescente ao <code>\/etc\/haproxy\/haproxy.cfg<\/code>, mantendo o bloco <code>global<\/code> do pacote:<\/p>\n<pre><code class=\"language-text\">defaults galera\n    mode    tcp\n    log     global\n    option  tcplog\n    timeout connect 5s\n    timeout client  8h\n    timeout server  8h\n\n# Escrita: um n\u00f3 s\u00f3 por vez; os outros dois assumem se ele cair\nfrontend galera_escrita from galera\n    bind *:3306\n    default_backend galera_escrita\n\nbackend galera_escrita from galera\n    option httpchk GET \/\n    http-check expect status 200\n    default-server port 9200 inter 2s fall 3 rise 2 on-marked-down shutdown-sessions\n    server db1 10.0.0.11:3306 check\n    server db2 10.0.0.12:3306 check backup\n    server db3 10.0.0.13:3306 check backup\n\n# Leitura: os tr\u00eas, quem tiver menos conex\u00f5es\nfrontend galera_leitura from galera\n    bind *:3307\n    default_backend galera_leitura\n\nbackend galera_leitura from galera\n    balance leastconn\n    option httpchk GET \/\n    http-check expect status 200\n    default-server port 9200 inter 2s fall 3 rise 2 on-marked-down shutdown-sessions\n    server db1 10.0.0.11:3306 check\n    server db2 10.0.0.12:3306 check\n    server db3 10.0.0.13:3306 check\n\nlisten estatisticas from galera\n    mode http\n    bind 127.0.0.1:8404\n    stats enable\n    stats uri \/\n    stats refresh 5s\n<\/code><\/pre>\n<pre><code class=\"language-bash\">sudo haproxy -c -f \/etc\/haproxy\/haproxy.cfg\nsudo systemctl reload haproxy\n<\/code><\/pre>\n<p>Os detalhes que importam:<\/p>\n<ul>\n<li><code>fall 3<\/code> com <code>inter 2s<\/code>: um n\u00f3 sai do pool depois de tr\u00eas checks ruins, uns 6 segundos. <code>rise 2<\/code> exige dois bons para voltar.<\/li>\n<li><code>on-marked-down shutdown-sessions<\/code> derruba as conex\u00f5es abertas no n\u00f3 que caiu, para a aplica\u00e7\u00e3o reconectar no pr\u00f3ximo em vez de ficar pendurada.<\/li>\n<li><code>timeout client\/server 8h<\/code> acompanha o <code>wait_timeout<\/code> padr\u00e3o do MariaDB (28800 s). Com timeout menor, o HAProxy corta conex\u00f5es ociosas de pool antes do banco.<\/li>\n<li>Os usu\u00e1rios da aplica\u00e7\u00e3o passam a chegar com o IP do HAProxy: crie-os como <code>'app'@'10.0.0.%'<\/code>, n\u00e3o com o IP da aplica\u00e7\u00e3o.<\/li>\n<\/ul>\n<p>Teste pelo balanceador:<\/p>\n<pre><code class=\"language-bash\">mariadb -h 10.0.0.21 -P 3306 -u app -p -e 'SELECT @@hostname'   # sempre db1\nmariadb -h 10.0.0.21 -P 3307 -u app -p -e 'SELECT @@hostname'   # alterna entre os tr\u00eas\n<\/code><\/pre>\n<p>No laborat\u00f3rio deste post, com o db1 derrubado, a escrita passou para o db2 em menos de 10 segundos e um <code>INSERT<\/code> pela porta 3306 entrou normalmente. Quando o db1 voltou (por IST, s\u00f3 com as transa\u00e7\u00f5es que perdeu), o HAProxy devolveu a escrita para ele. Para ver o estado dos backends: <code>ssh -L 8404:127.0.0.1:8404<\/code> na m\u00e1quina do HAProxy e abra <code>http:\/\/127.0.0.1:8404\/<\/code>.<\/p>\n<p>Um HAProxy sozinho vira o novo ponto \u00fanico de falha. Em produ\u00e7\u00e3o, rode dois, com a mesma configura\u00e7\u00e3o, e o <strong>keepalived<\/strong> segurando um IP virtual (VRRP) entre eles, como no diagrama; a aplica\u00e7\u00e3o aponta para esse IP.<\/p>\n<h2>Backup a quente<\/h2>\n<p>Backup do cluster \u00e9 backup de <strong>um<\/strong> n\u00f3. De prefer\u00eancia tire esse n\u00f3 do balanceador, porque ele fica mais lento durante a c\u00f3pia:<\/p>\n<pre><code class=\"language-bash\">sudo mkdir -p \/backup    # o mariadb-backup n\u00e3o cria o diret\u00f3rio pai\nsudo mariadb-backup --backup --galera-info \\\n  --target-dir=\/backup\/full-$(date +%F) \\\n  --user=mariabackup --password='troque-esta-senha'\nsudo mariadb-backup --prepare --target-dir=\/backup\/full-$(date +%F)\n<\/code><\/pre>\n<p>N\u00e3o precisa de <code>SET GLOBAL wsrep_desync=ON<\/code>: no Galera, o <code>mariadb-backup<\/code> j\u00e1 dessincroniza e pausa o n\u00f3 sozinho na fase de bloqueio. O n\u00f3 continua no cluster, recebe os writesets numa fila e a esvazia depois \u2014 n\u00e3o h\u00e1 IST. O <code>--galera-info<\/code> grava a posi\u00e7\u00e3o do cluster no arquivo <code>xtrabackup_galera_info<\/code>, que \u00e9 o que permite usar esse backup para reconstruir um n\u00f3.<\/p>\n<p>O <code>--prepare<\/code> deixa o backup consistente. Sem ele, o diret\u00f3rio n\u00e3o serve para restaurar.<\/p>\n<h2>Quando o cluster inteiro cai<\/h2>\n<p>Se os <strong>tr\u00eas<\/strong> ca\u00edrem juntos, o cluster acabou \u2014 os dados n\u00e3o. Em cada n\u00f3, olhe o <code>grastate.dat<\/code> no datadir:<\/p>\n<pre><code class=\"language-bash\">sudo cat \/var\/lib\/mysql\/grastate.dat    # ou \/var\/lib\/mariadb no 26.04\n<\/code><\/pre>\n<p>Desligamento limpo: o n\u00f3 com <code>safe_to_bootstrap: 1<\/code> (o \u00faltimo a sair) \u00e9 quem sobe primeiro. Queda brusca: todos ficam com <code>seqno: -1<\/code> e <code>safe_to_bootstrap: 0<\/code>. Descubra a posi\u00e7\u00e3o real em cada um:<\/p>\n<pre><code class=\"language-bash\">sudo galera_recovery\n<\/code><\/pre>\n<p>O n\u00f3 com o maior n\u00famero depois de <code>:<\/code> \u00e9 o mais avan\u00e7ado. S\u00f3 nele, edite o <code>grastate.dat<\/code> para <code>safe_to_bootstrap: 1<\/code> e:<\/p>\n<pre><code class=\"language-bash\">sudo galera_new_cluster          # no n\u00f3 mais avan\u00e7ado\nsudo systemctl start mariadb     # nos outros dois, um de cada vez\n<\/code><\/pre>\n<p>Nunca rode <code>galera_new_cluster<\/code> com algum n\u00f3 ainda no ar: nasce um cluster novo com outro UUID e voc\u00ea tem dois bancos divergindo (split-brain).<\/p>\n<h2>Atualizando a vers\u00e3o maior<\/h2>\n<p>Quem est\u00e1 na 10.11 do 24.04 e vai para a 11.8: o SST por <code>mariabackup<\/code> n\u00e3o funciona entre algumas vers\u00f5es maiores, porque o formato do redo log mudou na 10.5 e na 10.8 (<a href=\"https:\/\/jira.mariadb.org\/browse\/MDEV-27437\">MDEV-27437<\/a>). Durante a migra\u00e7\u00e3o use <code>wsrep_sst_method=rsync<\/code>, que atravessa vers\u00f5es, ou pare os tr\u00eas, atualize todos e fa\u00e7a o bootstrap de novo.<\/p>\n<h2>O que costuma quebrar<\/h2>\n<ul>\n<li><code>wsrep_sst_method=mariadb-backup<\/code> \u2014 nome errado. \u00c9 <code>mariabackup<\/code>; n\u00e3o existe script <code>wsrep_sst_mariadb-backup<\/code>.<\/li>\n<li>AppArmor no 26.04 negando o SST; o log do MariaDB s\u00f3 diz \u201cSST failed\u201d. Veja o <code>dmesg<\/code>.<\/li>\n<li><code>socat<\/code> ausente no doador ou no joiner.<\/li>\n<li>Porta 4444 fechada no firewall: o joiner espera e o SST morre por timeout.<\/li>\n<li>Dois n\u00f3s: um cai e o outro vira <code>Non-Primary<\/code> e para de aceitar escrita. Use tr\u00eas, ou dois mais um \u00e1rbitro <code>garbd<\/code>.<\/li>\n<li><code>bind-address=127.0.0.1<\/code> ainda ativo: os outros n\u00e3o conectam.<\/li>\n<li>Tabela MyISAM ou sem chave prim\u00e1ria: replica mal ou nem replica. Converta para InnoDB e crie a PK.<\/li>\n<\/ul>\n<p>Refer\u00eancias: c\u00f3digo do provider em <a href=\"https:\/\/github.com\/codership\/galera\">github.com\/codership\/galera<\/a> \u00b7 <a href=\"https:\/\/mariadb.com\/docs\/galera-cluster\/galera-management\/installation-and-deployment\/getting-started-with-mariadb-galera-cluster\">Getting Started<\/a> \u00b7 <a href=\"https:\/\/mariadb.com\/docs\/galera-cluster\/high-availability\/state-snapshot-transfers-ssts-in-galera-cluster\/mariadb-backup-sst-method\">SST com mariadb-backup<\/a> \u00b7 <a href=\"https:\/\/mariadb.com\/docs\/galera-cluster\/galera-management\/configuration\/configuring-mariadb-galera-cluster\">Configuring MariaDB Galera Cluster<\/a> \u00b7 <a href=\"https:\/\/mariadb.com\/docs\/server\/server-management\/install-and-upgrade-mariadb\/installing-mariadb\/binary-packages\/installing-mariadb-deb-files\">pacotes DEB<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Three Ubuntu nodes, one Galera, SST with mariabackup. It is not asynchronous replication: every node accepts writes and the majority decides who stays up. Two nodes are not enough \u2014 if one goes down, the other is left alone, without a majority. Below is the three-node cluster from the galera_new_cluster package, on Ubuntu 24.04 and 26.04, with backup a \u2026 <a title=\"MariaDB Galera cluster with mariabackup on Ubuntu\" class=\"read-more\" href=\"https:\/\/www.linuxpro.com.br\/en\/2026\/09\/mariadb-galera-cluster-mariabackup-ubuntu\/\" aria-label=\"Read more about Cluster MariaDB Galera com mariabackup no Ubuntu\">Read more<\/a><\/p>","protected":false},"author":0,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[21,12,2,120,3],"tags":[329,327,328,326,5],"class_list":["post-672","post","type-post","status-publish","format-standard","hentry","category-infra","category-lamp","category-linux","category-servidores","category-ubuntu","tag-cluster","tag-galera","tag-mariabackup","tag-mariadb","tag-ubuntu"],"_links":{"self":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/672","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/comments?post=672"}],"version-history":[{"count":10,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/672\/revisions"}],"predecessor-version":[{"id":1676,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/posts\/672\/revisions\/1676"}],"wp:attachment":[{"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/media?parent=672"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/categories?post=672"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.linuxpro.com.br\/en\/wp-json\/wp\/v2\/tags?post=672"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}