Seite wählen

NETWAYS Blog

Alle User in MySQL anzeigen

Oftmals wachsen Datenbankinstallationen im Laufe der Zeit und man legt immer wieder für neue Projekte neue Datenbanknutzer an. Um hier den Überblick zu behalten, zeige ich kurz, wie man sich die jeweiligen Nutzer anzeigen lassen kann.

Voraussetzungen:

  • Command line/Terminal
  • MySQL oder MariaDB installiert
  • Benutzer in MySQL:Benutzer mit Sudo- oder Root-Rechten

Bei der Installation von MySQL wird bei der Installation als erster Benutzer der Root-Benutzer erstellt – der MYSQL-Administrator. Der Root-Benutzer ist berechtigt, alles in der MySQL-Datenbank zu tun – Eine einfache und zuverlässige Möglichkeit, die MySQL-Sicherheit zu erhöhen, besteht darin, Benutzer mit eingeschränkten Berechtigungsbeschränkungen für die Datenbank zu erstellen.

Wenn Sie Zugriff auf Ihren Server haben, müssen Sie die MySQL-Konsole aufrufen. Dafür benötigen wir Root-Rechte. Geben Sie dies in die Befehlszeile ein:

sudo mysql -u root -p

root@galeria-1:~# mysql -u root -p
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 78
Server version: 10.4.13-MariaDB-1:10.4.13+maria~bionic-log mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]>

Dann müssen Sie Ihr MySQL-Root-Passwort eingeben. Es sollte sich vom System-Root-Passwort unterscheiden. Sobald Sie in der MySQL-Konsole root sind, können Sie Abfragen und Befehle ausführen. MySQL-Benutzer anzeigen: Jetzt können Sie alle Benutzer in MySQL mit dem folgenden MySQL-Befehl auflisten:

MariaDB [(none)]> SELECT user FROM mysql.user;
+-------------+
| User |
+-------------+
| mariadb.sys |
| mysql |
| root |
| testuser | 
+-------------+
4 rows in set (0.004 sec)
MariaDB [(none)]>

Hot Backups mittels Xtrabackup

Wie Markus in seinem letzten Blogpost schon beschrieben hat, hatte er die zweifelhafte Ehre ein Backup einer verhältnismäßig großen MySQL-Datenbank (MariaDB) zu machen. Das große Problem bei ihm war allerdings, dass das Kopieren auf Dateiebene eine Downtime der Datenbank voraussetzte und somit der laufende Betrieb eingestellt werden musste. Man legt sozusagen die Datenbank auf Eis und deshalb nennt man dieses Verfahren auch Cold Backup (Offline Backup). Dies war zumindest meine Schlussfolgerung zur Namensgebung…

Als wissensdurstiger Azubi bei NETWAYS wollte ich wissen ob es vielleicht eine Möglichkeit gibt, ein Backup einer MySQL-Datenbank während  des laufenden Betriebes zu machen. Bei meinen Recherchen bin ich letztlich auf ein heiß diskutiertes Thema gestoßen. Wie der Name schon sagt, auf das „heiße“, sogenannte Hot Backup (Online Backup). Bei diesem Backupverfahren ist es möglich während des laufenden Betriebes einer MySQL-Datenbank ein Backup zu erstellen und somit eine Downtime der Datenbank zu vermeiden. Das Online Backup kann somit mehrmals am Tag durchgeführt werden, des Weiteren ist es deutlich schneller als das Offline Backup. Allerdings birgt ein Hot Backup auch ein gewisses Risiko, da im Gegensatz zum Cold Backup, weiter Daten in die Datenbank geschrieben werden und diese somit nicht im Backup enthalten wären. Das wäre aber im Ernstfall (Ausfall der Datenbank) zu verschmerzen, da somit beispielsweise womöglich nur Daten der letzten paar Stunden und nicht von einem ganzen Arbeitstag verloren wären.

Im Folgenden zeige ich anhand eines kleinen Beispiels, wie so ein Hot Backup vonstatten geht. Das Tool meiner Wahl ist Xtrabackup von Percona. Xtrabackup kann ein Hot Backup erstellen indem es sich die sog. crash-recovery Funktion von InnoDB-Datenbanken zu Nutze macht. Die Installation von Xtrabackup ist in der Dokumentation hervorragend beschrieben.

