代码之家  ›  专栏  ›  技术社区  ›  rendybjunior

更新MongoDB范围碎片上的标记范围

  •  1
  • rendybjunior  · 技术社区  · 10 年前

    假设我使用范围标记为碎片设置了一个最小和最大键。之后,我发现我定义的标记范围将不平衡。然后我必须更改标记范围值。

    我在MongoDB文档中进行了搜索,它只提到了添加和删除标签,没有提到更新/更改标签范围值。

    然后我通过更新db-configcollectionshard中的值来做一些实验

    mongos> db.tags.find()
    { "_id" : { "ns" : "test.lab.range", "min" : { "_id" : 1 } }, "ns" : "test.lab.range", "min" : { "_id" : 1 }, "max" : { "_id" : 100 }, "tag" : "rangeTime1" }
    { "_id" : { "ns" : "test.lab.range", "min" : { "_id" : 100 } }, "ns" : "test.lab.range", "min" : { "_id" : 100 }, "max" : { "_id" : 200 }, "tag" : "rangeTime2" }
    mongos> db.tags.update({_id:{ "ns" : "test.lab.range", "min" : { "_id" : 100 } }},{$set:{min : {_id : 150}}})
    mongos> db.tags.update({_id:{ "ns" : "test.lab.range", "min" : { "_id" : 1 } }},{$set:{max : {_id : 150}}})
    mongos> db.tags.find()
    { "_id" : { "ns" : "test.lab.range", "min" : { "_id" : 1 } }, "ns" : "test.lab.range", "min" : { "_id" : 1 }, "max" : { "_id" : 150 }, "tag" : "rangeTime1" }
    { "_id" : { "ns" : "test.lab.range", "min" : { "_id" : 100 } }, "max" : { "_id" : 200 }, "min" : { "_id" : 150 }, "ns" : "test.lab.range", "tag" : "rangeTime2" }
    

    它工作得很好,但标签id没有更新。注意,即使在rangeTime2中将min更新为150,id也不会更新,这使得标记集合看起来不一致。

    它有点脏,但遗憾的是,它是有效的。

    这是更新标记范围的正确方法吗?还有其他更好的方法吗?

    1 回复  |  直到 10 年前
        1
  •  3
  •   Adam Comerford    10 年前

    这并不明显,但如果你跑步 sh.addTagRange() 如果具有相同的最小值(在您的情况下为1或100)和不同的最大值,则具有该最小值的现有标记范围将发生变化,基本上起到就地更新的作用( addTagRange() helper基本上运行 upsert 基于_id字段并进行一些健全性检查),这可以通过在没有括号的情况下运行它来看到:

    mongos> sh.addTagRange
    function ( ns, min, max, tag ) {
        if ( bsonWoCompare( min, max ) == 0 ) {
            throw new Error("min and max cannot be the same");
        }
    
        var config = db.getSisterDB( "config" );
        config.tags.update( {_id: { ns : ns , min : min } } ,
                {_id: { ns : ns , min : min }, ns : ns , min : min , max : max , tag : tag } ,
                true );
        sh._checkLastError( config );
    }
    

    要更改标记范围的最小值,这将不起作用-您需要删除并重新添加,或者需要手动更新 _id.min 子文档中的字段以及 min 字段,以避免您看到的不一致。我建议当前使用删除和重新添加选项,以避免混淆。这些命令将在稍后的版本中进行重构(尚未计划),我个人在 SERVER-6352 让这在未来变得不那么麻烦。