mongodb索引啥时候更新?

Posted

技术标签:

【中文标题】mongodb索引啥时候更新?【英文标题】:When are mongodb indexes updated?mongodb索引什么时候更新? 【发布时间】:2016-02-28 12:22:25 【问题描述】:

问题

在向应用程序报告写操作成功之前是否更新了 mongodb 索引,还是在后台运行索引更新?如果它们在后台运行:有没有办法等待索引更新完成?

背景

我有一个文件

person1obj = 
  email: 'user@domain.tld',
  [...]

people 集合中,其中一个唯一 索引应用于email 字段。现在我想插入另一个文档

person2obj = 
  email: 'user@domain.tld',
  [...]

显然,在插入person2 之前,我必须更改person1email 字段。使用猫鼬,代码看起来像

mongoose.model('Person').create(person1obj, function (err, person1) 
  // person1 has been saved to the db and 'user@domain.tld' is 
  // added to the *unique* email field index

  // change email for person1 and save
  person1.email = 'otheruser@domain.tld';
  person1.save(function(err, person1) 
    // person1 has been updated in the db

    // QUESTION: is it guaranteed that 'user@domain.tld' has been removed from
    //           the index? 

    // inserting person2 could fail if the index has not yet been updated
    mongoose.model('Person').create(person2obj, function (err, person2) 
      // ...
    );
  );
);

我看到我的单元测试随机失败,错误为E11000 duplicate key error index,这让我怀疑索引更新是否在后台运行。

这个问题可能与 mongodb 的 write concern 有关,但我找不到任何关于索引更新实际过程的文档。

【问题讨论】:

索引更新是写操作的一部分。它们不在后台运行。现在,如果您正在从辅助节点读取数据,那么您可能会得到陈旧的数据,但这与索引的工作方式无关。 @SergioTulentsev 谢谢!你有指向解释行为的文档的指针吗? 【参考方案1】:

至少在唯一索引的情况下,索引不会在后台运行。这一点很明显,当您尝试使用假定唯一的重复键编写新文档时,您会遇到重复键错误。

如果索引在后台异步发生,Mongo 将无法判断写入是否真的成功。因此,索引必须在写入序列期间发生。

虽然我没有证据证明这一点(虽然 Mongo 是开源的,但如果你有足够的时间可以查看它),我相信所有索引都是在写入序列期间完成的,即使它不是唯一索引。为影响唯一索引的写入设置特殊逻辑是没有意义的。

【讨论】:

【参考方案2】:

来自FAQ(强调我的):

写操作如何影响索引?

除了文档本身之外,任何更改索引字段的写入操作都需要更新索引。如果您更新的文档导致文档增长超出分配的记录大小,则 MongoDB 必须更新包含此文档的所有索引作为更新操作的一部分

因此,如果您的应用程序写入繁重,则创建过多索引可能会影响性能。

【讨论】:

以上是关于mongodb索引啥时候更新?的主要内容,如果未能解决你的问题,请参考以下文章

mongodb索引加错了有啥影响

mongodb batchsize 啥意思

MongoDB的位置索引在啥单位?米?迈尔斯?

哈希和升序索引之间的 Mongodb 性能差异(有啥理由不在无序字段中使用哈希?)

深入理解MongoDB的复合索引

如果列不断更新,MongoDB 如何保持索引的数字列始终排序?