Konfigurationslösung für die MySQL Dual-Master-Architektur (Master-Master)

Konfigurationslösung für die MySQL Dual-Master-Architektur (Master-Master)

In Unternehmen hat die hohe Verfügbarkeit von Datenbanken schon immer höchste Priorität. Viele kleine und mittlere Unternehmen verwenden die MySQL-Master-Slave-Lösung, einen Master und mehrere Slaves, Lese- und Schreibtrennung usw. Ein einzelner Master hat jedoch einen einzelnen Ausfallpunkt, und beim Wechsel von einer Slave-Datenbank zu einer Master-Datenbank müssen Änderungen vorgenommen werden. Daher wird bei Dual-Master oder Multi-Master der MySQL-Eintrag hinzugefügt, um die Hochverfügbarkeit zu erhöhen. Bei mehreren Mastern muss jedoch das Problem der selbstinkrementierenden ID berücksichtigt werden. Dies erfordert spezielle Konfigurationsdateien. Beispielsweise kann bei Dual-Mastern Parität verwendet werden. Kurz gesagt, das Konfliktproblem der selbstinkrementierenden ID kann perfekt gelöst werden, indem selbstinkrementierende IDs ohne Konflikte zwischen Mastern festgelegt werden.

Prinzip der synchronen Master-Slave-Replikation

Bevor wir beginnen, wollen wir zunächst das Prinzip der synchronen Master-Slave-Replikation verstehen.

Der Kopiervorgang gliedert sich in drei Schritte:

1. Der Master zeichnet die Änderungen im Binärprotokoll auf (diese Aufzeichnungen werden als Binärprotokollereignisse bezeichnet).
2. Der Slave kopiert die Binärprotokollereignisse des Masters in sein Relay-Protokoll.
3. Der Slave wiederholt die Ereignisse im Relay-Protokoll und ändert die Daten so, dass sie seine eigenen widerspiegeln.

Das folgende Diagramm beschreibt diesen Prozess:

Der erste Teil des Prozesses besteht für den Master darin, Binärprotokolle aufzuzeichnen. Bevor jede Transaktion die Datenaktualisierung abschließt, zeichnet der Master diese Änderungen im sekundären Protokoll auf. MySQL schreibt Transaktionen seriell in das Binärprotokoll, auch wenn Anweisungen in der Transaktion verschachtelt sind. Nachdem das Ereignis in das Binärprotokoll geschrieben wurde, benachrichtigt der Master die Speicher-Engine, dass die Transaktion bestätigt werden soll.

Im nächsten Schritt kopiert der Slave das Binärprotokoll des Masters in sein eigenes Relay-Protokoll. Zuerst startet der Slave einen Arbeitsthread – den I/O-Thread. Der E/A-Thread öffnet eine normale Verbindung auf dem Master und startet dann den Binlog-Dump-Prozess. Der Binlog-Dump-Prozess liest Ereignisse aus dem Binärprotokoll des Masters. Wenn er mit dem Master gleichgezogen hat, wird er in den Ruhezustand versetzt und wartet, bis der Master neue Ereignisse generiert. Der E/A-Thread schreibt diese Ereignisse in das Relay-Protokoll.

Der SQL-Slave-Thread übernimmt den letzten Schritt des Prozesses. Der SQL-Thread liest Ereignisse aus dem Relay-Protokoll und aktualisiert die Daten des Slaves, um sie mit den Daten im Master in Einklang zu bringen. Solange der Thread mit dem E/A-Thread konsistent bleibt, befindet sich das Relay-Protokoll normalerweise im Cache des Betriebssystems, sodass der Overhead des Relay-Protokolls gering ist.

Darüber hinaus gibt es auch im Master einen Worker-Thread: Wie bei anderen MySQL-Verbindungen führt das Öffnen einer Verbindung durch einen Slave im Master auch dazu, dass der Master einen Thread startet.

Der Replikationsprozess von Versionen vor MySQL 5.6 weist eine sehr wichtige Einschränkung auf: Die Replikation wird auf dem Slave serialisiert, was bedeutet, dass parallele Aktualisierungsvorgänge auf dem Master nicht parallel auf dem Slave ausgeführt werden können. Der MySQL 5.6-Versionsparameter „slave-parallel-workers=1“ bedeutet, dass die Multithreading-Funktion aktiviert wird.

Ab MySQL 5.6 wurde eine neue Funktion hinzugefügt, nämlich die Hinzufügung einer globalen Transaktions-ID (GTID), um die Master-Slave-Konsistenz, Fehlerbehebung und Fehlertoleranz der Datenbank zu verbessern.

