Skip to content

Commit

Permalink
SERVER-22970 fix update race with background index build
Browse files Browse the repository at this point in the history
There are two distinct fixes that must be done together:

- SERVER-23807: update should throw write conflict on unindex
- SERVER-18844: background index builds should reacquire the snapshot to
                properly detect write conflicts with concurrent updates
  • Loading branch information
ksuarz committed Apr 21, 2016
1 parent 33471d4 commit f27b0ca
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/mongo/db/catalog/index_create.cpp
Expand Up @@ -259,6 +259,8 @@ Status MultiIndexBlock::insertAllDocumentsInCollection(std::set<RecordId>* dupsO

WriteUnitOfWork wunit(_txn);
Status ret = insert(objToIndex.value(), loc);
if (_buildInBackground)
exec->saveState();
if (ret.isOK()) {
wunit.commit();
} else if (dupsOut && ret.code() == ErrorCodes::DuplicateKey) {
Expand All @@ -269,6 +271,8 @@ Status MultiIndexBlock::insertAllDocumentsInCollection(std::set<RecordId>* dupsO
// Fail the index build hard.
return ret;
}
if (_buildInBackground)
exec->restoreState(); // Handles any WCEs internally.

// Go to the next document
progress->hit();
Expand Down
20 changes: 19 additions & 1 deletion src/mongo/db/storage/wiredtiger/wiredtiger_index.cpp
Expand Up @@ -1069,8 +1069,17 @@ void WiredTigerIndexUnique::_unindex(WT_CURSOR* c,
// dups are allowed, so we have to deal with a vector of RecordIds.

int ret = WT_OP_CHECK(c->search(c));
if (ret == WT_NOTFOUND)
if (ret == WT_NOTFOUND) {
// WT_NOTFOUND is only expected during a background index build. Insert a dummy value and
// delete it again to trigger a write conflict in case this is being concurrently indexed by
// the background indexer.
c->set_key(c, keyItem.Get());
c->set_value(c, emptyItem.Get());
invariantWTOK(WT_OP_CHECK(c->insert(c)));
c->set_key(c, keyItem.Get());
invariantWTOK(WT_OP_CHECK(c->remove(c)));
return;
}
invariantWTOK(ret);

WT_ITEM old;
Expand Down Expand Up @@ -1178,6 +1187,15 @@ void WiredTigerIndexStandard::_unindex(WT_CURSOR* c,
int ret = WT_OP_CHECK(c->remove(c));
if (ret != WT_NOTFOUND) {
invariantWTOK(ret);
} else {
// WT_NOTFOUND is only expected during a background index build. Insert a dummy value and
// delete it again to trigger a write conflict in case this is being concurrently indexed by
// the background indexer.
c->set_key(c, item.Get());
c->set_value(c, emptyItem.Get());
invariantWTOK(WT_OP_CHECK(c->insert(c)));
c->set_key(c, item.Get());
invariantWTOK(WT_OP_CHECK(c->remove(c)));
}
}

Expand Down

0 comments on commit f27b0ca

Please sign in to comment.