我听说如果在数据库和邮件服务器运行时更改系统时间,它们会发生不良事件。但是,我很难找到有关实际风险的具体信息。
我在 Debian Wheezy 主机上运行了一个生产 Postgres 9.3 服务器,时间偏差了 367 秒。我可以ntpdate
在 Postgres 运行时运行或启动 openntp 吗?或者这是否可能会导致问题?如果是这样,有什么更安全的方法来纠正时间?
是否有其他服务对系统时间变化更敏感?可能是邮件服务器(exim、sendmail 等)或消息队列(activemq、rabbitmq、zeromq 等)?
答案1
数据库不喜欢时间倒退,因此您不想从跳跃时间的默认行为开始。-x
如果偏移量小于 600 秒(10 分钟),则在命令行中添加选项将调整时间。在最大调整率下,将时钟调整一分钟大约需要一天半的时间。这是一种缓慢但安全的调整时间的方法。
在运行ntp
调整时间之前,您可能希望先选择ntp
一个选项,例如-g 2
验证它检测到的偏移量有多大。这会将恐慌偏移量设置为 2 秒,这应该是相对安全的。
在此选项可用之前,我使用过的另一个选项是编写一个循环,每隔一分钟左右将时钟重置为秒数。如果您检查以确保重置不会改变秒数,那么这可能是安全的。如果您大量使用时间戳,则可能会出现顺序不一的记录。
一个常见的选项是关闭服务器足够长的时间,以使时钟不会倒退。 ntp
或者ntpdate
可以配置为在启动时将时钟跳转到正确的时间。这应该在启动数据库之前完成。
答案2
如果数据库非常活跃且内部记录带有时间戳,则数据库特别容易受到系统时间更改的影响。一般来说,如果您的时间落后,突然向前跳转会比向前跳转后突然向后跳转遇到的问题要少得多。
正如 Joffrey 指出的那样,应用程序比数据库本身更容易出现时间突然跳转的问题。更正时间的最安全方法是关闭应用程序 N+1 分钟(其中 N 是系统时钟快的分钟数),然后同步时间、启动 NTP 并重新启动应用程序。如果您不能让应用程序停机那么长时间,我只能建议您在同步时间之前备份数据库,然后向计算机界的神灵献上一只死松鼠,然后扣动扳机。好吧,我有点开玩笑,但除了让应用程序停机之外,我想不出任何其他“安全”的方法。
答案3
当发生瞬间时间跳跃时,通常不是数据库服务器容易出现错误,而是使用该时间的应用程序容易出现错误。
跟踪时间通常有两种方式:跟踪自己的时间或比较系统时间。两者都有各自的优缺点。
自己的时间追踪
我看到这在一些嵌入式编程和系统中使用,其中精确计时并不那么重要。在主应用程序循环中,跟踪“滴答”的方法得到了处理。这可能是内核、睡眠或选择发出的警报,指示经过的时间量。当你知道经过了多少时间时,你就知道你可以将这个时间加到计数器或从中减去。这个计数器就是让你的计时应用程序运行的原因。例如,如果计数器高于 10 秒,你可以丢弃某些东西,或者你需要做某事。
如果应用程序不跟踪时间,计数器将不会改变。这可能是应用程序设计所期望的。例如,使用计数器比使用开始/停止时间戳列表更容易跟踪长时间运行的进程所花的时间。
优点:
- 不依赖于系统时钟
- 不会因时间偏差过大而中断
- 无需昂贵的系统调用
- 小计数器比完整时间戳占用更少的内存
缺点:
- 时间不太准确
- 系统时间的变化可能会使其更加不准确
- 时间与应用程序的运行有关,不会持续存在
比较系统时间
这是最常用的系统:存储时间戳,并使用系统时间调用将其与时间戳进行比较。系统时间的巨大偏差可能会威胁应用程序的完整性,几秒钟的任务可能需要几个小时或立即结束,具体取决于时钟的方向。
优点:
- 精确的时间比较
- 重启和长时间中断后依然有效
缺点:
- 进行系统调用以获取新的时间戳,以便与其他时间戳进行比较
- 应用程序需要注意倾斜,否则可能会中断
受影响的系统
大多数应用程序将使用时间戳来比较计划任务。对于数据库系统来说,这可能是缓存清理。
如果应用程序没有检测并进行相应处理,所有使用数据库和查询语言中的调用时间函数的应用程序都将受到偏差的影响。根据其用途,应用程序永远不会停止运行或允许无限期的登录期。
邮件系统将使用时间戳和/或超时来处理过期或未送达的邮件。时钟偏差可能会影响这一点,但影响要小得多。重新连接到服务器的后退计时器可能会错过,从而导致连接服务器受到惩罚。
我不认为(没有研究过)更改系统时间时会发出内核警报。使用这些的系统应该是安全的。
解决方案
轻轻移动时间。这可以在您最喜欢的时间解决方案的文档中找到。