Offizielle Dokumentation: http://dev.mysql.com/doc/refman/5.6/en/replication-gtids.html

Die Idee der MySQL Dual-Master (Master-Master)-Architektur ist:

1. Beide MySQL-Server sind lesbar und beschreibbar und dienen gleichzeitig als Master und Backup. Standardmäßig wird nur ein Server (MasterA) zum Schreiben von Daten verwendet und der andere Server (MasterB) als Backup.
2. MasterA ist die Masterdatenbank von MasterB und MasterB ist die Masterdatenbank von MasterA. Sie sind Master und Slave füreinander.
3. Um eine hohe Verfügbarkeit zwischen den beiden Masterdatenbanken zu erreichen, können Sie Lösungen wie Keepalived verwenden (mit VIP zur Bereitstellung externer Dienste);
4. Alle Slave-Server, die Dienste bereitstellen, führen eine Master-Slave-Synchronisierung mit MasterB durch (Dual-Master und Multiple-Slave).
5. Bei der Übernahme der Hochverfügbarkeitsstrategie wird empfohlen, dass weder MasterA noch MasterB nach der Wiederherstellung aufgrund von Ausfallzeiten VIP vorzeitig beenden (nicht-präemptiver Modus).
Auf diese Weise kann die hohe Verfügbarkeit der Masterdatenbank bis zu einem gewissen Grad sichergestellt werden. Wenn eine Masterdatenbank ausfällt, kann sie innerhalb kürzester Zeit auf eine andere Masterdatenbank umgeschaltet werden (wodurch die Auswirkungen der Ausfallzeit der Masterdatenbank auf das Geschäft so weit wie möglich minimiert werden), wodurch der Druck der Master-Slave-Synchronisierung auf die Online-Masterdatenbank verringert wird.

Es gibt jedoch auch einige Mängel:

1. MasterB kann ständig im Leerlauf sein (er kann als Slave verwendet werden, um für einige Abfragen zuständig zu sein);
2. Die Slave-Datenbank, die Dienste hinter der Master-Datenbank bereitstellt, muss warten, bis MasterB Daten synchronisiert hat, bevor sie Daten mit MasterB synchronisieren kann. Dies kann zu einer gewissen Synchronisierungsverzögerung führen.
Ein vereinfachtes Diagramm der Architektur sieht wie folgt aus:

Master-Master-Umgebung (hier stellen wir nur die Konfiguration von 2 Mastern vor):

1. CentOS 6.8 64-Bit 2 Maschinen: MasterA (192.168.10.11), MasterB (192.168.10.12)

2. Offizielle MySQL 5.6-Version

Bauablauf:

1. MySQL-Dienst installieren (Quellcode-Installation wird empfohlen)

1.1 Yum-Installationsabhängigkeitspaket

yum -y install make gcc gcc-c++ ncurses-devel bison openssl-devel

1.2 Von MySQL benötigte Benutzer und Gruppen hinzufügen

groupadd -g 27 mysql
adduser -u 27 -g mysql -s /sbin/nologin mysql

1.3 MySQL-Quellcodepaket herunterladen

mkdir -p /Daten/Pakete/src
cd /Daten/Pakete/
wget http://distfiles.macports.org/cmake/cmake-3.2.3.tar.gz
wget http://dev.mysql.com/get/Downloads/MySQL-5.6/mysql-5.6.34.tar.gz

1.4 MySQL-Datenverzeichnis erstellen

mkdir -p /usr/local/mysql/data

1.5 Entpacken, kompilieren und installieren Sie cmake und MySQL

cd /Daten/Pakete/src
tar -zxvf ../cmake-3.2.3.tar.gz
cd cmake-3.2.3/
./Bootstrap
gmake
installieren
CD ../
tar xf mysql-5.6.34.tar.gz
cd mysql-5.6.34
cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql -DSYSCONFDIR=/etc \
-DWITH_SSL=gebündelt -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci \
-DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_MYISAM_STORAGE_ENGINE=1 \
-DMYSQL_TCP_PORT=3306 -DMYSQL_UNIX_ADDR=/tmp/mysql.sock \
-DMYSQL_DATADIR=/usr/local/mysql/data
machen && machen installieren

1.6 Ein Startskript hinzufügen

cp support-files/mysql.server /etc/rc.d/init.d/mysqld

1.7 Fügen Sie die MasterA-Konfigurationsdatei /etc/my.cnf hinzu

[Kunde]
Port = 3306
Socket = /tmp/mysql.sock

