辗转解决Ubuntu 14系统时间忽快忽慢的诡异问题

尝鲜习惯了,加之docker跟ubuntu基情正浓,为了部署gitlab等基础服务,申请了两台性能前卫的刀片开始了基于ubuntu 14的中二之路,但自此灵异事件开始了…

gitlab显示系统时间全乱

想象一下一个push event发生在未来7天的情景,是不是有点穿越的崩溃?我被这种感觉折磨,是从gitlab搭建完第二天开始的。当然多年修电脑经验告诉我,应该是系统时间有问题,立即登录,果然发现系统的时区、UTC和NTP服务不正确(系统是采购部同事帮忙安装的,所以并没注意这些设置),而且系统时间这速度——“nia nia!这系统时间刨滴苔快咧!”,于是反映给采购部,采购部反映给供应商,得到答复:可能是主板电池没电了。

哦,硬件里最简单的一个部件,换之!

但…然并卵…BIOS时间一切正常

不急,咱还有NTP,1分钟同步一次,三下五除二,搞定!gitlab时间终于正常了。

tips:
系统时间不准确,请开启NTP服务定期自动同步。

NTP服务设置参考:http://wiki.ubuntu.org.cn/NTP

mysqld莫名崩溃,音信全无

“你以为…解决了一个分钟级精度的问题就完了?”上地冷笑道。

运行没一周,gitlab 502了,因为mysqld消失了…

有问题,问日志,grep、vi齐上阵,瞬间菊花发紧…log呢?被黑了?mysql的error log在那段时间没有记录下任何事情…[恐怖]

后来(嗯,应该是我再次睁开眼的时候),理智告诉我,还是问问google吧…

东翻西找,这回google也没帮到我,搜出来的问题去check了,都不是。

故障时间没有记录,只好找启动记录了,当我打开mysql启动日志的时候,猛然发现了一个更诡异的事情 (如图):

虽然CRONTAB定时每1分钟运行NTP来同步时间,但由于系统时间走得太快,以至于每次同步都会有5秒左右的跳变幅度,更有甚者,幅度竟然达到了20多秒!这对一个依赖时间的mysqld来说,显然是一个噩梦,如果我是mysqld早就掀桌子不干了:一会1点,一会2点,到底几点啊?!(摔)

看来系统心律不齐的问题必须解决了。

野生程序员靠运气

说实话,作为一个野生程序员,对操作系统的理解(尤其是linux)还处在十知半解的水平,所以弯路走的那比十八盘还惊险。言归正传,既然是要根治系统心律不齐,那还是老办法:google。

还真别说,一搜一大堆,比如:

https://www.ubuntu.org.cn/viewtopic.php?f=42&t=4526&start=15

这个,如法炮制。更改了grub.cfg的clock设置:

clock=pit

重启…yeah!果然生效了!!

赶紧喝罐王老吉庆祝一下,顺便开始解决第二台机器。

可是…可是王老吉早就喝完了,第二台机器依然还是不行,是的,怎么都不行,跟第一台机器一模一样的设置也不行。

更可怕的是,我为了排除随机性(作为野生程序员,靠凑瞎猫碰死耗子最后吃大亏的事常有,得谨慎行事),把第一台正常机器重启了…然后…然后第一台又不正常了![抓狂]

完了,我遇到三体问题了吗?我被智子封锁了吗?救命…

野生程序员也得尊重科学

这时候的我真心比《三体》里的汪淼还郁闷,这真是意了大lang gou了…但根据时间表,三体文明还没封锁地球基础科学,所以,真相肯定只有一个,而现在,至少第一台服务器正常过一次,那就抓住这个唯一的线索,是时候拿出我的终极杀招:双盲对比!

既然我得到了一次正确结果,那么这次正确的结果肯定存在一个不同于其他的地方,既然系统时间跟BIOS有关,而BIOS又正常,那么在boot log里应该存在一些蛛丝马迹。

说干就干,把两个时间段(正常和不正常)所有产生的日志做diff,把差异打印出来之后逐行浏览(当时我的感觉就跟纳什一样),最后竟然终于被我发现了一个带有clock关键字的日志:

Switched to clocksource tsc

而当我grep出来所有跟clocksource关键字有关的log时,终于找到了这个隐藏至深的不同:

图中我们可以看到,16:29这次启动(恰恰是启动后时钟恢复正常的时间点),clocksource被设置了5次,而其他时候都是被设置3次,而最后一次他们不一样!

难道…这个诡异的clocksource立刻被我搜索到了:

http://www.wowotech.net/timer_subsystem/clocksource.html

clock!这么熟悉,而且前面已经设置了clock=pit啊…但,事情总有但是…

然并卵

虽然但是我离真相只有一步之遥,但由于被各种不负责任转载和层出不穷新情况的干扰,加上我这个野生程序员不尊重科学,这个线索被我生生掐断了。

真相大白

简单的说,系统时钟的算法依赖于clocksource,它是一种系统选择时钟源基点的方式,一般系统会存在三种(一种硬件方式,两种软件方式)候选模式,模式设置在grub引导时用clock参数传入。

ubuntu系统在启动的时候,如果不设置clock参数,则默认会动态检测三种时钟源,取精度最高的一个,这一隐藏规则恰恰解释了第一台服务器有一次正常的原因(幸亏那个时间点tsc的精度超过了refined-jiffies)

前面使用clock=pit的方式,确实是强制设置时钟源为硬件模式,但是…clock这一参数的设置可选值却受 /sys/devices/system/clocksource/clocksource0/available_clocksource 文件内容所限,如果设置的值不是该文件内的选项,则设置无效,依然采用默认方式(做这件事竟然没有任何log,典型的吞错陷阱)。

而该文件在我的服务器上只有 refined-jiffies jiffies tsc 三种方式,其中前两种为软件算法,依赖于操作系统函数的算法,不同算法实现不同,详见:

http://www.jiancool.com/article/18433795190/

而tsc模式是基于CPU内置寄存器计数器的时钟源,属硬件模式,详见:

http://blog.chinaunix.net/uid-149881-id-2780253.html

由于我申请的这两台服务器(不知道是不是服务器的原因)并不支持pit模式,所以系统在启动的时候,选择了很容易被干扰的软件算法(可能是算法选择的引脚定义已经改变),导致系统心律不齐(跟踪系统时间会发现明显的周期性加速和减速)。关于jiffies算法,详见:

http://my.oschina.net/u/174242/blog/71851

 

当我把启动配置中的 clock 参数设为 tsc 之后,系统心律不齐的病终于痊愈了。

总结:

  • 一定要相信科学,基于凑和拍脑袋的做法只是把自己交给了运气。
  • 把原理吃透才能根治问题。
  • 双盲实验在侦错中非常有效。
  • 珍惜生命,尽量不依赖不稳定的信号源编程。
标签: , , , , ,
文章分类 未分类

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

点赞
如果您觉得很赞,我将非常乐意接受虚拟币的捐赠,以示您对我的肯定。

比特币钱包地址:
1PqpqA8FyH3NbfCrbcRd1YxQk3LEsSEYDV
莱特币钱包地址:
LRTdmovGGVEHCKWz7JdL9aiB7VZkuNycJf
站点勋章
网站统计