在 MongoDB 分片集群上检查索引的一致性
2024-12-10 13:41 abce 阅读(51) 评论(0) 编辑 收藏 举报
在 MongoDB 分片集群中,各分片之间索引分布不一致的情况比你想象的要常见,这是因为用户不使用 MongoS 而是直接在分片中创建索引。
在块迁移过程中,由于索引不匹配,系统无法在分片间传输数据,从而导致迁移失败。
发生这种情况时,分片日志中的典型错误信息可能如下所示:
1 2 3 4 5 | { "t" :{ "$date" : "2024-05-23T14:27:49.111+00:00" }, "s" : "I" , "c" : "SHARDING" , "id" :5087102, "ctx" : "migrateThread" , "msg" : "Recipient failed to copy oplog entries for retryable writes and transactions from donor" , "attr" : { "namespace" : "test.cincomillones" , "migrationSessionId" : "Shard_1_Shard_2_646884t4835b68a1af8781" , "fromShard" : "Shard_1" , "error" : "migrate failed: CannotCreateCollection: aborting, shard is missing 1 indexes and collection is not empty. Non-trivial index creation should be scheduled manually" }} |
该错误表明,由于一个或多个分片上的索引缺失,无法迁移块。要解决这个问题,必须确保所有分片的索引一致性。
检查和解决此问题的步骤:
第一步是连接到每个分片的 PRIMARY 节点,检查有问题的集合的索引。在本示例中,正如我们在日志文件中看到的,集合 test.cincomillones 存在索引不一致问题。
以 PRIMARY 分片为参考,检查索引在哪个分区丢失是非常重要的。
分片1:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | shard1: PRIMARY > db.cincomillones.getIndexes() [ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" }, { "v" : 2, "key" : { "BetID" : "hashed" }, "name" : "BetID_hashed" }, { "v" : 2, "key" : { "MasterEventId" : 1 }, "name" : "MasterEventId_1" } ] |
分片2:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | shard2: PRIMARY > db.cincomillones.getIndexes() [ { "v" : 2, "key" : { "_id" : 1 }, "name" : "_id_" }, { "v" : 2, "key" : { "BetID" : "hashed" }, "name" : "BetID_hashed" } ] |
如上所示,与分片 2 相比,分片 1 多了一个索引(MasterEventId_1)。索引不匹配导致了块迁移失败。
要解决这个问题,我们需要在缺少索引的分片上创建缺少的索引。在这种情况下,我们将在分片 2 中添加 MasterEventId 索引:
1 | shard2: PRIMARY > db.cincomillones.createIndex({ "MasterEventId" : 1 }) |
创建缺失索引后,一个好的做法是验证所有分片的索引是否一致。
我们可以在所有分片上再次运行 getIndexes,或者使用 MongoDB 内置命令 shardedIndexConsistency 来检查。
你需要在 PRIMARY configServer 上运行以下命令来检查分片间的索引不一致性:
1 | config: PRIMARY > db.serverStatus().shardedIndexConsistency |
该命令将报告任何不一致,从而确保所有分片保持同步。
创建丢失的索引后,我们将不再看到有索引不一致:
1 2 3 | configRepl: PRIMARY > db.serverStatus().shardedIndexConsistency { "numShardedCollectionsWithInconsistentIndexes" : NumberLong(0) } |
如果运行的是 MongoDB 5.0,则可以使用聚合管道来查找分片间不一致的索引,如下所述:
1 | https://www.mongodb.com/docs/v5.0/tutorial/manage-indexes/#find-inconsistent-indexes-across-shards |
从 MongoDB 7.0 开始,可以使用一项新功能来检查不一致索引:
1 | https://www.mongodb.com/docs/manual/reference/inconsistency-type/InconsistentIndex/ |
该方法会返回一个游标,其中包含一批文档,显示在分片元数据中发现的不一致之处,即
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | { cursor : { id: Long( "0" ), ns: "test.$cmd.aggregate" , firstBatch: [ { type: "InconsistentIndex" , description: "Found an index of a sharded collection that is inconsistent between different shards" , details: { namespace: "test.authors" , info: { missingFromShards: [ "shard-rs1" ], inconsistentProperties: [ ], indexName: "index1" } } } ], }, ok: 1 } |
确保分片间的索引一致性对于 MongoDB 分片集群的顺利运行至关重要。不一致的索引可能会阻碍块迁移,从而导致潜在的停机或性能下降。
通过检查每个分片的索引、修复不匹配并使用所述方法验证一致性,可以保持集群平稳运行。
有关索引一致性检查的更多详情,请参阅 MongoDB 的官方文档:
1 2 3 4 5 | https://www.mongodb.com/docs/v5.0/reference/command/serverStatus/#mongodb-serverstatus-serverstatus.shardedIndexConsistency https://www.mongodb.com/docs/v5.0/tutorial/manage-indexes/#find-inconsistent-indexes-across-shards https://www.mongodb.com/docs/manual/reference/inconsistency-type/InconsistentIndex/ |
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 我与微信审核的“相爱相杀”看个人小程序副业
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~
2020-12-10 Oracle使用audit跟踪登录失败的连接信息
2015-12-10 threaded_execution
2015-12-10 数据块损坏(block corruption)