diff options
author | James Wahlin <james.wahlin@10gen.com> | 2016-08-25 08:36:22 -0400 |
---|---|---|
committer | James Wahlin <james.wahlin@10gen.com> | 2016-08-26 16:45:30 -0400 |
commit | a4a9a9ad29415239091db171e01f45677464f668 (patch) | |
tree | 461bbdd6275712543b617ce6e8b8bbc313ffb9e0 /src/mongo/db | |
parent | 752dcf912d5e45c8614ed749e20982e69cc89813 (diff) | |
download | mongo-a4a9a9ad29415239091db171e01f45677464f668.tar.gz |
SERVER-24771 Support killCursors & mongos getMore on view namespace
Diffstat (limited to 'src/mongo/db')
-rw-r--r-- | src/mongo/db/commands/killcursors_cmd.cpp | 22 | ||||
-rw-r--r-- | src/mongo/db/commands/list_collections.cpp | 10 | ||||
-rw-r--r-- | src/mongo/db/commands/list_indexes.cpp | 13 | ||||
-rw-r--r-- | src/mongo/db/namespace_string.cpp | 20 | ||||
-rw-r--r-- | src/mongo/db/namespace_string.h | 12 | ||||
-rw-r--r-- | src/mongo/db/namespace_string_test.cpp | 17 |
6 files changed, 77 insertions, 17 deletions
diff --git a/src/mongo/db/commands/killcursors_cmd.cpp b/src/mongo/db/commands/killcursors_cmd.cpp index ac43fa77680..4c85e5f8f99 100644 --- a/src/mongo/db/commands/killcursors_cmd.cpp +++ b/src/mongo/db/commands/killcursors_cmd.cpp @@ -32,6 +32,7 @@ #include "mongo/db/catalog/collection.h" #include "mongo/db/catalog/cursor_manager.h" #include "mongo/db/commands/killcursors_common.h" +#include "mongo/db/curop.h" #include "mongo/db/db_raii.h" #include "mongo/db/query/killcursors_request.h" @@ -45,7 +46,7 @@ public: private: Status _killCursor(OperationContext* txn, const NamespaceString& nss, CursorId cursorId) final { - std::unique_ptr<AutoGetCollectionForRead> ctx; + std::unique_ptr<AutoGetCollectionOrViewForRead> ctx; CursorManager* cursorManager; if (nss.isListIndexesCursorNS() || nss.isListCollectionsCursorNS()) { @@ -54,8 +55,25 @@ private: // data within a collection. cursorManager = CursorManager::getGlobalCursorManager(); } else { - ctx = stdx::make_unique<AutoGetCollectionForRead>(txn, nss); + ctx = stdx::make_unique<AutoGetCollectionOrViewForRead>(txn, nss); Collection* collection = ctx->getCollection(); + ViewDefinition* view = ctx->getView(); + if (view) { + Database* db = ctx->getDb(); + auto resolved = db->getViewCatalog()->resolveView(txn, nss); + if (!resolved.isOK()) { + return resolved.getStatus(); + } + ctx->releaseLocksForView(); + Status status = _killCursor(txn, resolved.getValue().getNamespace(), cursorId); + { + // Set the namespace of the curop back to the view namespace so ctx records + // stats on this view namespace on destruction. + stdx::lock_guard<Client>(*txn->getClient()); + CurOp::get(txn)->setNS_inlock(nss.ns()); + } + return status; + } if (!collection) { return {ErrorCodes::CursorNotFound, str::stream() << "collection does not exist: " << nss.ns()}; diff --git a/src/mongo/db/commands/list_collections.cpp b/src/mongo/db/commands/list_collections.cpp index 87a3c8a30e8..d3dce59c032 100644 --- a/src/mongo/db/commands/list_collections.cpp +++ b/src/mongo/db/commands/list_collections.cpp @@ -265,12 +265,10 @@ public: }); } - const std::string cursorNamespace = str::stream() << dbname << ".$cmd." << getName(); - dassert(NamespaceString(cursorNamespace).isValid()); - dassert(NamespaceString(cursorNamespace).isListCollectionsCursorNS()); + const NamespaceString cursorNss = NamespaceString::makeListCollectionsNSS(dbname); auto statusWithPlanExecutor = PlanExecutor::make( - txn, std::move(ws), std::move(root), cursorNamespace, PlanExecutor::YIELD_MANUAL); + txn, std::move(ws), std::move(root), cursorNss.ns(), PlanExecutor::YIELD_MANUAL); if (!statusWithPlanExecutor.isOK()) { return appendCommandStatus(result, statusWithPlanExecutor.getStatus()); } @@ -302,12 +300,12 @@ public: ClientCursor* cursor = new ClientCursor(CursorManager::getGlobalCursorManager(), exec.release(), - cursorNamespace, + cursorNss.ns(), txn->recoveryUnit()->isReadingFromMajorityCommittedSnapshot()); cursorId = cursor->cursorid(); } - appendCursorResponseObject(cursorId, cursorNamespace, firstBatch.arr(), &result); + appendCursorResponseObject(cursorId, cursorNss.ns(), firstBatch.arr(), &result); return true; } diff --git a/src/mongo/db/commands/list_indexes.cpp b/src/mongo/db/commands/list_indexes.cpp index fb32aad5a25..a943061a510 100644 --- a/src/mongo/db/commands/list_indexes.cpp +++ b/src/mongo/db/commands/list_indexes.cpp @@ -171,14 +171,11 @@ public: root->pushBack(id); } - const std::string cursorNamespace = str::stream() << dbname << ".$cmd." << getName() << "." - << ns.coll(); - dassert(NamespaceString(cursorNamespace).isValid()); - dassert(NamespaceString(cursorNamespace).isListIndexesCursorNS()); - dassert(ns == NamespaceString(cursorNamespace).getTargetNSForListIndexes()); + const NamespaceString cursorNss = NamespaceString::makeListIndexesNSS(dbname, ns.coll()); + dassert(ns == cursorNss.getTargetNSForListIndexes()); auto statusWithPlanExecutor = PlanExecutor::make( - txn, std::move(ws), std::move(root), cursorNamespace, PlanExecutor::YIELD_MANUAL); + txn, std::move(ws), std::move(root), cursorNss.ns(), PlanExecutor::YIELD_MANUAL); if (!statusWithPlanExecutor.isOK()) { return appendCommandStatus(result, statusWithPlanExecutor.getStatus()); } @@ -210,12 +207,12 @@ public: ClientCursor* cursor = new ClientCursor(CursorManager::getGlobalCursorManager(), exec.release(), - cursorNamespace, + cursorNss.ns(), txn->recoveryUnit()->isReadingFromMajorityCommittedSnapshot()); cursorId = cursor->cursorid(); } - appendCursorResponseObject(cursorId, cursorNamespace, firstBatch.arr(), &result); + appendCursorResponseObject(cursorId, cursorNss.ns(), firstBatch.arr(), &result); return true; } diff --git a/src/mongo/db/namespace_string.cpp b/src/mongo/db/namespace_string.cpp index 43f02e26bb5..1128552ca67 100644 --- a/src/mongo/db/namespace_string.cpp +++ b/src/mongo/db/namespace_string.cpp @@ -34,6 +34,8 @@ #include "mongo/db/namespace_string.h" +#include "mongo/util/mongoutils/str.h" + namespace mongo { using std::string; @@ -70,6 +72,7 @@ const string escapeTable[256] = { const char kConfigCollection[] = "admin.system.version"; +constexpr auto listCollectionsCursorCol = "$cmd.listCollections"_sd; constexpr auto listIndexesCursorNSPrefix = "$cmd.listIndexes."_sd; } // namespace @@ -105,7 +108,7 @@ const StringData NamespaceString::kLocalDb = "local"_sd; const NamespaceString NamespaceString::kConfigCollectionNamespace(kConfigCollection); bool NamespaceString::isListCollectionsCursorNS() const { - return coll() == "$cmd.listCollections"_sd; + return coll() == listCollectionsCursorCol; } bool NamespaceString::isListIndexesCursorNS() const { @@ -113,6 +116,21 @@ bool NamespaceString::isListIndexesCursorNS() const { coll().startsWith(listIndexesCursorNSPrefix); } +NamespaceString NamespaceString::makeListCollectionsNSS(StringData dbName) { + NamespaceString nss(dbName, StringData(str::stream() << listCollectionsCursorCol)); + dassert(nss.isValid()); + dassert(nss.isListCollectionsCursorNS()); + return nss; +} + +NamespaceString NamespaceString::makeListIndexesNSS(StringData dbName, StringData collectionName) { + NamespaceString nss(dbName, + StringData(str::stream() << listIndexesCursorNSPrefix << collectionName)); + dassert(nss.isValid()); + dassert(nss.isListIndexesCursorNS()); + return nss; +} + NamespaceString NamespaceString::getTargetNSForListIndexes() const { dassert(isListIndexesCursorNS()); return NamespaceString(db(), coll().substr(listIndexesCursorNSPrefix.size())); diff --git a/src/mongo/db/namespace_string.h b/src/mongo/db/namespace_string.h index 00ef04c4249..e4b3be50075 100644 --- a/src/mongo/db/namespace_string.h +++ b/src/mongo/db/namespace_string.h @@ -87,6 +87,18 @@ public: NamespaceString(StringData dbName, StringData collectionName); /** + * Contructs a NamespaceString representing a listCollections namespace. The format for this + * namespace is "<dbName>.$cmd.listCollections". + */ + static NamespaceString makeListCollectionsNSS(StringData dbName); + + /** + * Contructs a NamespaceString representing a listIndexes namespace. The format for this + * namespace is "<dbName>.$cmd.listIndexes.<collectionName>". + */ + static NamespaceString makeListIndexesNSS(StringData dbName, StringData collectionName); + + /** * Note that these values are derived from the mmap_v1 implementation and that * is the only reason they are constrained as such. */ diff --git a/src/mongo/db/namespace_string_test.cpp b/src/mongo/db/namespace_string_test.cpp index cd5e535d7ee..69884bd5ca9 100644 --- a/src/mongo/db/namespace_string_test.cpp +++ b/src/mongo/db/namespace_string_test.cpp @@ -255,4 +255,21 @@ TEST(NamespaceStringTest, NamespaceStringParse4) { ASSERT_EQUALS((string) "abc", ns.db()); ASSERT_EQUALS((string) "", ns.coll()); } + +TEST(NamespaceStringTest, makeListCollectionsNSIsCorrect) { + NamespaceString ns = NamespaceString::makeListCollectionsNSS("DB"); + ASSERT_EQUALS("DB", ns.db()); + ASSERT_EQUALS("$cmd.listCollections", ns.coll()); + ASSERT(ns.isValid()); + ASSERT(ns.isListCollectionsCursorNS()); +} + +TEST(NamespaceStringTest, makeListIndexesNSIsCorrect) { + NamespaceString ns = NamespaceString::makeListIndexesNSS("DB", "COLL"); + ASSERT_EQUALS("DB", ns.db()); + ASSERT_EQUALS("$cmd.listIndexes.COLL", ns.coll()); + ASSERT(ns.isValid()); + ASSERT(ns.isListIndexesCursorNS()); + ASSERT_EQUALS(NamespaceString("DB.COLL"), ns.getTargetNSForListIndexes()); +} } |