Jemand anders, der an einem Schaltsekundentag hohe Absturzraten bei Linux-Servern hat?

365

* ANMERKUNG: Wenn Ihr Server aufgrund verwirrter Kernel immer noch Probleme hat und Sie nicht neu starten können, lautet die einfachste Lösung, die mit installiertem gnu date auf Ihrem System vorgeschlagen wird: date -s now. Dadurch wird die interne Variable "time_was_set" des Kernels zurückgesetzt und die CPU-überlasteten Futex-Schleifen in Java und anderen Userspace-Tools behoben. Ich habe diesen Befehl auf meinem eigenen System ausgeführt und bestätigt, dass er das tut, was es verspricht. *

POSTMORTEM

Anticlimax: Als einziges Problem ist meine VPN-Verbindung (openvpn) zum Cluster gestorben, sodass es einige aufregende Sekunden dauerte, bis sie wiederhergestellt war. Alles andere war in Ordnung und das Starten von ntp verlief nach Ablauf der Schaltsekunde einwandfrei.

Ich habe meine volle Erfahrung des Tages bei http://blog.fastmail.fm/2012/07/03/a-story-of-leaping-seconds/ geschrieben

Wenn Sie Marcos Blog unter http://my.opera.com/marcomarongiu/blog/2012/06/01/an-humble-attempt-to-work-around-the-leap-second nachschlagen, hat er eine Lösung für Mit ntpd -x können Sie die Zeitänderung über 24 Stunden stufenweise ändern, um das Überspringen von 1 Sekunde zu vermeiden. Dies ist eine alternative Schmiermethode zum Betrieb Ihrer eigenen NTP-Infrastruktur.


Erst heute, am 30. Juni 2012 - kurz nach Tagesbeginn GMT. Wir hatten eine Handvoll Server in verschiedenen Rechenzentren, die von verschiedenen Teams verwaltet wurden. Alle werden dunkel - sie reagieren nicht auf Pings und haben keinen Bildschirm.

Sie alle führen Debian Squeeze aus - mit allem, was vom Standardkernel bis zu benutzerdefinierten 3.2.21-Builds reicht. Die meisten sind Dell M610-Blades, aber ich habe auch gerade einen Dell R510 verloren, und andere Abteilungen haben auch Maschinen von anderen Anbietern verloren. Es gab auch eine ältere IBM x3550, die abgestürzt ist und von der ich dachte, dass sie nichts damit zu tun hat, aber jetzt wundere ich mich.

Der eine Absturz, von dem ich einen Bildschirmauszug bekommen habe, sagte:

[3161000.864001] BUG: spinlock lockup on CPU#1, ntpd/3358
[3161000.864001]  lock: ffff88083fc0d740, .magic: dead4ead, .owner: imapd/24737, .owner_cpu: 0

Leider hatten alle Blades angeblich kdump konfiguriert, aber sie starben so stark, dass kdump nicht ausgelöst wurde - und die Konsolenausblendung war aktiviert. Ich habe die Konsolenaustastung jetzt deaktiviert, also drücke ich die Daumen, um nach dem nächsten Absturz weitere Informationen zu erhalten.

Ich möchte nur wissen, ob es ein roter Faden ist oder "nur wir". Es ist wirklich seltsam, dass es sich um unterschiedliche Einheiten in unterschiedlichen Rechenzentren handelt, die zu unterschiedlichen Zeiten gekauft wurden und von unterschiedlichen Administratoren ausgeführt werden (ich verwende die FastMail.FM-Einheiten) ... und jetzt sogar unterschiedliche Herstellerhardware. Die meisten Maschinen, die abgestürzt waren, waren seit Wochen / Monaten in Betrieb und liefen auf Kernels der 3.1- oder 3.2-Serie.

Der letzte Absturz war eine Maschine, die erst seit 6 Stunden in Betrieb war. 3.2.21.

DIE ABHILFE

