diff options
author | Benety Goh <benety@mongodb.com> | 2017-08-10 11:58:43 -0400 |
---|---|---|
committer | Benety Goh <benety@mongodb.com> | 2017-08-10 13:03:35 -0400 |
commit | b8eb96c3c9c2ad2e0c4520785ba49cb9830b1a21 (patch) | |
tree | ed07f18aa65417eb0ad902f03358a554dd99dafb | |
parent | 54ce75ef7074fefe343114e2855426271f1f418e (diff) | |
download | mongo-b8eb96c3c9c2ad2e0c4520785ba49cb9830b1a21.tar.gz |
SERVER-30554 relax locking mode in applyOps when applying CRUD-only ops non-atomically
This allows concurrent applyOps commands to update the same collection on storage
engines that support document level concurrency.
(cherry picked from commit bca3f70566991afa2dfb38dc06494b0f6f04fffa)
-rw-r--r-- | jstests/replsets/apply_ops_concurrent_non_atomic_same_collection.js | 11 | ||||
-rw-r--r-- | jstests/replsets/apply_ops_concurrent_non_atomic_same_db.js | 11 | ||||
-rw-r--r-- | src/mongo/db/catalog/apply_ops.cpp | 5 |
3 files changed, 25 insertions, 2 deletions
diff --git a/jstests/replsets/apply_ops_concurrent_non_atomic_same_collection.js b/jstests/replsets/apply_ops_concurrent_non_atomic_same_collection.js new file mode 100644 index 00000000000..004eeaaa52f --- /dev/null +++ b/jstests/replsets/apply_ops_concurrent_non_atomic_same_collection.js @@ -0,0 +1,11 @@ +(function() { + 'use strict'; + + load('jstests/replsets/libs/apply_ops_concurrent_non_atomic.js'); + + new ApplyOpsConcurrentNonAtomicTest({ + ns1: 'test.coll', + ns2: 'test.coll', + requiresDocumentLevelConcurrency: true, + }).run(); +}()); diff --git a/jstests/replsets/apply_ops_concurrent_non_atomic_same_db.js b/jstests/replsets/apply_ops_concurrent_non_atomic_same_db.js new file mode 100644 index 00000000000..10f874382a5 --- /dev/null +++ b/jstests/replsets/apply_ops_concurrent_non_atomic_same_db.js @@ -0,0 +1,11 @@ +(function() { + 'use strict'; + + load('jstests/replsets/libs/apply_ops_concurrent_non_atomic.js'); + + new ApplyOpsConcurrentNonAtomicTest({ + ns1: 'test.coll1', + ns2: 'test.coll2', + requiresDocumentLevelConcurrency: false, + }).run(); +}()); diff --git a/src/mongo/db/catalog/apply_ops.cpp b/src/mongo/db/catalog/apply_ops.cpp index 5756a068917..28ca548c18f 100644 --- a/src/mongo/db/catalog/apply_ops.cpp +++ b/src/mongo/db/catalog/apply_ops.cpp @@ -158,7 +158,8 @@ Status _applyOps(OperationContext* opCtx, invariant(opCtx->lockState()->isW()); status = repl::applyCommand_inlock(opCtx, opObj, true); } else { - Lock::DBLock dbWriteLock(opCtx->lockState(), nss.db(), MODE_X); + Lock::DBLock dbWriteLock(opCtx->lockState(), nss.db(), MODE_IX); + Lock::CollectionLock lock(opCtx->lockState(), nss.ns(), MODE_IX); OldClientContext ctx(opCtx, ns); status = @@ -329,7 +330,7 @@ Status applyOps(OperationContext* opCtx, // There's only one case where we are allowed to take the database lock instead of the global // lock - no preconditions; only CRUD ops; and non-atomic mode. if (!hasPrecondition && areOpsCrudOnly && !allowAtomic) { - dbWriteLock.emplace(opCtx->lockState(), dbName, MODE_X); + dbWriteLock.emplace(opCtx->lockState(), dbName, MODE_IX); } else { globalWriteLock.emplace(opCtx->lockState()); } |