diff options
author | Marcos José Grillo Ramírez <marcos.grillo@mongodb.com> | 2020-04-14 13:44:09 +0200 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-04-24 15:39:40 +0000 |
commit | 9ccfe0715fd23452c285471322529da8adec86e2 (patch) | |
tree | d460e95af7fdbf2fd8371a8e2130d2f3335388fe /src | |
parent | 341e5569281dfcf20422192f7db34f4a228bf846 (diff) | |
download | mongo-9ccfe0715fd23452c285471322529da8adec86e2.tar.gz |
SERVER-47526 Use getCollectionDescription on rename collection
- Add flag to renameCollection command to know when the source collection is temporary
- Prevent checks of isSharded on secondaries
- Prevent checks of isSharded on temporary collections
Diffstat (limited to 'src')
6 files changed, 40 insertions, 37 deletions
diff --git a/src/mongo/db/catalog/capped_utils.cpp b/src/mongo/db/catalog/capped_utils.cpp index d34b707ac9c..9134a7de6cf 100644 --- a/src/mongo/db/catalog/capped_utils.cpp +++ b/src/mongo/db/catalog/capped_utils.cpp @@ -286,6 +286,7 @@ void convertToCapped(OperationContext* opCtx, const NamespaceString& ns, long lo RenameCollectionOptions options; options.dropTarget = true; options.stayTemp = false; + options.skipSourceCollectionShardedCheck = true; uassertStatusOK(renameCollection(opCtx, tempNs, ns, options)); } diff --git a/src/mongo/db/catalog/rename_collection.cpp b/src/mongo/db/catalog/rename_collection.cpp index eaecc1bf97b..072da312dfc 100644 --- a/src/mongo/db/catalog/rename_collection.cpp +++ b/src/mongo/db/catalog/rename_collection.cpp @@ -72,8 +72,8 @@ boost::optional<NamespaceString> getNamespaceFromUUID(OperationContext* opCtx, c } bool isCollectionSharded(OperationContext* opCtx, const NamespaceString& nss) { - auto* const css = CollectionShardingState::get(opCtx, nss); - return css->getCollectionDescription_DEPRECATED().isSharded(); + return opCtx->writesAreReplicated() && + CollectionShardingState::get(opCtx, nss)->getCollectionDescription().isSharded(); } // From a replicated to an unreplicated collection or vice versa. @@ -98,7 +98,7 @@ Status checkSourceAndTargetNamespaces(OperationContext* opCtx, str::stream() << "Not primary while renaming collection " << source << " to " << target); - if (isCollectionSharded(opCtx, source)) + if (!options.skipSourceCollectionShardedCheck && isCollectionSharded(opCtx, source)) return {ErrorCodes::IllegalOperation, "source namespace cannot be sharded"}; if (isReplicatedChanged(opCtx, source, target)) @@ -498,6 +498,7 @@ Status renameBetweenDBs(OperationContext* opCtx, return Status(ErrorCodes::NamespaceNotFound, "source namespace does not exist"); } + // The source collection is not temporary, so we should check if is sharded or not. if (isCollectionSharded(opCtx, source)) return {ErrorCodes::IllegalOperation, "source namespace cannot be sharded"}; @@ -706,7 +707,9 @@ Status renameBetweenDBs(OperationContext* opCtx, // Getting here means we successfully built the target copy. We now do the final // in-place rename and remove the source collection. invariant(tmpName.db() == target.db()); - Status status = renameCollectionWithinDB(opCtx, tmpName, target, options); + RenameCollectionOptions tempOptions(options); + tempOptions.skipSourceCollectionShardedCheck = true; + Status status = renameCollectionWithinDB(opCtx, tmpName, target, tempOptions); if (!status.isOK()) return status; @@ -720,8 +723,7 @@ Status renameBetweenDBs(OperationContext* opCtx, void doLocalRenameIfOptionsAndIndexesHaveNotChanged(OperationContext* opCtx, const NamespaceString& sourceNs, const NamespaceString& targetNs, - bool dropTarget, - bool stayTemp, + const RenameCollectionOptions& options, std::list<BSONObj> originalIndexes, BSONObj originalCollectionOptions) { AutoGetDb dbLock(opCtx, targetNs.db(), MODE_X); @@ -758,13 +760,12 @@ void doLocalRenameIfOptionsAndIndexesHaveNotChanged(OperationContext* opCtx, currentIndexes.begin(), SimpleBSONObjComparator::kInstance.makeEqualTo())); - validateAndRunRenameCollection(opCtx, sourceNs, targetNs, dropTarget, stayTemp); + validateAndRunRenameCollection(opCtx, sourceNs, targetNs, options); } void validateAndRunRenameCollection(OperationContext* opCtx, const NamespaceString& source, const NamespaceString& target, - bool dropTarget, - bool stayTemp) { + const RenameCollectionOptions& options) { uassert(ErrorCodes::InvalidNamespace, str::stream() << "Invalid source namespace: " << source.ns(), source.isValid()); @@ -802,9 +803,6 @@ void validateAndRunRenameCollection(OperationContext* opCtx, "allowed"); } - RenameCollectionOptions options; - options.dropTarget = dropTarget; - options.stayTemp = stayTemp; uassertStatusOK(renameCollection(opCtx, source, target, options)); } diff --git a/src/mongo/db/catalog/rename_collection.h b/src/mongo/db/catalog/rename_collection.h index 7269fb93ac9..2af16a8ddee 100644 --- a/src/mongo/db/catalog/rename_collection.h +++ b/src/mongo/db/catalog/rename_collection.h @@ -42,23 +42,25 @@ namespace repl { class OpTime; } // namespace repl -void doLocalRenameIfOptionsAndIndexesHaveNotChanged(OperationContext* opCtx, - const NamespaceString& sourceNs, - const NamespaceString& targetNs, - bool dropTarget, - bool stayTemp, - std::list<BSONObj> originalIndexes, - BSONObj collectionOptions); /** - * Renames the collection from "source" to "target" and drops the existing collection iff + * Renames the collection from "source" to "target" and drops the existing collection if * "dropTarget" is true. "stayTemp" indicates whether a collection should maintain its - * temporariness. + * temporariness. "skipSourceCollectionShardedCheck" indicates the "source" collection sharding + * state shouldn't be checked. */ struct RenameCollectionOptions { bool dropTarget = false; bool stayTemp = false; + bool skipSourceCollectionShardedCheck = false; }; +void doLocalRenameIfOptionsAndIndexesHaveNotChanged(OperationContext* opCtx, + const NamespaceString& sourceNs, + const NamespaceString& targetNs, + const RenameCollectionOptions& options, + std::list<BSONObj> originalIndexes, + BSONObj collectionOptions); + Status renameCollection(OperationContext* opCtx, const NamespaceString& source, const NamespaceString& target, @@ -93,7 +95,6 @@ Status renameCollectionForRollback(OperationContext* opCtx, void validateAndRunRenameCollection(OperationContext* opCtx, const NamespaceString& source, const NamespaceString& target, - bool dropTarget, - bool stayTemp); + const RenameCollectionOptions& options); } // namespace mongo diff --git a/src/mongo/db/commands/internal_rename_if_options_and_indexes_match_cmd.cpp b/src/mongo/db/commands/internal_rename_if_options_and_indexes_match_cmd.cpp index 8e112043f5a..627e20b351a 100644 --- a/src/mongo/db/commands/internal_rename_if_options_and_indexes_match_cmd.cpp +++ b/src/mongo/db/commands/internal_rename_if_options_and_indexes_match_cmd.cpp @@ -54,11 +54,14 @@ public: auto thisRequest = request(); auto originalIndexes = thisRequest.getIndexes(); auto indexList = std::list<BSONObj>(originalIndexes.begin(), originalIndexes.end()); + RenameCollectionOptions options; + options.dropTarget = true; + options.stayTemp = false; + options.skipSourceCollectionShardedCheck = true; doLocalRenameIfOptionsAndIndexesHaveNotChanged(opCtx, thisRequest.getFrom(), thisRequest.getTo(), - true /* dropTarget */, - false /* stayTemp */, + options, std::move(indexList), thisRequest.getCollectionOptions()); } diff --git a/src/mongo/db/commands/rename_collection_cmd.cpp b/src/mongo/db/commands/rename_collection_cmd.cpp index 3226d38c550..cf63ff4406d 100644 --- a/src/mongo/db/commands/rename_collection_cmd.cpp +++ b/src/mongo/db/commands/rename_collection_cmd.cpp @@ -87,11 +87,11 @@ public: BSONObjBuilder& result) { auto renameRequest = RenameCollectionCommand::parse(IDLParserErrorContext("renameCollection"), cmdObj); - validateAndRunRenameCollection(opCtx, - renameRequest.getCommandParameter(), - renameRequest.getTo(), - renameRequest.getDropTarget(), - renameRequest.getStayTemp()); + RenameCollectionOptions options; + options.dropTarget = renameRequest.getDropTarget(); + options.stayTemp = renameRequest.getStayTemp(); + validateAndRunRenameCollection( + opCtx, renameRequest.getCommandParameter(), renameRequest.getTo(), options); return true; } diff --git a/src/mongo/db/pipeline/process_interface/non_shardsvr_process_interface.cpp b/src/mongo/db/pipeline/process_interface/non_shardsvr_process_interface.cpp index 0ae5f620abc..0482f9fb287 100644 --- a/src/mongo/db/pipeline/process_interface/non_shardsvr_process_interface.cpp +++ b/src/mongo/db/pipeline/process_interface/non_shardsvr_process_interface.cpp @@ -150,13 +150,13 @@ void NonShardServerProcessInterface::renameIfOptionsAndIndexesHaveNotChanged( const BSONObj& originalCollectionOptions, const std::list<BSONObj>& originalIndexes) { NamespaceString sourceNs = NamespaceString(renameCommandObj["renameCollection"].String()); - doLocalRenameIfOptionsAndIndexesHaveNotChanged(opCtx, - sourceNs, - targetNs, - renameCommandObj["dropTarget"].trueValue(), - renameCommandObj["stayTemp"].trueValue(), - originalIndexes, - originalCollectionOptions); + RenameCollectionOptions options; + options.dropTarget = renameCommandObj["dropTarget"].trueValue(); + options.stayTemp = renameCommandObj["stayTemp"].trueValue(); + // skip sharding validation on non sharded servers + options.skipSourceCollectionShardedCheck = true; + doLocalRenameIfOptionsAndIndexesHaveNotChanged( + opCtx, sourceNs, targetNs, options, originalIndexes, originalCollectionOptions); } void NonShardServerProcessInterface::createCollection(OperationContext* opCtx, |