[mysqld]
basedir = /usr/local/mysql
Port = 3306
Socket = /tmp/mysql.sock
Datenverzeichnis = /usr/local/mysql/data
pid-Datei = /usr/local/mysql/data/mysql.pid
log-error = /usr/local/mysql/data/mysql.err

Server-ID = 1
auto_increment_offset = 1
auto_increment_increment = 2 #ungerade Zahl ID

log-bin = mysql-bin #Binärfunktion aktivieren. Der MASTER-Server muss diese Option aktivieren binlog-format=ROW
binlog-row-p_w_picpath=minimal
log-slave-updates=true
gtid-mode=ein
erzwingen-gtid-Konsistenz=true
master-info-repository=TABELLE
relay-log-info-repository=TABELLE
Sync-Master-Info = 1
Slave-Parallelarbeiter = 0
sync_binlog=0
Binlog-Prüfsumme=CRC32
Master-Verify-Prüfsumme = 1
Slave-SQL-Verify-Prüfsumme = 1
binlog-rows-query-log_events=1
#expire_logs_days=5
max_binlog_size=1024M #Maximaler Wert einer einzelnen Binärlog-Datei replicate-ignore-db = mysql #Datenbanken ignorieren, die nicht zwischen Master und Slave synchronisiert sind replicate-ignore-db = information_schema
replicate-ignore-db = Leistungsschema
replizieren-ignorieren-db = Test
Replikation-Ignorier-DB = Zabbix

max_Verbindungen = 3000
max_connect_errors = 30

skip-character-set-client-handshake #Andere Zeichensätze ignorieren, die die Anwendung setzen möchte init-connect='SET NAMES utf8' #SQL wird beim Verbinden ausgeführt
character-set-server=utf8 #Standardzeichensatz auf dem Server wait_timeout=1800 #Maximale Verbindungszeit für eine Anfrage interactive_timeout=1800 #Dies wird nur wirksam, wenn es gleichzeitig mit dem vorherigen Parameter geändert wird sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES #SQL-Modus max_allowed_packet = 10M
Bulk_Insert_Buffer_Größe = 8 M
query_cache_type = 1
Abfrage-Cachegröße = 128 M
query_cache_limit = 4 M
Schlüsselpuffergröße = 256 M
Lesepuffergröße = 16 KB

Namensauflösung überspringen
langsames_Abfrageprotokoll = 1
lange_Abfragezeit = 6
slow_query_log_file=langsam-query.log
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 16 M

[mysql]
kein automatisches Wiederaufwärmen

[myisamchk]
Schlüsselpuffergröße = 20 M
Sortierpuffergröße = 20 M
Lesepuffer = 2M
Schreibpuffer = 2M

[mysqlhotcopy]
Interaktives Timeout

[mysqldump]
schnell
max_allowed_packet = 16M

[mysqld_safe]

1.8 Spezielle Parameterbeschreibung

log-slave-updates = true #Replikationsereignisse in Binärlog schreiben. Ein Server kann sowohl Master als auch Slave sein. Diese Option muss aktiviert sein. #MasterEine selbstinkrementierende ID
auto_increment_offset = 1
auto_increment_increment = 2 #ungerade Zahl ID
#masterB erhöht die ID selbst
auto_increment_offset = 2
auto_increment_increment = 2 #gerade ID

1.9 Fügen Sie die MasterB-Konfigurationsdatei /etc/my.cnf hinzu

[Kunde]
Port = 3306
Socket = /tmp/mysql.sock

[mysqld]
basedir = /usr/local/mysql
Port = 3306
Socket = /tmp/mysql.sock
Datenverzeichnis = /usr/local/mysql/data
pid-Datei = /usr/local/mysql/data/mysql.pid
log-error = /usr/local/mysql/data/mysql.err

Server-ID = 2
auto_increment_offset = 2
auto_increment_increment = 2 #gerade ID

log-bin = mysql-bin #Binärfunktion aktivieren. Der MASTER-Server muss diese Option aktivieren binlog-format=ROW
binlog-row-p_w_picpath=minimal
log-slave-updates=true
gtid-mode=ein
erzwingen-gtid-Konsistenz=true
master-info-repository=TABELLE
relay-log-info-repository=TABELLE
Sync-Master-Info = 1
Slave-Parallelarbeiter = 0
sync_binlog=0
Binlog-Prüfsumme=CRC32
Master-Verify-Prüfsumme = 1
Slave-SQL-Verify-Prüfsumme = 1
binlog-rows-query-log_events=1
#expire_logs_days=5
max_binlog_size=1024M #Maximaler Wert einer einzelnen Binärlog-Datei replicate-ignore-db = mysql #Datenbanken ignorieren, die nicht zwischen Master und Slave synchronisiert sind replicate-ignore-db = information_schema
replicate-ignore-db = Leistungsschema
replizieren-ignorieren-db = Test
Replikation-Ignorier-DB = Zabbix

