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

Mongos重启后数据丢失问题疑因路由缓存导致

重启mongos后未分片集合数据丢失问题的修复与规避方案

问题重现步骤

  • 在test数据库创建未分片的test集合:
use test
db.test.insert({"k": 1})
  • 手动修改config.databases切换主分片:
use config

db.databases.find({"_id": "test"})
{ "_id" : "test", "primary" : "rs2_1", "partitioned" : false }

db.databases.update({"_id": "test"}, {"$set": {"primary": "rs1_1"}})

db.databases.find({"_id": "test"})
{ "_id" : "test", "primary" : "rs1_1", "partitioned" : false }
  • 此时仍能正常查询数据:
use test
db.test.find()
{ "_id" : ObjectId("63f74df722fe0bf5b3d2d284"), "k" : 1}
  • 重启mongos进程:
kill 123
mongos -f /home/mongodb/mongo.conf
  • 重启后查询不到数据:
db.test.find()

原因分析

  • 未分片集合的路由依赖config.databases中的primary字段指向的分片
  • mongos会将路由信息缓存至内存,手动修改config.databases不会触发内存缓存的更新,因此重启前仍能从原分片读取数据
  • 重启mongos后,会重新加载config.databases中的配置,此时路由指向新分片,但新分片并没有对应的数据,导致查询为空

修复方案

  1. 恢复路由并通过官方命令迁移数据
    • 先将config.databases中的primary改回原分片rs2_1,执行db.adminCommand({flushRouterConfig: 1})刷新mongos路由缓存(无需重启),确保能正常读取数据
    • 使用MongoDB官方的movePrimary命令迁移未分片数据库的主分片,该命令会自动同步数据、更新集群配置并刷新路由:
      db.adminCommand({movePrimary: "test", to: "rs1_1"})
      
    • 迁移完成后,再次查询数据即可正常访问
  2. 手动迁移数据至目标分片
    • 如果无法恢复原配置,直接连接原分片rs2_1,将test.test集合的数据导出,再导入到新分片rs1_1的对应数据库中,之后确认config.databases的primary配置正确

规避方案

  • 禁止手动修改config库系统集合:config.databases、config.shards等属于集群核心配置集合,手动修改会导致配置与实际数据分布不一致,引发各类异常
  • 使用官方命令调整分片:迁移未分片数据库主分片必须用movePrimary命令,该命令会自动处理数据同步、配置更新和路由缓存刷新,保证集群状态一致
  • 修改配置后强制刷新缓存:若特殊情况必须修改配置(不推荐),修改后需在所有mongos节点执行db.adminCommand({flushRouterConfig: 1}),强制刷新内存路由缓存,避免重启后出现配置不一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 21:39:36