MariaDB Galera Cluster ermöglicht synchrone Multi-Master-Replikation. Alle Nodes sind gleichberechtigt und können Schreib- und Leseoperationen verarbeiten.

Vorteile von Galera

Features

- Synchrone Replikation
- Multi-Master (alle Nodes beschreibbar)
- Automatisches Failover
- Keine Master-Slave-Umschaltung nötig
- Konsistente Daten auf allen Nodes
- Hot Standby

Anforderungen

- Mindestens 3 Nodes (für Quorum)
- InnoDB-Tabellen
- Primärschlüssel auf allen Tabellen
- Netzwerk mit niedriger Latenz

Installation

Debian/Ubuntu

# Auf allen Nodes
apt update
apt install mariadb-server galera-4 mariadb-backup

# Service stoppen
systemctl stop mariadb

CentOS/RHEL

# Repository hinzufügen
cat > /etc/yum.repos.d/mariadb.repo << EOF
[mariadb]
name = MariaDB
baseurl = https://mirror.mariadb.org/yum/11.2/rhel9-amd64
gpgkey = https://mirror.mariadb.org/yum/RPM-GPG-KEY-MariaDB
gpgcheck = 1
EOF

dnf install MariaDB-server MariaDB-backup galera-4

Cluster-Konfiguration

Node 1

# /etc/mysql/mariadb.conf.d/60-galera.cnf

[mysqld]
binlog_format=ROW
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0

# Galera Provider
wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so

# Cluster-Name
wsrep_cluster_name="my_cluster"

# Cluster-Nodes
wsrep_cluster_address="gcomm://192.168.1.11,192.168.1.12,192.168.1.13"

# Node-Adresse
wsrep_node_address="192.168.1.11"
wsrep_node_name="node1"

# SST-Methode
wsrep_sst_method=mariabackup
wsrep_sst_auth=sst_user:password

Node 2

# /etc/mysql/mariadb.conf.d/60-galera.cnf

[mysqld]
binlog_format=ROW
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0

wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_name="my_cluster"
wsrep_cluster_address="gcomm://192.168.1.11,192.168.1.12,192.168.1.13"
wsrep_node_address="192.168.1.12"
wsrep_node_name="node2"
wsrep_sst_method=mariabackup
wsrep_sst_auth=sst_user:password

Node 3

# /etc/mysql/mariadb.conf.d/60-galera.cnf

[mysqld]
binlog_format=ROW
default_storage_engine=InnoDB
innodb_autoinc_lock_mode=2
bind-address=0.0.0.0

wsrep_on=ON
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_name="my_cluster"
wsrep_cluster_address="gcomm://192.168.1.11,192.168.1.12,192.168.1.13"
wsrep_node_address="192.168.1.13"
wsrep_node_name="node3"
wsrep_sst_method=mariabackup
wsrep_sst_auth=sst_user:password

Cluster starten

SST-User erstellen (auf erstem Node)

# MariaDB normal starten
systemctl start mariadb

# SST-User erstellen
mysql -u root << EOF
CREATE USER 'sst_user'@'localhost' IDENTIFIED BY 'password';
GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO 'sst_user'@'localhost';
FLUSH PRIVILEGES;
EOF

# MariaDB stoppen
systemctl stop mariadb

Bootstrap (erster Node)

# Auf Node 1 - Cluster initialisieren
galera_new_cluster

# Status prüfen
mysql -u root -e "SHOW STATUS LIKE 'wsrep_cluster_size';"
# Sollte 1 zeigen

Weitere Nodes starten

# Auf Node 2 und 3
systemctl start mariadb

# Status prüfen (sollte 3 zeigen)
mysql -u root -e "SHOW STATUS LIKE 'wsrep_cluster_size';"

Cluster-Status prüfen

Wichtige Status-Variablen

-- Cluster-Größe
SHOW STATUS LIKE 'wsrep_cluster_size';

-- Cluster-Status
SHOW STATUS LIKE 'wsrep_cluster_status';

