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
- 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)
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.
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.
Bearbeite /etc/my.cnf.d/server.cnf
auf beiden Servern.
[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
[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
CREATE USER 'replica'@'%' IDENTIFIED BY 'Repl1pass!';
GRANT REPLICATION SLAVE ON *.* TO 'replica'@'%';
FLUSH PRIVILEGES;
CREATE USER 'replica'@'%' IDENTIFIED BY 'Repl2pass!';
GRANT REPLICATION SLAVE ON *.* TO 'replica'@'%';
FLUSH PRIVILEGES;
SHOW MASTER STATUS;
Notiere dir auf beiden Knoten File
und Position
.
Beispiel:
- DB1:
mariadb-bin.000001
, Position1710
- DB2:
mariadb-bin.000001
, Position1200
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;
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;
SHOW SLAVE STATUS\G
Wichtig:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0
Auf beiden Servern.
CREATE USER 'srv-monitoring-r'@'localhost' IDENTIFIED BY 'monitoringpass';
GRANT SELECT ON *.* TO 'srv-monitoring-r'@'localhost';
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"
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 Usersrv-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
.
- 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.
- Healthcheck-Skripte für
keepalived
- Metriken mit Prometheus + mysqld_exporter
- Replikationsstatus regelmäßig prüfen und bei Fehlern alarmieren
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.