Red Hat Enterprise Linux で「うるう秒」問題を解決する
コンテンツ
はじめに
うるう秒は、Coordinated Universal Time (UTC) の日時を平均太陽時に近づけるために、UTC に適用される 1 秒の調整のことです。ただし、地球の自転速度は、気候または地質の条件によって変化するため、うるう秒が不定期に UTC に挿入されます。このナレッジでは、うるう秒に関する情報と、Red Hat Enterprise Linux がうるう秒の挿入問題にどのように対応するかについて説明します。
今後発生する「うるう秒」問題
次回のうるう秒は、2016 年 12 月 31 日の 23:59:60 (UTC 時間) に発生します。アナウンスの全文は INTERNATIONAL EARTH ROTATION AND REFERENCE SYSTEMS SERVICE (IERS) で確認できます。
システム構成
- Red Hat Enterprise Linux バージョン 4、5、6、7や8
うるう秒とは
世界中のほとんどすべてのローカルタイムゾーンは、世界中の国々をいくつかに区分している原子時計から得られた Coordinated Universal Time (UTC) に基づいています。地球の自転は一定ではなく、時間の経過とともに徐々に変化します。そして、平均速度は徐々に遅くなります。これにより、いわゆるうるう秒を UTC 時間スケールに挿入して、UTC 時間を実際の地球の自転に合わせて修正します。
このような余計な 1 秒は、主に月と太陽の引力によって、時間の経過とともに、地球が自転する速度が徐々に遅れていくために発生します。また、自転速度は、地球の内部条件 (核やマントルなど) や外部条件 (大気や海など) の影響も受けます。近年、時刻のほとんどは、複数の国にある 250 にもなる電子時計によって計測されています。これは、原子のエネルギーレベルの遷移を計測することで行います。この時計を使用して UTC を計算していますが、この時刻計測メカニズムは地球の自転とは連動していないため、その差異を「うるう秒」で定期的に調整する必要があります。また、1820 年と比べて、1 日が 2 ミリ秒長くなっていることを考慮する必要があります。このように、地球の自転速度は UTC と徐々に合わなくなってきています。
International Earth Rotation Service (IERS) は、正しい地球の自転を計測し、うるう秒を挿入すべきタイミングを決定します。うるう秒は、その月の最終日が終わる瞬間 (UTC 午前 0 時)、そして望ましくは、6 月または 12 月の終わりに挿入されます。うるう秒は、これまでは以下のいずれかで挿入されていました (*)。うるう秒が予定されているかどうかは、IERS が Bulletin C で告知します。現在の Bulletin C は、次のうるう秒の半年前に公開されています。
IERS Bulletin C #30 from July 2005 で、2005 年 12 月 31 日 (UTC) が終わる真夜中にうるう秒が挿入されることが発表されました。これは 1998 年以降、最初に挿入されたうるう秒になります。そのため、それ以前の 7 年間に開発したアプリケーションの多くがうるう秒に対応していませんでした。
うるう秒は、世界中で同時に挿入されたため、各地で挿入が行われるタイミングは、UTC から計算されるローカルタイムオフセットによって異なります。 たとえば、タイムゾーンが UTC +3h の場合は、午前 0 時 + 3 時間で、午前 3 時にうるう秒が挿入されます。
UTC にうるう秒が挿入される際の時間推移は以下のようになります。
2011/12/31 23.59.57
2011/12/31 23.59.58
2011/12/31 23.59.59
2011/12/31 23.59.60 <-- うるう秒
2012-01-01 00.00.00
2012-01-01 00.00.01
2012-01-01 00.00.02
TAI でシステム時間が維持され「正しい」タイムゾーンが使用されている場合は、23:59:60 が記載されている可能性がありますが、UTC の Unix の実装には 23:59:60 が存在しないので、Linux のカーネルでは 0:00 UTC 後の最初の時間更新時に 1 秒戻すことでうるう秒を挿入します。ローカルタイムでは、タイムゾーンのオフセットによって挿入されるタイミングが異なります。たとえば、UTC+3 の場合は以下のようになります。
2012-01-01 02:58:00.000
2012-01-01 02:58:00.500
2012-01-01 2:59:00.000
2012-01-01 2:59:00.500
2012-01-01 03:00:00.0xx <-- うるう秒
2012-01-01 02:59:00.0xx
2012-01-01 2:59:00.500
2012-01-01 3:00:00.000
2012-01-01 3:00:00.500
うるう秒は、常用時の不連続性となります。その時間は通常の単調増加の推移とは異なり、1 秒変更 (step) されます。うるう秒が挿入された瞬間と、その 1 秒後のタイムスタンプは以下のようになります。
2011/12/31 23.59.60 <-- うるう秒
2012-01-01 00.00.00
うるう秒の日時は標準化することができます。
60 秒は 1 分となり、分の位を 59 から 60 に変更します。
60 分は 1 時となり、時間の位を 23 から 24 にします。
24 時は 1 日となり、日の位を増加し、同様に続けます。
最後に、この 2 行の時間を同じにするか、この連続する 2 秒を同じタイムスタンプとします。
それぞれの時間伝達サービスは、IERS によってうるう秒の挿入が決定されると、うるう秒の告知を伝搬します。たとえば、ドイツの長波トランスミッタ DCF77 と衛星ナビゲーションシステム GPS などがそのサービスに当たります。したがって、これらのシステムから送られる信号をデコードするレシーバーは、うるう秒の告知もデコードします。これらのレシーバーからの時間を読み込むアプリケーションは、この情報が適用されたプロトコルに含まれていると、うるう秒の告知も判断できるようになります (例: time string transmitted by the receiver)。
時間コードのレシーバーはアプリケーションにうるう秒の告知だけを渡しその期間、時間を正しく刻みます。うるう秒を正しく処理するのは、アプリケーションや OS となります。
(*): 北米地区で、2012 年 8 月 31 日午前 0 時 (UTC) に、一部の NTP (Network Time Protocol) サーバーがうるう秒の告知を誤って発行しました。2 つの stratum 1 サーバー (truechimer.cites.illinois.edu および time-b.nist.gov) が、うるう秒の告知を誤って発信していることが特定されました。その 2 つのサーバーのいずれかを階層構造内に持つ、すべての下位の stratum (stratum 2、3、4....) の NTP サーバーはうるう秒を誤って告知したと考える必要があります。これらのサーバーを使用する NTP クライアントは、カーネルのうるう秒のインジケータフラグを設定します。これは、システムが再起動するまで削除されません。
うるう秒対応
うるう秒は主に 2 つの方法で対応されます。その方法は、システム時計をどのように設定しているかによって異なります。
UTC を使用してシステム時計の時間管理を行っており、NTP または PTP に同期する
前述したように、UTC にはうるう秒が存在しないため、システムが UTC を使用しているとうるう秒は処理されなくなります。したがって、システム時計が UTC より 1 秒早く進まないように、うるう秒の発生時に時刻を修正する必要があります。以下に示すように、さまざまな修正方法があります。
時刻を戻すようにカーネルに告知する
大部分のデーモンでデフォルトの方法は、うるう秒を追加するようにカーネルに告知することです。たとえば、うるう秒を修正する前の日に、うるう秒が発生することをクライアントに告知する必要があります。そして、UTC 時間の 23:59:59 に、Linux カーネルが 60 秒を 2 回発生させて余分な 1 秒を追加するか、60 秒を削除して余分な 1 秒を削除します。以下は、2008 年から 2009 年にかけて実施されたうるう秒の挿入時に、デフォルト設定がされている NTP クライアントとして動作していた Red Hat Enterprise Linux 上の時間の推移となります。
2008-12-31 23:59:59:052549000 UTC <-- 最初のうるう秒
2008-12-31 23:59:59:259988000 UTC
2008-12-31 23:59:59:465214000 UTC
2008-12-31 23:59:59:669629000 UTC
2008-12-31 23:59:59:873936000 UTC
2008-12-31 23:59:59:079184000 UTC <-- 2 番目のうるう秒
2008-12-31 23:59:59:284011000 UTC
2008-12-31 23:59:59:488648000 UTC
2008-12-31 23:59:59:692691000 UTC
2008-12-31 23:59:59:896577000 UTC
2009/01/01 0:00:00:052378000 UTC
うるう秒が発生すると、カーネルは、システムログにメッセージを出力します。
デーモンで時刻を瞬時に修正する
カーネルに告知して時間を瞬時に戻す代わりに、デーモンがシステム時計を戻すこともできます。時刻推移は、うるう秒を挿入するカーネルと同じです。ただし、デーモンがうるう秒を追加しているため、カーネルに関するバグは発生しません。
うるう秒を徐々に調整する (slew)
RHEL 6.8 および RHEL 7.2 では、Chrony を使用してうるう秒を徐々に調整するオプションが追加されました。これにより、時刻を一度に調整せず、時間をかけて「うるう秒」のずれを修正できるようになりました。これは、うるう秒が挿入される UTC 時間の 00:00:00、またはうるう秒が削除される 23:59:59 UTC に 1 秒のオフセットが積み上がり、時間をかけて調整されていきます。システムで実行しているアプリケーションが、システム時間が瞬時に変更される影響を受け、しばらくの間時刻のずれが発生する影響は受けない場合は、この方法が推奨されるかもしれません。
うるう秒を無視する
うるう秒を処理せず、完全に無視するようにデーモンを設定できます。これにより、別の予期せぬ変更が起こった時に時刻がゆっくりと修正されます。通常のオペレーションで処理されるまで、間違った時刻が使用されつづけます。複数のシステムをこの方法で設定している場合は、修正プロセスがやや無作為に行われるため、各システムの時刻が徐々にずれていきます。この方法は、同期接続が必要なシステムでは推奨されません。
NTP サーバーにおける「うるう秒」の調整 (leap smear)
RHEL 6.8 および RHEL 7.2 では、NTP サーバーで Chrony を実行しているときに「うるう秒」を調整するオプションが導入されました。クライアントがうるう秒を徐々に調整 (slew) する代わりに、サーバーでうるう秒を挿入せず、うるう秒を一度ではなく徐々に調整することで、正しい時間になるまでゆっくりと修正していきます。したがって、クライアントには特別な設定は必要ありません。クライアントではうるう秒を認識せず、UTC と同期するまでサーバーの時刻に従い続けます。サーバーでうるう秒を調整 (smear) すると、個々のクライアントで調整するよりもはるかに時間はかかりますが、すべてのクライアントが接続できるようになります。
NTP サーバーがうるう秒を調整するように設定すると、そのサーバーを指定しているすべてのクライアントで調整 (smear) される方法が同じになります。クライアントが、複数のサーバーからアップデートを受け取るように設定されていて、うるう秒を処理する方法がサーバー間で異なる場合は、 結果が同じになりません。
オプションの一覧
以下の表は、各デーモンで利用できるオプションを示しています。
方法 | NTPD | CHRONYD | PTP4L | PHC2SYS |
---|---|---|---|---|
カーネルによる瞬時の修正 | はい (デフォルト) | はい (デフォルト) | はい (デフォルト) | はい (デフォルト) |
デーモンによる瞬時の修正 | いいえ | はい (leapsecmode step) | いいえ | いいえ |
緩やかな調整 (Slew) | いいえ | はい (leapsecmode slew) | いいえ | いいえ |
無視 | はい (-x, disable kernel) | はい (leapsecmode ignore) | はい (kernel_leap 0) | はい (-x) |
このページの下部の設定例で、設定例が紹介されています。
以下の表は、各設定方法の効果を示しています。
クライアントカーネルによる瞬時の修正 | クライアントデーモンによる瞬時の修正 | クライアントによる緩やかな調整 (slew) | クライアントにおける無視 (ntpd -x) | サーバーによる緩やかな調整 (smear) | |
---|---|---|---|---|---|
連続時間 | いいえ | いいえ | はい | はい | はい |
時刻の誤差 | 1 秒 | 1 秒 | 数秒または数分 | 数時間 | 数時間 |
周波数誤差 | ゼロ* | ゼロ* | 大規模 | 小規模 | 小規模 |
カーネルのバグ | はい | いいえ | いいえ | いいえ | いいえ |
クライアントは互いに同期し続ける | はい* | はい* | はい | いいえ | はい |
- 時間の途切れを無視する
システム時計が TAI-10 秒で時間を管理し、同期はせず、right/* タイムゾーンを使用している
tzdata
パッケージを利用可能な最新バージョンにアップデートし、/usr/share/zoneinfo/right
ディレクトリから /etc/localtime
に適切なファイルをコピーして正しいローカル時間に時刻を再設定しても、 うるう秒を修正した時間を報告するように設定することができます。/usr/share/zoneinfo/right
のファイルには、1970-01-01 00:00:00 UTC に Epoch が開始してから発生したすべてのうるう秒を修正したローカル時間情報が含まれます。/usr/share/zoneinfo
におけるその他のタイムゾーンファイルには、うるう秒の修正は追加されていません。2008 年にうるう秒が追加された後、Epoch から 24 回のうるう秒が追加されます。時間が UTC であることが予想されるアプリケーションで、right/* タイムゾーンを使用すると問題が発生します。
たとえば、America/Los_Angeles (US Pacific) のタイムゾーンを使用している場合は、以下のコマンドを実行し、Pacific Time に時間をリセットすると、うるう秒を修正した時刻を報告するようにシステムを再設定できます。
cp /usr/share/zoneinfo/right/America/Los_Angeles /etc/localtime
/etc/localtime
を変更すると、glibc
がこのファイルを自動的に再ロードします。ただし、タイムゾーンを調整してもシステム時間は変更されません。localtime()
、ctime()
などの glibc 関数により、アプリケーションでシステム時間からローカル時間までの変換だけが行われます。これをアップデートしたあとにシステムを再起動する必要はありませんが、アプリケーションがこの関数の結果をキャッシュしている場合は、tzdata
をアップデートしてから再起動が必要になる場合があります。
注意: システムが互いに同期していることは保証されないため、時間同期のソースを使用せずに実行することは推奨されません。クロックソースにより決められた各システムで時間変動が起こる可能性があります。NTP、PTP、Chrony を使用せずに実行する決定は、時間変動が発生することを理解しつつ、システムごとまたはクラスターごとに行う必要があります。
デフォルトでは、時刻管理に NTP または PTP システムを使用していない Linux システムでは、うるう秒による時刻補正は実施できません。つまり、うるう秒が発生するとこのシステムでは 1 秒、時刻がずれることになります。うるう秒の発生後、手動で時刻を合わせる必要があります。
既知の問題
RHEL 4
- Red Hat Enterprise Linux 4 では、このメッセージが表示されると、カーネルがクラッシュする可能性があります。この問題については、System hangs on printing the leap second insertion message を参照してください。
- slew モードを使用しても ntp はカーネルフラグを設定します。この問題については In Red Hat Enterprise Linux 4, slew mode does not prevent ntp from setting the kernel flag を参照してください。
- システムが ntpd または ptp と同期していない場合は、12 月 31 日のうるう秒が含まれるアップデートした
tzdata
パッケージが必要になります。RHEA-2016-1982 で、アップデートしたtzdata
パッケージがリリースされました。ntpd または ptp と同期していない RHEL 4 を使用したシステムでこの修正を受け取るには、tzdata-2016g-2.el4
以降のバージョンにアップデートする必要があります。
RHEL 5
- Red Hat Enterprise Linux 5 では、このメッセージが表示されると、カーネルがクラッシュする可能性があります。この問題については、System hangs on printing the leap second insertion message を参照してください。
- slew モードで
ntp
を実行すると、うるう秒により時間が適切に設定されません。この問題については Time is not adjusted by a leap second when ntpd runs with -x option を参照してください。 - システムが ntpd または ptp と同期していない場合は、12 月 31 日のうるう秒が含まれるアップデートした
tzdata
パッケージが必要になります。RHEA-2016-1982 で、アップデートしたtzdata
パッケージがリリースされました。ntpd または ptp と同期していない RHEL 5 を使用したシステムでこの修正を受け取るには、tzdata-2016g-2.el5
以降のバージョンにアップデートする必要があります。
RHEL 6
- うるう秒の挿入告知を受け取ると、システムがハングアップする可能性があります。この問題については、Systems hang due to leap-second livelock を参照してください。
- うるう秒が追加されると、futex が重いアプリケーションが CPU を大量に消費するため、この問題は Why is there high CPU usage after inserting the leap second? に記載されます。
- うるう秒挿入時に TAI オフセットが正しくアップデートされません。この問題については TAI offset is incorrect during the leap second を参照してください。
- ntp で
-x
を使用しても、うるう秒の挿入が発生すると時刻は瞬時に変更になります。この問題については Does Red Hat plan to release xleap.patch with ntp? を参照してください。 - うるう秒が挿入される時に絶対時間タイマーが終了する場合があります。 この問題については Absolute Timers that Expire at Midnight UTC May Fire Early When the Leap Second is Inserted を参照してください。
- システムが ntpd または ptp と同期していない場合は、12 月 31 日のうるう秒が含まれるアップデートした
tzdata
パッケージが必要になります。RHEA-2016-1982 で、アップデートしたtzdata
パッケージがリリースされました。ntpd または ptp と同期していない RHEL 6 を使用したシステムでこの修正を受け取るには、tzdata-2016g-2.el6
以降のバージョンにアップデートする必要があります。 - うるう秒を調整 (smear) する際に chronyd がクラッシュする場合があります。この問題については Chronyd crashes when performing server leap smear を参照してください。
- NTP のバージョンの中には、うるう秒が挿入された後も通知し続けるものもあります。この問題については The ntpd leap status is not reset after inserting a leap second を参照してください。
RHEL 7
- ntp で
-x
を使用しても、うるう秒の挿入が発生すると時刻は瞬時に変更になります。この問題については Does Red Hat plan to release xleap.patch with ntp? を参照してください。 - うるう秒が挿入される時に絶対時間タイマーが終了する場合があります。この問題については Absolute Timers that Expire at Midnight UTC May Fire Early When the Leap Second is Inserted を参照してください。
- システムが ntpd または ptp と同期していない場合は、12 月 31 日のうるう秒が含まれるアップデートした
tzdata
パッケージが必要になります。RHEA-2016-1982 で、アップデートしたtzdata
パッケージがリリースされ、ntpd または ptp と同期していない RHEL 7 を使用したシステムでこの修正を受け取るには、tzdata-2016g-2.el7
以降のバージョンにアップデートする必要があります。 - うるう秒を調整 (smear) する際に chronyd がクラッシュする場合があります。この問題については Chronyd crashes when performing server leap smear を参照してください。
- うるう秒が挿入される前に hrtimers が発生する場合があります。この問題は Hrtimers may expire early when a leap second is inserted を参照してください。
- NTP のバージョンの中には、うるう秒が挿入された後も通知し続けるものもあります。この問題については The ntpd leap status is not reset after inserting a leap second を参照してください。
ここで対応している問題以外に、開発時にうるう秒の対応が行われていないアプリケーションで固有の問題が発生する場合があります。 この問題については Libraries and Applications do not account for the Leap Second を参照してください。
注意: PPC および IA64 アーキテクチャを使用している場合は、Systems not running NTP or PTP の方法を選択することが推奨されます。
リアルタイムカーネル
リアルタイムカーネルに関する問題に対応するためのナレッジが別途作成されました。詳細は Resolve Leap Second Issues in Realtime (RT) kernels を参照してください。
テスト
Red Hat はこの問題について引き続きテストを実施します。実施されたテストに関する情報があれば、このナレッジはアップデートされます。
このテストを実行するためのツールが、Access Lab で提供されています。ご利用になるには Leap Second Issue Detector に移動してください。
さらに、お客様自身がビルドおよび環境をテストすることが推奨されます。サンプルプログラムを含むテスト方法については、Are we susceptible to a leap second event? を参照してください。
設定例
Chrony を使用してうるう秒を一度に修正する
うるう秒を一度に修正するには、以下のオプションを /etc/chrony.conf
に追加します。
leapsecmode step
このオプションを使用すると、chronyd
がうるう秒を瞬時に戻すことでシステム時計を修正します。これにより、カーネルがうるう秒を挿入する際のバグを回避することができます。
chrony を使用してうるう秒を徐々に調整 (slew) する
うるう秒を調整 (slew) するには、以下のオプションを /etc/chrony.conf
に追加します。
leapsecmode slew
このオプションを使用すると、時間を瞬時に戻す代わりに、chronyd
がうるう秒を徐々に調整することでシステム時計を修正します。
chrony NTP サーバーを起点とする NTP クライアントのうるう秒の調整 (smear 方式) をする
うるう秒を調整するには、以下のオプションを /etc/chrony.conf
に追加します。
leapsecmode slew
maxslewrate 1000
smoothtime 400 0.001 leaponly
このオプションを使用すると chronyd
がうるう秒を徐々に調整することで、システム時計が修正されます。そして、ローカル時計の調整速度を 1000 ppm に制限します。
NTPD を使用してうるう秒を無視する
うるう秒を無視するには、通常の slew オペレーションで修正するようにします。以下の行が /etc/sysconfig/ntpd
に設定されていることを確認します。
OPTIONS="-g -x"
このフラグを追加して、カーネルのうるう秒の修正の追加が無効になり、うるう秒が時間をかけて修正されます。
関連ドキュメント
追加のうるう秒に関する情報と、それらがどのように Linux と NTP で処理されるかについては、以下のリンクを参照してください。
Comments