Bei der MM Replikation ist jeweils ein Knoten der Slave für den Partner. Wie läuft eine Replikation in der Praxis ab:

1. Schreiboperation auf dem Master

2. Mysql Master schreibt die Operationen in die eigene Bin-Log (/var/log/mysql/mysql-bin.0000zahl)

3. Mysql Master verarbeitet Einträge in der eigenen Bin-Log in die Datenbank.

3. Mysql Slave wird über Änderungen informiert und kopiert Änderungen aus der Master-Log des Masters (mysql-bin.0000zahl) in die eigene Slave Relay Log (/var/log/mysql/slave-relay.0000zahl)

4. Der Mysql Slave überträgt die Änderungen an der Slave Relay Log in die eigene Bin-Log /var/log/mysql/mysql-bin.0000zahl).

5. Der Mysql Slave verarbeitet Einträge in der eigenen Bin-Log in die Datenbank.
Da wir Mysql ausschließlich im Pacemaker-Cluster betreiben, stellen wir über die wechselnde virtuelle IP sicher, dass es immer nur einen Knoten gibt, auf dem geschrieben wird. Es kann jedoch durchaus zu gleichzeitigen Schreibvorgängen kommen.

Häufig wird in MySQL auto_increment verwendet. Das ist eine Funktion die dafür sorgt, beim Anlegen von neuen Einträgen in der Tabelle die eindeutige Kennung einer Zeile (z.B. über das Feld ID) fortlaufend hochzuzählen.

Hier ein Beispiel mit MySQL

> select * from changes where id>=300;
+—–+————————+————————+————-+——-+————+
| id | sourcekey | parentsourcekey | change_type | flags | sourcesync |
+—–+————————+————————+————-+——-+————+
| 300 | �UJ��3Uv@s� | �UJ��3Uv@s
| 4097 | 0 | 0 |
| 302 | �UJ��3Uv@s7 | �UJ��3Uv@s
| 4101 | 0 | 0 |
| 304 | �UJ��3Uv@s� | �UJ��3Uv@s
| 4097 | 0 | 0 |
| 305 | �UJ��3Uv@s� | �UJ��3Uv@s
| 4100 | 0 | 0 |
+—–+————————+————————+————-+——-+————+
4 rows in set (0,00 sec)

mysql> show columns from changes;
+—————–+——————+——+—–+———+—————-+
| Field | Type | Null | Key | Default | Extra |
+—————–+——————+——+—–+———+—————-+
| id | int(11) unsigned | NO | UNI | NULL | auto_increment |
| sourcekey | varbinary(64) | NO | PRI | NULL | |
| parentsourcekey | varbinary(64) | NO | PRI | NULL | |
| change_type | int(11) unsigned | NO | PRI | 0 | |
| flags | int(11) unsigned | YES | | NULL | |
| sourcesync | int(11) unsigned | YES | | NULL | |
+—————–+——————+——+—–+———+—————-+
6 rows in set (0,00 sec)

Wir sehen also, dass das Feld id, auto_increment verwendet. Uns fällt jedoch auf, dass die IDs nicht fortlaufend sind – wieso eigentlich?

Würden zur selben Zeit in unserem Cluster Einträge in der Tabelle changes erstellt werden, würde jeder Knoten die ID um Eins erhöhen und wir hätten eine Schlüsselkollision. Damit dies nicht passiert, kann mit der Option auto_increment_offset pro Knoten unabhängig bestimmt werden, in welchen Schritten hochgezählt wird. Unser Knoten 1 vewendet hier 1, der Knoten 2 verwendet 2.

Das führt zu den oben ersichtlichen Sprüngen. die Einträge mit ID 300, 302, 304 hat Knoten 2 erstellt. Eintrag 305 kam von Knoten 1.

Auto_increment ist eine Funktion, die es der Anwendung spart, einen Select zu machen, was die letzte verwendete ID ist. Da es „zwischendrin“ auch vorkommen kann, dass Einträge gelöscht werden, stellt auto_increment mit Sprüngen in der Regel kein Problem für die darüberliegende Anwendung dar.

Wichtig ist in der mysql-Konfiguration, dass sync_binlog= 1 aktiv ist. Dies sorgt dafür, dass Änderungen sofort geschrieben werden.

Exemplarisch eine komplette Konfiguration in einem master:master Szenario:

[mysqld_safe]
socket = /var/run/mysqld/mysqld.sock
nice = 0

[mysqld]
user = mysql
pid-file = /var/run/mysqld/mysqld.pid
socket = /var/run/mysqld/mysqld.sock
port = 3306
basedir = /usr
datadir = /var/lib/mysql
tmpdir = /tmp
lc-messages-dir = /usr/share/mysql
skip-external-locking
server-id = 1 # muss unterschiedlich sein pro Maschine
replicate-same-server-id = 0
auto-increment-increment = 2
auto-increment-offset = 1 # muss unterschiedlich sein pro Maschine
log-bin = /var/lib/mysql/mysql-bin.log
relay-log = /var/lib/mysql/slave-relay.log
relay-log-index = /var/lib/mysql/slave-relay-log.index
expire_logs_days = 10
max_binlog_size = 500M
log-slave-updates
sync_binlog= 1
key_buffer_size = 16M
max_allowed_packet = 16M
thread_stack = 192K
thread_cache_size = 8
myisam-recover-options = BACKUP
query_cache_limit = 1M
query_cache_size = 16M
log_error = /var/log/mysql/error.log

Categories: Blog