-- Node-Status
SHOW STATUS LIKE 'wsrep_local_state_comment';

-- Ready?
SHOW STATUS LIKE 'wsrep_ready';

-- Alle Galera-Variablen
SHOW STATUS LIKE 'wsrep_%';

Status-Werte

| Status | Bedeutung | |--------|-----------| | wsrep_cluster_size | Anzahl Nodes | | wsrep_cluster_status | Primary = OK | | wsrep_local_state_comment | Synced = OK | | wsrep_ready | ON = Ready | | wsrep_connected | ON = Connected |

clustercheck

#!/bin/bash
# /usr/local/bin/clustercheck

MYSQL_USER="clustercheck"
MYSQL_PASS="password"

STATUS=$(mysql -u$MYSQL_USER -p$MYSQL_PASS -N -e "SHOW STATUS LIKE 'wsrep_local_state'" 2>/dev/null | cut -f2)

if [ "$STATUS" == "4" ]; then
    echo "HTTP/1.1 200 OK"
    echo "Content-Type: text/plain"
    echo ""
    echo "Galera Cluster Node is synced."
    exit 0
else
    echo "HTTP/1.1 503 Service Unavailable"
    echo "Content-Type: text/plain"
    echo ""
    echo "Galera Cluster Node is not synced."
    exit 1
fi

Load Balancer

HAProxy-Konfiguration

# /etc/haproxy/haproxy.cfg

global
    log /dev/log local0
    maxconn 4096

defaults
    log global
    mode tcp
    option tcplog
    timeout connect 5s
    timeout client 30s
    timeout server 30s

frontend mysql_frontend
    bind *:3306
    default_backend mysql_backend

backend mysql_backend
    balance roundrobin
    option mysql-check user haproxy_check
    server node1 192.168.1.11:3306 check
    server node2 192.168.1.12:3306 check
    server node3 192.168.1.13:3306 check

frontend stats
    bind *:8080
    mode http
    stats enable
    stats uri /stats
    stats auth admin:password

Check-User für HAProxy

CREATE USER 'haproxy_check'@'%';
FLUSH PRIVILEGES;

ProxySQL (Alternative)

-- ProxySQL Admin
mysql -u admin -padmin -h 127.0.0.1 -P 6032

-- Server hinzufügen
INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES (10, '192.168.1.11', 3306);
INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES (10, '192.168.1.12', 3306);
INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES (10, '192.168.1.13', 3306);

-- Benutzer
INSERT INTO mysql_users(username, password, default_hostgroup) VALUES ('app', 'password', 10);

-- Aktivieren
LOAD MYSQL SERVERS TO RUNTIME;
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
SAVE MYSQL USERS TO DISK;

SST-Methoden

mariabackup (empfohlen)

wsrep_sst_method=mariabackup
wsrep_sst_auth=sst_user:password

rsync

wsrep_sst_method=rsync
# Keine Authentifizierung nötig

mysqldump

wsrep_sst_method=mysqldump
wsrep_sst_auth=sst_user:password
# Blockiert den Donor-Node!

Node-Wiederherstellung

Node neu starten

# Wenn Cluster läuft
systemctl start mariadb
# Node synct automatisch (IST)

Node komplett neu aufsetzen

