在 MongoDB 分片集群中,各分片之间索引分布不一致的情况比你想象的要常见,这是因为用户不使用 MongoS 而是直接在分片中创建索引。
在块迁移过程中,由于索引不匹配,系统无法在分片间传输数据,从而导致迁移失败。
发生这种情况时,分片日志中的典型错误信息可能如下所示:
{"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:
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:
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 索引:
shard2:PRIMARY> db.cincomillones.createIndex({ "MasterEventId": 1 })
创建缺失索引后,一个好的做法是验证所有分片的索引是否一致。
我们可以在所有分片上再次运行 getIndexes,或者使用 MongoDB 内置命令 shardedIndexConsistency 来检查。
你需要在 PRIMARY configServer 上运行以下命令来检查分片间的索引不一致性:
config:PRIMARY> db.serverStatus().shardedIndexConsistency
该命令将报告任何不一致,从而确保所有分片保持同步。
创建丢失的索引后,我们将不再看到有索引不一致:
configRepl:PRIMARY> db.serverStatus().shardedIndexConsistency { "numShardedCollectionsWithInconsistentIndexes" : NumberLong(0) }
如果运行的是 MongoDB 5.0,则可以使用聚合管道来查找分片间不一致的索引,如下所述:
https://www.mongodb.com/docs/v5.0/tutorial/manage-indexes/#find-inconsistent-indexes-across-shards
从 MongoDB 7.0 开始,可以使用一项新功能来检查不一致索引:
https://www.mongodb.com/docs/manual/reference/inconsistency-type/InconsistentIndex/
该方法会返回一个游标,其中包含一批文档,显示在分片元数据中发现的不一致之处,即
{ 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 的官方文档:
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/标签:MongoDB,分片,PRIMARY,索引,mongodb,id From: https://www.cnblogs.com/abclife/p/18593653