Ok Leute, hier ist, wie ich daran gearbeitet habe.

  1. deaktiviert ntp: /etc/init.d/ntp stop
  2. Erstellt http://linux.brong.fastmail.fm/2012-06-30/fixtime.pl (Code von Marco gestohlen, siehe Blog-Beiträge in Kommentaren)
  3. lief fixtime.plohne ein Argument, um zu sehen, dass es einen Schaltsekundensatz gab
  4. lief fixtime.plmit einem Argument, um die Schaltsekunde zu entfernen

HINWEIS: abhängig von adjtimex. Ich habe eine Kopie der Squeeze- adjtimexBinärdatei unter http://linux.brong.fastmail.fm/2012-06-30/adjtimex abgelegt. Sie wird ohne Abhängigkeiten von einem Squeeze-64-Bit-System ausgeführt. Wenn Sie es in dasselbe Verzeichnis wie fixtime.plablegen, wird es verwendet, wenn das System nicht vorhanden ist. Natürlich, wenn Sie kein 64-Bit-Squeeze haben ... finden Sie Ihr eigenes.

Ich fange ntpmorgen wieder an.

Wie von einem anonymen Benutzer vorgeschlagen, besteht eine Alternative zum Ausführen adjtimexdarin, die Zeit selbst festzulegen, wodurch vermutlich auch der Schaltsekundenzähler gelöscht wird.

Bron Gondwana
quelle
58
Heute, dem 30., gibt es eine Schaltsekunde. Ich zögere zu implizieren, dass dies Ihr Problem ist, aber ich werde meine Debian-Maschinen genau beobachten.
Jscott
2
seit morgen haben wir mindestens 9 verschiedene debian squeeze boxen von verschiedenen herstellern verloren, die alle stock squeeze 2.6.32 kernel ausführen. Es ist uns nicht gelungen, einen Crash-Dump zu bekommen, da die Konsole
ausgeblendet wurde
3
lkml Posting über diese lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html
Daniel S. Sterling
2
Vielen Dank für den Hinweis! Ich starre jetzt sehr, sehr genau auf meine Server.
Janne Pikkarainen
5
Der LKML-Thread zeigte an, dass es date -s "`date`"hilft - es hat mir sicherlich geholfen.
Pointy

Antworten:

321

Dies wird durch eine Livesperre verursacht, wenn ntpd adjtimex (2) aufruft, um den Kernel anzuweisen, eine Schaltsekunde einzufügen. Siehe lkml-Posting http://lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html

Red Hat sollte auch seinen KB-Artikel aktualisieren. https://access.redhat.com/knowledge/articles/15145

UPDATE: Red Hat hat einen zweiten KB-Artikel nur für dieses Problem hier: https://access.redhat.com/knowledge/solutions/154713 - der vorherige Artikel bezieht sich auf ein früheres, nicht verwandtes Problem

Die Problemumgehung besteht darin, ntpd einfach auszuschalten. Wenn ntpd den Aufruf adjtimex (2) bereits ausgegeben hat, müssen Sie möglicherweise ntpd deaktivieren und neu starten, um 100% sicher zu sein.

Dies betrifft RHEL 6 und andere Distributionen mit neueren Kerneln (neuer als ca. 2.6.26), jedoch nicht RHEL 5.

Der Grund dafür, dass dies geschieht, bevor die Schaltsekunde tatsächlich geplant ist, ist, dass der Kernel mit ntpd die Schaltsekunde um Mitternacht verarbeiten kann, den Kernel jedoch warnen muss, die Schaltsekunde vor Mitternacht einzufügen. ntpd ruft daher irgendwann am Tag der Schaltsekunde adjtimex (2) auf, an welchem ​​Punkt dieser Fehler ausgelöst wird.

Wenn Sie adjtimex (8) installiert haben, können Sie mithilfe dieses Skripts feststellen, ob Flag 16 gesetzt ist. Flag 16 ist "Schaltsekunde einfügen":

adjtimex -p | perl -p -e 'undef $_, next unless m/status: (\d+)/; (16 & $1) && print "leap second flag is set:\n"'

AKTUALISIEREN:

