Вопрос: Кто-нибудь еще сталкивается с высокими темпами сбоя Linux-сервера во время прыжка на второй день?


* ПРИМЕЧАНИЕ. Если ваш сервер по-прежнему имеет проблемы из-за запутанных ядер, и вы не можете перезагрузиться - самое простое решение, предлагаемое с установленной в вашей системе датой gnu: date -s now. Это приведет к сбросу внутренней переменной «time_was_set» ядра и исправлению петли futex процессора в java и других инструментах пользовательского пространства. Я прервал эту команду в своей собственной системе, подтвердил, что она делает то, что она говорит на олове *

POSTMORTEM

Anticlimax: единственная вещь, которая умерла, была моей связью VPN (openvpn) с кластером, поэтому было несколько захватывающих секунд, пока она была восстановлена. Все остальное было хорошо, и запуск ntp прошел чисто после того, как прошел второй прыжок.

Я написал свой полный опыт дня в http://blog.fastmail.fm/2012/07/03/a-story-of-leaping-seconds/

Если вы посмотрите блог Марко на http://my.opera.com/marcomarongiu/blog/2012/06/01/an-humble-attempt-to-work-around-the-leap-second - У него есть решение для фазирования изменения времени в течение 24 часов с помощью ntpd -x, чтобы избежать 1-секундного пропуска. Это альтернативный метод смазывания для запуска вашей собственной инфраструктуры ntp.


Только сегодня, суббота, 30 июня 2012 г. - начало скоро после начала дня GMT. У нас было несколько серверов в разных центрах обработки данных, которые управляются разными командами, все темнеет - не реагирует на звонки, экран пуст.

Все они работают с Debian Squeeze - от всего ядра от обычного ядра до настраиваемых 3.2.21 сборок. Большинство из них - blade-серверы Dell M610, но я также потерял Dell R510, а другие отделы также потеряли машины от других производителей. Был также старый IBM x3550, который разбился и который, как я думал, может быть не связан, но теперь мне интересно.

Одна авария, которую я получил, дал свалку экрана из сказанного:

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

К сожалению, у лезвий, по-видимому, было настроено kdump, но они так сильно погибли, что kdump не срабатывал - и они включили консольное гашение. Теперь я отключил консольное гашение, так что пальцы скрещены. У меня будет дополнительная информация после следующего сбоя.

Просто хочу знать, является ли это обычной нитью или «просто нами». Странно, что они разные подразделения в разных центрах обработки данных, которые покупаются в разное время и управляются разными администраторами (я запускаю FastMail.FM) ... и теперь даже другое оборудование поставщика. Большинство машин, которые разбились, работали в течение недель / месяцев и запускали ядра 3.1 или 3.2 серии.

Самая последняя авария была машиной, которая работала всего на 6 часов 3.2.21.

ПРОГРАММА

Ок, люди, вот как я работал вокруг.

  1. отключено ntp: /etc/init.d/ntp stop
  2. созданный http://linux.brong.fastmail.fm/2012-06-30/fixtime.pl (код, украденный у Марко, см. записи в блогах в комментариях)
  3. побежал fixtime.pl без аргумента, чтобы увидеть, что был второй шаг в прыжке
  4. побежал fixtime.pl с аргументом, чтобы удалить второй прыжок

ПРИМЕЧАНИЕ: зависит от adjtimex, Я поставил копию сжимания adjtimex двоичный http://linux.brong.fastmail.fm/2012-06-30/adjtimex - он будет работать без зависимостей от сжатия 64-битной системы. Если вы поместите его в тот же каталог, что и fixtime.pl, он будет использоваться, если система отсутствует. Очевидно, если вы не сжимаете 64-битный ... найдите свой собственный.

Я собираюсь начать ntp снова завтра.

Как анонимный пользователь предложил - альтернативу запуску adjtimex это просто установить время самостоятельно, что, по-видимому, также очистит счетчик leapsecond.


366
2018-06-30 16:15


Источник


Сегодня есть прыжок второй, 30-й. Я не решаюсь предположить, что это ваша проблема, но я буду внимательно следить за моими машинами Debian. - jscott
с утра. Мы потеряли по меньшей мере 9 различных ящиков с debian от различных поставщиков, все запущенные ядра сжимают ядро ​​2.6.32. мы также не смогли получить аварийную свалку из-за пускового гашения ... - kargig
Сообщение lkml об этом lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html - Daniel S. Sterling
Спасибо, что сообщили об этом! Я сейчас очень внимательно смотрю на свои серверы. - Janne Pikkarainen
В потоке LKML указано, что date -s "`date`" помогает - это, безусловно, помогло мне. - Pointy


