Bất cứ ai khác trải qua tốc độ cao của máy chủ Linux gặp sự cố trong một ngày thứ hai nhảy vọt?


365

* LƯU Ý: nếu máy chủ của bạn vẫn gặp sự cố do các hạt nhân bị nhầm lẫn và bạn không thể khởi động lại - giải pháp đơn giản nhất được đề xuất với ngày gnu được cài đặt trên hệ thống của bạn là: date -s now. Điều này sẽ thiết lập lại biến "time_was_set" bên trong của kernel và sửa lỗi CPU lặp lại các vòng lặp Futex trong java và các công cụ không gian người dùng khác. Tôi đã thực hiện lệnh này trên hệ thống của riêng mình và xác nhận rằng nó đang thực hiện những gì nó nói trên tin *

BÀI VIẾT

Anticlimax: điều duy nhất đã chết là liên kết VPN (openvpn) của tôi với cụm, vì vậy có một vài giây thú vị trong khi nó được thiết lập lại. Mọi thứ khác đều ổn, và khởi động ntp diễn ra sạch sẽ sau khi bước nhảy vọt thứ hai trôi qua.

Tôi đã viết lên trải nghiệm đầy đủ của mình trong ngày tại http://blog.fastmail.fm/2012/07/03/a-story-of-leaping-seconds/

Nếu bạn xem blog của Marco tại http://my.opera.com/marcomarongiu/blog/2012/06/01/an-humble-atteem-to-work-around-the-leap-second - anh ấy có một giải pháp cho giảm dần thời gian thay đổi trong 24 giờ bằng cách sử dụng ntpd -x để tránh bỏ qua 1 giây. Đây là một phương pháp bôi nhọ thay thế để chạy cơ sở hạ tầng ntp của riêng bạn.


Chỉ hôm nay, Thứ bảy ngày 30 tháng 6 năm 2012 - bắt đầu ngay sau khi bắt đầu ngày GMT. Chúng tôi đã có một số ít máy chủ ở các trung tâm dữ liệu khác nhau do các đội khác nhau quản lý đều chìm trong bóng tối - không phản hồi với ping, màn hình trống.

Tất cả đều đang chạy Debian Squeeze - với mọi thứ từ kernel stock đến các bản dựng 3.2,21 tùy chỉnh. Hầu hết là các lưỡi Dell M610, nhưng tôi cũng vừa mất một chiếc Dell R510 và các bộ phận khác cũng bị mất máy từ các nhà cung cấp khác. Ngoài ra còn có một chiếc IBM x3550 cũ hơn đã bị hỏng và tôi nghĩ có thể không liên quan, nhưng bây giờ tôi đang tự hỏi.

Một sự cố mà tôi đã nhận được một màn hình từ nói:

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

Thật không may, tất cả các lưỡi được cho là đã được cấu hình kdump, nhưng chúng đã chết rất mạnh đến nỗi kdump không kích hoạt - và chúng đã được bật giao diện điều khiển. Bây giờ tôi đã vô hiệu hóa giao diện điều khiển trống, vì vậy các ngón tay vượt qua tôi sẽ có thêm thông tin sau vụ tai nạn tiếp theo.

Chỉ muốn biết nếu đó là một chủ đề chung hoặc "chỉ chúng tôi". Thật kỳ lạ khi chúng là các đơn vị khác nhau trong các trung tâm dữ liệu khác nhau được mua tại các thời điểm khác nhau và được điều hành bởi các quản trị viên khác nhau (tôi chạy các đơn vị FastMail.FM) ... và bây giờ thậm chí là phần cứng của nhà cung cấp khác nhau. Hầu hết các máy bị hỏng đã hoạt động trong nhiều tuần / tháng và đang chạy các hạt nhân 3.1 hoặc 3.2.

Sự cố gần đây nhất là một chiếc máy chỉ mới chạy được khoảng 6 giờ chạy 3.2,21.

CÔNG VIỆC

