[SERVER-39901] Direct writes to system.views need the database exclusive lock Created: 01/Mar/19  Updated: 01/Mar/19  Resolved: 01/Mar/19

Status: Closed
Project: Core Server
Component/s: Aggregation Framework, Concurrency, Querying
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Major - P3
Reporter: Charlie Swanson Assignee: Geert Bosch
Resolution: Won't Fix Votes: 0
Labels: None
Remaining Estimate: Not Specified
Time Spent: Not Specified
Original Estimate: Not Specified

Operating System: ALL
Participants:

 Description   

In SERVER-37283 we enforced that modifications to system.views need a MODE_X collection lock, but further testing has showed that because the view catalog is tracked per-database, they need a MODE_X database lock as well.



 Comments   
Comment by Charlie Swanson [ 01/Mar/19 ]

Actually, closing this ticket since it doesn't make sense to keep open as a SERVER ticket while we investigate the failure.

Comment by Charlie Swanson [ 01/Mar/19 ]

This proposed fix was rejected upon further thought. Assigning this to Geert to investigate an alternate fix.

geert.bosch, I applied the following patch and I was still able to reproduce a failure when running

python buildscripts/resmoke.py --suites=concurrency_simultaneous jstests/concurrency/fsm_workloads/view_catalog_direct_system_writes.js jstests/concurrency/fsm_workloads/create_database.js

diff --git a/src/mongo/db/commands/list_collections.cpp b/src/mongo/db/commands/list_collections.cpp
index 4c7784f..630ff7f 100644
--- a/src/mongo/db/commands/list_collections.cpp
+++ b/src/mongo/db/commands/list_collections.cpp
@@ -342,6 +342,9 @@ public:
                     SimpleBSONObjComparator::kInstance.evaluate(
                         filterElt.Obj() == ListCollectionsFilter::makeTypeCollectionFilter());
                 if (!skipViews) {
+                    Lock::CollectionLock(opCtx->lockState(),
+                                         NamespaceString::kSystemDotViewsCollectionName,
+                                         MODE_IS);
                     db->getViewCatalog()->iterate(opCtx, [&](const ViewDefinition& view) {
                         BSONObj viewBson = buildViewBson(view, nameOnly);
                         if (!viewBson.isEmpty()) {
diff --git a/src/mongo/db/repl/sync_tail.cpp b/src/mongo/db/repl/sync_tail.cpp
index f06f635..0b9d3e2 100644
--- a/src/mongo/db/repl/sync_tail.cpp
+++ b/src/mongo/db/repl/sync_tail.cpp
@@ -333,8 +333,10 @@ Status SyncTail::syncApply(OperationContext* opCtx,
         return finishApply(writeConflictRetry(opCtx, "syncApply_CRUD", nss.ns(), [&] {
             // Need to throw instead of returning a status for it to be properly ignored.
             try {
-                AutoGetCollection autoColl(
-                    opCtx, getNsOrUUID(nss, op), fixLockModeForSystemDotViewsChanges(nss, MODE_IX));
+                AutoGetCollection autoColl(opCtx,
+                                           getNsOrUUID(nss, op),
+                                           MODE_IX,
+                                           fixLockModeForSystemDotViewsChanges(nss, MODE_IX));
                 auto db = autoColl.getDb();
                 uassert(ErrorCodes::NamespaceNotFound,
                         str::stream() << "missing database (" << nss.db() << ")",
diff --git a/src/mongo/db/views/durable_view_catalog.cpp b/src/mongo/db/views/durable_view_catalog.cpp
index e0f829b..b3d9e4f 100644
--- a/src/mongo/db/views/durable_view_catalog.cpp
+++ b/src/mongo/db/views/durable_view_catalog.cpp
@@ -54,7 +54,7 @@ namespace mongo {
 // DurableViewCatalog
 
 void DurableViewCatalog::onExternalChange(OperationContext* opCtx, const NamespaceString& name) {
-    dassert(opCtx->lockState()->isDbLockedForMode(name.db(), MODE_IX));
+    invariant(opCtx->lockState()->isCollectionLockedForMode(name.ns(), MODE_X));
     auto databaseHolder = DatabaseHolder::get(opCtx);
     auto db = databaseHolder->getDb(opCtx, name.db());
     if (db) {

Generated at Thu Feb 08 04:53:27 UTC 2024 using Jira 9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66.