Mysqldump - trotz Exitcode 0 keine Daten im Dumpfile
Ich verwende diesen Aufruf, um Schemata auf dem Mysql Server zu dumpen:
mysqldump --opt --default-character-set=utf8 --flush-logs --single-transaction --no-autocommit --result-file="$_dumpfile" "$_dbname" 2>&1 $myrc=$?
… und stand vor dem Phänomen, dass der Exitcode 0 war - also eigentlich den Erfolg meldet - aber es keinerlei Daten im Dump gab.
Das Betriebssystem war ein Centos8 Stream. Das Problem lag in der Option –flush-logs, die nicht ausgeführt werden konnte, da das Verzeichnis /var/log/mysql/ (warum auch immer) nicht mehr vorhanden war. Dass ein leerer Dump ohne Daten erzeugt wird und kein Exitcode > 0, ist m.E. ein Fehler im mysqldump. Und den versuche ich, zu umschiffen.
Ich habe nach dem Dump noch einen Check hinzugefügt, der das Vorhandensein auf mind. ein CREATE oder aber INSERT Statements prüft. Oder anders: wenn man eine (korrekte) leere Datenbank ohne einzige Tabelle oder auch nur 1 einzigem gesicherten Datensatz hat, würde ein Fehler beim Backup gemeldet. Ich meine, damit lässt es sich leben.
mysqldump --opt --default-character-set=utf8 --flush-logs --single-transaction --no-autocommit --result-file="$_dumpfile" "$_dbname" 2>&1 $myrc=$? if [ $myrc -eq 0 ]; then if ! zgrep -iE "(CREATE|INSERT)" "$_dumpfile" >/dev/null then typeset -i local _iTables _iTables=$( mysql --skip-column-names --batch -e "use $_dbname; show tables ;" | wc -l ) if [ $_iTables -eq 0 ]; then echo "EMPTY DATABASE: $_dbname" else echo "ERROR: no data - the dump doesn't contain any CREATE or INSERT statement." # force an error $myrc=1 fi fi fi if [ $myrc -eq 0 ]; then echo "OK" # Und dann hier noch komprimieren... # gzip $_dumpfile" # ... und Erfolg der Kompression auswerten else echo "ERROR: mysqldump failed." fi
Update:
- 24.03.2022 - eine leere Datenbank würde als Fehler gemeldet - daher zähle ich mal noch die Tabellen
weiterführende Links:
- mysql.com: mysqldump
- mariadb.com: mysqldump
- IML open source: IML-Backup (mein Backup Tool an unserem Institut zum lokalen Dumpen div. DBs und Backup mit Restic/ Duplicity)
- DOCs: os-docs.iml.unibe.ch/iml-backup/
20 Jahre Axels Cron-wrapper
Ich habe grad in die History geschaut: 20 Jahre (!!!) nutze ich schon den meinigen Cronwrapper auf Linux/ Unix-Systemen.
Und ich bin noch immer am Aktualisieren und Verfeinern von dessen Skripten oder Dokumentation. Auch weil ich dessen Idee so mag. Alles ist OpenSource - GNU GPL 3.0.
Das Repository [1] enthält
- cronwrapper.sh - ein Wrapper - wenn man Cronjobs hat, dann stellt man den einfach mal vorn dran
- cronstatus.sh - das Skript zeigt den Status aller auf dem System befindlichen Cronjobs
- inc_cronfunctions.sh - ein Script, dass in Bash geschriebene Cronjobs gesourct werden kann, um div. nützliche Funktionen zu nutzen.
- Dokumentation im Markdown Format zur Installation und allen Features.
Der einfachste Einstieg ist, den Wrapper cronwrapper.sh zu verwenden: mit allen bestehenden Cronjobs, egal welcher Programmiersprache jene sind, lässt sich dieser ergänzen. Und man erhält out-of-the-box kleine nette Features.
- STDOUT und STDERR werden eingefangen und in ein normiertes Logfile geschrieben (ohne jenes explizit angeben zu müssen)
- Das Logfile wird normiert und ist mit grep nach Output oder Metadaten durchsuchbar
Alle Cronjobs, die den Wrapper verwenden, werden mit dem Skript cronstatus.sh aufgelistet und bewertet:
- weisen sie exitcode 0 auf?
- sind sie in der vorgegebenen Frist gestartet worden?
Diese Ausgabe kann man auch in einem Monitoring Script für die Überwachng aller Cronjobs auf seinen Systemen einbinden.
Und als Goodie gibt es ein Include file inc_cronfunctions.sh,welches hilfreich sein kann, sofern die Cronjobs in Bash geschrieben sind: eine Reihe nützlicher Funktionen werden darin bereitgestellt, um das Schreiben von “sicheren” und lesbaren Conjobs zu erleichtern.
weiterführende Links: (en)
- Github: cronwrapper
- Docs auf axel-hahn.de
Bash: Debug Infos und Fehler auf STDERR ausgeben
Manchmal möchte man Hilfsausgaben in seinem Bash-Skript haben. 2 kleine Hildfsfunktionen definiert:
- _wd für write debug infos zur Ausgabe von optional sichtbaren Kommentaren und
- _we für write error zum Einblenden von Fehlermeldungen.
# write a debug message in yellow to STDERR function _wd(){ test $DEBUG -eq 0 || echo -e "e[33m# DEBUG: $*e[0m" >&2 } # write error message in red to STDERR function _we(){ echo -e "e[31m# ERROR: $*e[0m" >&2 }
… und dann kann man in seinem Skript schreiben
# global var: enable debug output: 0|1 DEBUG=1 ... # example debug output _wd "show 3 oldest items in directory content" ls -ltr | head -3 ... # example error _we "Something went wrong :-/" exit 1
Bash: Mehrfachaufrufe eines Skriptes sequentiell abarbeiten
Ich habe ein Shellskript. Dieses wird von mehreren Rechnern und auch von denen ggf. mehrfach aufgerufen.
Und nun möchte ich, dass viele dieser Aufrufe nicht parallel, sondern nacheinander ausgeführt werden - gern in der Reihenfolge des Aufrufs.
In diesem Fall war es ein Wrapper Skript [1], das mit Acme.sh [2] SSL Zertifikate via Let’s Encrypt [3] löst. Man kann ein Ansible [4] Skript parallelisieren: N Server möchten also gleichzeitig vielleicht dasselbe Zertifikat. Nur der erste Aufruf soll ein Zertifikat erstellen und die nachfolgenden Aufrufe, die “vielleicht” dasselbe Zertifikat bearbeitet haben wollen, sollen nicht ebenfalls das Zertifikat erstellen, sondern auf die Ausstellung des ersten Aufrufes warten und dann dessen erstellte Zertifikatsdateien verwenden.
Anm: Let’s Encrypt Live-Server blockieren nach zu vielen Aufrufen für dieselbe Domain für 1 Woche alle Zertifikats-Aktionen, was sehr unangenehm für ein produktives System “sein kann” - auch das möchte ich daher applikatorisch unterbinden.
Ein Queuing will ich nicht bauen oder Semaphoren nutzen. Alles zu kompliziert für diesen Zweck.
Mein Ansatz: die Prozessliste.
Ich baue zunächst eine Funktion - so rein für Wiederverwendungszwecke und/ oder für ein gesourctes Skript mit Funktionen. Aus der Prozessliste per ps -ef filtere ich alle Prozesse, die den Interpreter Bash enthalten und das Shellskript des eigenen Namens $0. Die Prozessliste wird nach der Spalte mit den PIDs numerisch sortiert. Das Filtern mit der Bash ist wichtig, dass nicht andere Prozesse mit demselben Shellskript - z.B. ein offener Editor, der das Skript gerade bearbeitet - versehentlich die echten Abrufe blockieren.
ps -ef | grep "bash.*$0" | grep -v "grep" | sort -k 2 -n
Wenn darin in der ersten Zeile …
[irgendein Kommando] | head -1
… die eigene Prozess ID $$ in der 2. Spalte steht, dann ist der gerade laufende Prozess derjenige mit der kleinsten PID und darf weiterlaufen.
Wenn nicht, gibt es ein sleep für ein paar Sekunden, bevor nochmals getestet wird.
Und so sieht die Funktion _wait_for_free_slot() dann aus:
showdebug=1 # "neverending" loop that waits until the current process is # the one with lowest PID function _wait_for_free_slot(){ local _bWait=true typeset -i local _iFirstPID=0 _wd "--- Need to wait until own process PID $$ is on top ... " while [ $_bWait = true ]; do _iFirstPID=$( ps -ef | grep "bash.*$0" | grep -v "grep" | sort -k 2 -n | head -1 | awk '{ print $2}' ) if [ $_iFirstPID -eq $$ ]; then _bWait=false _wd "OK. Go!" else _wd "- all instances" test ${showdebug} && ps -ef | grep "bash.*$0" | grep -v "grep" | sort -k 2 -n sleep 10 fi done } # write debug output if showdebug is set to 1 function _wd(){ test ${showdebug} && echo "DEBUG: $*" }
Und dann baue ich in mein Skript jene Funktion _wait_for_free_slot ein - immer dort, wo ich eine sequentielle Ausführung wünsche. Wenn ich dasselbe Skript mit einem Parameter für die Hilfe-Ausgabe starte oder die Liste wartender Instanzen auflisten lasse, dann will ich eigentlich nicht auf die Abarbeitung aller vorherigen Instanzen warten. Naja, ihr seht vielleicht schon, worauf es hinausläuft. Bei jeder Aktion zum Erstellen, Erneuern oder Löschen eines Zertifikats wird die sequentielle Ausführung erzwungen, indem die Funktion _wait_for_free_slot in die erste Zeile geschrieben wird. Und bei den anderen Funktionalitäten lässt man den evtl. parallelisierten Aufruf zu.
# # pulic function ADD certificate # function add(){ _wait_for_free_slot // actions follow here ... }
weiterführende Links:
- IML certman Wrapper für Acme.sh mit DNS Authentication
- DOCs: os-docs.iml.unibe.ch/iml-certman/
- Acme.sh Let’ Encrypt Client als Bash Implementierung
- Let’s Encrypt Kostenlose SSL Zertifikate
- Ansible Automations Plattform
Manjaro update - pacman (6.0.0-1) breaks dependency ‘pacman<5.3′ required by package-query
Der grafische Software-Manager wollte pacman nicht aktualisieren … und wegen jenes Konflikts alle möglichen Pakete auch nicht.
Dann aktualisere ich halt “pamac upgrade pacman” von Hand und schaue, was passiert.
axel@mypc~> pamac upgrade pacman (...) vulkan-intel 21.1.4-1 (21.1.2-1) extra 2.3 MB vulkan-radeon 21.1.4-1 (21.1.2-1) extra 1.7 MB wireless-regdb 2021.04.21-1 (2020.11.20-1) core 10.3 kB Wird installiert (10): syndication 5.84.0-1 extra 1.0 MB electron12 12.0.14-1 community 50.7 MB layer-shell-qt 5.22.3-1 extra 23.1 kB ksystemstats 5.22.3-1 extra 162.9 kB pahole 1.21-1 extra 262.9 kB nodejs-nopt 5.0.0-2 community 13.4 kB libpamac 11.0.1-3 (Ersetzt: pamac-common) extra 818.4 kB kio-fuse 5.0.1-1 extra 70.3 kB fakeroot 1.25.3-2 core bison 3.7.6-1 core Zu erstellen (2): package-query 1.12-1 (1.10-1) AUR zoom 5.7.1-1 (5.6.7-1) AUR Wird entfernt (1): pamac-common 10.0.6-2 (Konflikt mit: libpamac) Download-Größe gesamt: 2.3 GB Gesamtgröße installiert: 269.3 MB Gesamtgröße entfernt: 9.5 MB Build-Dateien bearbeiten : [e] Transaktion durchführen ? [e/j/N] j Warning: installing pacman (6.0.0-1) breaks dependency 'pacman<5.3' required by package-query Add package-query to remove Fehler: Failed to prepare transaction: could not satisfy dependencies: - removing package-query breaks dependency 'package-query>=1.9' required by yaourt, - if possible, remove yaourt and retry
Leider nein.
Beim Lesen von “installing pacman (6.0.0-1) breaks dependency ‘pacman<5.3' " dachte ich schon fast: oh, ein Henne-Ei-Problem?
Die Lösung:
Ich bin einfach dem letzten Rat in der Ausgabe gefolgt und habe yaourt entfernt.
axel@mypc~ [1]> pamac remove yaourt Vorbereitung... Abhängigkeiten werden überprüft... Wird entfernt (1): yaourt 1.9-2 Gesamtgröße entfernt: 849.9 kB Transaktion durchführen ? [j/N] j Removing yaourt (1.9-2)... [1/1] Vorgang erfolgreich abgeschlossen.
Und nun nochmal der Versuch eines Updates …
axel@mypc~> pamac upgrade pacman ...
… hurra, nun klappt es!
weiterführende Links:
- manjaro.org (en)