diff options
author | Mathias Stearn <mathias@10gen.com> | 2015-11-24 18:31:14 -0500 |
---|---|---|
committer | Mathias Stearn <mathias@10gen.com> | 2015-11-30 19:50:09 -0500 |
commit | f45b7c8e34743ba89407d90ee3392acb0d2be255 (patch) | |
tree | ee1250257c3931cd63caf35af641e6d106063ab6 | |
parent | 0e4d706953cd4db25fc9ffa4abf106541157f971 (diff) | |
download | mongo-f45b7c8e34743ba89407d90ee3392acb0d2be255.tar.gz |
SERVER-21646 limit concurrency of writes to replicated capped collections
This prevents the primary from running significantly faster than secondaries.
-rw-r--r-- | src/mongo/db/catalog/collection.cpp | 15 | ||||
-rw-r--r-- | src/mongo/db/catalog/collection.h | 11 |
2 files changed, 21 insertions, 5 deletions
diff --git a/src/mongo/db/catalog/collection.cpp b/src/mongo/db/catalog/collection.cpp index 8a71e6d5095..e7cad0bf046 100644 --- a/src/mongo/db/catalog/collection.cpp +++ b/src/mongo/db/catalog/collection.cpp @@ -174,6 +174,7 @@ Collection::Collection(OperationContext* txn, _details(details), _recordStore(recordStore), _dbce(dbce), + _needCappedLock(supportsDocLocking() && _recordStore->isCapped() && _ns.db() != "local"), _infoCache(this), _indexCatalog(this), _validatorDoc(_details->getCollectionOptions(txn).validator.getOwned()), @@ -425,6 +426,13 @@ Status Collection::_insertDocuments(OperationContext* txn, "Can't batch inserts into indexed capped collections"}; } + 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}; + } + std::vector<Record> records; for (auto it = begin; it != end; it++) { Record record = {RecordId(), RecordData(it->objdata(), it->objsize())}; @@ -529,6 +537,13 @@ StatusWith<RecordId> Collection::updateDocument(OperationContext* txn, dassert(txn->lockState()->isCollectionLockedForMode(ns().toString(), MODE_IX)); invariant(oldDoc.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 = oldDoc.value()["_id"]; diff --git a/src/mongo/db/catalog/collection.h b/src/mongo/db/catalog/collection.h index a176a48dc66..1ba17ee3ba4 100644 --- a/src/mongo/db/catalog/collection.h +++ b/src/mongo/db/catalog/collection.h @@ -448,10 +448,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; @@ -474,7 +475,7 @@ private: // on this object until notified of the arrival of new data. // // This is non-null if and only if the collection is a capped collection. - std::shared_ptr<CappedInsertNotifier> _cappedNotifier; + const std::shared_ptr<CappedInsertNotifier> _cappedNotifier; const bool _mustTakeCappedLockOnInsert; |