İkinci gün atılan Linux sunucularında yüksek oranlarda çökme yaşayan başka biri var mı?


365

* NOT: Sunucunuzda hala şaşkın çekirdeklerden dolayı sorun varsa ve yeniden başlatamazsanız - sisteminizde kurulu gnu tarihiyle önerilen en basit çözüm şudur: date -s now. Bu, çekirdeğin dahili "time_was_set" değişkenini sıfırlar ve javadaki ve diğer kullanıcı araçları araçlarındaki CPU takma futex döngülerini düzeltir. Bu emri kendi sistemime verdim, bir kutuda ne yazdığını onayladım *

ÖLÜMDEN

Anticlimax: ölen tek şey kümemdeki VPN (openvpn) bağlantımdı, bu yüzden yeniden kurulurken heyecan verici bir kaç saniye vardı. Her şey yolundaydı ve artık saniye geçtikten sonra ntp'nin başlatılması temiz geçti.

Günün tüm tecrübesini http://blog.fastmail.fm/2012/07/03/a-story-of-leaping-seconds/ adresinde yazdım.

Marco’nun bloguna http://my.opera.com/marcomarongiu/blog/2012/06/01/an-humble-attempt-to-work-around-the-leap-second adresinden bakarsanız - bunun için bir çözümü vardır. 1 saniyelik atlamadan kaçınmak için ntpd -x kullanarak zamanın 24 saat boyunca değişmesi. Bu, kendi ntp altyapınızı çalıştırmak için alternatif bir bulaşma yöntemidir.


Tam bugün, 30 Haziran 2012, Sat - GMT gününün başlamasından hemen sonra başlıyor. Farklı ekipler tarafından yönetilen farklı veri merkezlerinde bir avuç dolusu sunucu kullandık - ping'lere cevap vermiyor, ekran boş.

Hepsi Debian Squeeze kullanıyor - stok çekirdeğinden özel 3.2.21'e kadar her şey. Çoğu Dell M610 blade'leri ancak bir Dell R510'u da kaybettim ve diğer bölümler de diğer üreticilerin makinelerini kaybetti. Ayrıca kaza yapan ve ilgisiz olabileceğini düşündüğüm eski bir IBM x3550 vardı, ama şimdi merak ediyorum.

Bir ekran dökümü aldım ki düştü dedi:

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

Maalesef, bıçakların tümü sözde kdump konfigüre edilmiş, ancak kdump'ın tetiklemeyeceği kadar sert öldüler - ve konsolun körleştirilmesi açıktı. Konsolun boşluğunu şimdi devre dışı bıraktım, bu nedenle parmaklar geçti.

