summaryrefslogtreecommitdiff
path: root/src/mongo/db/catalog
diff options
context:
space:
mode:
authorSiyuan Zhou <siyuan.zhou@mongodb.com>2016-11-07 14:57:51 -0500
committerSiyuan Zhou <siyuan.zhou@mongodb.com>2016-11-08 14:41:48 -0500
commit17c37d0e626a61aeae8f4f149da98df2496740fa (patch)
tree9b82e98ffde8067f2314a5fde713c03fc0e7b38a /src/mongo/db/catalog
parenta79c8b6455ba50d40f42bead5ce24a6093734dc3 (diff)
downloadmongo-17c37d0e626a61aeae8f4f149da98df2496740fa.tar.gz
SERVER-26202 Relax index constraints in oplog application
This reverts commit d23e79eb9e69bd746416d9f674dfaee59457c887.
Diffstat (limited to 'src/mongo/db/catalog')
-rw-r--r--src/mongo/db/catalog/collection.cpp10
-rw-r--r--src/mongo/db/catalog/index_catalog.cpp34
-rw-r--r--src/mongo/db/catalog/index_catalog.h9
-rw-r--r--src/mongo/db/catalog/index_create.cpp8
4 files changed, 40 insertions, 21 deletions
diff --git a/src/mongo/db/catalog/collection.cpp b/src/mongo/db/catalog/collection.cpp
index 60b8ce717a1..757077efb56 100644
--- a/src/mongo/db/catalog/collection.cpp
+++ b/src/mongo/db/catalog/collection.cpp
@@ -674,10 +674,7 @@ StatusWith<RecordId> Collection::updateDocument(OperationContext* txn,
IndexAccessMethod* iam = ii.accessMethod(descriptor);
InsertDeleteOptions options;
- options.logIfError = false;
- options.dupsAllowed =
- !(KeyPattern::isIdKeyPattern(descriptor->keyPattern()) || descriptor->unique()) ||
- repl::getGlobalReplicationCoordinator()->shouldIgnoreUniqueIndex(descriptor);
+ IndexCatalog::prepareInsertDeleteOptions(txn, descriptor, &options);
UpdateTicket* updateTicket = new UpdateTicket();
updateTickets.mutableMap()[descriptor] = updateTicket;
Status ret = iam->validateUpdate(txn,
@@ -1105,7 +1102,10 @@ public:
// There's no need to compute the prefixes of the indexed fields that cause the
// index to be multikey when validating the index keys.
MultikeyPaths* multikeyPaths = nullptr;
- iam->getKeys(recordBson, &documentKeySet, multikeyPaths);
+ iam->getKeys(recordBson,
+ IndexAccessMethod::GetKeysMode::kEnforceConstraints,
+ &documentKeySet,
+ multikeyPaths);
if (!descriptor->isMultikey(_txn) && documentKeySet.size() > 1) {
string msg = str::stream() << "Index " << descriptor->indexName()
diff --git a/src/mongo/db/catalog/index_catalog.cpp b/src/mongo/db/catalog/index_catalog.cpp
index f8d3a04f4c1..ffbfea515fd 100644
--- a/src/mongo/db/catalog/index_catalog.cpp
+++ b/src/mongo/db/catalog/index_catalog.cpp
@@ -1249,23 +1249,12 @@ const IndexDescriptor* IndexCatalog::refreshEntry(OperationContext* txn,
// ---------------------------
-namespace {
-bool isDupsAllowed(IndexDescriptor* desc) {
- bool isUnique = desc->unique() || KeyPattern::isIdKeyPattern(desc->keyPattern());
- if (!isUnique)
- return true;
-
- return repl::getGlobalReplicationCoordinator()->shouldIgnoreUniqueIndex(desc);
-}
-}
-
Status IndexCatalog::_indexFilteredRecords(OperationContext* txn,
IndexCatalogEntry* index,
const std::vector<BsonRecord>& bsonRecords,
int64_t* keysInsertedOut) {
InsertDeleteOptions options;
- options.logIfError = false;
- options.dupsAllowed = isDupsAllowed(index->descriptor());
+ prepareInsertDeleteOptions(txn, index->descriptor(), &options);
for (auto bsonRecord : bsonRecords) {
int64_t inserted;
@@ -1306,8 +1295,8 @@ Status IndexCatalog::_unindexRecord(OperationContext* txn,
bool logIfError,
int64_t* keysDeletedOut) {
InsertDeleteOptions options;
+ prepareInsertDeleteOptions(txn, index->descriptor(), &options);
options.logIfError = logIfError;
- options.dupsAllowed = isDupsAllowed(index->descriptor());
// For unindex operations, dupsAllowed=false really means that it is safe to delete anything
// that matches the key, without checking the RecordID, since dups are impossible. We need
@@ -1376,6 +1365,25 @@ BSONObj IndexCatalog::fixIndexKey(const BSONObj& key) {
return key;
}
+void IndexCatalog::prepareInsertDeleteOptions(OperationContext* txn,
+ const IndexDescriptor* desc,
+ InsertDeleteOptions* options) {
+ auto replCoord = repl::ReplicationCoordinator::get(txn);
+ if (replCoord->shouldRelaxIndexConstraints(NamespaceString(desc->parentNS()))) {
+ options->getKeysMode = IndexAccessMethod::GetKeysMode::kRelaxConstraints;
+ } else {
+ options->getKeysMode = IndexAccessMethod::GetKeysMode::kEnforceConstraints;
+ }
+
+ // Don't allow dups for Id key. Allow dups for non-unique keys or when constraints relaxed.
+ if (KeyPattern::isIdKeyPattern(desc->keyPattern())) {
+ options->dupsAllowed = false;
+ } else {
+ options->dupsAllowed = !desc->unique() ||
+ options->getKeysMode == IndexAccessMethod::GetKeysMode::kRelaxConstraints;
+ }
+}
+
StatusWith<BSONObj> IndexCatalog::_fixIndexSpec(OperationContext* txn,
Collection* collection,
const BSONObj& spec) {
diff --git a/src/mongo/db/catalog/index_catalog.h b/src/mongo/db/catalog/index_catalog.h
index bd0c919076a..4016b7860d4 100644
--- a/src/mongo/db/catalog/index_catalog.h
+++ b/src/mongo/db/catalog/index_catalog.h
@@ -48,6 +48,7 @@ class Collection;
class IndexDescriptor;
class IndexAccessMethod;
+struct InsertDeleteOptions;
/**
* how many: 1 per Collection
@@ -337,6 +338,14 @@ public:
static BSONObj fixIndexKey(const BSONObj& key);
+ /**
+ * Fills out 'options' in order to indicate whether to allow dups or relax
+ * index constraints, as needed by replication.
+ */
+ static void prepareInsertDeleteOptions(OperationContext* txn,
+ const IndexDescriptor* desc,
+ InsertDeleteOptions* options);
+
private:
static const BSONObj _idObj; // { _id : 1 }
diff --git a/src/mongo/db/catalog/index_create.cpp b/src/mongo/db/catalog/index_create.cpp
index b9ca4f87a3f..17a3d981d5d 100644
--- a/src/mongo/db/catalog/index_create.cpp
+++ b/src/mongo/db/catalog/index_create.cpp
@@ -245,9 +245,11 @@ StatusWith<std::vector<BSONObj>> MultiIndexBlock::init(const std::vector<BSONObj
const IndexDescriptor* descriptor = index.block->getEntry()->descriptor();
- index.options.logIfError = false; // logging happens elsewhere if needed.
- index.options.dupsAllowed = !descriptor->unique() || _ignoreUnique ||
- repl::getGlobalReplicationCoordinator()->shouldIgnoreUniqueIndex(descriptor);
+ IndexCatalog::prepareInsertDeleteOptions(_txn, descriptor, &index.options);
+ index.options.dupsAllowed = index.options.dupsAllowed || _ignoreUnique;
+ if (_ignoreUnique) {
+ index.options.getKeysMode = IndexAccessMethod::GetKeysMode::kRelaxConstraints;
+ }
log() << "build index on: " << ns << " properties: " << descriptor->toString();
if (index.bulk)