Ответы:


Это вызвано livelock, когда ntpd вызывает adjtimex (2), чтобы сообщить ядру вставить секунду прыжка. См. Публикацию lkml http://lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html

Red Hat также должен обновлять свою статью в KB. https://access.redhat.com/knowledge/articles/15145

UPDATE: у Red Hat есть вторая статья в KB для этой проблемы: https://access.redhat.com/knowledge/solutions/154713 - предыдущая статья предназначена для более ранней, несвязанной проблемы

Обход - это просто отключить ntpd. Если ntpd уже выпустил вызов adjtimex (2), вам может потребоваться отключить ntpd и перезагрузить, чтобы быть на 100% безопасным.

Это влияет на RHEL 6 и другие дистрибутивы с новыми ядрами (новее, чем приблизительно 2.6.26), но не RHEL 5.

Причина, по которой это происходит до на самом деле запланирован переход на скачок, так это то, что ntpd позволяет ядру обрабатывать прыжок второй в полночь, но ему необходимо предупредить ядро, чтобы вставить прыжок второй до полуночи. Поэтому ntpd вызывает adjtimex (2) когда-нибудь в течение дня скачка, после чего эта ошибка запускается.

Если у вас установлено adjtimex (8), вы можете использовать этот скрипт, чтобы определить, установлен ли флаг 16. Флаг 16 - «вставка секунды прыжка»:

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

ОБНОВИТЬ:

Red Hat обновила свою статью в KB, чтобы отметить: «Клиенты RHEL 6 могут быть затронуты известной проблемой, которая заставляет NMI Watchdog обнаруживать зависание при получении анонса leapsecond NTP. Эта проблема решается своевременно. объявление leapsecond и не испытывало этой проблемы, тогда они больше не затрагиваются ».

ОБНОВЛЕНИЕ: вышеупомянутый язык был удален из статьи Red Hat; и было добавлено второе решение KB, в котором подробно описывается проблема сбоя adjtimex (2): https://access.redhat.com/knowledge/solutions/154713

Тем не менее, изменение кода в сообщении LKML от IBM Engineer John Stultz отмечает, что также может возникнуть тупик, когда фактически применяется скачок, поэтому вы можете отключить скачок второй путем перезагрузки или использовать adjtimex (8) после отключения ntpd.

ЗАКЛЮЧИТЕЛЬНОЕ ОБНОВЛЕНИЕ:

Ну, я не разработчик ядра, но я снова рассмотрел патч Джона Штутца: https://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=6b43ae8a619d17c4935c3320d2ef9e92bdeed05d

Если на этот раз я его правильно прочитал, я ошибался, когда был применен другой тупик, когда применяется второй прыжок. Это похоже на мнение Red Hat, основываясь на их записи в КБ. Однако если вы отключили ntpd, отключите его еще на 10 минут, чтобы вы не попали в тупик, когда ntpd вызывает adjtimex (2).

Мы выясним, скоро ли будет больше ошибок :)

ВТОРОЕ ОБНОВЛЕНИЕ ПОСТ-ЛЕЕВ:

Последние несколько часов я читал через код ядра ntpd и pre-patch (buggy), и, хотя я могу быть очень не прав, я попытаюсь объяснить, что я думаю:

Во-первых, ntpd вызывает adjtimex (2) все время. Он делает это как часть своего «фильтра петли часов», определенного в local_clock в ntp_loopfilter.c. Вы можете увидеть этот код здесь: http://www.opensource.apple.com/source/ntp/ntp-70/ntpd/ntp_loopfilter.c (из ntp версии 4.2.6).

Фильтр синхронизации часов работает довольно часто - он запускается каждый раз, когда ntpd опросает свои восходящие серверы, которые по умолчанию - каждые 17 минут или более. Соответствующим битом фильтра синхронизации часов является:

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

А потом:

ntp_adjtime(&ntv)

Другими словами, в дни, когда есть секунда скачка, ntpd устанавливает флаг «STA_INS» и вызывает adjtimex (2) (через свою переносимость-обертку).

Этот системный вызов пробивается к ядру. Вот соответствующий код ядра: https://github.com/mirrors/linux/blob/a078c6d0e6288fad6d83fb6d5edd91ddb7b6ab33/kernel/time/ntp.c

