MySQL bleibt hängen, wenn es über systemd gestartet wird ...

mysqld: Bruder, ich kann nicht aufstehen ...

Autor: Ben Shaohua, Ingenieur im ACOSEN R&D Center, verantwortlich für Projektanforderungen und Wartung. Andere Identitäten: Corgi-Schaufler.

Produziert von der Aikeson Open Source Community. Bitte kontaktieren Sie den Herausgeber und geben Sie die Quelle für den Nachdruck an.

Dieser Artikel ist etwa 2.100 Wörter lang und die Lektüre dauert voraussichtlich 7 Minuten.

Einführung

Wie der Titel schon sagt, kann MySQL in automatisierten Testszenarien nicht über systemd gestartet werden .

Beenden Sie kontinuierlich kill -9den Instanzprozess und prüfen Sie , ob mysqld nach dem Beenden korrekt aufgerufen wird.

Spezifische Informationen lauten wie folgt:

  1. Hostinformationen: CentOS 8 (Docker-Container)
  2. Verwenden Sie systemd , um den mysqld- Prozess zu verwalten
  3. Der Betriebsmodus des systemd-Dienstes ist: forking
  4. Der Startbefehl lautet wie folgt:
# systemd 启动命令
sudo -S systemctl start mysqld_11690.service

# systemd service 内的 ExecStart 启动命令
/opt/mysql/base/8.0.34/bin/mysqld --defaults-file=/opt/mysql/etc/11690/my.cnf --daemonize --pid-file=/opt/mysql/data/11690/mysqld.pid --user=actiontech-mysql --socket=/opt/mysql/data/11690/mysqld.sock --port=11690

Symptom

Der Startbefehl bleibt weiterhin hängen, ohne Erfolg oder Rückgabe. Nach mehreren Versuchen kann das Szenario nicht manuell reproduziert werden.

Die folgende Abbildung zeigt ein Reproduktionsszenario. Wenn die Service- Portnummern inkonsistent sind, ignorieren Sie sie bitte.

Das MySQL-Fehlerprotokoll enthält keine Informationen. Überprüfen Sie den Status des Systemd-Dienstes und stellen Sie fest, dass die Ausführung des Startskripts MAIN PIDaufgrund fehlender Parameter fehlgeschlagen ist.

Die endgültige Informationsausgabe von systemd lautet:New main PID 31036 does not exist or is a zombie

Zusammenfassung der Gründe

Wenn systemd mysqld startet , wird es zunächst gemäß der Konfiguration in der Dienstvorlage ausgeführt:

  1. ExecStart ( mysqld starten )
  2. mysqld beginnt mit der Erstellung pidvon Dateien
  3. ExecStartPost (einige benutzerdefinierte Post-Skripte: Berechtigungen anpassen, pidin cgroup schreiben usw.)

Im Zwischenzustand von Schritt 2-3 , also pidwenn die Datei gerade erstellt wird, empfängt der Host den vom automatisierten Test ausgegebenen Befehl: sudo -S kill -9 $(cat /opt/mysql/data/11690/mysqld.pid).

Da diese pidDatei und dieser pidProzess vorhanden sind (wenn killder Befehl oder Befehl nicht vorhanden ist, catwird ein Fehler gemeldet), geht automatisiertes CASE davon aus, dass killder Vorgang erfolgreich beendet wurde. Da diese Datei jedoch mysqld.pidvon MySQL selbst verwaltet wird, müssen Sie aus Sicht von systemd noch auf den Abschluss von Schritt 3 warten, bevor der Start als erfolgreich angesehen wird.

Wenn systemd den Forking- Modus verwendet , bestimmt es PIDanhand des Werts des untergeordneten Prozesses, ob der Dienst erfolgreich gestartet wurde.

Wenn der untergeordnete Prozess erfolgreich gestartet wird und kein unerwarteter Abbruch erfolgt, betrachtet systemd den Dienst als gestartet und setzt den PIDWert des untergeordneten Prozesses auf MAIN PID.

Wenn der untergeordnete Prozess nicht gestartet werden kann oder unerwartet beendet wird, geht systemd davon aus, dass der Dienst nicht erfolgreich gestartet werden konnte.

