Skip to content

Instantly share code, notes, and snippets.

@OnkelDom
Last active March 30, 2025 20:58
Show Gist options
  • Save OnkelDom/f75610062b4187de505cf7fc709d5466 to your computer and use it in GitHub Desktop.
Save OnkelDom/f75610062b4187de505cf7fc709d5466 to your computer and use it in GitHub Desktop.
Erstellen einer MariaDB Master/Master Replikation und Keepalived

MariaDB Master-Master Replikation auf Rocky Linux 9.5

Ziel

Einrichtung einer Master-Master Replikation mit MariaDB auf zwei Knoten (DB1 und DB2) unter Rocky Linux 9.5. Der Datenbankzugriff erfolgt bevorzugt auf DB1 via keepalived, mit einer virtuellen IP. Bei Split-Brain soll weiterhin Schreibzugriff auf beide Nodes bestehen.

Quelle: https://github.com/jomyg/MariaDB-Master-Master-Replication

Voraussetzungen

  • Zwei MariaDB-Server (DB1 und DB2) mit privaten IPs (z. B. 192.168.1.11 und 192.168.1.12)
  • firewalld oder eine andere Firewall ist konfiguriert (Port 3306 TCP offen zwischen beiden Nodes)
  • SELinux ist korrekt konfiguriert (siehe unten)

Installation

sudo dnf install mariadb-server -y
sudo systemctl enable --now mariadb

Führe auf beiden Knoten mysql_secure_installation durch und setze das Root-Passwort.


SELinux-Konfiguration

MariaDB benötigt die Erlaubnis, Netzwerkzugriffe zu akzeptieren:

# Erlaube MariaDB Zugriff auf Netzwerk
sudo setsebool -P mysql_connect_any 1

# Falls du einen benutzerdefinierten Port nutzt:
sudo semanage port -a -t mysqld_port_t -p tcp 3306

Stelle sicher, dass folgende SELinux-Kontexte korrekt gesetzt sind:

sudo restorecon -Rv /var/lib/mysql
sudo restorecon -Rv /var/log/mariadb

Überprüfung:

sudo ausearch -m avc -ts recent

Wenn du keepalived oder Healthchecks über eigene Skripte nutzt, stelle sicher, dass auch diese ggf. per SELinux erlaubt sind oder über eigene Policies (mit audit2allow) freigegeben werden.


Konfiguration

Bearbeite /etc/my.cnf.d/server.cnf auf beiden Servern.

DB1 (/etc/my.cnf.d/server.cnf)

[mysqld]
server-id=1
log_bin=/var/log/mariadb/mariadb-bin
log_slave_updates=1
binlog_format=ROW
auto_increment_increment=2
auto_increment_offset=1
bind-address=0.0.0.0
gtid_strict_mode=ON
enforce_gtid_consistency=ON

DB2 (/etc/my.cnf.d/server.cnf)

[mysqld]
server-id=2
log_bin=/var/log/mariadb/mariadb-bin
log_slave_updates=1
binlog_format=ROW
auto_increment_increment=2
auto_increment_offset=2
bind-address=0.0.0.0
gtid_strict_mode=ON
enforce_gtid_consistency=ON
sudo systemctl restart mariadb

Replikationsbenutzer anlegen

Auf DB1:

CREATE USER 'replica'@'%' IDENTIFIED BY 'Repl1pass!';
GRANT REPLICATION SLAVE ON *.* TO 'replica'@'%';
FLUSH PRIVILEGES;

Auf DB2:

CREATE USER 'replica'@'%' IDENTIFIED BY 'Repl2pass!';
GRANT REPLICATION SLAVE ON *.* TO 'replica'@'%';
FLUSH PRIVILEGES;

Status prüfen

SHOW MASTER STATUS;

Notiere dir auf beiden Knoten File und Position.

Beispiel:

  • DB1: mariadb-bin.000001, Position 1710
  • DB2: mariadb-bin.000001, Position 1200

Replikation konfigurieren

Auf DB1:

STOP SLAVE;
CHANGE MASTER TO
  MASTER_HOST='192.168.1.12',
  MASTER_USER='replica',
  MASTER_PASSWORD='Repl2pass!',
  MASTER_LOG_FILE='mariadb-bin.000001',
  MASTER_LOG_POS=1200,
  GET_MASTER_PUBLIC_KEY = 1,
  MASTER_USE_GTID = current_pos;