Sadece ortak bir konu veya "sadece biz" olup olmadığını bilmek istiyorum. Farklı zamanlarda satın alınan ve farklı yöneticiler tarafından çalıştırılan (FastMail.FM'i çalıştırıyorum) ... ve şimdi bile farklı satıcı donanımıyla çalışan farklı veri merkezlerinde farklı birimler olması gerçekten garip. Çöken makinelerin çoğu haftalar / aylar boyunca sürdü ve 3.1 veya 3.2 seri çekirdekler kullanıyordu.

En yeni kaza, yalnızca 3.2.21 çalışan yaklaşık 6 saat süren bir makineydi.

ÇALIŞMA

Tamam millet, işte nasıl çalıştığımı.

  1. devre dışı bırakılmış ntp: /etc/init.d/ntp stop
  2. http://linux.brong.fastmail.fm/2012-06-30/fixtime.pl oluşturuldu (Marco'dan çalınan kod, yorumlardaki blog yazılarına bakın)
  3. fixtime.plartık bir ikinci set olduğunu görmek için tartışmasız koştum
  4. fixtime.plartık saniye kaldırmak için bir argüman ile koştu

NOT: bağlıdır adjtimex. Sıkıştırma adjtimexikilisinin bir kopyasını http://linux.brong.fastmail.fm/2012-06-30/adjtimex adresime koydum - sıkma 64 bit sistemine bağımlı olmadan çalışacak. Aynı dizine koyarsanız fixtime.pl, sistem yoksa, kullanılır. Açıkçası, 64-bit sıkmak yoksa… kendi bul.

ntpYarın tekrar başlayacağım .

Anonim bir kullanıcının önerdiği gibi - koşuya bir alternatif, adjtimexsadece kendi zamanınızı ayarlamaktır; bu da büyük olasılıkla artık saniye sayacını temizler.


58
Bugün atılan ikinci, 30'uncu. Bunun senin sorunun olduğunu ima etmekte tereddüt ediyorum, ama Debian makinelerimi yakından izliyor olacağım.
jscott

2
sabahtan beri Çeşitli satıcılardan en az 9 farklı debian sıkma kutusunu kaybettik. Konsol
boşluğu


2
Bunu bildirdiğin için teşekkürler! Şimdi sunucularımı çok çok yakından inceliyorum.
Janne Pikkarainen

5
LKML dizisi bunun işe yaradığını date -s "`date`"- kesinlikle bana yardımcı olduğunu belirtti .
Pointy

Yanıtlar:


321

Bu, ntpd, çekirdeğe bir artık saniye eklemesini söylemek için adjtimex (2) 'yi çağırdığında bir livelock'tan kaynaklanır. Lkml ilanı gör http://lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html

Red Hat ayrıca KB makalelerini de güncellemelidir. https://access.redhat.com/knowledge/articles/15145

GÜNCELLEME: Red Hat'ın burada sadece bu sayı için ikinci bir KB makalesi var: https://access.redhat.com/knowledge/solutions/154713 - önceki makale daha önce ilgisiz bir problem için

Çözüm sadece ntpd'yi kapatmak. Ntpd zaten adjtimex (2) çağrısını yaptıysa, ntpd'yi devre dışı bırakmanız ve% 100 güvenli olması için yeniden başlatmanız gerekebilir.

Bu, RHEL 6'yı ve daha yeni çekirdekleri çalıştıran (yaklaşık 2.6.26'dan daha yeni) diğer dağıtımları etkiler, ancak RHEL 5'i etkilemez.

Bunun , sıçrama saniyesinin gerçekte gerçekleşmesi planlanandan önce meydana gelmesinin nedeni, ntpd'nin çekirdeğin gece yarısını ikinci saniye idare etmesine izin vermesidir, ancak gece yarısından önce saniyeyi atması için çekirdeği uyarması gerekir. Bu nedenle ntpd artık saniye saniye boyunca adjtimex'i (2) çağırır, bu noktada bu hata tetiklenir.

Eğer adjtimex (8) kurmuşsanız, bayrak 16 ayarlanmış olup olmadığını belirlemek için bu betiği kullanabilirsiniz. Bayrak 16, "artık ikinci ekleme" dir:

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

GÜNCELLEME:

Red Hat, KB makalelerini not etmek için güncelledi: "RHEL 6 müşterileri, NTP Gözetleme bildirisini alırken NMI Gözcü'nün askıda kalmasını algılamasına neden olan bilinen bir sorundan etkilenebilir. Bu sorun zamanında ele alınıyor. artık ilan ve bu sorunu yaşamamış, o zaman artık etkilenmiyorlar. ”

GÜNCELLEME: Yukarıdaki dil Red Hat makalesinden kaldırıldı; ve adjtimex (2) kilitlenme sorununu ayrıntılandıran ikinci bir KB çözümü eklendi: https://access.redhat.com/knowledge/solutions/154713

Bununla birlikte, IBM Engineer John Stultz tarafından LKML postasındaki kod değişikliği, artık saniye gerçekten uygulandığında bir kilitlenme olabileceğine dikkat çeker, bu nedenle ntpd'yi devre dışı bıraktıktan sonra yeniden başlatmayı veya adjtimex (8) kullanarak artık saniyeyi devre dışı bırakmak isteyebilirsiniz.

NİHAİ GÜNCELLEME:

Şey, ben çekirdek devi değilim, ama John Stultz'in yamasını burada tekrar gözden geçirdim: https://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h = 6b43ae8a619d17c4935c3320d2ef9e92bdeed05d

Bu sefer doğru okuyorsam, artık saniye uygulandığında başka bir kilitlenme olduğu konusunda yanılmışım. KB girişlerine göre bu, Red Hat'in görüşü gibi görünüyor. Ancak ntpd'yi devre dışı bıraktıysanız, 10 dakika daha devre dışı bırakın, böylece ntpd adjtimex'i çağırdığında kilitlenmeye girmezsiniz.

Yakında daha fazla hata olup olmadığını öğreneceğiz :)

