Назад | Перейти на главную страницу

Кто-нибудь еще сталкивался с высокими показателями сбоев сервера Linux в течение второго дня?

* ПРИМЕЧАНИЕ: если на вашем сервере все еще есть проблемы из-за перепутанных ядер, и вы не можете перезагрузиться - самое простое решение, предлагаемое с установкой gnu date в вашей системе: date -s now. Это приведет к сбросу внутренней переменной ядра "time_was_set" и исправлению циклов фьютексов процессора в 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 г. - начало дня сразу после начала дня по Гринвичу. У нас было несколько серверов в разных центрах обработки данных, которыми управляют разные команды, и все они гаснут - не отвечают на пинги, экран пустой.

Все они работают под управлением Debian Squeeze - от стандартного ядра до пользовательских сборок 3.2.21. Большинство из них - это блейд-серверы 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 это просто установить время самостоятельно, что предположительно также очистит счетчик високосных секунд.

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

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

ОБНОВЛЕНИЕ: у Red Hat есть вторая статья в базе знаний только по этой проблеме: 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 обновила свою статью в базе знаний, указав: «Клиенты RHEL 6 могут столкнуться с известной проблемой, которая заставляет NMI Watchdog обнаруживать зависание при получении объявления о леапсекунде NTP. Эта проблема своевременно устраняется. Если ваши системы получили сообщение о високосной секунде и не испытывали этой проблемы, то они больше не затронуты ".

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

Однако изменение кода в сообщении LKML инженера IBM Джона Стульца отмечает, что при фактическом применении секунды координации может также возникнуть тупик, поэтому вы можете отключить секунду координации путем перезагрузки или использования 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 (глючный), и хотя я могу ошибаться здесь, я попытаюсь объяснить, что, по моему мнению, происходит:

Во-первых, 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

Путь к коду ядра примерно такой:

  • строка 663 - начало подпрограммы do_adjtimex.
  • строка 691 - отменить любой существующий таймер секунды координации.
  • строка 709 - захватить спин-блокировку ntp_lock (эта блокировка участвует в возможном сбое livelock)
  • строка 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, затем блокируется ядро. вот почему Джон Стульц написал патч, чтобы избежать использования таймеров. Это то, что доставляло всем сегодня неприятности.
  • строка 598 - если ntp_start_leap_timer на самом деле не запускал таймер прыжка, установите time_state в TIME_OK
  • строка 751 - при условии, что ядро ​​не находится в режиме livelock, стек разматывается и спин-блокировка 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

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

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

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

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

Простая программа на 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 после дополнительной секунды.

Postmortem кажется ./lsec не дает никакого эффекта.

То, что мы видим, - это множество процессов softirqd, потребляющих CPU (обычно линейно в зависимости от загрузки 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

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».