MariaDB Replikation (Ubuntu)

Aus Tutorials
Version vom 2. Juni 2023, 15:46 Uhr von Martin Kirner (Diskussion | Beiträge) (→‎Synchronen Status wiederherstellen)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Zur Navigation springen Zur Suche springen

Server A (10.0.0.157) - Teil 1

Die Datei /etc/mysql/mariadb.conf.d/50-server.cnf editieren

sudo vi /etc/mysql/mariadb.conf.d/50-server.cnf

und folgende Zeilen hinzufügen/anpassen:

bind-address=10.0.0.157

server-id              = 1
# if 'log-basename' is set, logfile would be '/var/log/mysql/<log-basename>-bin.log'
log_bin                = /var/log/mysql/mysql-bin.log
expire_logs_days       = 10
binlog_do_db           = powerdns
binlog_do_db           = ddns
replicate-do-db        = powerdns
replicate-do-db        = ddns
# Basename for all log files and the .pid file. This sets all log file names 
# at once (in 'datadir') and is normally the only option you need for specifying 
# log files. This is especially recommended to be set if you are using 
# replication as it ensures that your log file names are not dependent on your 
# host name. 
log-basename           = master1

binlog_do_db kennzeichnen die Datenbanken, für die der Server Logs schreiben soll.

replicate-do-db im Gegezug kennzeichnet die Datenbanken, für die dieser Server als Klient die Änderungen vom Master abfragen soll.

Mit log-basename wird der Basisname der Log-Dateien festgelegt - siehe dazu auch Log-Files.


Danach den Server neu starten:

sudo systemctl restart mariadb

Für die Replikation ist weiters ein Benutzer (in unserem Fall master) notwendig, der auf alle Datenbanken REPLICATION Zugriff hat:

CREATE USER 'master'@'%' IDENTIFIED BY '<password>';
GRANT REPLICATION SLAVE ON *.* TO 'master'@'%';
FLUSH PRIVILEGES;

Für die Konfiguration des Slaves, brauchen wir die aktuelle Binärdatei und die Position des Masters. Diese Information bekommen wir über folgenden SQL-Befehl:

SHOW MASTER STATUS;

Die Ausgabe sollte dann wie folgt aussehen:

+------------------+----------+---------------+------------------+
| File             | Position | Binlog_Do_DB  | Binlog_Ignore_DB |
+------------------+----------+---------------+------------------+
| mysql-bin.000001 |      774 | powerdns,ddns |                  |
+------------------+----------+---------------+------------------+
1 row in set (0.000 sec)

Server B (10.0.0.167)

Die Datei /etc/mysql/mariadb.conf.d/50-server.cnf editieren

sudo vi /etc/mysql/mariadb.conf.d/50-server.cnf

und ähnlich wie bei Server A folgende Zeilen hinzufügen/anpassen:

bind-address=10.0.0.167

server-id              = 2
# if 'log-basename' is set, logfile would be '/var/log/mysql/<log-basename>-bin.log'
log_bin                = /var/log/mysql/mysql-bin.log
expire_logs_days       = 10
binlog_do_db           = powerdns
binlog_do_db           = ddns
replicate-do-db        = powerdns
replicate-do-db        = ddns
# Basename for all log files and the .pid file. This sets all log file names 
# at once (in 'datadir') and is normally the only option you need for specifying 
# log files. This is especially recommended to be set if you are using 
# replication as it ensures that your log file names are not dependent on your 
# host name. 
log-basename           = master2

Danach den Server wieder neu starten:

sudo systemctl restart mariadb

Wie bei Server A wird hier ebenfalls ein Datenbank-Benutzer benötigt:

mysql -u root -p
CREATE USER 'master'@'%' IDENTIFIED BY '<password>';
GRANT REPLICATION SLAVE ON *.* TO 'master'@'%';
FLUSH PRIVILEGES;

Als nächstes den Slave stoppen:

STOP SLAVE;

Folgender Befehl muss, mit den vorhin unter SHOW MASTER STATUS angezeigten Daten, ausgeführt werden:

CHANGE MASTER TO MASTER_HOST = '10.0.0.157', MASTER_USER = 'master', MASTER_PASSWORD = '<password>', MASTER_LOG_FILE = 'mysql-bin.000001', MASTER_LOG_POS = 774;

Zum Abschluss den Slave wieder starten:

START SLAVE;

Für eine Master-zu-Master-Replikation muss auf diesem auch wieder der Master-Status abgefragt werden:

SHOW MASTER STATUS;

Die ausgegebenen Werte müssen wieder in Server A eingetragen werden:

+------------------+----------+---------------+------------------+
| File             | Position | Binlog_Do_DB  | Binlog_Ignore_DB |
+------------------+----------+---------------+------------------+
| mysql-bin.000001 |      774 | powerdns,ddns |                  |
+------------------+----------+---------------+------------------+
1 row in set (0.000 sec)

Server A (10.0.0.157) - Teil 2

Zum Abschluss müssen noch der Status von Server B in Server A eingetragen werden:

mysql -u root -p

Slave wieder stoppen:

STOP SLAVE;

Status eintragen:

CHANGE MASTER TO MASTER_HOST = '10.0.0.167', MASTER_USER = 'master', MASTER_PASSWORD = '<password>', MASTER_LOG_FILE = 'mysql-bin.000001', MASTER_LOG_POS = 774;

Slave wieder starten:

START SLAVE;

Im Anschluss sollte die Änderungen auf jeweils den anderen Server repliziert werden.

Client Status