abschließend

Da beim Ausführen von ExecStartPost die untergeordnete Prozess- ID 31036 gelöscht wurde kill, fehlen der Nachverarbeitung shellStartparameter, aber der ExecStart-Schritt wurde abgeschlossen, was dazu führt, dass MAIN PID 31036 zu einem Zombie-Prozess wird, der nur in systemd existiert .

Fehlerbehebungsprozess

Als ich auf dieses Problem stieß, war ich etwas verwirrt und überprüfte einfach die grundlegenden Informationen zum Speicher und zur Festplatte. Es hat die Erwartungen erfüllt und es gab keinen Mangel an Ressourcen.

Schauen wir uns zunächst das Fehlerprotokoll von MySQL an, um zu sehen, was wir finden. Sehen Sie sich die Ergebnisse wie folgt an:

...无关内容省略...
2024-02-05T05:08:42.538326+08:00 0 [Warning] [MY-010539] [Repl] Recovery from source pos 3943309 and file mysql-bin.000001 for channel ''. Previous relay log pos and relay log file had been set to 4, /opt/mysql/log/relaylog/11690/mysql-relay.000004 respectively.
2024-02-05T05:08:42.548513+08:00 0 [System] [MY-010931] [Server] /opt/mysql/base/8.0.34/bin/mysqld: ready for connections. Version: '8.0.34'  socket: '/opt/mysql/data/11690/mysqld.sock'  port: 11690  MySQL Community Server - GPL.
2024-02-05T05:08:42.548633+08:00 0 [System] [MY-013292] [Server] Admin interface ready for connections, address: '127.0.0.1'  port: 6114
2024-02-05T05:08:42.548620+08:00 5 [Note] [MY-010051] [Server] Event Scheduler: scheduler thread started with id 5

Bei der Beobachtung des Fehlerprotokolls haben wir festgestellt, dass es keine nützlichen Informationen gibt, da nach der Startzeit keine Protokollinformationen ausgegeben werden.

Überprüfen Sie den Systemctl-Status , um den aktuellen Status des Dienstes zu bestätigen:

Das Bild unten zeigt die Statusinformationen unter normalen Umständen :

Nach dem Vergleich wurden zwei nützliche Informationen zusammengestellt:

  1. Die Nachausführung ist shellaufgrund fehlender -pParameter fehlgeschlagen ( -pdie Parameter sind MAIN PID, d. h. nachdem der untergeordnete Fork-Prozess gestartet wurde PID).
  2. systemd kann nicht abgerufen werden PID 31036, existiert nicht oder ist ein Zombie-Prozess.

Schauen wir uns zunächst den Prozess an IDund mysqld.pidsehen:

Bestätigungshinweise:

  1. PID 31036ist nicht vorhanden
  2. mysqld.pidDie Datei existiert und der Dateiinhalt ist 31036
  3. topBefehl zum Überprüfen, ob kein Zombie-Prozess vorhanden ist

Sie müssen noch weitere Hinweise zur Bestätigung der Ursache erhalten. Überprüfen Sie journalctl -uden Inhalt, um zu sehen, ob er hilfreich ist:

sh-4.4# journalctl -u mysqld_11690.service
-- Logs begin at Mon 2024-02-05 04:00:35 CST, end at Mon 2024-02-05 17:08:01 CST. --
Feb 05 05:07:54 udp-11 systemd[1]: Starting MySQL Server...
Feb 05 05:07:56 udp-11 systemd[1]: Started MySQL Server.
Feb 05 05:08:31 udp-11 systemd[1]: mysqld_11690.service: Main process exited, code=killed, status=9/KILL
Feb 05 05:08:31 udp-11 systemd[1]: mysqld_11690.service: Failed with result 'signal'.
Feb 05 05:08:32 udp-11 systemd[1]: Starting MySQL Server...
Feb 05 05:08:36 udp-11 systemd[1]: Started MySQL Server.
Feb 05 05:08:37 udp-11 systemd[1]: mysqld_11690.service: Main process exited, code=killed, status=9/KILL
Feb 05 05:08:37 udp-11 systemd[1]: mysqld_11690.service: Failed with result 'signal'.
Feb 05 05:08:39 udp-11 systemd[1]: Starting MySQL Server...
Feb 05 05:08:42 udp-11 u_set_iops.sh[31507]: /etc/systemd/system/mysqld_11690.service.d/u_set_iops.sh: option requires an argument -- p
Feb 05 05:08:42 udp-11 systemd[1]: mysqld_11690.service: New main PID 31036 does not exist or is a zombie.