Red Hat hat den KB-Artikel folgendermaßen aktualisiert: "RHEL 6-Kunden sind möglicherweise von einem bekannten Problem betroffen, das dazu führt, dass NMI Watchdog beim Empfang der NTP-Schaltsekunden-Ankündigung einen Stillstand erkennt. Dieses Problem wird rechtzeitig behoben. Wenn Ihre Systeme empfangen werden die Schaltsekundenansage und dieses Problem nicht aufgetreten, dann sind sie nicht mehr betroffen. "

UPDATE: Die oben genannte Sprache wurde aus dem Red Hat-Artikel entfernt. und eine zweite KB-Lösung wurde hinzugefügt, die das Absturzproblem von adjtimex (2) detailliert beschreibt: https://access.redhat.com/knowledge/solutions/154713

Die Codeänderung im LKML-Beitrag von IBM Engineer John Stultz weist jedoch darauf hin, dass möglicherweise auch ein Deadlock vorliegt, wenn die Schaltsekunde tatsächlich angewendet wird. Sie können die Schaltsekunde daher deaktivieren, indem Sie einen Neustart durchführen oder adjtimex (8) nach dem Deaktivieren von ntpd verwenden.

FINAL UPDATE:

Nun, ich bin kein Kernel-Entwickler, aber ich habe den Patch von John Stultz hier noch einmal durchgesehen: https://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h = 6b43ae8a619d17c4935c3320d2ef9e92bdeed05d

Wenn ich es dieses Mal richtig lese, habe ich mich geirrt, dass es einen weiteren Deadlock gibt, wenn die Schaltsekunde angewendet wird. Dies scheint auch Red Hats Meinung zu sein, basierend auf ihrem KB-Eintrag. Wenn Sie jedoch ntpd deaktiviert haben, lassen Sie es weitere 10 Minuten deaktiviert, damit Sie nicht den Deadlock erreichen, wenn ntpd adjtimex (2) aufruft.

Wir werden bald herausfinden, ob es weitere Bugs gibt :)

ZWEITES UPDATE NACH DEM LEAP:

Ich habe die letzten Stunden damit verbracht, den ntpd- und Pre-Patch- (Buggy-) Kernel-Code durchzulesen, und obwohl ich mich hier sehr irre, werde ich versuchen zu erklären, was meiner Meinung nach vor sich ging:

Zunächst ruft ntpd die ganze Zeit adjtimex (2) auf. Dies geschieht im Rahmen des "Clock Loop Filters", das in local_clock in ntp_loopfilter.c definiert ist. Sie können diesen Code hier sehen: http://www.opensource.apple.com/source/ntp/ntp-70/ntpd/ntp_loopfilter.c (ab NTP-Version 4.2.6).

Der Taktschleifenfilter wird ziemlich oft ausgeführt - er wird jedes Mal ausgeführt, wenn ntpd seine Upstream-Server abfragt. Standardmäßig sind dies alle 17 Minuten oder mehr. Das relevante Bit des Taktschleifenfilters ist:

if (sys_leap == LEAP_ADDSECOND)
    ntv.status |= STA_INS;

Und dann:

ntp_adjtime(&ntv)

Mit anderen Worten, an Tagen, an denen es eine Schaltsekunde gibt, setzt ntpd das "STA_INS" -Flag und ruft adjtimex (2) auf (über seinen Portabilitäts-Wrapper).

Dieser Systemaufruf gelangt zum Kernel. Hier ist der relevante Kernel-Code: https://github.com/mirrors/linux/blob/a078c6d0e6288fad6d83fb6d5edd91ddb7b6ab33/kernel/time/ntp.c

