diff options
author | Charlie Swanson <charlie.swanson@mongodb.com> | 2019-02-05 11:43:52 -0500 |
---|---|---|
committer | Charlie Swanson <charlie.swanson@mongodb.com> | 2019-02-11 12:13:38 -0500 |
commit | d568e329a67eee8ba241d52067750a3d8c42dc0f (patch) | |
tree | e8180ccc44f243f603cb91eaed431afeeabe8676 /src/mongo/db/ops | |
parent | b54d9905a167867a2655910799573378aff2ce89 (diff) | |
download | mongo-d568e329a67eee8ba241d52067750a3d8c42dc0f.tar.gz |
SERVER-37283 Use stronger locks for system.views
Readers of the view catalog depend on a MODE_IS DB lock preventing
concurrent writes to the view catalog. This is true for regular view
maintenance commands like collMod, create, and drop. However, on
secondaries these commands are replicated as direct writes to
system.views and do not hold as strong of a lock. Further, a user is
permitted to write directly to system.views and so could hit a similar
issue on the primary.
Diffstat (limited to 'src/mongo/db/ops')
-rw-r--r-- | src/mongo/db/ops/write_ops_exec.cpp | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/src/mongo/db/ops/write_ops_exec.cpp b/src/mongo/db/ops/write_ops_exec.cpp index 200f263a283..1007bb72d3c 100644 --- a/src/mongo/db/ops/write_ops_exec.cpp +++ b/src/mongo/db/ops/write_ops_exec.cpp @@ -302,6 +302,10 @@ SingleWriteResult createIndex(OperationContext* opCtx, return result; } +LockMode fixLockModeForSystemDotViewsChanges(const NamespaceString& nss, LockMode mode) { + return nss.isSystemDotViews() ? MODE_X : mode; +} + void insertDocuments(OperationContext* opCtx, Collection* collection, std::vector<InsertStatement>::iterator begin, @@ -373,7 +377,10 @@ bool insertBatchAndHandleErrors(OperationContext* opCtx, uasserted(ErrorCodes::InternalError, "failAllInserts failpoint active!"); } - collection.emplace(opCtx, wholeOp.getNamespace(), MODE_IX); + collection.emplace( + opCtx, + wholeOp.getNamespace(), + fixLockModeForSystemDotViewsChanges(wholeOp.getNamespace(), MODE_IX)); if (collection->getCollection()) break; @@ -605,7 +612,7 @@ static SingleWriteResult performSingleUpdateOp(OperationContext* opCtx, collection.emplace(opCtx, ns, MODE_IX, // DB is always IX, even if collection is X. - MODE_IX); + fixLockModeForSystemDotViewsChanges(ns, MODE_IX)); if (collection->getCollection() || !updateRequest.isUpsert()) break; @@ -845,7 +852,7 @@ static SingleWriteResult performSingleDeleteOp(OperationContext* opCtx, AutoGetCollection collection(opCtx, ns, MODE_IX, // DB is always IX, even if collection is X. - MODE_IX); + fixLockModeForSystemDotViewsChanges(ns, MODE_IX)); if (collection.getDb()) { curOp.raiseDbProfileLevel(collection.getDb()->getProfilingLevel()); } |