Ядро codepath примерно следующее:

  • строка 663 - начало процедуры do_adjtimex.
  • строка 691 - отменить любой существующий секундомер.
  • строка 709 - захватить спин-блокировку ntp_lock (эта блокировка задействована в возможном сбое в работе)
  • строка 724 - вызов process_adjtimex_modes.
  • строка 616 - вызов process_adj_status.
  • строка 590 - установить глобальную переменную time_status на основе флагов, установленных в вызове adjtimex (2)
  • строка 592 - проверить глобальную переменную time_state. в большинстве случаев вызовите ntp_start_leap_timer.
  • строка 554 - проверить глобальную переменную time_status. STA_INS будет установлен, поэтому установите time_state в TIME_INS и вызовите hrtimer_start (другая функция ядра), чтобы запустить секундомер второго уровня. в процессе создания таймера этот код захватывает xtime_lock. если это произойдет, когда другой процессор уже захватил xtime_lock а также ntp_lock, затем ядро ​​livelocks. поэтому Джон Стулц написал патч, чтобы избежать использования hrtimers. Это то, что вызывало у всех сегодня проблемы.
  • строка 598 - если ntp_start_leap_timer фактически не запускает таймер прыжка, установите time_state в TIME_OK
  • line 751 - при условии, что ядро ​​не работает, стек разворачивается, и отключается spinlock ntp_lock.

Здесь есть пара интересных вещей.

Во-первых, строка 691 отменяет существующий таймер каждый раз, когда вызывается adjtimex (2). Затем 554 повторно создает этот таймер. Это означает, что каждый раз, когда ntpd запускает свой фильтр синхронизации часов, вызывается код ошибки.

Поэтому я считаю, что Red Hat ошибалась, когда они говорили, что, как только ntpd установил флаг прыжков, система не потерпит крах. Я полагаю, что каждая система, работающая под управлением ntpd, имела потенциал для оживления каждые 17 минут (или более) для 24-часового периода до прыжка-секунды. Я считаю, что это также может объяснить, почему так много систем разбилось; вероятность однократного сбоя будет гораздо менее вероятна, чем 3 шанса в час.

ОБНОВЛЕНИЕ: в решении Red Hat KB на https://access.redhat.com/knowledge/solutions/154713 , Инженеры Red Hat пришли к такому же выводу (что запуск ntpd будет постоянно ударять по багги-коду). И действительно, они сделали это за несколько часов до этого. Это решение не было связано с основной статьей https://access.redhat.com/knowledge/articles/15145 , поэтому я этого не замечал до сих пор.

Во-вторых, это объясняет, почему загруженные системы с большей вероятностью будут разбиваться. Загруженные системы будут обрабатывать больше прерываний, в результате чего функция ядра do_tick будет вызываться чаще, что дает больше шансов для запуска этого кода и захвата ntp_lock во время создания таймера.

В-третьих, есть ли вероятность сбоя системы, когда действительно произойдет прыжок? Я не знаю точно, но, возможно, да, потому что таймер, который запускает и фактически выполняет настройку скачкообразной перестройки (ntp_leap_second, строка 388), также захватывает спин-блокировку ntp_lock и имеет вызов hrtimer_add_expires_ns. Я не знаю, может ли этот вызов вызвать ожидание, но это не кажется невозможным.

Наконец, что приводит к отключению флага прыжка-секунды после прогона прыжка? Ответ: ntpd останавливает установку знака прыжка в какой-то момент после полуночи, когда он вызывает adjtimex (2). Поскольку флаг не установлен, строка проверки 554 будет недействительной, и таймер не будет создан, а строка 598 сбросит глобальную переменную time_state на TIME_OK. Это объясняет, почему, если вы проверили флаг с помощью adjtimex (8) сразу после второго прыжка, вы все равно увидите установленный флаг прыжков.

Короче говоря, лучший совет на сегодняшний день кажется первым, что я дал в конце концов: отключить ntpd и отключить флаг прыжков.