Der Kernel-Codepfad sieht ungefähr so ​​aus:

  • Zeile 663 - Start der Routine do_adjtimex.
  • Zeile 691 - annulliert einen existierenden Schaltsekunden-Timer.
  • Zeile 709 - Nimm den Spinlock ntp_lock (diese Sperre ist am möglichen Absturz von livelock beteiligt)
  • Zeile 724 - process_adjtimex_modes aufrufen.
  • Zeile 616 - process_adj_status aufrufen.
  • Zeile 590 - globale Variable time_status setzen, basierend auf Flags, die im adjtimex (2) -Aufruf gesetzt wurden
  • Zeile 592 - Überprüfen Sie die globale Variable time_state. Rufen Sie in den meisten Fällen ntp_start_leap_timer auf.
  • Zeile 554 - Überprüfen Sie die globale Variable time_status. STA_INS wird gesetzt, setzen Sie also time_state auf TIME_INS und rufen Sie hrtimer_start (eine andere Kernelfunktion) auf, um den Schaltsekunden-Timer zu starten. Während der Erstellung eines Timers wird mit diesem Code die xtime_lock erfasst. Wenn dies passiert, während eine andere CPU bereits den xtime_lock und den ntp_lock gepackt hat, wird der Kernel gesperrt. Aus diesem Grund hat John Stultz den Patch geschrieben, um die Verwendung von Hrtimern zu vermeiden. Das hat heute allen Ärger bereitet.
  • Zeile 598 - Wenn ntp_start_leap_timer keinen Sprungtimer gestartet hat, setzen Sie time_state auf TIME_OK
  • Zeile 751 - Unter der Annahme, dass der Kernel nicht gesperrt ist, wird der Stack aufgelöst und der Spinlock ntp_lock freigegeben.

Hier gibt es ein paar interessante Dinge.

Zuerst löscht die Leitung 691 den vorhandenen Zeitgeber bei jedem Aufruf von adjtimex (2). Dann erstellt 554 diesen Zeitgeber neu. Dies bedeutet, dass jedes Mal, wenn ntpd seinen Clock-Loop-Filter ausführt, der Buggy-Code aufgerufen wurde.

Daher glaube ich, dass Red Hat falsch lag, als sie sagten, dass das System nicht abstürzen würde, wenn ntpd das Schaltsekunden-Flag gesetzt hätte. Ich glaube, dass jedes System, auf dem ntpd ausgeführt wird, das Potenzial hatte, alle 17 Minuten (oder länger) für den Zeitraum von 24 Stunden vor der Schaltsekunde zu blockieren. Ich glaube, das könnte auch erklären, warum so viele Systeme abgestürzt sind. Eine einmalige Crash-Chance würde viel seltener getroffen als drei Chancen pro Stunde.

UPDATE: In der KB-Lösung von Red Hat unter https://access.redhat.com/knowledge/solutions/154713 kamen die Red Hat-Ingenieure zu dem gleichen Schluss (dass das Ausführen von ntpd den Buggy-Code ständig beeinträchtigen würde). Und tatsächlich taten sie dies einige Stunden vor mir. Diese Lösung war nicht mit dem Hauptartikel unter https://access.redhat.com/knowledge/articles/15145 verknüpft , daher habe ich sie bis jetzt nicht bemerkt.

Zweitens erklärt dies, warum geladene Systeme häufiger abstürzen. Auf geladenen Systemen werden mehr Interrupts verarbeitet, wodurch die Kernelfunktion "do_tick" häufiger aufgerufen wird, sodass dieser Code häufiger ausgeführt und der Befehl ntp_lock abgerufen werden kann, während der Zeitgeber erstellt wurde.

Drittens: Kann das System abstürzen, wenn die Schaltsekunde tatsächlich eintritt? Ich weiß es nicht genau, aber möglicherweise auch, weil der Timer, der die Schaltsekundenanpassung auslöst und tatsächlich ausführt (ntp_leap_second, Zeile 388), auch den Spinlock ntp_lock erfasst und hrtimer_add_expires_ns aufruft. Ich weiß nicht, ob dieser Anruf möglicherweise auch eine Lebenssperre auslösen kann, aber es scheint nicht unmöglich zu sein.

Was bewirkt schließlich, dass das Schaltsekunden-Flag deaktiviert wird, nachdem die Schaltsekunde abgelaufen ist? Die Antwort ist, dass ntpd das Setzen des Schaltsekunden-Flags nach Mitternacht stoppt, wenn es adjtimex (2) aufruft. Da das Flag nicht gesetzt ist, ist die Prüfung in Zeile 554 nicht wahr, und es wird kein Zeitgeber erstellt, und Zeile 598 setzt die globale Variable time_state auf TIME_OK zurück. Dies erklärt, warum, wenn Sie das Flag mit adjtimex (8) direkt nach der Schaltsekunde markieren, das Schaltsekunden-Flag immer noch gesetzt ist.