Mọi người, đây là cách tôi làm việc xung quanh nó.

  1. ntp bị vô hiệu hóa: /etc/init.d/ntp stop
  2. đã tạo http://linux.brong.fastmail.fm/2012-06-30/fixtime.pl (mã bị đánh cắp từ Marco, xem bài đăng trên blog trong phần bình luận)
  3. chạy fixtime.plmà không có đối số để thấy rằng có một bước nhảy vọt thứ hai
  4. chạy fixtime.plvới một đối số để loại bỏ bước nhảy vọt thứ hai

LƯU Ý: phụ thuộc vào adjtimex. Tôi đã đặt một bản sao của adjtimexnhị phân nén tại http://linux.brong.fastmail.fm/2012-06-30/adjtimex - nó sẽ chạy mà không phụ thuộc vào hệ thống nén 64 bit. Nếu bạn đặt nó trong cùng thư mục fixtime.pl, nó sẽ được sử dụng nếu hệ thống không có mặt. Rõ ràng nếu bạn không siết chặt 64-bit thì hãy tự tìm.

Tôi sẽ bắt đầu ntplại vào ngày mai.

Như một người dùng ẩn danh đã đề xuất - một giải pháp thay thế cho việc chạy adjtimexlà chỉ tự đặt thời gian, điều này có lẽ cũng sẽ xóa bộ đếm bước nhảy vọt.


58
Có một bước nhảy vọt thứ hai ngày hôm nay, ngày 30. Tôi ngần ngại ám chỉ đó là vấn đề của bạn, nhưng tôi sẽ theo dõi chặt chẽ các máy Debian của mình.
jscott

2
kể từ buổi sáng, chúng tôi đã mất ít nhất 9 hộp bóp debian khác nhau từ các nhà cung cấp khác nhau, tất cả đều chạy kernel bóp 2.6.32 kernel. chúng tôi cũng không thể có được một bãi chứa sự cố do trống giao diện điều khiển ...
kargig


2
Cảm ơn đã báo cáo này! Bây giờ tôi đang nhìn chằm chằm vào máy chủ của mình rất, rất chặt chẽ.
Janne Pikkarainen

5
Chủ đề LKML chỉ ra rằng có date -s "`date`"ích - nó chắc chắn đã giúp tôi.
Pointy

Câu trả lời:


321

Điều này được gây ra bởi một livelock khi ntpd gọi adjtimex (2) để báo cho kernel chèn một bước nhảy vọt thứ hai. Xem lkml đăng http://lkml.indiana.edu/hypermail/linux/kernel/1203.1/04598.html

Red Hat cũng nên cập nhật bài viết KB của họ. https://access.redhat.com/ledgeledge/articles/15145

CẬP NHẬT: Red Hat có một bài viết KB thứ hai chỉ dành cho vấn đề này tại đây: https://access.redhat.com/ledgeledge/solutions/154713 - bài viết trước dành cho một vấn đề không liên quan trước đó

Cách giải quyết là tắt ntpd. Nếu ntpd đã ban hành lệnh gọi adjtimex (2), bạn có thể cần phải tắt ntpd và khởi động lại để an toàn 100%.

Điều này ảnh hưởng đến RHEL 6 và các bản phát hành khác chạy hạt nhân mới hơn (mới hơn khoảng 2,6,26), nhưng không ảnh hưởng đến RHEL 5.

Lý do điều này xảy ra trước khi bước nhảy vọt thứ hai thực sự được lên kế hoạch là vì ntpd cho phép hạt nhân xử lý bước nhảy vọt thứ hai vào lúc nửa đêm, nhưng cần cảnh báo hạt nhân để chèn bước nhảy vọt thứ hai trước nửa đêm. Do đó, ntpd gọi adjtimex (2) đôi khi trong ngày của bước nhảy vọt thứ hai, tại thời điểm này, lỗi này được kích hoạt.

Nếu bạn đã cài đặt adjtimex (8), bạn có thể sử dụng tập lệnh này để xác định xem cờ 16 có được đặt không. Cờ 16 là "chèn bước nhảy vọt thứ hai":

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