Der Inhalt hier journalctl -ubeschreibt nur das Phänomen und kann die spezifischen Gründe nicht analysieren. Er ähnelt dem Inhalt von systemctl status und ist nicht sehr hilfreich.

Sehen Sie sich /var/log/messagesden Inhalt des Systemprotokolls an:

Es wurde festgestellt, dass die Schleife einige Speicherfehlerinformationen gemeldet hat. Bei der Suche wurde festgestellt, dass es sich bei dem Fehler möglicherweise um ein Hardwareproblem handelt. Nachdem ich Kollegen im Bereich automatisiertes Testen befragt hatte, kam ich zu dem Schluss:

  1. Das Szenario ist ein gelegentliches Problem. Der Anwendungsfall wird viermal ausgeführt, zweimal erfolgreich und zweimal fehlgeschlagen.
  2. Jede Ausführung erfolgt auf demselben Host und demselben Container-Image.
  3. Wenn dies fehlschlägt, ist der Container, in dem sich der Hang befindet, derselbe.

Da es erfolgreiche Ausführungsergebnisse gibt, werden wir die Hardwareprobleme hier ignorieren.

Da nun Container erwähnt werden, gibt es ein Problem, wenn ich darüber nachdenke, ob cgroups dem Host zugeordnet werden? Im oben überprüften Systemctl-Status ist ersichtlich, dass das von cgroup zugeordnete Hostverzeichnis wie folgt lautet:CGroup: /docker/3a72b2cdc7bd9beb1c7b2abec24763046604602a38f0fcb7406d17f5d33353d2/system.slice/mysqld_11690.service

Überprüfen Sie die Lese- und Schreibberechtigungen des übergeordneten Ordners. system.sliceEs liegt keine Anomalie vor. Beseitigen Sie zunächst vorübergehend das Problem der cgroup- Zuordnung (da auf dem Host andere von systemd übernommene Dienste vorhanden sind , die ebenfalls dieselbe cgroup verwenden ).

Ich habe vor, zu versuchen , ob pstack speziell für systemctl start erkennen kann , wo systemd hängt :3048143pid

sh-4.4# pstack 3048143
#0  0x00007fdfaef33ade in ppoll () from /lib64/libc.so.6
#1  0x00007fdfaf7768ee in bus_poll () from /usr/lib/systemd/libsystemd-shared-239.so
#2  0x00007fdfaf6a8f3d in bus_wait_for_jobs () from /usr/lib/systemd/libsystemd-shared-239.so
#3  0x000055b4c2d59b2e in start_unit ()
#4  0x00007fdfaf7457e3 in dispatch_verb () from /usr/lib/systemd/libsystemd-shared-239.so
#5  0x000055b4c2d4c2b4 in main ()

Die Beobachtung ergab, dass start_unit verdächtig ist. start_unit()Die Funktion befindet sich in der ausführbaren Datei. Sie wird zum Starten von systemd-Einheiten verwendet , was nicht hilfreich ist.

Basierend auf vorhandenen Hinweisen können wir Folgendes spekulieren:

  1. mysqld.pidWenn die Datei vorhanden ist, bedeutet dies, dass es tatsächlich einen mysqld-Prozess mit der Prozessnummer gab, der zuvor 31036gestartet wurde .
  2. Nachdem der Prozess gestartet wurde, wird er durch den automatisierten Anwendungsfall kill -9beendet .
  3. systemd hat eine bereits beendete Version erhalten MAIN PID, die Ausführung nach der Shell ist fehlgeschlagen und der Fork- Prozess ist fehlgeschlagen.

