-
Notifications
You must be signed in to change notification settings - Fork 457
Open
Labels
enhancementNew feature or requestNew feature or request
Description
由于 MongoDB 的 $gt/$gte 、 $lt/$lte 只会返回和 key 相同类型的数据,所以使用 splitVector + range query 并行拉取时,可能由于表中的 key 存在多种类型而漏掉数据。
关于上面的问题,MongoShake 在配置中已经做了很好的提示:
# 单个表最大拉取的线程数,默认是单线程拉取。需要具备splitVector权限。
# 注意:对单个表来说,仅支持索引对应的value是同种类型,如果有不同类型请勿启用该配置项!
full_sync.reader.parallel_thread = 1
但是问题在于,很多用户可能并不理解其中的原因,或者忘记或者不知道如何检查。从而错误配置,并导致同步之后误丢失数据。
因此,建议在执行 parallel fetching 之前增加一个类型检查,确保类型是一致的。
检查的方法可以做的简单高效:获取 key 的最大值和最小值,判断他们类型是否一样。
比如有一个表,key 是 _id:
mymongo:PRIMARY> db.t1.find().sort({_id:1})
{ "_id" : 1 }
{ "_id" : 2 }
{ "_id" : 3 }
{ "_id" : "2" }
{ "_id" : ObjectId("68b6f358504f693358471f4b") }
{ "_id" : ObjectId("68b6f47c504f693358471f4c"), "a" : 2 }
{ "_id" : ObjectId("68b6f47d504f693358471f4d"), "a" : 3 }
{ "_id" : ISODate("2025-09-02T13:38:32.559Z") }
# 获取 key 的最小值,是一个数字
mymongo:PRIMARY> db.t1.find().sort({_id:1}).limit(1)
{ "_id" : 1 }
# 获取 key 的最大值,是一个 Date
mymongo:PRIMARY> db.t1.find().sort({_id:-1}).limit(1)
{ "_id" : ISODate("2025-09-02T13:38:32.559Z") }
上述语句会走 IDHACK IndexScan,所以不用担心效率问题。
如果存在多种类型,则打印 原因,并 "give up parallel fetching",回退到单并发。
否则,可以放心大胆的走多并发。。
不过需要注意的是,需要将数字类型视为同一种"归一化"类型。参考 BSONTypes:https://www.mongodb.com/docs/manual/reference/bson-types/#bson-types
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
enhancementNew feature or requestNew feature or request