summaryrefslogtreecommitdiff
path: root/src/mongo
diff options
context:
space:
mode:
authorMathias Stearn <mathias@10gen.com>2015-11-24 18:31:14 -0500
committerMathias Stearn <redbeard0531@gmail.com>2015-12-02 18:44:54 -0500
commit405a5c8d09ccd32294e70d525c4168780356ff16 (patch)
tree30bc46a1c349426c52cd9c9fcce13761bddfe306 /src/mongo
parentc53eebbb6120ab0be19bf746d592ce426afa7682 (diff)
downloadmongo-405a5c8d09ccd32294e70d525c4168780356ff16.tar.gz
SERVER-21646 limit concurrency of writes to replicated capped collections
This prevents the primary from running significantly faster than secondaries. (cherry picked from commit f45b7c8e34743ba89407d90ee3392acb0d2be255)
Diffstat (limited to 'src/mongo')
-rw-r--r--src/mongo/db/catalog/collection.cpp18
-rw-r--r--src/mongo/db/catalog/collection.h9
2 files changed, 20 insertions, 7 deletions
diff --git a/src/mongo/db/catalog/collection.cpp b/src/mongo/db/catalog/collection.cpp
index 9b8e9a0726a..936909a4456 100644
--- a/src/mongo/db/catalog/collection.cpp
+++ b/src/mongo/db/catalog/collection.cpp
@@ -44,6 +44,7 @@
#include "mongo/db/catalog/collection_catalog_entry.h"
#include "mongo/db/catalog/database_catalog_entry.h"
#include "mongo/db/catalog/index_create.h"
+#include "mongo/db/global_environment_experiment.h"
#include "mongo/db/index/index_access_method.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/repl/replication_coordinator_global.h"
@@ -92,6 +93,7 @@ Collection::Collection(OperationContext* txn,
_details(details),
_recordStore(recordStore),
_dbce(dbce),
+ _needCappedLock(supportsDocLocking() && _recordStore->isCapped() && _ns.db() != "local"),
_infoCache(this),
_indexCatalog(this),
_cursorManager(fullNS) {
@@ -227,9 +229,12 @@ StatusWith<RecordId> Collection::_insertDocument(OperationContext* txn,
bool enforceQuota) {
dassert(txn->lockState()->isCollectionLockedForMode(ns().toString(), MODE_IX));
- // TODO: for now, capped logic lives inside NamespaceDetails, which is hidden
- // under the RecordStore, this feels broken since that should be a
- // collection access method probably
+ if (_needCappedLock) {
+ // X-lock the metadata resource for this capped collection until the end of the WUOW. This
+ // prevents the primary from executing with more concurrency than secondaries.
+ // See SERVER-21646.
+ Lock::ResourceLock{txn->lockState(), ResourceId(RESOURCE_METADATA, _ns.ns()), MODE_X};
+ }
StatusWith<RecordId> loc = _recordStore->insertRecord(
txn, docToInsert.objdata(), docToInsert.objsize(), _enforceQuota(enforceQuota));
@@ -296,6 +301,13 @@ StatusWith<RecordId> Collection::updateDocument(OperationContext* txn,
dassert(txn->lockState()->isCollectionLockedForMode(ns().toString(), MODE_IX));
invariant(objOld.snapshotId() == txn->recoveryUnit()->getSnapshotId());
+ if (_needCappedLock) {
+ // X-lock the metadata resource for this capped collection until the end of the WUOW. This
+ // prevents the primary from executing with more concurrency than secondaries.
+ // See SERVER-21646.
+ Lock::ResourceLock{txn->lockState(), ResourceId(RESOURCE_METADATA, _ns.ns()), MODE_X};
+ }
+
SnapshotId sid = txn->recoveryUnit()->getSnapshotId();
BSONElement oldId = objOld.value()["_id"];
diff --git a/src/mongo/db/catalog/collection.h b/src/mongo/db/catalog/collection.h
index f09cbd9b79b..d64dd95aef8 100644
--- a/src/mongo/db/catalog/collection.h
+++ b/src/mongo/db/catalog/collection.h
@@ -319,10 +319,11 @@ private:
int _magic;
- NamespaceString _ns;
- CollectionCatalogEntry* _details;
- RecordStore* _recordStore;
- DatabaseCatalogEntry* _dbce;
+ const NamespaceString _ns;
+ CollectionCatalogEntry* const _details;
+ RecordStore* const _recordStore;
+ DatabaseCatalogEntry* const _dbce;
+ const bool _needCappedLock;
CollectionInfoCache _infoCache;
IndexCatalog _indexCatalog;