И некоторые последние мысли:

  • ни один из поставщиков Linux не заметил патча Джона Штутца и применил его к своим ядрам :(
  • почему Джон Стальц не предупредил некоторых продавцов, что это было необходимо? возможно, шанс на ожидание казался достаточно низким, чтобы шум не был оправдан.
  • Я слышал, как отчеты о процессах Java блокировались или вращались при применении прыжковой секунды. Возможно, нам следует следовать руководству Google и переосмыслить, как мы применяем скачки в наших системах: http://googleblog.blogspot.com/2011/09/time-technology-and-leaping-seconds.html

06/02 Обновление от Джона Стулца:

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

Сообщение содержало пошаговое описание того, почему второй шаг заставил таймеры futex истекать преждевременно и непрерывно, что привело к загрузке процессора.


322
2018-06-30 19:56



Спасибо за отличный ответ. Таким образом, остальные наши серверы сидят, ожидая аварии. Прекрасный. Роллинг начинается здесь, мы приходим! - Bron Gondwana
Как узнать, adjtimex было выпущено, ядро ​​печатает что-то в dmesg? Какой шанс, что система, которая не сработала, прежде чем отключить ntpd, рухнет? - Hubert Kario
Hubert: запустите «adjtimex» (обычно он упакован отдельно) и найдите флаг 16, чтобы указать, что второй второй ожидается. - Dominic Cleal
Вы будете ненавидеть репутацию. - Wesley
@WesleyDavid: Не стоит беспокоиться, колпачок будет сброшен в полдень в UTC. Может быть. - mmyers


Это сильно ударило нас. После перезагрузки многих наших хостов следующее оказалось неловко простым и полностью эффективным без перезапуска хоста:

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

Все, что требуется, это сбросить системные часы. Sheesh. То, что я дал, знал это шесть часов назад.


33
2017-07-01 07:49



date -s "`date`" работал на меня. - Pointy
@DeanB: Я опубликовал в 3 часа ночи UTC, что сброс часов делает трюк, к сожалению, потребовалось некоторое время, чтобы получить модерацию. Мы также начали перезагружать серверы - Gregor


Простая программа на C, которая очищает второй бит второго уровня в поле состояния времени ядра:

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

Сохранить как lsec.c, скомпилировать с gcc -Wall -Wextra -o lsec lsec.c и выполняются как root.

Скорее всего, вы захотите остановить ntpd перед запуском и перезапустить ntpd после второго прыжка.


24
2018-06-30 23:13



Что значит (void) argc; достичь? Заблокировать предупреждение для неиспользуемой переменной? Не использовал бы int main() выполнить то же самое? Не пытаясь быть педантом, мне действительно любопытно. - gparent


Кажется, посмертное кажется ./lsec не имеет эффекта.

То, что мы видим, - это много процессов softirqd, в которых используется процессор (обычно линейный для загрузки java-процессов)

Что работает, чтобы исправить POSTMORTEM со скачкообразными секундами, уже примененными ntp, является следующее:

Кажется, достаточно просто выпустить:

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

Это должно уменьшить нагрузку без перезагрузки или перезагрузки ntpd. В качестве альтернативы вы можете указать:

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

18
2017-07-01 03:41



Зачем sntp -s и не ntpdate? - errordeveloper
ntpdate - это всего лишь оболочка для sntp здесь, конечно, хорошо использовать ntpdate. - Gregor
а я полностью пропустил, есть пакет ntpdate для сжатия, где он фактически является двоичным. Я отредактировал мое сообщение, чтобы включить это. - Gregor
Я слышал подобные сообщения об устранении этой проблемы (например, использование date -s). Похоже, что исправление просто требует установки системного времени вместо его поворота (поведение по умолчанию ntpd при небольшом смещении). Я предполагаю, что установка времени заставляет внутреннюю механику учета времени ядра перезагружать себя. - Patrick
Я также использовал процессорное приложение для Java-приложений (с большим количеством процессорного времени, потраченного на softirqd), это исправило это. - Hubert Kario


http://my.opera.com/marcomarongiu/blog/2012/03/12/no-step-back похоже, указывает, что ядро ​​сжимания Debian не будет обрабатывать секунды прыжка.

Этот поток на comp.protocols.tim.ntp представляет интерес, также: https://groups.google.com/forum/?fromgroups#!topic/comp.protocols.time.ntp/KSflIgjUdPE

Тем не менее, скачок второй еще не произошел: 23:59:60 UTC

В заключение, https://access.redhat.com/knowledge/articles/15145 должен сказать следующее: «Когда происходит скачок, ядро ​​печатает сообщение в системном журнале. Существует вероятность того, что печать этого сообщения может привести к сбою ядра в Red Hat Enterprise Linux».


17
2018-06-30 18:47



Но ядро ​​3.2.21 должно, предположительно, - это то, что работает хотя бы одна из разбитых машин - Bron Gondwana
На некоторых из тех машин, которые Брон указывал, мы фактически выпустили исправление, которое должно правильно обработать предстоящий прыжок второй. - cosimo
можете ли вы опубликовать исправление где-нибудь, чтобы другие могли просмотреть / предложить идеи / попробовать? - kargig
У меня нет исправления ... Я просто собираю информацию. Возможно, следовало бы поставить это как комментарий к исходному вопросу. - Luca Filipozzi
my.opera.com/marcomarongiu/blog/2012/06/01/... содержит более подробную информацию об их устранении - Bron Gondwana