Ich arbeite an der Erstellung von Diensten, die sowohl ein logisches als auch ein physisches MySQL-Backup durchführen können. Die logischen Backups würden alle 4 Stunden durchgeführt, während die physischen Backups einmal täglich zu einer bestimmten Zeit durchgeführt würden. Beide basieren auf dem Herunterfahren des MySQL-Slaves, auf dem das Backup basiert. Sie müssen auch damit umgehen können, nicht gleichzeitig ausgeführt zu werden. Darüber hinaus sollten diese beim Booten/Neustarten nicht beim ersten Aufruf ausgeführt werden.
Bei der logischen Sicherung wird S3 verwendet mysqldump
und anschließend hochgeladen. Bei der physischen Sicherung wird ein Snapshot des EBS erstellt.
Ich habe eine einfache Stressfallversion ausgeführt, bei der beide im Abstand von 1 Minute ausgelöst werden. Die Datenbank ist leer und klein. Das EBS-Volumen beträgt 1 GiB. Beides kann in weniger als einer Minute erledigt werden.
Ich verwende einen Timer-Dienst, um den Oneshot auszulösen. Ich habe außerdem jeden Timer miteinander verknüpft Conflicts
und den Timer in neu angegeben ExecStopPost
.
Ein Beispiel für die Servicedatei sieht so aus. Jede verweist auf die andere
[Unit]
After=mysql-slave.service
Conflicts=other-backup-type.timer
[Service]
Type=oneshot
# Just arbitrary name for this example
ExecStart=do_backup.sh
ExecStopPost=/bin/systemctl start other-backup-type.timer
Was ich gesehen habe, systemctl list-timers
ist, dass beide Timer synchron sind. Wenn beide 0 erreichen, wird einer ausgelöst. Was ich herausgefunden habe, ist, dass der andere, sobald dies geschehen ist, nicht ausgelöst wird. Es scheint, dass in diesem Fall der Timer tatsächlich gestoppt wird, aber der Auslöser für den anderen Oneshot nie erfolgt.
Gibt es eine Möglichkeit, dies richtig zu handhaben, ohne die Zeit versetzen zu müssen? Ich habe festgestellt, dass es funktioniert, wenn ich den Zeitraum leicht versetze (Sekunden können nicht ein Faktor von 60 sein). Ich prüfe, ob es eine bessere/elegantere Möglichkeit gibt, dies zu unterstützen.
Antwort1
Ich bin mir nicht ganz sicher, ob das die 100%ig richtige Antwort ist. Ich habe viele Permutationen durchgespielt und bin auf dieser Grundlage zu folgender Antwort gekommen.
Beobachtungen zufolge scheint es so zu sein, dass, wenn ich zwei Timer (A und B) habe, die so eingerichtet sind Conflicts=
und bei Ablauf mit einem anderen Timer kollidieren (z. B. beide so eingerichtet sind, dass sie jede Minute ausgelöst werden), der auslösende Timer (sagen wir, es ist A) zuerst den anderen stoppt und dann dessen Dienst auslöst. Dieser Stopp führt jedoch dazu, dass der Trigger für den Dienst von Timer B verloren geht. Ich vermute, dass der Trigger aus einer Warteschlange gezogen wird und schließlich während des Stoppvorgangs weggeworfen wird.