diff options
author | Mathias Stearn <mathias@10gen.com> | 2015-11-24 18:31:14 -0500 |
---|---|---|
committer | Mathias Stearn <redbeard0531@gmail.com> | 2015-12-02 18:44:54 -0500 |
commit | 405a5c8d09ccd32294e70d525c4168780356ff16 (patch) | |
tree | 30bc46a1c349426c52cd9c9fcce13761bddfe306 /src/mongo | |
parent | c53eebbb6120ab0be19bf746d592ce426afa7682 (diff) | |
download | mongo-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.cpp | 18 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection.h | 9 |
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; |