Zunächst benötigt man einen Datenbankuser mit folgenden Rechten:
mysql> CREATE USER 'backupuser'@'localhost' IDENTIFIED BY 'SuperGeheim!';
mysql> GRANT BACKUP_ADMIN, PROCESS, RELOAD, LOCK TABLES, REPLICATION CLIENT ON *.* TO 'backupuser'@'localhost';
mysql> GRANT SELECT ON performance_schema.log_status TO 'backupuser'@'localhost';

Der nächste Schritt ist ein Backup anzustoßen:
$ xtrabackup --backup --user=backupuser --password=SuperGeheim! --target-dir=/var/test_backup
„–target-dir“: In diesem frei zu wählenden Ordner werden die Backups gespeichert.

Man kann bei der Ausgabe sehr gut erkennen, dass Xtrabackup sich die sog. LSN (Log Sequence Number) „merkt“ und ab diesem Zeitpunkt die Tabellen der Datenbank sperrt sowie alle weiteren Schreiboperationen „puffert“. Nach dem Kopieren der Daten werden die Tabellen wieder frei gegeben und der Betrieb ab der „gemerkten“ LSN wieder aufgenommen:
190829 10:27:43 >> log scanned up to (146090017)
xtrabackup: Generating a list of tablespaces
190829 10:27:43 [01] Copying ./ibdata1 to /var/test_backup/ibdata1
190829 10:27:44 [01] ...done
190829 10:27:44 >> log scanned up to (146090017)
190829 10:27:44 Executing FLUSH NO_WRITE_TO_BINLOG TABLES...
190829 10:27:44 Executing FLUSH TABLES WITH READ LOCK...
190829 10:27:44 Starting to backup non-InnoDB tables and files
[...]
[...]
190829 10:27:46 Finished backing up non-InnoDB tables and files
190829 10:27:46 Executing FLUSH NO_WRITE_TO_BINLOG ENGINE LOGS...
xtrabackup: The latest check point (for incremental): '146090233'
xtrabackup: Stopping log copying thread.
.190829 10:27:46 >> log scanned up to (146090233)
190829 10:27:46 Executing UNLOCK TABLES
190829 10:27:46 All tables unlocked
190829 10:27:46 Backup created in directory '/var/test_backup'
190829 10:27:46 [00] Writing /var/test_backup/backup-my.cnf
190829 10:27:46 [00] ...done
190829 10:27:46 [00] Writing /var/test_backup/xtrabackup_info
190829 10:27:46 [00] ...done
xtrabackup: Transaction log of lsn (146086198) to (146090233) was copied.
190829 10:27:46 completed OK

Wenn das Backup erfolgreich war und man dieses wieder einspielen will, muss man dieses zuvor „vorbereiten“. Da die kopierten Daten womöglich nicht mit den aktuellen Daten übereinstimmen:
$ xtrabackup --prepare --target-dir=/var/test_backup

Hat man ein InnoDB: Shutdown completed; log sequence number 146093758
190829 10:45:05 completed OK!
erhalten, lässt sich das Backup wiederherstellen

ACHTUNG: Es müssen beim Wiederherstellen alle Daten aus /var/lib/mysql/ gelöscht werden. Hierbei sollte man sehr aufpassen, ansonsten kann es zum kompletten Datenverlust führen!!!