# Daten löschen
systemctl stop mariadb
rm -rf /var/lib/mysql/*

# Neu starten (SST wird durchgeführt)
systemctl start mariadb

Cluster nach komplettem Ausfall

# Node mit aktuellsten Daten finden
cat /var/lib/mysql/grastate.dat
# Höchster seqno = aktuellster Node

# Auf diesem Node:
galera_new_cluster

# Andere Nodes:
systemctl start mariadb

Safe-to-Bootstrap

# /var/lib/mysql/grastate.dat
safe_to_bootstrap: 1

# Wenn alle Nodes safe_to_bootstrap: 0 haben:
# Auf gewünschtem Node manuell setzen
sed -i 's/safe_to_bootstrap: 0/safe_to_bootstrap: 1/' /var/lib/mysql/grastate.dat
galera_new_cluster

Performance-Tuning

Galera-spezifisch

# Parallel-Replikation
wsrep_slave_threads=4

# Flow Control (Bremse bei langsamen Nodes)
wsrep_provider_options="gcs.fc_limit=256; gcs.fc_factor=0.8"

# Größere Transaktionen
wsrep_max_ws_rows=131072
wsrep_max_ws_size=2147483647

InnoDB-Tuning

innodb_buffer_pool_size=4G
innodb_log_file_size=256M
innodb_flush_log_at_trx_commit=2
innodb_flush_method=O_DIRECT

Netzwerk

# Größere Pakete
wsrep_provider_options="gcache.size=1G"

Monitoring

Galera-Metriken

-- Replikationsstatus
SHOW STATUS LIKE 'wsrep_local_recv_queue%';
SHOW STATUS LIKE 'wsrep_local_send_queue%';
SHOW STATUS LIKE 'wsrep_flow_control%';

-- Konflikte
SHOW STATUS LIKE 'wsrep_local_cert_failures';
SHOW STATUS LIKE 'wsrep_local_bf_aborts';

Prometheus Exporter

# mysqld_exporter mit Galera-Metriken
docker run -d \
  -p 9104:9104 \
  -e DATA_SOURCE_NAME="exporter:password@(localhost:3306)/" \
  prom/mysqld-exporter

Alerts

# Prometheus Alert Rules
groups:
  - name: galera
    rules:
      - alert: GaleraClusterSize
        expr: mysql_global_status_wsrep_cluster_size < 3
        for: 1m
        labels:
          severity: critical
        annotations:
          summary: "Galera cluster size is {{ $value }}"

      - alert: GaleraNodeNotReady
        expr: mysql_global_status_wsrep_ready != 1
        for: 1m
        labels:
          severity: critical

Troubleshooting

Node startet nicht

# Log prüfen
journalctl -u mariadb

# Grastate prüfen
cat /var/lib/mysql/grastate.dat

# Manuelles Bootstrap
galera_new_cluster

Split-Brain vermeiden

- Immer ungerade Anzahl Nodes (3, 5, 7)
- Oder Arbitrator (garbd) verwenden

Arbitrator (garbd)

# Auf separatem Server
garbd -a gcomm://192.168.1.11,192.168.1.12 \
      -g my_cluster \
      -l /var/log/garbd.log

Flow Control zu hoch

-- Prüfen
SHOW STATUS LIKE 'wsrep_flow_control_paused';

-- Wenn > 0.1: Node ist zu langsam
-- Lösung: wsrep_slave_threads erhöhen oder Hardware verbessern

Zusammenfassung

| Komponente | Beschreibung | |------------|--------------| | wsrep_cluster_address | Alle Node-Adressen | | wsrep_node_address | Eigene IP | | wsrep_sst_method | Sync-Methode | | wsrep_cluster_name | Cluster-Name |

| Status | Bedeutung | |--------|-----------| | wsrep_cluster_size=3 | 3 Nodes aktiv | | wsrep_cluster_status=Primary | OK | | wsrep_local_state=4 | Synced | | wsrep_ready=ON | Node bereit |

| Befehl | Funktion | |--------|----------| | galera_new_cluster | Cluster initialisieren | | SHOW STATUS LIKE 'wsrep_%' | Status prüfen |

Fazit

MariaDB Galera Cluster bietet echte Multi-Master-Replikation mit synchroner Datenkonsistenz. Die Einrichtung erfordert Planung, insbesondere bei der Netzwerk-Konfiguration. Mit einem Load Balancer wie HAProxy wird die Hochverfügbarkeit komplett. Wichtig ist die Überwachung der Flow Control und regelmäßige Tests des Failover-Verhaltens. Für Anwendungen, die konsistente Lesezugriffe auf allen Nodes benötigen, ist Galera ideal.