max_Verbindungen = 3000
max_connect_errors = 30

skip-character-set-client-handshake #Andere Zeichensätze ignorieren, die die Anwendung setzen möchte init-connect='SET NAMES utf8' #SQL wird beim Verbinden ausgeführt
character-set-server=utf8 #Standardzeichensatz auf dem Server wait_timeout=1800 #Maximale Verbindungszeit für eine Anfrage interactive_timeout=1800 #Dies wird nur wirksam, wenn es gleichzeitig mit dem vorherigen Parameter geändert wird sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES #SQL-Modus max_allowed_packet = 10M
Bulk_Insert_Buffer_Größe = 8 M
query_cache_type = 1
Abfrage-Cachegröße = 128 M
query_cache_limit = 4 M
Schlüsselpuffergröße = 256 M
Lesepuffergröße = 16 KB

Namensauflösung überspringen
langsames_Abfrageprotokoll = 1
lange_Abfragezeit = 6
slow_query_log_file=langsam-query.log
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 16 M

[mysql]
kein automatisches Wiederaufwärmen

[myisamchk]
Schlüsselpuffergröße = 20 M
Sortierpuffergröße = 20 M
Lesepuffer = 2M
Schreibpuffer = 2M

[mysqlhotcopy]
Interaktives Timeout

[mysqldump]
schnell
max_allowed_packet = 16M

[mysqld_safe]

1.10 MySQL initialisieren

cd /usr/local/mysql
Skripte/mysql_install_db --user=mysql

1.11 Erteilen Sie dem Startskript Ausführungsberechtigungen und starten Sie MySQL

chmod +x /etc/rc.d/init.d/mysqld
/etc/init.d/mysqld starten

2. Konfigurieren Sie die Master-Slave-Synchronisierung

2.1 Hinzufügen eines Master-Slave-Synchronisierungskontos
Auf MasterA:

mysql> gewähre Replikations-Slave auf *.* an 'repl'@'192.168.10.12', identifiziert durch '123456';
mysql> Berechtigungen leeren;

Auf MasterB:

mysql> gewähre Replikations-Slave auf *.* an 'repl'@'192.168.10.11', identifiziert durch '123456';
mysql> Berechtigungen leeren;

2.2 Überprüfen Sie den Status der Hauptdatenbank
Auf MasterA:

mysql> Masterstatus anzeigen;

+------------------+----------+--------------+------------------+-------------------+

| Datei | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+----------+--------------+------------------+-------------------+

| mysql-bin.000003 | 120 | | | |

+------------------+----------+--------------+------------------+-------------------+

1 Zeile im Satz (0,00 Sek.)

Auf MasterB

mysql> Masterstatus anzeigen;

+------------------+----------+--------------+------------------+-------------------+

| Datei | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |

+------------------+----------+--------------+------------------+-------------------+

| mysql-bin.000003 | 437 | | | |

+------------------+----------+--------------+------------------+-------------------+

1 Zeile im Satz (0,00 Sek.)

2.3 Informationen zur Konfigurationssynchronisierung:

Auf MasterA:

mysql> ändere Master in master_host='192.168.10.12',master_port=3306,master_user='repl',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=437;

mysql> Slave starten;

mysql> Slave-Status anzeigen\G;

Wenn folgender Status angezeigt wird, ist das normal:

Slave_IO_Running: Ja

Slave_SQL_Running: Ja

Auf MasterB:

#Ich befinde mich in einer Testumgebung und kann garantieren, dass keine Daten geschrieben werden. Ansonsten sind folgende Schritte erforderlich: zuerst sperrt MasterA die Tabelle --> MasterA sichert Daten --> MasterA entsperrt die Tabelle --> MasterB importiert Daten --> MasterB richtet Master-Slave ein --> Master-Slave-MySQL anzeigen> Master ändern in master_host='192.168.10.11',master_port=3306,master_user='repl',master_password='123456',master_log_file='mysql-bin.000003',master_log_pos=120;

Slave starten;

mysql> Slave-Status anzeigen\G;

Wenn folgender Status angezeigt wird, ist das normal:

Slave_IO_Running: Ja

Slave_SQL_Running: Ja

3. Testen Sie die Master-Slave-Synchronisation

3.1 Erstellen Sie eine Datenbank auf MasterA, um den Synchronisierungseffekt zu testen

