Datenbank-Replikation synchronisiert Daten zwischen Servern. Sie ermöglicht Hochverfügbarkeit, Lastverteilung für Leseoperationen und einfache Backups.

Replikationstypen

Master-Slave

       ┌──────────┐
       │  Master  │ ← Schreiben
       └────┬─────┘
            │ Binlog
    ┌───────┴───────┐
    ▼               ▼
┌──────┐       ┌──────┐
│Slave1│       │Slave2│ ← Lesen
└──────┘       └──────┘

Anwendungsfälle

- Read-Scaling: Lesezugriffe auf Slaves verteilen
- Backup: Backup vom Slave ohne Master zu belasten
- Failover: Slave bei Master-Ausfall übernehmen
- Reporting: Reports auf Slave ausführen

Voraussetzungen

Systemvoraussetzungen

Master-Server: 192.168.1.10
Slave-Server:  192.168.1.20

- MariaDB 10.6+ auf beiden Servern
- Netzwerkverbindung zwischen Servern
- Port 3306 offen

Master konfigurieren

my.cnf bearbeiten

# /etc/mysql/mariadb.conf.d/50-server.cnf (Debian)
# Oder /etc/my.cnf.d/server.cnf (CentOS)

[mysqld]
# Server-ID (eindeutig im Cluster)
server-id = 1

# Binary Logging aktivieren
log_bin = /var/log/mysql/mysql-bin.log
binlog_format = ROW

# Datenbanken replizieren (optional)
# binlog_do_db = meine_db

# Datenbanken ausschließen (optional)
binlog_ignore_db = mysql
binlog_ignore_db = information_schema

# Binlog-Aufbewahrung
expire_logs_days = 7
max_binlog_size = 100M

# Für InnoDB
innodb_flush_log_at_trx_commit = 1
sync_binlog = 1

MariaDB neu starten

systemctl restart mariadb

Replikations-Benutzer erstellen

mysql -u root -p
-- Benutzer für Replikation erstellen
CREATE USER 'replication'@'192.168.1.20' IDENTIFIED BY 'SicheresPasswort!';
GRANT REPLICATION SLAVE ON *.* TO 'replication'@'192.168.1.20';
FLUSH PRIVILEGES;

-- Für mehrere Slaves
-- CREATE USER 'replication'@'192.168.1.%' IDENTIFIED BY 'SicheresPasswort!';

Master-Status notieren

-- Tabellen sperren
FLUSH TABLES WITH READ LOCK;

-- Status anzeigen
SHOW MASTER STATUS;
+------------------+----------+
| File             | Position |
+------------------+----------+
| mysql-bin.000001 | 12345    |
+------------------+----------+

Wichtig: File und Position notieren!

Daten exportieren

# In neuem Terminal (Sperre nicht aufheben!)
mysqldump -u root -p --all-databases --master-data > master-dump.sql

Sperre aufheben

UNLOCK TABLES;

Slave konfigurieren

my.cnf bearbeiten

# /etc/mysql/mariadb.conf.d/50-server.cnf

[mysqld]
# Eindeutige Server-ID
server-id = 2

# Relay-Log
relay_log = /var/log/mysql/relay-bin.log

# Optional: Binlog auf Slave (für Kaskadierung)
log_bin = /var/log/mysql/mysql-bin.log
log_slave_updates = 1

# Read-only (empfohlen für Slave)
read_only = 1

MariaDB neu starten

systemctl restart mariadb

Daten importieren

# Dump vom Master kopieren
scp root@192.168.1.10:/root/master-dump.sql /root/

# Importieren
mysql -u root -p < /root/master-dump.sql

Replikation starten

mysql -u root -p
-- Replikation konfigurieren
CHANGE MASTER TO
    MASTER_HOST='192.168.1.10',
    MASTER_USER='replication',
    MASTER_PASSWORD='SicheresPasswort!',
    MASTER_LOG_FILE='mysql-bin.000001',
    MASTER_LOG_POS=12345;

-- Replikation starten
START SLAVE;

-- Status prüfen
SHOW SLAVE STATUS\G

Wichtige Status-Felder

SHOW SLAVE STATUS\G

# Wichtige Felder:
# Slave_IO_Running: Yes
# Slave_SQL_Running: Yes
# Seconds_Behind_Master: 0
# Last_Error: (sollte leer sein)

GTID-basierte Replikation

Vorteile

- Einfachere Verwaltung
- Automatische Positionierung
- Einfacherer Failover

Master konfigurieren

[mysqld]
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
binlog_format = ROW
gtid_strict_mode = ON

Slave konfigurieren

[mysqld]
server-id = 2
relay_log = /var/log/mysql/relay-bin.log
log_slave_updates = 1
gtid_strict_mode = ON
read_only = 1

Replikation mit GTID starten

-- Auf Slave
CHANGE MASTER TO
    MASTER_HOST='192.168.1.10',
    MASTER_USER='replication',
    MASTER_PASSWORD='SicheresPasswort!',
    MASTER_USE_GTID=slave_pos;