POST-LEAP İKİNCİ GÜNCELLEME:

Son birkaç saatimi ntpd ve pre-patch (buggy) çekirdek kodunu okuyarak geçirdim ve burada çok yanlış olabilirken, neler olduğunu düşündüğümü açıklamaya çalışacağım:

İlk olarak, ntpd her zaman adjtimex'i (2) çağırır. Bunu, ntp_loopfilter.c dosyasında local_clock içinde tanımlanmış olan "saat döngüsü filtresinin" bir parçası olarak yapar. Bu kodu burada görebilirsiniz: http://www.opensource.apple.com/source/ntp/ntp-70/ntpd/ntp_loopfilter.c (ntp sürüm 4.2.6'dan).

Saat döngüsü filtresi oldukça sık çalışır - ntpd her zaman dakikada bir 17 dakika veya daha fazla olan akış yukarı sunucularını sorguladığında çalışır. Saat döngüsü filtresinin ilgili biti:

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

Ve sonra:

ntp_adjtime(&ntv)

Başka bir deyişle, artık bir saniyenin geçtiği günlerde, ntpd "STA_INS" bayrağını ayarlar ve adjtimex (2) öğesini çağırır (taşınabilirliği sarmalayıcısı aracılığıyla).

Bu sistem çağrısı çekirdeğe doğru ilerliyor. İşte ilgili çekirdek kodu: https://github.com/mirrors/linux/blob/a078c6d0e6288fad6d83fb6d5edd91ddb7b6ab33/kernel/time/ntp.c

Çekirdek codepath kabaca bu:

  • satır 663 - do_adjtimex rutininin başlangıcı.
  • satır 691 - mevcut artık saniye sayacını iptal edin.
  • satır 709 - ntp_lock çevirme kilidini tut (bu kilit olası livelock kazasında yer alır)
  • satır 724 - call process_adjtimex_modes.
  • satır 616 - call process_adj_status.
  • line 590 - adjtimex (2) çağrısında ayarlanan bayrakları temel alarak time_status global değişkenini ayarlayın
  • satır 592 - time_state global değişkenini kontrol eder. Çoğu durumda, ntp_start_leap_timer'i çağırın.
  • satır 554 - time_status global değişkenini kontrol eder. STA_INS ayarlanacaktır, bu yüzden time_state değerini TIME_INS olarak ayarlayın ve artık saniye sayacını başlatmak için hrtimer_start (başka bir çekirdek işlevi) çağırın. Bir zamanlayıcı oluşturma sürecinde, bu kod xtime_lock'u alır. eğer başka bir CPU zaten xtime_lock ve ntp_lock'u yakalamışsa bu gerçekleşirse , çekirdek çekirdeklenir. Bu yüzden John Stultz hrtimers kullanmaktan kaçınmak için yamayı yazdı. Bugün herkesin başına bela açıyordu.
  • satır 598 - eğer ntp_start_leap_timer bir sıçrama zamanlayıcıyı gerçekten başlatmadıysa, time_state değerini TIME_OK olarak ayarlayın
  • Satır 751 - Çekirdeğin livelock olmadığı varsayılırsa, yığın çözülür ve ntp_lock döndürme kilidi serbest bırakılır.

Burada birkaç ilginç şey var.

İlk olarak, satır 691, adjtimex (2) her çağrıldığında mevcut zamanlayıcıyı iptal eder. Ardından, 554 bu zamanlayıcıyı yeniden oluşturur. Bu, ntpd'nin saat döngüsü filtresini çalıştırdığı her seferde, buggy kodunun çağrıldığı anlamına gelir.

Bu nedenle, ntpd'nin artık ikinci bayrağı koyduktan sonra sistemin çökmeyeceğini söylediklerinde Red Hat'in yanlış olduğuna inanıyorum. Ntpd çalıştıran her sistemin, artık saniyeden 24 saat boyunca her 17 dakikada (veya daha fazla) canlı kalma potansiyeline sahip olduğuna inanıyorum. Bunun neden bu kadar çok sistemin düştüğünü de açıklayabileceğine inanıyorum; tek seferlik çökme şansının saatte 3 şansa kıyasla daha düşük olması muhtemeldir.