mysql> Datenbanken anzeigen;

+--------------------+

| Datenbank |

+--------------------+

| Informationsschema |

|mysql |

| Leistungsschema |

| Prüfung |

+--------------------+

4 Zeilen im Satz (0,00 Sek.)

mysql> Datenbank test01 erstellen;

Abfrage OK, 1 Zeile betroffen (0,00 Sek.)

mysql> Datenbanken anzeigen;

+--------------------+

| Datenbank |

+--------------------+

| Informationsschema |

|mysql |

| Leistungsschema |

| Prüfung |

|test01|

+--------------------+

5 Zeilen im Satz (0,00 Sek.)

mysql> beenden

Tschüss

[root@masterA-Daten]

3.2 Gehen Sie zu MasterB, um zu überprüfen, ob die Datenbank synchron erstellt wurde

mysql> Datenbanken anzeigen;

+--------------------+

| Datenbank |

+--------------------+

| Informationsschema |

|mysql |

| Leistungsschema |

| Prüfung |

|test01|

+--------------------+

5 Zeilen im Satz (0,00 Sek.)

mysql> beenden

Tschüss

[root@masterB-Daten]#

4. Aktivieren Sie die GTID-Funktion von MySQL 5.6

MasterA und MasterB führen jeweils die folgenden Befehle aus:

mysql> Slave stoppen;

Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)

mysql> ändere Master in MASTER_AUTO_POSITION=1;

Abfrage OK, 0 Zeilen betroffen (0,01 Sek.)

mysql> Slave starten;

Abfrage OK, 0 Zeilen betroffen (0,00 Sek.)

5. Aufgetretene Probleme

Ein von mir seit langem gemeldeter Master-Slave-Fehler:

Last_IO_Errno: 1236

Last_IO_Error: Beim Lesen der Daten aus dem Binärprotokoll ist vom Master der schwerwiegende Fehler 1236 aufgetreten: „Protokolldatei konnte nicht geöffnet werden“

Später wurden die mit der Master-Slave-Synchronisierung verbundenen Parameter geändert, um zu bestätigen, dass der Grund darin lag, dass my.cnf die folgenden Parameter hinzugefügt hatte:

log-bin = mysql-bin

Relay-Log = MySQL-Bin

Die Binärprotokolldateien während der normalen Master-Master-Synchronisierung zeigen, dass zwei Sätze Binärprotokolle vorhanden sind. Daraus lässt sich schlussfolgern, dass die beiden oben genannten Parameter dazu führen, dass keine zwei Sätze Binärdateien generiert werden können, was zu Verwirrung und Verlust der Binärdateien führt.

Dies ist das Ende dieses Artikels über die Konfigurationslösung für die MySQL Dual-Master-Architektur (Master-Master). Weitere relevante MySQL Dual-Master-Inhalte finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den verwandten Artikeln weiter unten. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Tiefgreifendes Verständnis der logischen Architektur von MySQL
  • Einführung in die MySQL-Gesamtarchitektur
  • MySQL 20-Designprinzipien für Hochleistungsarchitekturen (es lohnt sich, sie zu sammeln)
  • Gängige Master-Slave-Replikationsarchitekturen in MySQL 4
  • MySQL-Lernzusammenfassung: Ein vorläufiges Verständnis des Architekturdesigns der InnoDB-Speicher-Engine
  • Zusammenfassung der Wissenspunkte zur MySQL-Architektur
  • Detaillierte Erläuterung der logischen Architektur von MySQL
  • Details zur MySQL-Datenbankarchitektur

<<:  Detailliertes Tutorial zur Installation des ElasticSearch:7.8.0-Clusters mit Docker

>>:  Detailliertes Beispiel für die Verwendung von Typescript zum Einkapseln von Axios in Vue3

Artikel empfehlen

Zusammenfassung der Befehle zur Benutzerverwaltung im Linux-System

Benutzer- und Gruppenverwaltung 1. Grundlegende K...

Codebeispiele für den Import und Export von Docker-Images

Import und Export von Docker-Images Dieser Artike...

Docker-Speicherüberwachung und Stresstestmethoden

Der ausgeführte Docker-Container zeigt, dass der ...

Detaillierte Analyse des langsamen Abfrageproblems beim Senden von MySQL-Daten

Anhand eines Beispiels habe ich Ihnen die Lösung ...

Grafisches Tutorial zur Installation und Konfiguration von MySQL 8.0.11 (Win10)

In diesem Artikel werden die Installations- und K...

Was ist ein MySQL-Tablespace?

Das Thema, das ich heute mit Ihnen teilen möchte,...