Um den aktuellen Client-Status bzw. eventuelle Fehler anzuzeigen, folgenden Befehl ausführen:

SHOW SLAVE STATUS\G

Die Ausgabe sollte in etwa so aussehen:

*************************** 1. row ***************************
                Slave_IO_State: Waiting for master to send event
                   Master_Host: 10.0.0.167
                   Master_User: master
                   Master_Port: 3306
                 Connect_Retry: 60
               Master_Log_File: mysql-bin.000006
           Read_Master_Log_Pos: 987
                Relay_Log_File: master1-relay-bin.000007
                 Relay_Log_Pos: 1286
         Relay_Master_Log_File: mysql-bin.000006
              Slave_IO_Running: Yes
             Slave_SQL_Running: Yes
               Replicate_Do_DB: powerdns,ddns
           Replicate_Ignore_DB: 
            Replicate_Do_Table: 
        Replicate_Ignore_Table: 
       Replicate_Wild_Do_Table: 
   Replicate_Wild_Ignore_Table: 
                    Last_Errno: 0
                    Last_Error: 
                  Skip_Counter: 0
           Exec_Master_Log_Pos: 987
               Relay_Log_Space: 1896
               Until_Condition: None
                Until_Log_File: 
                 Until_Log_Pos: 0
            Master_SSL_Allowed: No
            Master_SSL_CA_File: 
            Master_SSL_CA_Path: 
               Master_SSL_Cert: 
             Master_SSL_Cipher: 
                Master_SSL_Key: 
         Seconds_Behind_Master: 0
 Master_SSL_Verify_Server_Cert: No
                 Last_IO_Errno: 0
                 Last_IO_Error: 
                Last_SQL_Errno: 0
                Last_SQL_Error: 
   Replicate_Ignore_Server_Ids: 
              Master_Server_Id: 2
                Master_SSL_Crl: 
            Master_SSL_Crlpath: 
                    Using_Gtid: No
                   Gtid_IO_Pos: 
       Replicate_Do_Domain_Ids: 
   Replicate_Ignore_Domain_Ids: 
                 Parallel_Mode: conservative
                     SQL_Delay: 0
           SQL_Remaining_Delay: NULL
       Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it
              Slave_DDL_Groups: 0
Slave_Non_Transactional_Groups: 0
    Slave_Transactional_Groups: 3
1 row in set (0.001 sec)

Log-Files

Wenn die Konfiguration log-basename gesetzt ist, dann werden die Log-Dateien direkt im Datenverzeichnis abgelegt. Wo sich das Datenverzeichnis befindet, findet man über folgenden SQL-Befehl heraus:

SHOW VARIABLES LIKE '%datadir%';

Das sollte dann in etwa folgendes Ergebnis zurückgeben:

+---------------------------------------------+------------------------+
| Variable_name                               | Value                  |
+---------------------------------------------+------------------------+
| datadir                                     | /var/lib/mysql/        |
+---------------------------------------------+------------------------+

Synchronen Status wiederherstellen

Server B - Teil 1

mysql> STOP SLAVE;

Server A - Teil 1

Datenbanken exportieren

mysql> RESET MASTER;
mysql> FLUSH TABLES WITH READ LOCK;
mysqldump -u root -p ddns > ddns-dump.sql
mysqldump -u root -p powerdns > powerdns-dump.sql
mysql> UNLOCK TABLES;
mysql> SHOW MASTER STATUS;

Server B - Teil 2

Datenbanken importieren

mysqldump -u root -p ddns < ddns-dump.sql
mysqldump -u root -p powerdns < powerdns-dump.sql

Slave neu konifgurieren

Daten aus mysql> SHOW MASTER STATUS; auf Server A verwenden:

mysql> RESET SLAVE;
mysql> CHANGE MASTER TO MASTER_LOG_FILE = 'master1-bin.000001', MASTER_LOG_POS = 330;
mysql> START SLAVE;
mysql> SHOW MASTER STATUS;

Server A - Teil 2

Slave neu konifgurieren

Daten aus mysql> SHOW MASTER STATUS; auf Server B verwenden:

mysql> STOP SLAVE;
mysql> RESET SLAVE;
mysql> CHANGE MASTER TO MASTER_LOG_FILE = 'master2-bin.000026', MASTER_LOG_POS = 15048;
mysql> START SLAVE;

Slave-Status kontrollieren

Auf beiden Servern den Status kontrollieren:

mysql> show slave status \G

Links

https://tecadmin.net/reset-re-sync-mysql-master-slave-replication/

https://stackoverflow.com/questions/2366018/how-to-re-sync-the-mysql-db-if-master-and-slave-have-different-database-incase-o

Probleme

Could not initialize master info structure for ; more error messages can be found in the MariaDB error log

Nach Änderung der Konfiguration habe ich obenstehende Fehlermeldung beim Ausführen von

CHANGE MASTER TO MASTER_HOST = '10.0.0.157', MASTER_USER = 'master', MASTER_PASSWORD = '<password>', MASTER_LOG_FILE = 'mysql-bin.000001', MASTER_LOG_POS = 774;

bekommen. Nach Ausführen von

RESET SLAVE;

ist der Fehler nicht mehr aufgetreten.

Links

https://mariadb.com/kb/en/setting-up-replication/

https://forums.mysql.com/read.php?26,171776,205870

https://mariadb.com/kb/en/standard-replication/

https://www.vpsserver.com/community/tutorials/9/setup-a-master-to-master-replication-between-two-mariadb-servers/


Zurück zu MariaDB