GÜNCELLEME: Red Hat'in https://access.redhat.com/knowledge/solutions/154713 adresindeki KB çözümünde , Red Hat mühendisleri aynı sonuca vardılar (ntpd çalışanı sürekli olarak buggy koduna çarpacaktı). Gerçekten de benden birkaç saat önce yaptılar. Bu çözüm https://access.redhat.com/knowledge/articles/15145 adresindeki ana makaleyle bağlantılı değildi , bu yüzden şimdiye kadar farketmedim.

İkincisi, bu, yüklü sistemlerin neden çökme ihtimalinin daha yüksek olduğunu açıklar. Yüklenen sistemler, daha fazla kesintilerle uğraşacak ve "do_tick" çekirdek işlevinin daha sık çağrılmasına neden olacak ve zamanlayıcı oluşturulurken bu kodun ntp_lock komutunu çalıştırma ve yakalama şansını vermiştir.

Üçüncüsü, artık saniye gerçekleştiğinde sistemin çökme şansı var mı? Emin değilim, ama muhtemelen evet, çünkü artık saniye ayarını ateşleyen ve gerçekten gerçekleştiren zamanlayıcı (388 satırındaki ntp_leap_second) aynı zamanda ntp_lock döndürme kilidini kapar ve hrtimer_add_expires_ns çağrısına sahiptir. Bu çağrının bir livelock'a da neden olup olamayacağını bilemiyorum, ama imkansız gözükmüyor.

Son olarak, ikinci saniye çalıştıktan sonra ikinci saniye bayrağının devre dışı kalmasına neden olan nedir? Buradaki cevap ntpd, adjteks (2) çağırdığında gece yarısından sonraki bir noktada artık bayrağın bayrağını ayarlamayı durduruyor. Bayrak ayarlanmadığından 554 satırındaki kontrol doğru olmaz ve hiçbir zamanlayıcı oluşturulmaz ve 598 satır time_state global değişkenini TIME_OK olarak sıfırlar. Bu, eğer sadece saniye saniye sonra bayrak işaretini adjtimex (8) ile kontrol ettiyseniz neden hala ikinci saniye bayrak setini göreceğinizi açıklar.

Kısacası, bugün için en iyi tavsiye, sonuçta ilk verdiğim gibi görünüyor: ntpd'yi devre dışı bırak ve artık ikinci bayrağı devre dışı bırak.

Ve bazı son düşünceler:

  • Linux satıcılarından hiçbiri John Stultz'in yamasını farketmedi ve onu çekirdeklerine uyguladı :(
  • John Stultz neden ihtiyaç duyduğu bazı satıcıları uyarmadı? belki de livelock'un şansı yeterince düşük gözüküyordu.
  • Artık saniye uygulandığında Java işlemlerinin kilitlendiğini veya döndüğünü duydum. Belki de Google’ın öncülüğünü izlemeli ve sistemimize artık saniye nasıl uygulayacağımızı yeniden düşünmeliyiz: http://googleblog.blogspot.com/2011/09/time-technology-and-leaping-seconds.html

06.02 John Stultz'dan Güncelleme:

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

Yazı, artık saniyenin futex zamanlayıcılarının CPU yükünü hızlandırarak erken ve sürekli olarak sona ermesine neden olduğu adım adım gözden geçirme içeriyordu.


7
Mükemmel cevap için teşekkürler. Yani sunucularımızın geri kalanı çökmeyi bekliyor. Güzel, hoş. Haddeleme yeniden başladı!
Bron Gondwana

3
adjtimexVerilip verilmediğini, çekirdeğin dmesg'de bir şey yazdığını nasıl anlarım ? Ntpd'yi kapatmadan önce çökmeyen bir sistemin çökmesi olasılığı nedir?
Hubert Kario,

3
Hubert: "adjtimex" i çalıştırın (genellikle ayrı olarak paketlenir) ve ikinci bekleyen bir sıçramayı belirtmek için bayrak 16'yı arayın.
Dominic Cleal

22
Temsilcilerden nefret edeceksin.
Wesley

26
@WesleyDavid: Endişeye gerek yok, rep cap UTC'de gece yarısı sıfırlanacak. Olabilir.
mmyers

33

Bu bizi çok etkiledi. Çoğu ana bilgisayarımızı yeniden başlattıktan sonra, aşağıdakiler ana bilgisayar yeniden başlatması olmadan utanç verici derecede basit ve tamamen etkili olduğu ortaya çıktı:

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