CẬP NHẬT:

Red Hat đã cập nhật bài viết KB của họ để lưu ý: "Khách hàng của RHEL 6 có thể bị ảnh hưởng bởi một sự cố đã biết khiến NMI Watchdog phát hiện bị treo khi nhận được thông báo nhảy vọt NTP. Vấn đề này được giải quyết kịp thời. Nếu hệ thống của bạn nhận được thông báo bước nhảy vọt và không gặp phải vấn đề này, sau đó họ không còn bị ảnh hưởng nữa. "

CẬP NHẬT: Ngôn ngữ trên đã bị xóa khỏi bài viết Red Hat; và một giải pháp KB thứ hai đã được thêm vào chi tiết về sự cố sự cố của adjtimex (2): https://access.redhat.com/ledgeledge/solutions/154713

Tuy nhiên, thay đổi mã trong bài viết LKML của Kỹ sư IBM John Stultz lưu ý rằng cũng có thể có sự bế tắc khi bước nhảy vọt thứ hai thực sự được áp dụng, do đó bạn có thể muốn vô hiệu hóa bước nhảy vọt thứ hai bằng cách khởi động lại hoặc sử dụng adjtimex (8) sau khi vô hiệu hóa ntpd.

CẬP NHẬT CUỐI CÙNG:

Chà, tôi không phải là nhà phát triển kernel, nhưng tôi đã xem lại bản vá của John Stultz tại đây: https://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h = 6b43ae8a619d17c4935c3320d2ef9e92bdeed05d

Nếu tôi đọc nó đúng lúc này, tôi đã sai về việc có một bế tắc khác khi bước nhảy vọt thứ hai được áp dụng. Đó dường như cũng là ý kiến ​​của Red Hat, dựa trên mục nhập KB của họ. Tuy nhiên, nếu bạn đã tắt ntpd, hãy tắt nó thêm 10 phút nữa để bạn không gặp bế tắc khi ntpd gọi adjtimex (2).

Chúng tôi sẽ tìm ra nếu có thêm bất kỳ lỗi nào sớm :)

CẬP NHẬT THỨ HAI SAU:

Tôi đã dành vài giờ qua để đọc mã hạt nhân ntpd và tiền vá lỗi (lỗi) và trong khi tôi có thể rất sai ở đây, tôi sẽ cố gắng giải thích những gì tôi nghĩ đang xảy ra:

Đầu tiên, ntpd gọi adjtimex (2) mọi lúc. Nó thực hiện điều này như là một phần của "bộ lọc vòng lặp đồng hồ", được định nghĩa trong local_clock trong ntp_loopfilter.c. Bạn có thể xem mã đó tại đây: http://www.opensource.apple.com/source/ntp/ntp-70/ntpd/ntp_loopfilter.c (từ phiên bản ntp 4.2.6).

Bộ lọc vòng lặp đồng hồ chạy khá thường xuyên - nó chạy mỗi lần ntpd thăm dò các máy chủ ngược dòng của nó, theo mặc định là cứ sau 17 phút trở lên. Bit có liên quan của bộ lọc vòng lặp đồng hồ là:

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

Và sau đó:

ntp_adjtime(&ntv)

Nói cách khác, vào những ngày có bước nhảy vọt thứ hai, ntpd sẽ đặt cờ "STA_INS" và gọi adjtimex (2) (thông qua trình bao bọc tính di động của nó).

Cuộc gọi hệ thống đó thực hiện theo cách của nó đến kernel. Đây là mã hạt nhân có liên quan: https://github.com/mirrors/linux/blob/a078c6d0e6288fad6d83fb6d5edd91ddb7b6ab33/kernel/time/ntp.c