Kurz gesagt, der beste Rat für heute scheint der erste zu sein, den ich immerhin gegeben habe: Deaktiviere ntpd und deaktiviere das Schaltsekunden-Flag.

Und noch ein paar abschließende Gedanken:

  • Keiner der Linux-Anbieter bemerkte John Stultz 'Patch und wendete ihn auf ihre Kernel an :(
  • Warum hat John Stultz nicht einige der Anbieter alarmiert, die dies benötigten? Vielleicht schien die Chance, dass das Livelock Lärm machte, gering genug zu sein, nicht gerechtfertigt.
  • Ich habe gehört, dass Java-Prozesse abstürzen oder sich drehen, als die Schaltsekunde angewendet wurde. Vielleicht sollten wir dem Beispiel von Google folgen und überdenken, wie wir Schaltsekunden auf unsere Systeme anwenden: http://googleblog.blogspot.com/2011/09/time-technology-and-leaping-seconds.html

06/02 Update von John Stultz:

https://lkml.org/lkml/2012/7/1/203

Der Beitrag enthielt eine schrittweise Anleitung, warum die Schaltsekunde dazu führte, dass die Futex-Timer vorzeitig und kontinuierlich abliefen und die CPU-Last anstieg.

Daniel S. Sterling
quelle
7
Danke für die hervorragende Antwort. Der Rest unserer Server wartet auf den Absturz. Schön. Rollende Neustarts hier kommen wir!
Bron Gondwana
3
Woher weiß ich, ob der adjtimexausgegeben wurde? Gibt der Kernel etwas in dmesg aus? Welche Chance besteht, dass ein System, das vor dem Ausschalten von ntpd nicht abgestürzt ist, abstürzt?
Hubert Kario
3
Hubert: Führen Sie "adjtimex" aus (normalerweise separat verpackt) und suchen Sie nach Flag 16, um anzuzeigen, dass eine Schaltsekunde ansteht.
Dominic Cleal
22
Du wirst die Repräsentantenmütze hassen.
Wesley
26
@WesleyDavid: Keine Sorge, die Wiederholungszahl wird um Mitternacht UTC zurückgesetzt. Vielleicht.
mmyers
33

Das hat uns hart getroffen. Nach dem Neustart vieler unserer Hosts stellte sich Folgendes als peinlich einfach und ohne Neustart des Hosts als voll wirksam heraus:

/etc/init.d/ntp stop
ntpdate 0.us.pool.ntp.org
/etc/init.d/ntp start

Sie müssen lediglich die Systemuhr zurücksetzen. Meine Güte. Was ich gegeben habe, um das vor sechs Stunden gewusst zu haben.

HikeOnPast
quelle
8
date -s "`date`"arbeitete für mich.
Pointy
@DeanB: Ich habe um 3 Uhr UTC gepostet, dass das Zurücksetzen der Uhr den Trick macht. Leider hat es eine Weile gedauert, bis es moderiert war. Wir haben auch angefangen, Server neu zu starten
Gregor
24

Ein einfaches C-Programm, das das Schaltsekundenbit im Zeitstatusfeld des Kernels löscht:

#include <sys/timex.h>
#include <string.h>
#include <stdio.h>

int main(int argc, char **argv) {
    struct timex txc;
    int ret;

    (void) argc;
    (void) argv;

    bzero(&txc, sizeof(txc));
    txc.modes = 0;  /* fetch */
    ret = adjtimex(&txc);
    if (ret < 0) {
        perror("adjtimex (get)");
        return 1;
    }

    txc.modes = ADJ_STATUS;
    txc.status &= ~16;
    ret = adjtimex(&txc);
    if (ret < 0) {
        perror("adjtimex (set)");
        return 1;
    }

    return 0;
}