Tek gereken sistem saatini sıfırlamak. Sheesh. Bunu altı saat önce bildiğim için verdiklerimi.


8
date -s "`date`"benim için çalıştı.
Pointy

@ DeanB: Ben saatini sıfırlamak hile yapar, ne yazık ki bu biraz zaman aldı, saat 3 UTC gönderdi. Sunucuları da yeniden başlatmaya başladık
Gregor

24

Çekirdeğin zaman durumu alanındaki ikinci sıçramayı temizleyen basit bir C programı:

#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;
}

Farklı kaydet lsec.c, derle gcc -Wall -Wextra -o lsec lsec.cve root olarak çalıştır.

Büyük olasılıkla çalıştırmadan önce ntpd'yi durdurmak ve artık saniye sonra ntpd'yi yeniden başlatmak isteyeceksiniz.


Ne (void) argc;başarır? Kullanılmayan değişken için uyarıyı susturmak? Kullanarak int main()aynı şeyi olmaz mıydı? Bilgi sahibi olmaya çalışmıyorum, gerçekten merak ediyorum.
ebeveyni

18

Postmortem göründüğü gibi. / Ls bir etkisi yoktur.

Gördüğümüz şey CPU kullanan çok sayıda softirqd işlemidir (genellikle java işlemlerinin yüküne doğrusaldır)

POSTMORTEM'i, ntp tarafından zaten uygulanmış olan artık saniye ile düzeltmek için ne işe yarar:

Sadece sorun çıkarması yeterli gözüküyor:

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

Bu, ntpd yeniden başlatılmadan veya yeniden başlatılmadan yükü azaltmalıdır. Alternatif olarak:

apt-get install ntpdate
/etc/init.d/ntpd stop; ntpdate pool.ntp.org; /etc/init.d/ntpd start

Neden sntp -sdeğil ntpdate?
errordeveloper

ntpdate burada sntp yapmak için sadece bir sarmalayıcıdır, ntpdate'i kullanmak da iyidir.
Gregor,

ah ben tamamen özledim sıkmak için bir ikili paketi var bir ntpdate paketi var. Bunu eklemek için gönderimi değiştirdim.
Gregor,

Bu sorunu gidermeye ilişkin benzer raporlar da duydum (kullanma gibi date -s). Düzeltme, yalnızca çevirmek yerine sistem saatini ayarlamayı gerektirir (ofset küçükken varsayılan ntpd davranışı). Zaman ayarının çekirdeğin dahili zaman tutma mekanizmasının kendilerini sıfırlamasına neden olduğunu tahmin ediyorum.
Patrick

4
Java uygulamalarım CPU kullanımını da arttırdı (softirqd'de harcanan yüksek CPU zamanıyla).
Hubert Kario

16

http://my.opera.com/marcomarongiu/blog/2012/03/12/no-step-back , Debian sıkma çekirdeğinin artık sıçramanın üstesinden gelmeyeceğini gösteriyor.

Comp.protocols.tim.ntp'daki bu konu ayrıca ilgi çekicidir: https://groups.google.com/forum/?fromgroups#!topic/comp.protocols.time.ntp/KSflIgjUdPE

Yani, artık saniye henüz gerçekleşmedi: 23:59:60 UTC

Son olarak, https://access.redhat.com/knowledge/articles/15145 şunu söyler: "Artık saniye gerçekleştiğinde, çekirdek sistem günlüğüne bir ileti yazdırır. Bu iletinin yazdırılması olasılığı vardır Red Hat Enterprise Linux'ta çekirdeğin çökmesine neden olabilir. "


Fakat 3.2.21 çekirdeği, muhtemelen - kaza yapan makinelerin en az birinin çalıştığı şeydi
Bron Gondwana,

Bron'un belirttiği bu makinelerin birçoğunda, yaklaşmakta olan sıçramayı ikinci kez doğru bir şekilde halletmesi gereken bir düzeltme yaptık.
Cosimo

Düzeltmeyi bir yere gönderebilir misiniz?
kargig

Bir fikrim yok ... Sadece bilgi topluyorum. Belki de bunu asıl soruya karşı bir yorum olarak koymalıydım.
Luca Filipozzi

4
my.opera.com/marcomarongiu/blog/2012/06/01/… bunu düzeltmekle ilgili daha fazla ayrıntı içeriyor
Bron Gondwana,
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.