summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorLouis Williams <louis.williams@mongodb.com>2018-01-31 17:06:33 -0500
committerLouis Williams <louis.williams@mongodb.com>2018-02-08 15:51:12 -0500
commitb77e46685dc7ae8b9893ef019a1cbc67798bb749 (patch)
tree04c4fb644337ebdde61cc5907f0f6e7f5550d2f5 /src/mongo
parent38aa3dfd1edd6a83540c9c5b5e654803cc960f69 (diff)
downloadmongo-b77e46685dc7ae8b9893ef019a1cbc67798bb749.tar.gz
SERVER-29876 Check if partial filter applies when unindexing documents
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/index/index_access_method.cpp16
-rw-r--r--src/mongo/db/index/index_access_method.h12
2 files changed, 24 insertions, 4 deletions
diff --git a/src/mongo/db/index/index_access_method.cpp b/src/mongo/db/index/index_access_method.cpp
index 7bc0c321b62..fe6f85b8cc0 100644
--- a/src/mongo/db/index/index_access_method.cpp
+++ b/src/mongo/db/index/index_access_method.cpp
@@ -220,7 +220,10 @@ Status IndexAccessMethod::remove(OperationContext* opCtx,
// multikey when removing a document since the index metadata isn't updated when keys are
// deleted.
MultikeyPaths* multikeyPaths = nullptr;
- getKeys(obj, options.getKeysMode, &keys, multikeyPaths);
+
+ // Relax key constraints on removal when deleting documents with invalid formats, but only
+ // those that don't apply to the partialIndex filter.
+ getKeys(obj, GetKeysMode::kRelaxConstraintsUnfiltered, &keys, multikeyPaths);
for (BSONObjSet::const_iterator i = keys.begin(); i != keys.end(); ++i) {
removeOneKey(opCtx, *i, loc, options.dupsAllowed);
@@ -595,11 +598,11 @@ void IndexAccessMethod::getKeys(const BSONObj& obj,
try {
doGetKeys(obj, keys, multikeyPaths);
} catch (const AssertionException& ex) {
+ // Suppress all indexing errors when mode is kRelaxConstraints.
if (mode == GetKeysMode::kEnforceConstraints) {
throw;
}
- // Suppress indexing errors when mode is kRelaxConstraints.
keys->clear();
if (multikeyPaths) {
multikeyPaths->clear();
@@ -608,6 +611,15 @@ void IndexAccessMethod::getKeys(const BSONObj& obj,
if (whiteList.find(ex.code()) == whiteList.end()) {
throw;
}
+
+ // If the document applies to the filter (which means that it should have never been
+ // indexed), do not supress the error.
+ const MatchExpression* filter = _btreeState->getFilterExpression();
+ if (mode == GetKeysMode::kRelaxConstraintsUnfiltered && filter &&
+ filter->matchesBSON(obj)) {
+ throw;
+ }
+
LOG(1) << "Ignoring indexing error for idempotency reasons: " << redact(ex)
<< " when getting index keys of " << redact(obj);
}
diff --git a/src/mongo/db/index/index_access_method.h b/src/mongo/db/index/index_access_method.h
index 32b821379c8..d6c5202487d 100644
--- a/src/mongo/db/index/index_access_method.h
+++ b/src/mongo/db/index/index_access_method.h
@@ -260,9 +260,17 @@ public:
std::set<RecordId>* dups);
/**
- * Specifies whether getKeys should relax the index constraints or not.
+ * Specifies whether getKeys should relax the index constraints or not, in order of most
+ * permissive to least permissive.
*/
- enum class GetKeysMode { kRelaxConstraints, kEnforceConstraints };
+ enum class GetKeysMode {
+ // Relax all constraints.
+ kRelaxConstraints,
+ // Relax all constraints on documents that don't apply to a partialFilterIndex.
+ kRelaxConstraintsUnfiltered,
+ // Enforce all constraints.
+ kEnforceConstraints
+ };
/**
* Fills 'keys' with the keys that should be generated for 'obj' on this index.