You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修改服务器时间致MongoDB副本集故障:跨6个月跳转后27017无监听

MongoDB副本集因大幅时间跳转(6个月+)导致27017端口停止监听的故障排查与解决

问题背景

生产服务器上有一套每日执行的开票流程,耗时约4小时。当前部署的QA环境在同一台机器上搭建了3节点MongoDB副本集,测试目标为:用当日数据执行开票流程后,通过sudo timedatectl set-time ${TIME}修改服务器时间至次日重复执行,计划2天内完成一周流程测试。

故障现象

  • 时间跳转幅度为1天或1个月时,系统无异常;
  • 跳转6个月及以上时,MongoDB故障,27017端口不再处于LISTENING状态;
  • 执行netstat -nap | grep mongo得到以下输出:
netstat -nap | grep mongo
(Not all processes could be identified, non-owned process info
 will not be shown, you would have to be root to see it all.)
unix  2      [ ]         STREAM                   4107509  -                    /tmp/mongodb-27017.sock
unix  2      [ ACC ]     STREAM     LISTENING     32418    -                    /tmp/mongodb-27012.sock
unix  2      [ ACC ]     STREAM     LISTENING     32393    -                    /tmp/mongodb-27011.sock
unix  2      [ ACC ]     STREAM     LISTENING     24202    -                    /tmp/mongodb-20000.sock
unix  2      [ ACC ]     STREAM     LISTENING     33524    -                    /tmp/mongodb-27023.sock
unix  2      [ ACC ]     STREAM     LISTENING     29140    -                    /tmp/mongodb-20002.sock
unix  2      [ ACC ]     STREAM     LISTENING     26360    -                    /tmp/mongodb-20001.sock
unix  2      [ ACC ]     STREAM     LISTENING     34090    -                    /tmp/mongodb-27013.sock
unix  2      [ ACC ]     STREAM     LISTENING     34093    -                    /tmp/mongodb-27021.sock
unix  2      [ ACC ]     STREAM     LISTENING     30073    -                    /tmp/mongodb-27022.sock

已尝试的无效操作

  • 重启MongoDB进程
  • 手动删除socket文件
  • 重启机器

排查步骤

  1. 查看MongoDB核心日志
    检查MongoDB日志文件(默认路径/var/log/mongodb/mongod.log,或自定义配置路径),搜索时间跳转后的报错信息。大幅时间变更可能触发副本集心跳时间戳校验、oplog时间戳冲突等内部逻辑报错。执行命令:

    tail -n 200 /var/log/mongodb/mongod.log
    
  2. 检查副本集节点状态
    通过正常监听的本地socket连接到副本集节点,执行rs.status()查看集群状态:

    mongo --socket /tmp/mongodb-27011.sock
    > rs.status()
    

    重点关注节点stateStr、optime、optimeDate字段,确认是否存在时间戳不匹配、节点无法选举等异常。

  3. 验证oplog时间范围
    大幅时间跳转可能导致oplog时间戳超出MongoDB可处理范围,执行以下命令查看oplog的首尾时间:

    mongo --socket /tmp/mongodb-27011.sock
    > use local
    > db.oplog.rs.find().sort({$natural: -1}).limit(1).pretty()  # 最新oplog条目
    > db.oplog.rs.find().sort({$natural: 1}).limit(1).pretty()   # 最早oplog条目
    

    核对返回的ts字段对应时间,确认是否与跳转后的系统时间存在冲突。

  4. 检查系统时间同步服务
    若系统开启NTP服务,可能自动将时间同步回原时间,导致MongoDB异常。执行命令确认NTP状态:

    timedatectl status
    

    若NTP service处于active状态,先停止同步:

    sudo systemctl stop systemd-timesyncd
    sudo timedatectl set-ntp false
    

解决方法

  1. 修复副本集时间戳冲突
    如果日志显示oplog时间戳异常,需重新初始化副本集:

    • 停止所有MongoDB节点;
    • 删除所有节点的local数据库目录(默认路径/var/lib/mongodb/local);
    • 重新初始化副本集:
      mongo --socket /tmp/mongodb-27011.sock
      > rs.initiate()
      > rs.add("localhost:27012")
      > rs.add("localhost:27013")
      
    • 重新导入测试数据或从备份恢复。
  2. 调整MongoDB时间校验参数
    修改mongod.conf配置文件,添加时间校验放宽参数(适用于MongoDB 3.4及以上版本):

    setParameter:
      enableClockSkewAdjustment: true
      maxClockSkewSeconds: 864000  # 设置为10天,可根据测试需求调整
    

    修改后重启所有MongoDB节点。

  3. 替换大幅时间跳转的测试方案
    避免直接修改系统时间,改用应用层时间模拟:

    • 在开票流程代码中注入自定义时间,覆盖系统时间获取逻辑;
    • 使用Docker等容器化工具,为测试环境隔离独立的系统时间,不影响宿主机MongoDB运行。

内容的提问来源于stack exchange,提问作者Rodrigo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 09:05:35