MySQL, MariaDB und Percona Multi-Master Galera Cluster
Was ist Galera?
Das Galera Plugin für MySQL (InnoDB und MyISAM) ist eine synchrone Master-Master clustering Methode.
Galera schafft es mehrere Transaktionen in ein und die selbe Tabelle durchzuführen, benötigt werden mindestens 2 Instanzen; Quorum-Schutz liefert zusätzlich ein Schiedsrichter Dienst „garbd“.
Vor- und Nachteile
MySQL Galera:
- – kein Repository
- + SST Methoden: xtrabackup, mysqldump, rsync
MariaDB Galera:
- + Repository vorhanden
- + kompatibel zu MySQL
- – SST Methoden: mysqldump, rsync (kein xtrabackup)
Percona Galera:
- + Repository vorhanden
- + kompatibel zu MySQL
- + SST Methoden: xtrabackup, mysqldump, rsync
SST Vergleichstabelle
method | speed | blocks the donor | can be done on live node? | logical/physical | requires root access to MySQL server? |
---|---|---|---|---|---|
mysqldump | slow | yes | yes | logical | both donor and joiner |
rsync | fastest | yes | no | physical | none |
xtrabackup | fast | for a very short time | no | physical | donor only |
Mehr unter: http://www.codership.com/wiki/doku.php?id=sst_mysql
Vorteile Galera vs. MySQL Replikation
- synchrone Replikation
- aktiv-aktiv Multi-Master Topologie
- lesen und schreiben in jede Cluster Node
- automatische Node-Verwaltung, fehlerhafte werden ausgestoßen
- Nodes synchen sich automatisch neu in das Cluster, kein mysqldump nötig
- echte parallele Replikation, Row Level
- kein Keepalive/Heartbeat nötig, eine Fehlerquelle weniger
- ein Schiedsrichter Dienst (garbd) kann als Relay-Node (ohne Datenbestand) auf einem weiteren Server laufen
Teststellung
Getestet wurde das Galera Plugin auf 3 völlig unterschiedlichen Servern ohne „garbd“.
Hardware: System A 192.168.1.10 (8x 2,00GHz), System B 192.168.1.20 (2x 1,86GHz), System C 192.168.1.30 (2x 2,80GHz)
Netz: public
OS: CentOS 6.4
Galera Version: 23.2.4(r147)
MySQL Version: 5.5.29
Config: /etc/my.cnf
Installation CentOS 6.4
MySQL 5.5
Pakete herunterladen:
1 2 3 | wget https://launchpad.net/galera/2.x/23.2.4/+download/galera-23.2.4-1.rhel6.x86_64.rpm wget https://launchpad.net/codership-mysql/5.5/5.5.29-23.7.3/+download/MySQL-server-5.5.29_wsrep_23.7.3-1.rhel6.x86_64.rpm wget http://mirrors.develooper.com/mysql/Downloads/MySQL-5.5/MySQL-client-5.5.29-2.el6.x86_64.rpm |
Galera gepatchte MySQL Version + Galera Plugin installieren:
1 | yum install galera-23.2.4-1.rhel6.x86_64.rpm MySQL-server-5.5.29_wsrep_23.7.3-1.rhel6.x86_64.rpm MySQL-client-5.5.29-2.el6.x86_64.rpm |
Kennwort für den xtrabackup/mysqldump SST User setzen:
1 2 3 | SET wsrep_on = OFF; grant all on *.* to 'root'@'localhost' identified by 'password'; SET wsrep_on = OFF; grant all on *.* to 'root'@'%' identified by 'password'; flush privileges; |
MariaDB 5.5
Repository hinzufügen:
1 2 3 4 5 6 7 8 9 | cat > /etc/yum.repos.d/MariaDB.repo << EOF # MariaDB 5.5 CentOS repository list - created 2013-03-11 17:09 UTC # http://mariadb.org/mariadb/repositories/ [mariadb] name = MariaDB baseurl = http://yum.mariadb.org/5.5/centos6-amd64 gpgkey=https://yum.mariadb.org/RPM-GPG-KEY-MariaDB gpgcheck=1 EOF |
Pakete installieren:
1 | yum install MariaDB-Galera-server MariaDB-client |
Kennwort für den mysqldump SST User setzen:
1 2 3 | SET wsrep_on = OFF; grant all on *.* to 'root'@'localhost' identified by 'AXqGyZxKv'; SET wsrep_on = OFF; grant all on *.* to 'root'@'%' identified by 'AXqGyZxKv'; flush privileges; |
Percona 5.5
Repository hinzufügen:
1 | rpm -Uhv http://www.percona.com/redir/downloads/percona-release/percona-release-0.0-1.x86_64.rpm |
Pakete installieren:
1 | yum install Percona-XtraDB-Cluster-client.x86_64 Percona-XtraDB-Cluster-server.x86_64 percona-xtrabackup perl-Time-HiRes.x86_64 |
Kennwort für den xtrabackup SST User setzen:
1 2 3 | SET wsrep_on = OFF; grant all on *.* to 'root'@'localhost' identified by 'AXqGyZxKv'; SET wsrep_on = OFF; grant all on *.* to 'root'@'%' identified by 'AXqGyZxKv'; flush privileges; |
Konfiguration von Galera
Dies ist eine minimale Galera Konfiguration, die Werte solltet Ihr in die my.cnf übernehmen.
Eine ausführliche Version findet Ihr im Anhang galera_example.cnf.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | [mysqld] bind-address=0.0.0.0 # (This must be substituted by wsrep_format) binlog_format=ROW # Full path to wsrep provider library or 'none' wsrep_provider=/usr/lib64/libgalera_smm.so # Logical cluster name. Should be the same for all nodes. wsrep_cluster_name="[CLUSTER_NAME]" # Group communication system handle wsrep_cluster_address="gcomm://[NODE1_IP],[NODE2_IP],[NODE3_IP]" # If no other Node is available you must start one Node as Donor. #wsrep_cluster_address="gcomm://" # Address for incoming client connections. Autodetect by default. wsrep_node_incoming_address=[IP_DIESER_NODE] # State Snapshot Transfer method wsrep_sst_method=xtrabackup # SST authentication string. This will be used to send SST to joining nodes. # Depends on SST method. For mysqldump method it is root:<root password> wsrep_sst_auth=root:AXqGyZxKv # how many times to retry deadlocked autocommits wsrep_retry_autocommit=1 # MyISAM replication ON/OFF wsrep_replicate_myisam=1 # to avoid issues with 'bulk mode inserts' using autoinc innodb_autoinc_lock_mode=2 # How many threads will process writesets from other nodes wsrep_slave_threads=4 |
Garbd Schiedsrichter Dienst
Sollte aus Gründen der Einsparung nur ein 2 Node Cluster geplant sein, muss bedingt durch den Split-Brain Schutz ein kleiner Dienst namens „garbd“ auf einem Server mit laufen.
Dieser Dienst hält keine Daten vor sondern dient lediglich als Relay und Quorum Mitglied. Gestartet wird er wie folgt.
1 | garbd -d -a gcomm://192.168.1.10,192.168.1.20,192.168.1.30 -g TESTCLUSTER |
Cluster Status Abfrage / Node Überprüfung
Ihr könnt den Cluster-Status wie folgt abfragen.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | mysql> SHOW STATUS LIKE 'wsrep%'; +----------------------------+--------------------------------------+ | Variable_name | Value | +----------------------------+--------------------------------------+ | wsrep_local_state_uuid | b8ed263b-778c-11e2-0800-a5f2a584bcea | | wsrep_protocol_version | 4 | | wsrep_last_committed | 123116 | | wsrep_replicated | 0 | | wsrep_replicated_bytes | 0 | | wsrep_received | 21 | | wsrep_received_bytes | 3240 | | wsrep_local_commits | 0 | | wsrep_local_cert_failures | 0 | | wsrep_local_bf_aborts | 0 | | wsrep_local_replays | 0 | | wsrep_local_send_queue | 0 | | wsrep_local_send_queue_avg | 0.000000 | | wsrep_local_recv_queue | 0 | | wsrep_local_recv_queue_avg | 0.000000 | | wsrep_flow_control_paused | 0.000000 | | wsrep_flow_control_sent | 0 | | wsrep_flow_control_recv | 0 | | wsrep_cert_deps_distance | 0.000000 | | wsrep_apply_oooe | 0.000000 | | wsrep_apply_oool | 0.000000 | | wsrep_apply_window | 0.000000 | | wsrep_commit_oooe | 0.000000 | | wsrep_commit_oool | 0.000000 | | wsrep_commit_window | 0.000000 | | wsrep_local_state | 4 | | wsrep_local_state_comment | Synced | | wsrep_cert_index_size | 0 | | wsrep_causal_reads | 0 | | wsrep_incoming_addresses | 192.168.1.10,192.168.1.20,192.168.1.30 | | wsrep_cluster_conf_id | 11 | | wsrep_cluster_size | 3 | | wsrep_cluster_state_uuid | b8ed263b-778c-11e2-0800-a5f2a584bcea | | wsrep_cluster_status | Primary | | wsrep_connected | ON | | wsrep_local_index | 0 | | wsrep_provider_name | Galera | | wsrep_provider_vendor | Codership Oy <info@codership.com> | | wsrep_provider_version | 23.2.2(r137) | | wsrep_ready | ON | +----------------------------+--------------------------------------+ 40 rows in set (0.00 sec) |
Ob eine Node im Cluster ist seht Ihr an dem Status:
1 | | wsrep_local_state_comment | Synced | |
Wie weit, also welche Node die aktuellsten Daten hat, seht Ihr an der Höhe dieser Zahl:
1 | | wsrep_last_committed | 123116 | |
Anzahl der im Cluster befindlichen Nodes:
1 2 3 | | wsrep_incoming_addresses | 192.168.1.10,192.168.1.20,192.168.1.30 | ... | wsrep_cluster_size | 3 | |
Die aufgerufene Node ist definitiv im Cluster wenn dieser Wert auf „ON“ steht:
1 | | wsrep_ready | ON | |
Problemlösungen
Informationen: http://www.codership.com/wiki/doku.php?id=faq
- Sollte eine Node sich nicht mehr in das Cluster einfügen lassen kann es an der „grastate.dat“ Datei im MySQL Home Ordner liegen, diese müsste dann gelöscht und MySQLd neu gestartet werden.
- Sollte aus einem eher unwahrscheinlichen Grund keine MySQL Node mehr aktiv sein, muss eine Node mit „wsrep_cluster_address=gcomm://“ gestartet werden. Wenn das Cluster wieder „Synced“ ist kann dieser Wert wieder auf den Ursprung zurückgestellt werden, also z.B. „wsrep_cluster_address=gcomm://192.168.1.10,192.168.1.20,192.168.1.30“
Beispiel Szenario
Eine Node im Galera Cluster zeigt den Status „Initialized“ was unter anderem vor einem Split-Brain schützen soll.
1 | | wsrep_local_state_comment | Initialized | |
Dieser Fehler tritt z.B. auf wenn keine LAN Verbindung zum Cluster besteht. Es können nur noch bedingt Statements abgesetzt werden:
1 2 3 4 5 6 7 8 9 10 11 12 13 | mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | +--------------------+ 4 rows in set (0.00 sec) mysql> use mysql; ERROR 1047 (08S01): Unknown command |
Es ist möglich diesen Split-Brain Schutz zu deaktivieren, dies sollte aber vermieden werden, es ist somit wichtig 3 Nodes oder 2 Nodes + garbd einzusetzen.wsrep_provider_options = “pc.ignore_sb = true” schaltet den Split-Brain Schutz aus, nur sinnvoll in einem Master-Slave Galera Setup wsrep_provider_options = „pc.ignore_quorum = true“ schaltet die Quorum Berechnung ab, sollte ein Master alleine existieren gewährt dieser dennoch volle Funktionalität. Weitere Nodes können dem Cluster aber nicht mehr automatisch beitreten. |
Benchmarks
Zuerst erstellen wir 1.000.000 Einträge auf einer Node in die Datenbank „test“, das sollte recht zügig geschehen und auch instand auf die restlichen Nodes übertragen werden:
1 | sysbench --test=oltp --oltp-table-size=1000000 --mysql-db=test --mysql-user=root --mysql-password=AXqGyZxKv prepare |
Jetzt kann auf allen Nodes ein kleiner 60 Sekunden Lesetest gestartet werden, wobei die Anzahl der Threads den CPU Kernen entsprechen sollte (mehr bringt meist nichts):
1 | sysbench --test=oltp --oltp-table-size=1000000 --mysql-db=test --mysql-user=root --mysql-password=AXqGyZxKv --max-time=60 --oltp-read-only=on --max-requests=0 --num-threads=8 run |
Beim Ergebnis sind vor allem die Transaktionen in der Sekunden interessant:
1 2 3 4 5 6 7 8 | System A(8x 2,00GHz): transactions: 307606 (5126.65 per sec.) System B (2x 1,86GHz): transactions: 82552 (1375.81 per sec.) System C (2x 2,80GHz): transactions: 100969 (1682.75 per sec.) |
Es können auch alle Nodes auf einmal im Round-Robin Verfahren getestet werden:
1 | sysbench --test=oltp --mysql-host=192.168.1.10,192.168.1.20,192.168.1.30 --mysql-user=root --mysql-password=AXqGyZxKv --mysql-db=test --mysql-table-engine=InnoDB --mysql-engine-trx=yes --oltp-table-size=2000000 --max-time=60 --max-requests=0 --num-threads=16 --oltp-auto-inc=off run |
Links:
Download: http://www.codership.com/downloads/download-mysqlgalera
Dokumentation: http://www.codership.com/wiki/doku.php
SST Methoden: http://www.codership.com/wiki/doku.php?id=sst_mysql
MariaDB Repositories: https://downloads.mariadb.org/mariadb/repositories/
MariaDB vs. MySQL – Compatibility: https://kb.askmonty.org/en/mariadb-versus-mysql-compatibility/
WSREP Variablen: http://www.percona.com/doc/percona-xtradb-cluster/wsrep-system-index.html
-Dominion
0