ようこそ!
答えてねっと for Businessは、
マイクロソフトが運営する
ビジネスで使うパソコンや
ITに関するQ&Aサイトです。

質問

Win2003のタイムサービス(w32time)の挙動がオカシイ

製品名:デスクトップ OS、サーバー OS/Windows Server 2003

現象:おかしい/エラーが出る

この質問は解決で締め切られています

Oracleが稼動するDBサーバでNTPを利用した時刻同期を行っています。DBサーバなので時刻戻りを回避すべく、Slewモードに設定しています。確かにシステム稼動時は、徐々にNTPの時刻に同期されて行きます。しかし再起動時にシステム時刻がCMOS時刻(Real Time Clock)に戻ってしまい、イベントログに時刻のズレが大きすぎて同期できないというエラーが出てしまいました。MaxNegPhaseCorrectionをデフォルトの15時間から短めに変更しています。
その後、動作をいろいろ検証してみると、デフォルトのStepモードではNTPの時刻が即座にRTCに反映されるのに対して、SlewモードではOSのシステム時刻が調整されるのみでRTCには一切反映されないように見受けられます。
NTPをタイムソースとする設定の下では、当然NTPの時刻がRTCに反映されるべきものと考えていました。これではDBサーバには必ずUNIXを使わなければならないのか?とすら思えて来ます。
何かいい方法があったら教えていただけませんでしょうか?
どうぞよろしくお願いします。

質問者からのコメント

  • 投稿日時:2008/07/16 09:55

お蔭様で助かりました。ありがとうございました。

回答1 (この回答は質問に対する回答です)

  • 投稿ID:A2008049551
  • 投稿日時:2008/07/02 11:40

チャブーンです。

Windows Time で Slew モードの挙動について、個人的に調べたことがあります。私が調べた限りですが、おっしゃるとおり Slew モードで動作中の場合、RTC に時刻を強制することはありません。

Windows では Windows Time が動作しない環境では 1 時間ごとに RTC とシステムクロック (OS ソフトウェア時刻) が同期する実装ですが、Slew モードではこれは働きません。

http://support.microsoft.com/kb/232488/ja
http://support.microsoft.com/kb/946033

また、linux でいうところの hwclock -systohc にあたるコマンドはありません。同じ機能を持たせたいなら setSystemTime() APIを使ってプログラムを作る、などといった対応になるでしょう。

なお、Windows では Windows Time を一旦止めてしばらく置いておいたり、OS シャットダウン時に (60 秒以内のずれなら) システムクロック時刻から RTC に同期する、というように思うのですが、そういう挙動はなかったでしょうか?

挙動を確かめるために、Windows から RTC 時刻を直接呼び出せるツールがありますので、調べてみるといいように思いますよ。

http://www.softdevlabs.com/ClockMon/ClockMon.htmlマイクロソフト以外のサイトへ移動する

  •  

回答2 (この回答は回答1に対する回答です)

  • 投稿ID:A2008049580
  • 投稿日時:2008/07/02 17:10

ご回答ありがとうございます。みのちゃんです。

タイムサーバーが無い状況ではシステム時刻よりRTCの方が正確なので、タイムデーモンが1時間ごとにRTCをシステム時刻に反映することは正しいと思います。

一方でタイムサーバーが存在する場合にはRTCよりタイムサーバーの方がより正確な時間を提供してくれます。そして1時間に1回のタイムデーモンが起動してRTCをシステム時刻に反映してしまうと、せっかくタイムサーバーで時刻同期したシステム時刻が壊れてしまいます。このような場合にはタイムデーモンが起動しないWindowsの実装は、適切であると思います。

しかしサーバー起動時にはRTCからシステム時刻が設定される以上、タイムサーバーから取得した正しいシステム時刻は最終的にはRTCに反映されている必要があります。(デフォルトのStepモードでは正しく反映されます。)
しかしSlewモードではRTCへの反映が行われず、起動時にエラーを引き起こしてしまうのです。

チャブーンさんのおっしゃる通り、setSystemTime() APIを使うと設定したシステム時刻がRTCに反映される様です。よって、時刻同期をカスタムのプログラムで行うようにすればいいのでしょうが、これはちょっと敷居が高いです。それなりの開発費がかかってしまいます。

タイムサーバーとの同期から時間の経過があるので精度はちょっと落ちますが、シャットダウン時にsetSystemTime() APIを呼び出す方法もあるかと思います。カスタムのプログラムで実装する部分が限定できるので、少しマシかなあと思案しているところです。
また本番業務で使用する以上、Windows Time をしばらく止めて置くのは難しいです。

  •  

回答4 (この回答は回答2に対する回答です)

  • 投稿ID:A2008049759
  • 投稿日時:2008/07/05 11:40
  • 最も役に立った投稿として評価されました

チャブーンです。

私の方でもちょっと検証してみましたが、少なくとも 2 〜 30 秒のずれでは、Windows Time を止めても、RTC との同期は行われないようです。

NTP の世界では基本的に mS (ミリ秒) 単位での時刻同期を問題とするため、数秒以上の時刻ずれは、別の方法 (NTP の Set モードを使って) で事前にあわせておいてから、細かいところをあわせる、といった方法もよく使われます。mS 単位の正確性にパソコンの RTC は対応できないので、システムクロックと RTC はつねに同期すべし、と Windows Time (を作った人) に求めるのは難しい面があると思います (linux の ntpd がどういう実装になっているかは別にして)。

この件では、再起動時に以前のシステムクロックが反映されないと困る、という話しかと思いますので、シャットダウン時に RTC にシステム時刻を反映させるために、下のような簡単なバッチを組んで、シャットダウンスクリプトを動作させればいいかしら、と思います。完全に確認はしていませんが、time コマンドは setSystemTime() で動作するかと思います。

----
@echo off
TIME=%TIME%
----

シャットダウンスクリプトを行う方法は、したのページを見てみてください。実行した結果や時刻の精度については、ご自身で確認いただいた方が確実だと思います。

http://itaya.corso-b.net/TIPS/TIPS22.htmlマイクロソフト以外のサイトへ移動する

  •  

回答5 (この回答は回答4に対する回答です)

  • 投稿ID:A2008049878
  • 投稿日時:2008/07/08 14:09

みのちゃんです。ご回答ありがとうございます。

チャブーンさんのおっしゃる通り、TIMEコマンドはsetSystemTime() で動作するようですね。システム時刻がRTCに反映されることが確認できました。

これにより再起動時のエラー出力が解消されたので、回避策としては十分だと思われます。

本当にありがとうございました。

  •  

回答3 (この回答は回答1に対する回答です)

  • 投稿ID:A2008049589
  • 投稿日時:2008/07/02 20:41

みのちゃんです。

OSシャットダウン時にシステム時刻がRTCに反映されるか否かを実際に検証してみました。
システム時刻とRTCの差分が20秒程度でも65秒程度でも、再起動後のシステム時刻は停止前のRTCと一致しておりました。

60秒以内ならRTCに反映されるのであれば、セットアップ時にタイムサーバーとの差分を60秒以内にして置けば済むので大いに期待しておりましたが・・・。

  •