Indem wir die Schritte des systemd- Startvorgangs sortieren , können wir über die Möglichkeiten spekulieren. Die MySQL-Instanz generiert Dateien erst, nachdem mysqldmysqld.pid erfolgreich gestartet wurde. Daher kann es sein, dass sie in nachfolgenden Schritten kill -9versehentlich beendet wird .

Reproduktionsmethode

Da es keine weiteren Hinweise oder Hinweise gibt, habe ich vor, zu versuchen, es auf der Grundlage der abgeleiteten Schlussfolgerung zu reproduzieren.

4.1 Systemd-MySQL-Dienstvorlage anpassen

/etc/systemd/system/mysqld_11690.serviceBearbeiten Sie die Vorlagendatei Sekunden nach dem Start von mysqld , sleep10sodass Sie das Szenario des Beendens des Instanzprozesses innerhalb dieses Zeitfensters simulieren können.

4.2 Neuladen der Konfiguration

Änderungen der Ausführungsaufträge systemctl daemon-reloadwerden wirksam.

4.3 Szenenwiedergabe

  1. [SSH-Sitzung A] Bereiten Sie zunächst einen neuen Container vor, nehmen Sie die entsprechenden Konfigurationen vor und führen Sie ihn aus, um sudo -S systemctl start mysqld_11690.serviceeinen MySQL- Prozess zu starten. Zu diesem Zeitpunkt sleepbleibt die Sitzung aus bestimmten Gründen hängen.
  2. [SSH-Sitzung B] Überprüfen Sie in einem anderen Sitzungsfenster, startwährend der Befehl hängt, mysqld.piddie Datei und führen Sie sie sofort aus, sobald die Datei erstellt wurde sudo -S kill -9 $(cat /opt/mysql/data/11690/mysqld.pid).
  3. Beobachten Sie zu diesem Zeitpunkt den Systemctl-Status und die Leistung entspricht den Erwartungen.

Lösung

Entfernen Sie zunächst den killhängenden Befehl systemctl start und führen Sie ihn aus systemctl stop mysqld_11690.service. Dadurch kann systemd den Zombie-Prozess aktiv beenden. Obwohl stopder Befehl möglicherweise einen Fehler meldet, hat dies keine Auswirkungen.

Warten Sie, bis stopdie Ausführung abgeschlossen ist, und verwenden Sie dann startden Befehl, um erneut zu starten und zum Normalzustand zurückzukehren.

Weitere technische Artikel finden Sie unter: https://opensource.actionsky.com/

Über SQLE

SQLE ist eine umfassende SQL-Qualitätsmanagementplattform, die die SQL-Prüfung und -Verwaltung von der Entwicklung bis zur Produktionsumgebung abdeckt. Es unterstützt gängige Open-Source-, kommerzielle und inländische Datenbanken, bietet Prozessautomatisierungsfunktionen für Entwicklung, Betrieb und Wartung, verbessert die Online-Effizienz und verbessert die Datenqualität.

SQLE erhalten

Typ Adresse
Repository https://github.com/actiontech/sqle
dokumentieren https://actiontech.github.io/sqle-docs/
Neuigkeiten veröffentlichen https://github.com/actiontech/sqle/releases
Entwicklungsdokumentation für das Datenaudit-Plug-in https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse
High-School-Schüler erstellen ihre eigene Open-Source-Programmiersprache als Coming-of-Age-Zeremonie – scharfe Kommentare von Internetnutzern: Unter Berufung auf die Verteidigung hat Apple den M4-Chip RustDesk veröffentlicht. Inländische Dienste wurden wegen grassierenden Betrugs eingestellt . In Zukunft plant er, ein unabhängiges Spiel auf der Windows-Plattform Taobao (taobao.com) zu produzieren. Webversionsoptimierungsarbeiten neu starten, Ziel für Programmierer, Visual Studio Code 1.89 veröffentlicht Java 17, die am häufigsten verwendete Java LTS-Version, Windows 10 hat eine Marktanteil von 70 %, Windows 11 geht weiter zurück ; Google unterstützt Hongmeng bei der Übernahme von Open-Source-Rabbit-R1;
{{o.name}}
{{m.name}}

Ich denke du magst

Origin my.oschina.net/actiontechoss/blog/11105637
Empfohlen
Rangfolge