Speichern unter lsec.c, kompilieren mit gcc -Wall -Wextra -o lsec lsec.cund starten als root.

Sie möchten wahrscheinlich ntpd stoppen, bevor Sie es ausführen, und ntpd nach der Schaltsekunde neu starten.

jon
quelle
Was leistet (void) argc;das? Warnung für die nicht verwendete Variable stumm schalten? Würde die Verwendung nicht int main()dasselbe bewirken? Ich versuche nicht, Pedant zu sein, aber ich bin wirklich neugierig.
gparent
18

Postmortem scheint ./lsec keine Wirkung zu haben.

Was wir sehen, sind viele Softirqd-Prozesse, die CPU verbrauchen (normalerweise linear zur Last von Java-Prozessen)

Was funktioniert, um POSTMORTEM mit Schaltsekunden zu reparieren, die bereits von ntp angewendet wurden, ist Folgendes:

Es scheint ausreichend zu sein, nur Folgendes herauszugeben:

export LANG="en_EN"; date -s "`date`"

Dies sollte die Last ohne ntpd-Neustart oder Neustart reduzieren. Alternativ können Sie Folgendes ausstellen:

apt-get install ntpdate
/etc/init.d/ntpd stop; ntpdate pool.ntp.org; /etc/init.d/ntpd start
Gregor
quelle
warum sntp -snicht ntpdate?
Fehlerentwickler
ntpdate ist nur ein Wrapper für sntp, sicher ist es auch in Ordnung, ntpdate zu verwenden.
Gregor
ah, ich habe komplett vermisst, dass es ein ntpdate-Paket für Squeeze gibt, bei dem es sich tatsächlich um eine Binärdatei handelt. Ich habe mein Posting so bearbeitet, dass es dies enthält.
Gregor,
Ich habe ähnliche Berichte über die Behebung dieses Problems gehört (z. B. über die Verwendung von date -s). Es hört sich so an, als müsste für die Korrektur nur die Systemzeit eingestellt werden, anstatt sie zu drehen (das Standardverhalten von ntpd bei geringem Versatz). Ich vermute, dass das Einstellen der Zeit dazu führt, dass sich die interne Zeitmessmechanik des Kernels zurücksetzt.
Patrick
4
Die CPU-Auslastung meiner Java-Apps hat ebenfalls zugenommen (da viel CPU-Zeit in softirqd aufgewendet wurde). Dies wurde behoben.
Hubert Kario
16

http://my.opera.com/marcomarongiu/blog/2012/03/12/no-step-back scheint darauf hinzudeuten, dass der Debian-Squeeze-Kernel die Schaltsekunde nicht bewältigt.

Dieser Thread auf comp.protocols.tim.ntp ist auch von Interesse: https://groups.google.com/forum/?fromgroups#!topic/comp.protocols.time.ntp/KSflIgjUdPE

Die Schaltsekunde ist allerdings noch nicht passiert: 23:59:60 UTC

Schließlich hat https://access.redhat.com/knowledge/articles/15145 Folgendes zu sagen: "Wenn die Schaltsekunde auftritt, druckt der Kernel eine Nachricht in das Systemprotokoll. Möglicherweise wird diese Nachricht gedruckt kann dazu führen, dass der Kernel in Red Hat Enterprise Linux abstürzt. "

Luca Filipozzi
quelle
Aber der 3.2.21-Kernel sollte vermutlich - was zumindest eine der abgestürzten Maschinen war
Bron Gondwana am
Auf einigen dieser Maschinen, von denen Bron angab, dass wir tatsächlich einen Fix eingeführt haben, der die anstehende Schaltsekunde korrekt handhaben sollte.
Cosimo
Kannst du das Update irgendwo posten, damit andere Ideen überprüfen / vorschlagen / ausprobieren können?
Kargig
Ich habe keine Lösung ... Ich sammle nur Informationen. Hätte dies vielleicht als Kommentar gegen die ursprüngliche Frage setzen sollen.
Luca Filipozzi
4
my.opera.com/marcomarongiu/blog/2012/06/01/… enthält weitere Details zur Fehlerbehebung
Bron Gondwana