START SLAVE;

Auf DB2:

STOP SLAVE;
CHANGE MASTER TO
  MASTER_HOST='192.168.1.11',
  MASTER_USER='replica',
  MASTER_PASSWORD='Repl1pass!',
  MASTER_LOG_FILE='mariadb-bin.000001',
  MASTER_LOG_POS=1710,
  GET_MASTER_PUBLIC_KEY = 1,
  MASTER_USE_GTID = current_pos;
START SLAVE;

Replikation prüfen

SHOW SLAVE STATUS\G

Wichtig:

  • Slave_IO_Running: Yes
  • Slave_SQL_Running: Yes
  • Seconds_Behind_Master: 0

Auf beiden Servern.


Monitoring Benutzer anlegen

CREATE USER 'srv-monitoring-r'@'localhost' IDENTIFIED BY 'monitoringpass';
GRANT SELECT ON *.* TO 'srv-monitoring-r'@'localhost';

Testdatenbank anlegen

CREATE DATABASE company;
USE company;
CREATE TABLE employees (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(255));
INSERT INTO employees (name) VALUES ('Alice'), ('Bob'), ('Charlie');
SELECT * FROM employees;

Teste von beiden Seiten:

mysql -u root -p -h 192.168.1.11 -e "SELECT * FROM company.employees"
mysql -u root -p -h 192.168.1.12 -e "SELECT * FROM company.employees"

Keepalived-Einsatz

Installiere keepalived und konfiguriere eine virtuelle IP auf DB1 mit hoher Priorität. Die Clients verbinden sich über die VIP, z. B. 192.168.1.100.

In /etc/keepalived/keepalived.conf (nur Beispiel):

global_defs {
   router_id mariadb1
}
vrrp_script chk_mariadb {
    script "/usr/local/bin/check_mariadb.sh"
    interval 5
    weight -20
}

vrrp_instance VI_1 {
    state MASTER
    interface eth0
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass secret
    }
    virtual_ipaddress {
        192.168.1.100
    }
    track_script {
        chk_mariadb
    }
}

Beispielinhalt /usr/local/bin/check_mariadb.sh:

#!/bin/bash
mysql -u srv-monitoring-r -p'monitoringpass' -e "SELECT 1;" > /dev/null 2>&1 || exit 1

Ersetze das Passwort im Skript durch ein sicheres, lokal lesbares .my.cnf oder nutze alternativ den User srv-monitoring-r mit eingeschränkten Rechten nur für diesen Zweck. mit einem abgesicherten Zugriff z. B. über .my.cnf oder eigene MySQL-User mit eingeschränkten Rechten.

Skript ausführbar machen:

chmod +x /usr/local/bin/check_mariadb.sh

Auf DB2 entsprechend mit priority 90.


Hinweise zur Schreibbarkeit bei Split-Brain

  • Standardmäßig empfiehlt man nur einen aktiven Writer (DB1) mit read_only=1 auf DB2.
  • In deinem Fall bewusst nicht, damit Split-Brain-Situationen trotzdem beide Seiten schreibfähig halten.

Risiko: Schreibkonflikte ohne Conflict-Detection.

Lösungsideen bei gleichzeitiger Nutzung:

  • Primärschlüssel-Kollisionen vermeiden: durch auto_increment_increment/offset wie oben bereits konfiguriert.
  • Zwingend sicherstellen, dass Applikationen keine widersprüchlichen Daten erzeugen.

Alternativen bei höherem Bedarf:

  • Galera Cluster mit wsrep-basierter Replikation (echtes Multi-Master), aber komplexer.

Optional: Monitoring & Recovery

  • Healthcheck-Skripte für keepalived
  • Metriken mit Prometheus + mysqld_exporter
  • Replikationsstatus regelmäßig prüfen und bei Fehlern alarmieren

Fazit

Du erhältst mit dieser Konfiguration eine funktionale Master-Master-Replikation mit einfacher HA über keepalived. Schreibkonflikte sind bei Split-Brain möglich, aber durch auto_increment_* technisch begrenzt. Für produktive Systeme mit gleichzeitigen Writes ist ein Galera-Cluster robuster, aber aufwendiger.

Diese Konfiguration eignet sich ideal zum Verproben und für kleine/mittlere HA-Umgebungen ohne massiven parallelen Schreibzugriff.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment