2020-12-20

服务器修改本地时间踩坑纪实

一.背景知识

      如果大家用过Linux的话就会知道,linux下我们通常是使用date命令来获取系统的时间,但是我们有没有想过这个具体的过程呢?我在Ubuntu下面使用strace跟踪了一下date命令的执行过程如下

root@ubuntu:~# strace date
execve("/bin/date", ["date"], [/* 65 vars */]) = 0
brk(NULL)                               = 0x16a3000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=97822, ...}) = 0
mmap(NULL, 97822, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f29e04d8000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0`\t\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1868984, ...}) = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f29e04d7000
mmap(NULL, 3971488, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f29dff01000
mprotect(0x7f29e00c1000, 2097152, PROT_NONE) = 0
mmap(0x7f29e02c1000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x1c0000) = 0x7f29e02c1000
mmap(0x7f29e02c7000, 14752, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f29e02c7000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f29e04d6000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f29e04d5000
arch_prctl(ARCH_SET_FS, 0x7f29e04d6700) = 0
mprotect(0x7f29e02c1000, 16384, PROT_READ) = 0
mprotect(0x60f000, 4096, PROT_READ)     = 0
mprotect(0x7f29e04f0000, 4096, PROT_READ) = 0
munmap(0x7f29e04d8000, 97822)           = 0
brk(NULL)                               = 0x16a3000
brk(0x16c4000)                          = 0x16c4000
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=6586032, ...}) = 0
mmap(NULL, 6586032, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f29df8b9000
close(3)                                = 0
open("/etc/localtime", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=582, ...}) = 0
fstat(3, {st_mode=S_IFREG|0644, st_size=582, ...}) = 0
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\3\0\0\0\3\0\0\0\0"..., 4096) = 582
lseek(3, -357, SEEK_CUR)                = 225
read(3, "TZif2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\3\0\0\0\3\0\0\0\0"..., 4096) = 357
close(3)                                = 0
fstat(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 18), ...}) = 0
write(1, "2020\345\271\264 12\346\234\210 20\346\227\245 \346\230\237\346\234\237\346\227\245 09"..., 4320201220日 星期日 09:01:17 CST
) = 43
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++
root@ubuntu:~# ls /etc/localtime 
/etc/localtime
root@ubuntu:~# cd /etc

      从上面的执行过程我们可以看出,“open(”/etc/localtime", O_RDONLY|O_CLOEXEC) = 3",date命令打开了/etc/localtime,那这个文件是干什么的,我们就一起去研究研究。登录我的Ubuntu16.04,虽然生产环境一般在centos下,但是这些基本的东西是没有什么变化的:

root@ubuntu:/etc# ls -la localtime 
lrwxrwxrwx 1 root root 33 112 08:59 localtime -> /usr/share/zoneinfo/Asia/Shanghai
root@ubuntu:/etc#

      这样就很明确了吧,大概的过程就是date会先读取/etc/localtime的内容,而/etc/localtime又链接到/usr/share/zoneinfo/Asia/Shanghai,那就不得不去研究一下。

root@ubuntu:/usr/share/zoneinfo/Asia# ls -la Shanghai 
lrwxrwxrwx 1 root root 6 1029 00:54 Shanghai -> ../PRC
root@ubuntu:/usr/share/zoneinfo/Asia# pwd
/usr/share/zoneinfo/Asia
root@ubuntu:/usr/share/zoneinfo/Asia#

      这个文件又链接到另一个文件,继续跟踪。不管是用cat,还是vim都显示的是乱码。隐约可以看见CST字眼。那基本就可以确定它的内容没有问题。

二.问题

      我新装好的centos7.3上面date后,显示的是UTC时间,比北京时间慢8个小时,这是怎么回事。

三.踩坑

      自己也想过用ntp方式来矫正时间。

[root@linux ~]# ntpdate time.ntp.org

      时间还是没有改过来,这就奇怪了。经过网上一番查找,说是时区的问题。在一篇CSDN里面介绍说是执行如下命令:

[root@linux ~]# ln -sf /etc/localtime /usr/share/zoneinfo/Asia/ShangHai

      我就在服务器上执行了,结果悲剧了。仔细分析上述命令就可以知道,它是把/etc/localtime的内容赋予了…/ShangHai,就相当于有三个节点“时区文件1->/etc/localtime->…/ShangHai”,这三个文件的内容一模一样,这不就是导致ShangHai这个时区文件丢失了吗。在这种情况下,重启、改链接、ntp都不会改正时间。那也不能放弃,继续百度。看见有人说可以在/etc/profile里面写入通过tzselect的生成的脚本就可以,那必须得试试。

.....................20分钟之后

还是不行,UTC成为了我心里挥之不去的阴影。不行,不能这样乱投医。静下心仔细想想自己进行过什么样的魔鬼操作。终于意识到问题所在了。那怎么解决呢,谁也没教过我怎么搞定这种刁钻的问题,百度“不小心把时区文件删了”,你什么都搜不到,因为没有人会去动这个东西,besides me.

四.问题解决

      其实最后经过自己深入的了解,得出两种解决的办法。个人还是比较推荐第二种,以防以后会出问题。

  1. 直接通过date -s修改时间,然后写入时钟硬件。这种也能用,只不过总感觉不可靠,如果以后的服务要求ntp同步,那基本就玩完了,因为时区还是不是中国。
[root@linux ~]# date -s [时间]
[root@linux ~]# hwclock --systohc
  1. 寻找替代品。自己当时也是瞎搞,想着从自己的虚拟机ubuntu找一下ShangHai文件,直接导入到服务器中。本来没抱希望,结果居然可以。
root@ubuntu:/etc# ln -s /usr/share/zoneinfo/Asia/Shanghai localtime
root@ubuntu:/etc# date
20201220日 星期日 10:50:44 CST
root@ubuntu:/etc# 

五.备注

test

  • 在做链接的时候尽量不要用“ln -sf”,很容易出问题。
  • 在进行文件的增删改时,一定要备份。即便你的操作有问题,也可以复原。
  • 自己多动动脑子。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值