START SLAVE;

Monitoring

Replikations-Status

-- Auf Slave
SHOW SLAVE STATUS\G

-- Wichtig:
-- Slave_IO_Running: Yes
-- Slave_SQL_Running: Yes
-- Seconds_Behind_Master: 0

Binlog-Status auf Master

SHOW MASTER STATUS;
SHOW BINARY LOGS;

Monitoring-Skript

#!/bin/bash
# check-replication.sh

STATUS=$(mysql -u root -ppassword -e "SHOW SLAVE STATUS\G")

IO_RUNNING=$(echo "$STATUS" | grep "Slave_IO_Running" | awk '{print $2}')
SQL_RUNNING=$(echo "$STATUS" | grep "Slave_SQL_Running" | awk '{print $2}')
LAG=$(echo "$STATUS" | grep "Seconds_Behind_Master" | awk '{print $2}')

if [ "$IO_RUNNING" != "Yes" ] || [ "$SQL_RUNNING" != "Yes" ]; then
    echo "CRITICAL: Replication not running!"
    exit 2
fi

if [ "$LAG" -gt 60 ]; then
    echo "WARNING: Replication lag: $LAG seconds"
    exit 1
fi

echo "OK: Replication running, lag: $LAG seconds"
exit 0

Troubleshooting

Replikation gestoppt

-- Fehler anzeigen
SHOW SLAVE STATUS\G
-- Last_Error prüfen

-- Fehler überspringen (vorsichtig!)
STOP SLAVE;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE;

Replikation neu synchronisieren

# Auf Master
mysql -e "FLUSH TABLES WITH READ LOCK;"
mysql -e "SHOW MASTER STATUS;"
mysqldump -u root -p --all-databases --master-data > dump.sql
mysql -e "UNLOCK TABLES;"

# Auf Slave
mysql -e "STOP SLAVE;"
mysql < dump.sql
mysql -e "CHANGE MASTER TO MASTER_LOG_FILE='...', MASTER_LOG_POS=...;"
mysql -e "START SLAVE;"

Lag reduzieren

-- Auf Slave
-- Mehr parallele Worker
STOP SLAVE;
SET GLOBAL slave_parallel_threads = 4;
START SLAVE;

Failover

Manueller Failover

-- Auf aktuellem Slave (wird neuer Master):

-- 1. Replikation stoppen
STOP SLAVE;
RESET SLAVE ALL;

-- 2. Read-only deaktivieren
SET GLOBAL read_only = OFF;

-- 3. Andere Slaves auf neuen Master umstellen
-- Auf anderen Slaves:
STOP SLAVE;
CHANGE MASTER TO
    MASTER_HOST='192.168.1.20',
    MASTER_USER='replication',
    MASTER_PASSWORD='SicheresPasswort!',
    MASTER_USE_GTID=slave_pos;
START SLAVE;

Automatisierter Failover mit MaxScale

MariaDB MaxScale bietet:
- Automatische Failover-Erkennung
- Automatische Umschaltung
- Query-Routing (Read/Write-Split)

Read-Write-Split

Mit ProxySQL

-- Regeln für Read-Write-Split
INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup)
VALUES
    (1, 1, '^SELECT.*', 20),  -- Lesen auf Slaves
    (2, 1, '.*', 10);         -- Schreiben auf Master

In Anwendung

// PHP Beispiel
$master = new PDO("mysql:host=192.168.1.10;dbname=app", "user", "pass");
$slave = new PDO("mysql:host=192.168.1.20;dbname=app", "user", "pass");

// Schreiben auf Master
$master->exec("INSERT INTO ...");

// Lesen von Slave
$result = $slave->query("SELECT * FROM ...");

Backup vom Slave

#!/bin/bash
# Backup ohne Master zu belasten

# Slave pausieren
mysql -e "STOP SLAVE SQL_THREAD;"

# Backup erstellen
mysqldump -u root -p --all-databases > backup.sql

# Slave fortsetzen
mysql -e "START SLAVE SQL_THREAD;"

Zusammenfassung

| Server | Konfiguration | |--------|---------------| | Master | server-id=1, log_bin, binlog_format=ROW | | Slave | server-id=2, relay_log, read_only=1 |

| Befehl | Funktion | |--------|----------| | SHOW MASTER STATUS | Master-Position | | SHOW SLAVE STATUS | Replikations-Status | | START SLAVE | Replikation starten | | STOP SLAVE | Replikation stoppen | | CHANGE MASTER TO | Replikation konfigurieren |

Fazit

MariaDB-Replikation erhöht Verfügbarkeit und Skalierbarkeit. Die Master-Slave-Konfiguration ist unkompliziert, und mit GTID wird die Verwaltung noch einfacher. Überwachen Sie den Replikationsstatus regelmäßig und planen Sie Failover-Szenarien im Voraus. Für automatischen Failover und Load-Balancing empfiehlt sich MaxScale oder ProxySQL.