Codepath hạt nhân đại khái là thế này:

  • dòng 663 - bắt đầu thói quen do_adjtimex.
  • dòng 691 - hủy bỏ bất kỳ bộ đếm thời gian nhảy vọt thứ hai hiện có.
  • dòng 709 - lấy spinlock ntp_lock (khóa này có liên quan đến sự cố livelock có thể xảy ra)
  • dòng 724 - gọi process_adjtimex_modes.
  • dòng 616 - gọi process_adj_status.
  • dòng 590 - đặt biến toàn cục time_status, dựa trên các cờ được đặt trong lệnh gọi của adjtimex (2)
  • dòng 592 - kiểm tra biến toàn cục time_state. trong hầu hết các trường hợp, hãy gọi ntp_start_leap_timer.
  • dòng 554 - kiểm tra biến toàn cục time_status. STA_INS sẽ được đặt, vì vậy hãy đặt time_state thành TIME_INS và gọi hrtimer_start (một hàm nhân khác) để bắt đầu bộ đếm thời gian nhảy vọt thứ hai. trong quá trình tạo bộ đếm thời gian, mã này lấy xtime_lock. nếu điều này xảy ra trong khi một CPU khác đã lấy xtime_lock ntp_lock, thì kernel sẽ hoạt động. đây là lý do tại sao John Stultz đã viết bản vá để tránh sử dụng hrtimers. Đây là những gì đã gây ra tất cả mọi người rắc rối ngày hôm nay.
  • dòng 598 - nếu ntp_start_leap_timer không thực sự bắt đầu bộ đếm thời gian nhảy vọt, hãy đặt time_state thành TIME_OK
  • dòng 751 - giả sử hạt nhân không hoạt động, ngăn xếp không được mở và spinlock ntp_lock được giải phóng.

Có một vài điều thú vị ở đây.

Đầu tiên, dòng 691 hủy bộ đếm thời gian hiện tại mỗi lần điều chỉnh (2) được gọi. Sau đó, 554 tạo lại bộ đếm thời gian đó. Điều này có nghĩa là mỗi lần ntpd chạy bộ lọc vòng lặp đồng hồ, mã lỗi được gọi.

Do đó, tôi tin rằng Red Hat đã sai khi họ nói rằng một khi ntpd đã đặt cờ bước nhảy vọt thứ hai, hệ thống sẽ không gặp sự cố. Tôi tin rằng mỗi hệ thống chạy ntpd có khả năng sinh động cứ sau 17 phút (hoặc hơn) trong khoảng thời gian 24 giờ trước khi bước nhảy vọt thứ hai. Tôi tin rằng điều này cũng có thể giải thích tại sao rất nhiều hệ thống bị sập; cơ hội một lần bị rơi sẽ ít có khả năng bị tấn công hơn so với 3 cơ hội một giờ.

CẬP NHẬT: Trong giải pháp KB của Red Hat tại https://access.redhat.com/ledgeledge/solutions/154713 , các kỹ sư của Red Hat đã đi đến kết luận tương tự (việc chạy ntpd sẽ liên tục gặp mã lỗi). Và thực sự họ đã làm như vậy vài giờ trước khi tôi làm. Giải pháp này không được liên kết đến bài viết chính tại https://access.redhat.com/ledgeledge/articles/15145 , vì vậy tôi đã không nhận thấy nó cho đến bây giờ.

Thứ hai, điều này giải thích tại sao các hệ thống được tải có nhiều khả năng bị sập. Các hệ thống được tải sẽ xử lý nhiều ngắt hơn, khiến hàm kernel "do_tick" được gọi thường xuyên hơn, tạo cơ hội nhiều hơn cho mã này để chạy và lấy ntp_lock trong khi bộ định thời được tạo.

Thứ ba, có khả năng hệ thống bị sập khi bước nhảy vọt thứ hai thực sự xảy ra không? Tôi không biết chắc chắn, nhưng có thể là có, bởi vì bộ đếm thời gian kích hoạt và thực sự thực hiện điều chỉnh bước nhảy vọt thứ hai (ntp_leap_second, trên dòng 388) cũng lấy spinlock ntp_lock và có lệnh gọi đến hrtimer_add_recires_ns. Tôi không biết liệu cuộc gọi đó cũng có thể gây ra tiếng vang hay không, nhưng dường như không thể.

