MariaDB Replikation einrichten

Replikation trennt Lese- und Schreib-Last auf verschiedene Server. Der Primary nimmt alle Writes, ein oder mehrere Replicas beantworten SELECT-Anfragen. Außerdem ein gutes Fundament für Hochverfügbarkeit.

Konzept

Primary schreibt alle Änderungen in das Binlog. Replica verbindet sich, liest das Binlog und wendet die Änderungen auf seiner eigenen Kopie an. Asynchron — der Primary wartet nicht auf Bestätigung.

Primary konfigurieren

# /etc/mysql/mariadb.conf.d/50-server.cnf
[mysqld]
server-id        = 1
log_bin          = /var/log/mysql/mariadb-bin
binlog_format    = ROW
bind-address     = 0.0.0.0   ; oder interne IP des Replica-Servers
systemctl restart mariadb
-- Replikations-User anlegen
CREATE USER 'repl'@'<replica-ip>' IDENTIFIED BY 'starkes-passwort';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'<replica-ip>';
FLUSH PRIVILEGES;

Initialen Dump erstellen

# Auf dem Primary: konsistenter Dump
mysqldump --single-transaction --master-data=2 --all-databases \
    | gzip > /tmp/full-backup.sql.gz

# Binlog-Position aus dem Dump lesen
zcat /tmp/full-backup.sql.gz | head -40 | grep "MASTER_LOG"
# -- CHANGE MASTER TO MASTER_LOG_FILE='mariadb-bin.000001', MASTER_LOG_POS=1234;

Replica konfigurieren

# /etc/mysql/mariadb.conf.d/50-server.cnf
[mysqld]
server-id   = 2
read_only   = 1       ; schreibt nur der Replikations-Thread
# Dump einspielen
zcat /tmp/full-backup.sql.gz | mysql -u root

# Replikation starten
mysql -u root
CHANGE MASTER TO
    MASTER_HOST     = '<primary-ip>',
    MASTER_USER     = 'repl',
    MASTER_PASSWORD = 'starkes-passwort',
    MASTER_LOG_FILE = 'mariadb-bin.000001',
    MASTER_LOG_POS  = 1234;

START SLAVE;
SHOW SLAVE STATUS\G

Seconds_Behind_Master: 0 bedeutet in Sync.

In PHP nutzen

// Writes auf Primary
$primary = new PDO('mysql:host=primary-server;dbname=myapp', $user, $pass);

// Reads auf Replica
$replica = new PDO('mysql:host=replica-server;dbname=myapp', $user, $pass);

// Schreiben
$primary->prepare('INSERT INTO events (name) VALUES (?)')->execute([$name]);

// Lesen
$rows = $replica->query('SELECT * FROM events ORDER BY id DESC LIMIT 50')->fetchAll();

Wenn nach einem Write sofort gelesen werden muss (z. B. Redirect-After-Post): vom Primary lesen um Replication-Lag zu vermeiden.

Monitoring

SHOW SLAVE STATUS\G
-- Seconds_Behind_Master: Replikationsverzögerung
-- Slave_IO_Running: Yes
-- Slave_SQL_Running: Yes

Wenn eines davon nicht Yes ist und Last_Error gefüllt ist gibt es ein Problem.