MySQL-Replikation ermöglicht die automatische Synchronisierung von Daten zwischen mehreren Datenbankservern. Sie ist essentiell für Hochverfügbarkeit, Backups und Lastverteilung.
Replikations-Typen
Übersicht
| Typ | Beschreibung | Verwendung | |-----|--------------|------------| | Asynchron | Standard, leicht verzögert | Allgemein | | Semi-synchron | Bestätigung vor Commit | Höhere Konsistenz | | Gruppen-Replikation | Multi-Master-fähig | Hochverfügbarkeit |
Architektur
┌─────────────┐
│ Master │
│ (Schreiben) │
└──────┬──────┘
│
Binary Log │
│
┌───────────────┼───────────────┐
│ │ │
┌──────┴──────┐ ┌──────┴──────┐ ┌──────┴──────┐
│ Slave 1 │ │ Slave 2 │ │ Slave 3 │
│ (Lesen) │ │ (Lesen) │ │ (Backup) │
└─────────────┘ └─────────────┘ └─────────────┘Voraussetzungen
Server-Daten
Master: 192.168.1.10
Slave: 192.168.1.11Netzwerk-Konnektivität
# Vom Slave aus testen
telnet 192.168.1.10 3306Firewall öffnen
# Auf Master
ufw allow from 192.168.1.11 to any port 3306Master-Konfiguration
my.cnf anpassen
# /etc/mysql/mysql.conf.d/mysqld.cnf (Master)
[mysqld]
# Eindeutige Server-ID
server-id = 1
# Binary Log aktivieren
log_bin = /var/log/mysql/mysql-bin.log
binlog_format = ROW
binlog_expire_logs_seconds = 604800
max_binlog_size = 100M
# Synchrone Schreibvorgänge
sync_binlog = 1
# Welche Datenbanken replizieren
# binlog-do-db = mydb
# binlog-ignore-db = mysql
# InnoDB für Crash-Recovery
innodb_flush_log_at_trx_commit = 1
# Bind Address für Remote-Zugriff
bind-address = 0.0.0.0MySQL neu starten
systemctl restart mysqlReplikations-Benutzer erstellen
-- Auf Master ausführen
CREATE USER 'replication'@'192.168.1.11' IDENTIFIED BY 'sicheres_passwort';
GRANT REPLICATION SLAVE ON *.* TO 'replication'@'192.168.1.11';
FLUSH PRIVILEGES;Master-Status ermitteln
-- Binary Log Position notieren
SHOW MASTER STATUS;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000001 | 154 | | |
+------------------+----------+--------------+------------------+Slave-Konfiguration
my.cnf anpassen
# /etc/mysql/mysql.conf.d/mysqld.cnf (Slave)
[mysqld]
# Eindeutige Server-ID (unterschiedlich vom Master)
server-id = 2
# Relay Log
relay-log = /var/log/mysql/mysql-relay-bin.log
# Read-Only (empfohlen)
read_only = 1
super_read_only = 1
# Binary Log auf Slave (für Ketten-Replikation)
# log_bin = /var/log/mysql/mysql-bin.log
# log_slave_updates = 1
# Crash-Safe
relay_log_recovery = 1
relay_log_info_repository = TABLE
master_info_repository = TABLEMySQL neu starten
systemctl restart mysqlDaten synchronisieren
Mit mysqldump (kleine Datenbanken)
# Auf Master: Daten exportieren
mysqldump --all-databases --master-data=2 --single-transaction \
--routines --triggers --events -u root -p > master_dump.sql
# Dump auf Slave übertragen
scp master_dump.sql root@192.168.1.11:/tmp/
# Auf Slave: Daten importieren
mysql -u root -p < /tmp/master_dump.sqlMit Lock (große Datenbanken)
-- Auf Master
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;
-- Position notieren
-- In anderem Terminal: Dump erstellen
mysqldump --all-databases -u root -p > /tmp/master_dump.sql
-- Lock aufheben
UNLOCK TABLES;Mit Percona XtraBackup (produktiv)
# Auf Master: Backup erstellen
xtrabackup --backup --target-dir=/backup/full -u root -p
# Backup vorbereiten
xtrabackup --prepare --target-dir=/backup/full
# Auf Slave kopieren und wiederherstellen
rsync -avz /backup/full/ slave:/var/lib/mysql/Replikation starten
Slave konfigurieren
-- Auf Slave ausführen
CHANGE MASTER TO
MASTER_HOST='192.168.1.10',
MASTER_USER='replication',
MASTER_PASSWORD='sicheres_passwort',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154;
-- Replikation starten
START SLAVE;
-- Status prüfen
SHOW SLAVE STATUS\GMySQL 8.0+ Syntax
-- Neue Syntax ab MySQL 8.0.22
CHANGE REPLICATION SOURCE TO
SOURCE_HOST='192.168.1.10',
SOURCE_USER='replication',
SOURCE_PASSWORD='sicheres_passwort',
SOURCE_LOG_FILE='mysql-bin.000001',
SOURCE_LOG_POS=154;
START REPLICA;
SHOW REPLICA STATUS\GStatus prüfen
Wichtige Felder
SHOW SLAVE STATUS\G
*************************** 1. row ***************************
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Seconds_Behind_Master: 0
Master_Log_File: mysql-bin.000001
Read_Master_Log_Pos: 154
Relay_Log_File: mysql-relay-bin.000002
Relay_Log_Pos: 320
Relay_Master_Log_File: mysql-bin.000001
Last_Error:Erwartete Werte
| Feld | Erwartet | |------|----------| | Slave_IO_Running | Yes | | Slave_SQL_Running | Yes | | Seconds_Behind_Master | 0 (oder niedrig) | | Last_Error | (leer) |
GTID-basierte Replikation
Was ist GTID?
Global Transaction Identifier
- Eindeutige ID für jede Transaktion
- Vereinfacht Failover
- Keine manuelle Binlog-Position nötigMaster-Konfiguration
# /etc/mysql/mysql.conf.d/mysqld.cnf
[mysqld]
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
binlog_format = ROW
# GTID aktivieren
gtid_mode = ON
enforce_gtid_consistency = ONSlave-Konfiguration
[mysqld]
server-id = 2
relay-log = /var/log/mysql/mysql-relay-bin.log
read_only = 1
# GTID aktivieren
gtid_mode = ON
enforce_gtid_consistency = ONGTID-Replikation starten
-- Auf Slave
CHANGE MASTER TO
MASTER_HOST='192.168.1.10',
MASTER_USER='replication',
MASTER_PASSWORD='sicheres_passwort',
MASTER_AUTO_POSITION=1;
START SLAVE;
SHOW SLAVE STATUS\GSemi-synchrone Replikation
Plugin installieren
-- Auf Master
INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';
SET GLOBAL rpl_semi_sync_master_enabled = 1;
-- Auf Slave
INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';
SET GLOBAL rpl_semi_sync_slave_enabled = 1;
-- Slave neu verbinden
STOP SLAVE;
START SLAVE;Permanente Konfiguration
# Master
[mysqld]
rpl_semi_sync_master_enabled = 1
rpl_semi_sync_master_timeout = 10000
# Slave
[mysqld]
rpl_semi_sync_slave_enabled = 1Status prüfen
-- Auf Master
SHOW STATUS LIKE 'Rpl_semi_sync%';
+--------------------------------------------+-------+
| Variable_name | Value |
+--------------------------------------------+-------+
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_master_clients | 1 |
+--------------------------------------------+-------+Mehrere Slaves
Konfiguration
# Slave 2
[mysqld]
server-id = 3
relay-log = /var/log/mysql/mysql-relay-bin.log
read_only = 1Chained Replication
Master → Slave 1 → Slave 2 → Slave 3
# Slave 1 als Relay
[mysqld]
server-id = 2
log_bin = /var/log/mysql/mysql-bin.log
log_slave_updates = 1
read_only = 1Failover
Manueller Failover
-- Auf altem Master: Schreibvorgänge stoppen
SET GLOBAL read_only = 1;
SHOW MASTER STATUS;
-- Auf Slave: Replikation prüfen
SHOW SLAVE STATUS\G
-- Warten bis Seconds_Behind_Master = 0
-- Slave zum Master promoten
STOP SLAVE;
RESET SLAVE ALL;
SET GLOBAL read_only = 0;
-- Anwendung auf neuen Master umstellenMit Orchestrator
# Installation
wget https://github.com/openark/orchestrator/releases/download/v3.2.6/orchestrator_3.2.6_amd64.deb
dpkg -i orchestrator_3.2.6_amd64.deb
# Web-Interface: http://server:3000Troubleshooting
Replikations-Fehler
-- Fehler überspringen (vorsichtig!)
STOP SLAVE;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE;
-- Bei GTID
STOP SLAVE;
SET GTID_NEXT='uuid:transaction_id';
BEGIN; COMMIT;
SET GTID_NEXT='AUTOMATIC';
START SLAVE;Replikation neu aufbauen
-- Auf Slave
STOP SLAVE;
RESET SLAVE ALL;
-- Daten neu synchronisieren
-- (mysqldump oder xtrabackup)
-- Replikation neu starten
CHANGE MASTER TO ...;
START SLAVE;Lag analysieren
-- Aktuelle Position
SHOW SLAVE STATUS\G
-- Binary Log Events
SHOW BINLOG EVENTS IN 'mysql-bin.000001' LIMIT 10;
-- Langsame Queries auf Slave
SHOW PROCESSLIST;IO Thread Probleme
-- Verbindung prüfen
-- Slave_IO_Running: No
-- Mögliche Ursachen:
-- 1. Netzwerk-Problem
-- 2. Falsches Passwort
-- 3. Firewall blockiert
-- 4. Master nicht erreichbar
-- Test vom Slave
mysql -h 192.168.1.10 -u replication -pSQL Thread Probleme
-- Slave_SQL_Running: No
-- Last_SQL_Error: ...
-- Häufige Ursachen:
-- 1. Duplicate Key
-- 2. Table nicht vorhanden
-- 3. Unterschiedliche Schema
-- Last Error anzeigen
SHOW SLAVE STATUS\GMonitoring
Replikations-Lag
#!/bin/bash
# /usr/local/bin/check-replication.sh
LAG=$(mysql -N -e "SHOW SLAVE STATUS\G" | grep "Seconds_Behind_Master" | awk '{print $2}')
if [ "$LAG" == "NULL" ]; then
echo "CRITICAL: Replication not running"
exit 2
elif [ "$LAG" -gt 300 ]; then
echo "WARNING: Replication lag is ${LAG}s"
exit 1
else
echo "OK: Replication lag is ${LAG}s"
exit 0
fiPrometheus + mysqld_exporter
# prometheus.yml
scrape_configs:
- job_name: 'mysql'
static_configs:
- targets: ['localhost:9104']Best Practices
Empfohlene Einstellungen
# Master
[mysqld]
server-id = 1
log_bin = /var/log/mysql/mysql-bin.log
binlog_format = ROW
gtid_mode = ON
enforce_gtid_consistency = ON
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1
# Slave
[mysqld]
server-id = 2
relay-log = /var/log/mysql/mysql-relay-bin.log
read_only = 1
super_read_only = 1
gtid_mode = ON
enforce_gtid_consistency = ON
relay_log_recovery = 1Sicherheit
-- Minimale Rechte für Replikations-User
CREATE USER 'replication'@'slave_ip' IDENTIFIED BY 'passwort';
GRANT REPLICATION SLAVE ON *.* TO 'replication'@'slave_ip';
-- SSL für Replikation
CHANGE MASTER TO
MASTER_SSL = 1,
MASTER_SSL_CA = '/etc/mysql/ca.pem',
MASTER_SSL_CERT = '/etc/mysql/client-cert.pem',
MASTER_SSL_KEY = '/etc/mysql/client-key.pem';Zusammenfassung
| Komponente | Master | Slave | |------------|--------|-------| | server-id | Eindeutig | Eindeutig | | log_bin | An | Optional | | read_only | Nein | Ja | | relay-log | - | An |
| Befehl | Funktion | |--------|----------| | SHOW MASTER STATUS | Position anzeigen | | SHOW SLAVE STATUS | Replikations-Status | | START SLAVE | Replikation starten | | STOP SLAVE | Replikation stoppen |
| Problem | Lösung | |---------|--------| | IO Thread down | Netzwerk/Auth prüfen | | SQL Thread down | Fehler analysieren | | Hoher Lag | Slave-Performance |
Fazit
MySQL-Replikation ist fundamental für Hochverfügbarkeit und Skalierung. GTID-basierte Replikation vereinfacht Failover erheblich. Semi-synchrone Replikation bietet höhere Datensicherheit auf Kosten der Performance. Monitoring ist essentiell um Replikationsprobleme frühzeitig zu erkennen. Für produktive Umgebungen sollte immer ein automatisiertes Failover-System wie Orchestrator eingesetzt werden.