Um das „vorbereitete“ Backup einzuspielen, muss der MySQL (MariaDB) Dienst gestoppt sein (was bei einem Ausfall sowieso der Fall sein dürfte). Der nächste Schritt wäre den Benutzer der Daten anzupassen und den Dienst erneut zu starten:
$ systemctl stop mariadb.service
$ rm -rf /var/lib/mysql/*
$ xtrabackup --move-back --target-dir=/var/test_backup
$ chown -R mysql:mysql /var/lib/mysql/
$ systemctl start mariadb.service

Als Fazit kann man sagen, dass sich Hot Backups sehr lohnen, aber auch ein gewisses Risiko beherbergen können. Cold Backups sind dazu im Gegensatz sehr „starr“ und können nur während einer Downtime durchgeführt werden. Sie bieten jedoch die höhere Chance auf Datenkonsistenz und sind deutlich einfacher zu handhaben. Empfehlenswert ist es auf jeden Fall sich eine geeignete Datensicherungsstrategie aus beiden Varianten zu überlegen, bei der man zum Beispiel am Ende des Tages ein Cold Backup und während der Geschäftszeiten mehrere Hot Backups macht.

rsync und was dann?

Diese Woche hatte ich die zweifelhafte Ehre die mit 1,6TB schon etwas größere MySQL-Datenbank (MariaDB) eines Kunden auf den zweiten Datenbankknoten zu spielen. Dabei war die Herausforderung das die ganze Show außerhalb der Geschäftszeiten von 17:30 Uhr bis max. 5:00 Uhr stattfindet. Ein Dump der Datenbank dauert erfahrungsgemäß zu lange um das Wartungsfenster einzuhalten. Kein Problem dachte ich mir, dann halt rsync auf Dateiebene. Also die Datenbankzugriffe pünktlich zu Beginn des Wartungsfensters unterbunden, die Datenbank gestoppt und den rsync vom Zielsystem aus wie folgt gestartet:

# rsync -avPz --exclude 'ib_logfile*' root@a.b.c.d:/var/lib/mysql/ /var/lib/mysql/

Eine kurze Erklärung der gesetzten Parameter:

  • a – kopiert rekursiv unter Beibehaltung der Dateiberechtigungen
  • v – sorgt für eine ausführlichere Ausgabe (verbose)
  • P – zeigt eine Fortschrittsanzeige (progress) und setzt den Transfer bei einem evtl. Abbruch fort (partial)
  • z – aktiviert die Komprimierung, meistens bei einer Übertragung via Netzwerk sinnvoll

Die beiden InnoDB Logfiles (ib_logfile0 und ib_logfile1) mit jeweils 11GB wurden für eine schnellere Übertragung ausgeschlossen, da sie beim Anstarten eh wieder neu erstellt werden.

Leider hat sich relativ schnell herausgestellt dass das nicht der Weisheit letzter Schluss war, da die Übertragung mit ca. 15MB/s an die 32 Stunden gedauert und damit das Wartungsfenster überschritten hätte. Auch eine Anpassung der Parameter und der Synchronisationsvorgang auf ein schnelleres Storage mit max. 40MB/s und damit fast 15 Stunden wären zu lange gewesen.

Nach einer kurzen Internetrecherche bin ich auf eine mögliche Lösung mit mbuffer gestossen. Der „measuring buffer“ steht bereits als kleines Paket für die gängigen Linux-Distributionen zur Verfügung und sorgt dafür das es durch einen Puffer nie zu einem Leerlauf des Datenstroms kommt und die Verbindung somit nicht abreißen kann. Mit Komprimierungsfunktionalität und etwas „Bash-Magic“ außenrum kann das dann so aussehen:

# tar cf - * | mbuffer -m 1024M | ssh a.b.c.d '(cd /var/lib/mysql; tar xf -)'

Dem zuzusehen war schon fast eine Freude, hätte nur noch eine Tüte Chips und vielleicht ein passendes Kaltgetränk gefehlt. Mit Transferraten von bis zu 350MB/s hat der Kopiervorgang so gerade mal über 2 Stunden gedauert (Durchschnitt 216MB/s) und die Umgebung bis zum Ende des Wartungsfensters längst wieder im Normalzustand. Das in vielen Fällen schon hilfreiche rsync kommt v.a. bei sehr vielen oder sehr großen Dateien durch die Checksummenberechnung an seine Grenzen, sodass mbuffer hier durchaus mehr als nur eine Alternative sein kann.

Markus Waldmüller
Markus Waldmüller
Head of Strategic Projects

Markus war bereits mehrere Jahre als Sysadmin in Neumarkt i.d.OPf. und Regensburg tätig. Nach Technikerschule und Selbständigkeit ist er nun Anfang 2013 bei NETWAYS als Senior Manager Services gelandet. Seit September 2023 kümmert er sich bei der NETWAYS Gruppe um strategische Projekte. Wenn er nicht gerade die Welt bereist, ist der sportbegeisterte Neumarkter mit an Sicherheit grenzender Wahrscheinlichkeit auf dem Mountainbike oder am Baggersee zu finden.

HAProxy und SQL Grants

In diesem kurzen Beitrag will ich auf einen Fallstrick im Bezug von HAProxy und SQL Backends wie MySQL oder MariaDB eingehen. Speziell geht es um Grants und die damit verbunden Quell Hosts. Diese werden bei einem Standard Setup mit HAProxy durch die IP des Proxys ersetzt. Solange man sich in dem selben Netz wie die DB Server und dem Proxy befindet und die Host-Beschränkungen nicht all zu streng sind, kann es gut sein, das man dieses Szenario nicht erreicht. Sobald die Verbindungen aber Netz übergreifend erfolgen und die Grants damit umso wichtiger sind, kommt das Detail zum Tragen und stellt einen vor neue Herausforderungen. Dafür gibt es an sich schon etwas länger das Proxy Protokoll, welches aber erst nach und nach in mögliche Backend Software implementiert wurde/wird. Bei MariaDB war es mit der 10.3.1 z.B. erst Ende letzten Jahres soweit.
Die Arbeitsweise des Protokolls beschreibt sich einfach gesagt so, dass mit dem Aufbau der Verbindung zuerst ein zus. Header geschickt wird, in dem die IP des Quell Hosts bekannt gegeben wird. Dazu muss das Backend jedoch von der IP des HAProxys das Proxy Protokoll erlauben. Das Ganze drum rum kann mit Seiten über weitere Details und Sicherheit befüllt werden. Damit verschone ich Euch aber und weise nur auf eine schlichte Zusammenfassung im Blog von HAProxy hin.

Galera Cluster – Tips für die Praxis

Galera Cluster für MySQL ist mal ein „einfacher“ Cluster für MySQL und seit MariaDB Version 10.1 standardmäßig mit an Board. Dadurch erhält man mit ein paar Zeilen Konfiguration einen produktionsfähigen Cluster, um den man sich wenig kümmern muss. In der Praxis allerdings, bieten sich genügend Fallstricke, die es zu meistern gilt.

Die Terminologie

  • Joiner: Neues Member welches dem Cluster hinzugefügt wird
  • Donor: Meldet sich ein Joiner stellt der Cluster einen Lieferanten bereit welcher die Daten auf den Joiner überträgt
  • SST: Snapshot State Transfer – Ist Lücke zum aktuellen Stand zu groß, werden der komplette Stand übertragen
  • IST: Incremental State Transfer – Im laufenden Betrieb werden Änderungen direkt übertragen. Die Änderung ist am Cluster erst verfügbar wenn alle Mitglieder diesen Stand empfangen haben

Tipps

1. SST Vermeiden

Einen kompletten Stand der Daten zu übertragen ist keine gute Idee. Ein Cluster, welcher 1 TB Nutzdaten verwaltet, ist auch nach drei Tagen nicht fertig. Dadurch können stabile Member ihre Integrität verlieren und der Cluster wird instabil. Hat man eine solche Situation erreicht empfiehlt es sich, den kompletten Cluster manuell zu syncen (MySQL Daten löschen und per rsync kopieren – Aber bitte keine Binlogs!).

2. SST Method

Galera bietet verschiedene Methoden um einen SST durchzuführen. Laut Statistik ist SSH die schnellste Methode – D’Accord – Aber der dadurch entstehende Donor ist für Anfragen gelockt und fällt aus dem Cluster. Dadurch wären wir bei Punkt 1 angelangt. Der beste trade-off ist hier xtrabackup-v2. Dadurch wird ein Donor am wenigsten blockiert. Bitte dabei den Benutzer zur MySQL Authentifizierung nicht vergessen – Sonst geht gar nichts!

3. SST Konfiguration

SST und das ausführen auf dem Joiner kann maßgeblich verbessert werden mit folgender MySQL Konfiguration:

[sst]
inno-apply-opts="--use-memory=20G"
compressor="pigz"
decompressor="pigz -d"

Dadurch geben wir dem innobackupex Script, welches auf dem Joiner ausgeführt mehr Speicher um Daten aus den Logs (–apply-log) auszuführen. Weiterhin parallelisieren wir den Vorgang um Daten auf dem Donor zu komprimieren und – guess what – auf dem Joiner zu dekomprimieren.
Um die Transaktionen weiter zu parallelisieren erhöhen wir die Einstellung wsrep_slave_threads auf eine dem System angepasste Anzahl (Anzahl Cores und Auslastung).

4. Dedizierten Donor

Bei großen Datenmengen empfiehlt es sich einen eigenständigen Donor bereitzustellen welcher keine Anfragen entgegen nimmt.

[mysqld]
 wsrep_sst_donor = node-donor

Eventuell sollte man auch Queries mit der Einstellung wsrep_sst_donor_rejects_queries verbieten

5. Locking Queries

Galera ist maximal transparent für Applikationen. Einzig, LOCKING wird nicht akzeptiert. Falls es von der Applikation benötigt wird könnte man mit der Einstellung wsrep_convert_LOCK_to_trx die Queries in Transaktionen kapseln.

6. Provider Cache

Standardmäßig auf 128M eingestellt, enthält dieser Ringpuffer die zu Verfügung stehen write-sets für einen IST. Die Größe sollte man entsprechend hoch wählen. So kann auch bei größeren Lücken immer noch ein IST durchgeführt werden:

[mysqld]
wsrep_provider_options="gcache.size=1G"

Bei entsprechend Arbeitsspeicher oder SSD Storage ist es durchaus eine gute Idee die Datei auf das schnellste Storage zu legen oder eine Lastaufteilung vorzunehmen:

[mysqld]
wsrep_provider_options="gcache.size = 8G; gcache.name = /var/cache/ssd/galera.cache"
7. HAProxy verwenden

Der stabilste Cluster bringt einem gar nichts wenn man nur einen Knoten abfragt. Eine der Stärken von Galera ist es, von allen Knoten zu lesen. Hier sollte man sich Gedanken zur Aufteilung machen:

  • Die schnellsten Knoten zum lesen und in den HAProxy
  • Donor exkludieren
  • Backup members bereitstellen (hot-standby)

Eine Konfiguration können z.B. folgendermaßen aussehen:

backend mysql_pool   mode tcp
  balance roundrobin   option mysql-check user haproxy   option tcpka # keep-alive!   server galera-donor1   192.168.17.20:3306 check inter 12000 disabled   server galera-standby1 192.168.17.21:3306 check inter 12000 disabled   server galera-node3    192.168.17.22:3306 check inter 12000
  server galera-node4    192.168.17.23:3306 check inter 12000
  server galera-node5    192.168.17.24:3306 check inter 12000

Dadurch erhalten wir einen Donor, einen hot-standby und drei read-heads. Durch die HAProxy API kann man das auch je nach Zustand des Cluster zu oder abschalten. Auch wäre eine standortübergreifende Verteilung möglich. Man stelle sich verschiedene Pools in verschiedenen Ländern vor. Je nach Ursprung und Applikation können dann die Anfragen zu den schnellsten read-heads weitergeleitet werden. Dann sollte man sich aber überlegen, z.B.  wsrep_dirty_reads an den Standorten zu verwenden.

8. Bin Logs

Ein richtiger Klassiker der Cluster Pitfalls, die Binary Logs von MySQL. Man würde sie für Galera nicht unbedingt benötigen aber sie bieten Sicherheit beim Crash und helfen einen SST im Falle zu vermeiden. In großen Umgebungen muss man folgendes bedenken:

  • Speicherplatz begrenzen
  • Vorhaltezeit verkürzen
  • An das verfügbare Storage anpassen

Ansonsten dauert ein FLUSH LOGS gerne auch mal 3 Tage und blockiert einen unseren Knoten – Beim Donor besonders schlecht!

Fazit

Für mich ein fantastisches Cluster System für MySQL! Es gibt noch viele gute Tips da draussen und noch viel mehr Möglichkeiten (und auch schmerzen) mit InnoDB / MySQL Konfiguration. Es funktioniert auch leider beim Galera Cluster nichts ohne vorher die eigene Rübe einzuschalten 😉

Links

 

Marius Hein
Marius Hein
Head of IT Service Management

Marius Hein ist schon seit 2003 bei NETWAYS. Er hat hier seine Ausbildung zum Fachinformatiker absolviert und viele Jahre in der Softwareentwicklung gearbeitet. Mittlerweile ist er Herr über die interne IT und als Leiter von ITSM zuständig für die technische Schnittmenge der Abteilungen der NETWAYS Gruppe. Wenn er nicht gerade IPv6 IPSec Tunnel bohrt, sitzt er daheim am Schlagzeug und treibt seine Nachbarn in den Wahnsinn.