Cuối cùng, điều gì khiến cờ nhuận thứ hai bị vô hiệu hóa sau khi bước nhảy vọt thứ hai chạy? Câu trả lời là ntpd dừng đặt cờ bước nhảy vọt vào một thời điểm nào đó sau nửa đêm khi nó gọi adjtimex (2). Vì cờ không được đặt, kiểm tra trên dòng 554 sẽ không đúng và sẽ không có bộ đếm thời gian nào được tạo và dòng 598 sẽ đặt lại biến toàn cục time_state thành TIME_OK. Điều này giải thích tại sao nếu bạn kiểm tra cờ bằng adjtimex (8) ngay sau bước nhảy thứ hai, bạn vẫn sẽ thấy cờ bước thứ hai được thiết lập.

Nói tóm lại, lời khuyên tốt nhất cho ngày hôm nay dường như là lời khuyên đầu tiên tôi đưa ra: vô hiệu hóa ntpd và vô hiệu hóa cờ nhuận thứ hai.

Và một số suy nghĩ cuối cùng:

  • không ai trong số các nhà cung cấp Linux nhận thấy bản vá của John Stultz và áp dụng nó cho hạt nhân của họ :(
  • Tại sao John Stultz không cảnh báo một số nhà cung cấp điều này là cần thiết? có lẽ cơ hội của con ruồi dường như đủ thấp để gây ra tiếng ồn.
  • Tôi đã nghe các báo cáo về các quy trình Java bị khóa hoặc quay khi bước nhảy vọt thứ hai được áp dụng. Có lẽ chúng ta nên theo dõi sự dẫn dắt của Google và suy nghĩ lại về cách chúng ta áp dụng bước nhảy vọt cho các hệ thống của mình: http://googleblog.blogspot.com/2011/09/time-t Technology -and-leaping- seconds.html

06/02 Cập nhật từ John Stultz:

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

Bài đăng chứa từng bước từng bước về lý do tại sao bước nhảy vọt thứ hai khiến bộ định thời Futex hết hạn sớm và liên tục, làm tăng tải CPU.


7
Cảm ơn câu trả lời tuyệt vời. Vì vậy, phần còn lại của máy chủ của chúng tôi đang chờ để sụp đổ. Đáng yêu. Chúng tôi đến đây!
Bron Gondwana

3
Làm thế nào để tôi biết nếu adjtimexđã được ban hành, hạt nhân có in một cái gì đó trong dmesg không? Cơ hội nào mà một hệ thống không gặp sự cố trước khi tắt ntpd sẽ gặp sự cố?
Hubert Kario

3
Hubert: chạy "adjtimex" (thường được đóng gói riêng) và tìm cờ 16 để chỉ ra bước nhảy vọt thứ hai đang chờ xử lý.
Đột kích Dominic

22
Bạn sẽ ghét nắp đại diện.
Wesley

26
@WesleyDavid: Không phải lo lắng, nắp đại diện sẽ được đặt lại vào nửa đêm UTC. Có lẽ.
mmyer

33

Điều này đánh chúng tôi mạnh mẽ. Sau khi khởi động lại nhiều máy chủ của chúng tôi, việc sau đây trở nên đơn giản và hiệu quả hoàn toàn mà không cần khởi động lại máy chủ:

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

Tất cả những gì được yêu cầu là để thiết lập lại đồng hồ hệ thống. Sheesh. Những gì tôi đã cho đã biết điều này sáu giờ trước.


8
date -s "`date`"đã làm cho tôi.
Pointy

@DeanB: Tôi đã đăng vào lúc 3 giờ sáng UTC rằng việc đặt lại đồng hồ thực hiện thủ thuật, thật không may, phải mất một thời gian để kiểm duyệt. Chúng tôi cũng đã bắt đầu khởi động lại máy chủ
Gregor

24

Một chương trình C đơn giản giúp xóa bit thứ hai trong trường trạng thái thời gian của kernel:

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

Lưu dưới dạng lsec.c, biên dịch với gcc -Wall -Wextra -o lsec lsec.cvà chạy bằng root.

Bạn có thể muốn dừng ntpd trước khi chạy nó và khởi động lại ntpd sau bước nhảy vọt thứ hai.


Thành (void) argc;tựu gì? Im lặng cảnh báo cho biến không sử dụng? Sẽ không sử dụng int main()hoàn thành như nhau? Không cố gắng trở thành một giáo viên, tôi thực sự tò mò.
gparent

18

Dường như postmortem ./lsec không có hiệu lực.

Những gì chúng ta đang thấy là rất nhiều tiến trình softirqd ăn CPU (thường là tuyến tính với tải của các tiến trình java)

Những gì hoạt động để sửa POSTMORTEM với giây nhuận đã được áp dụng bởi ntp là như sau:

Nó dường như là đủ để chỉ vấn đề:

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

Điều này sẽ giảm tải mà không cần khởi động lại hoặc khởi động lại. Ngoài ra, bạn có thể phát hành:

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

Tại sao sntp -svà không ntpdate?
triển sai lầm

ntpdate chỉ là một trình bao bọc cho sntp ở đây, chắc chắn cũng tốt khi sử dụng ntpdate.
Gregor

ah tôi hoàn toàn bỏ lỡ có một gói ntpdate để ép trong đó thực sự là một nhị phân. Tôi đã chỉnh sửa bài đăng của mình để bao gồm điều này.
Gregor

Tôi cũng đã nghe các báo cáo tương tự về việc khắc phục vấn đề này (chẳng hạn như sử dụng date -s). Có vẻ như bản sửa lỗi chỉ yêu cầu thiết lập thời gian hệ thống thay vì xoay vòng (hành vi ntpd mặc định khi độ lệch nhỏ). Tôi đoán việc cài đặt thời gian sẽ khiến cơ chế giữ thời gian bên trong của hạt nhân tự thiết lập lại.
Patrick

4
Các ứng dụng java của tôi sử dụng CPU tăng đột biến (với lượng thời gian CPU cao dành cho softirqd), điều này đã khắc phục nó.
Hubert Kario

16

http://my.opera.com/marcomarongiu/blog/2012/03/12/no-step-back dường như chỉ ra rằng hạt nhân nén Debian sẽ không xử lý bước nhảy vọt thứ hai.

Chủ đề này trên comp.prot Protocol.tim.ntp cũng được quan tâm: https://groups.google.com/forum/?fromgroups#!topic/comp.prot Protocol.time.ntp/KSflIgjUdPE

Điều đó nói rằng, bước nhảy vọt thứ hai chưa xảy ra: 23:59:60 UTC

Cuối cùng, https://access.redhat.com/ledgeledge/articles/15145 có đoạn sau: "Khi bước nhảy vọt thứ hai xảy ra, kernel sẽ in một thông báo tới nhật ký hệ thống. Có khả năng việc in thông báo này có thể khiến kernel bị sập trong Red Hat Enterprise Linux. "


Nhưng hạt nhân 3.2,21, có lẽ, có lẽ - đó là thứ mà ít nhất một trong số các máy bị sự cố đang chạy
Bron Gondwana

Trên một vài trong số những máy mà Bron chỉ ra, chúng tôi thực sự đã đưa ra một bản sửa lỗi cần xử lý chính xác bước nhảy vọt thứ hai sắp tới.
Cosimo

bạn có thể đăng bản sửa lỗi ở đâu đó để người khác có thể xem xét / đề xuất ý tưởng / thử không?
kargig

Tôi không có cách khắc phục ... Tôi chỉ thu thập thông tin. Có lẽ nên đặt điều này như một bình luận chống lại câu hỏi ban đầu.
Luca Filipozzi

4
my.opera.com/marcomarongiu/blog/2012/06/01/ từ chứa nhiều chi tiết hơn về cách sửa lỗi
Bron Gondwana
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.