diff options
| author | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-18 17:02:53 -0300 |
|---|---|---|
| committer | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-18 17:02:53 -0300 |
| commit | 959575a5ca598bf5f37fb5cebe7ed1d80d3d71f7 (patch) | |
| tree | acc8d60aedb12b70048e676e8a7349deb0010db8 /src/mongo/db/commands/compact.cpp | |
| parent | 76588293975fc059cf076779e4283e6ffaf8afff (diff) | |
New upstream version 6.0.20upstream
Diffstat (limited to 'src/mongo/db/commands/compact.cpp')
| -rw-r--r-- | src/mongo/db/commands/compact.cpp | 73 |
1 files changed, 54 insertions, 19 deletions
diff --git a/src/mongo/db/commands/compact.cpp b/src/mongo/db/commands/compact.cpp index 26ee8ab5d4b..48d899efcd1 100644 --- a/src/mongo/db/commands/compact.cpp +++ b/src/mongo/db/commands/compact.cpp @@ -27,23 +27,34 @@ * it in the license file. */ +#include <absl/container/btree_set.h> #include <string> #include <vector> #include "mongo/db/auth/action_set.h" #include "mongo/db/auth/action_type.h" +#include "mongo/db/auth/authorization_session.h" #include "mongo/db/auth/privilege.h" #include "mongo/db/catalog/collection.h" +#include "mongo/db/catalog/collection_catalog.h" #include "mongo/db/catalog/collection_compact.h" #include "mongo/db/catalog/database.h" #include "mongo/db/commands.h" #include "mongo/db/concurrency/d_concurrency.h" #include "mongo/db/curop.h" +#include "mongo/db/db_raii.h" #include "mongo/db/jsobj.h" +#include "mongo/db/namespace_string.h" +#include "mongo/db/operation_context.h" +#include "mongo/db/repl/member_state.h" #include "mongo/db/repl/replication_coordinator.h" namespace mongo { +namespace { +static absl::btree_set<UUID> compactsRunning; +} // namespace + using std::string; using std::stringstream; @@ -65,6 +76,7 @@ public: actions.addAction(ActionType::compact); out->push_back(Privilege(parseResourcePattern(dbname, cmdObj), actions)); } + std::string help() const override { return "compact collection\n" "warning: this operation locks the database and is slow. you can cancel with " @@ -75,36 +87,59 @@ public: CompactCmd() : ErrmsgCommandDeprecated("compact") {} virtual bool errmsgRun(OperationContext* opCtx, - const string& db, + const std::string& dbName, const BSONObj& cmdObj, string& errmsg, BSONObjBuilder& result) { - NamespaceString nss = CommandHelpers::parseNsCollectionRequired(db, cmdObj); - - repl::ReplicationCoordinator* replCoord = repl::ReplicationCoordinator::get(opCtx); - if (replCoord->getMemberState().primary() && !cmdObj["force"].trueValue()) { - errmsg = - "will not run compact on an active replica set primary as this is a slow blocking " - "operation. use force:true to force"; - return false; - } + NamespaceString collectionNss = CommandHelpers::parseNsCollectionRequired(dbName, cmdObj); + + Lock::GlobalLock lk(opCtx, + MODE_IX, + Date_t::max(), + Lock::InterruptBehavior::kThrow, + /*skipRSTLLock=*/true); + + // Hold reference to the catalog for collection lookup without locks to be safe. + auto collectionCatalog = CollectionCatalog::get(opCtx); - if (nss.isSystem()) { - // Items in system.* cannot be moved as there might be pointers to them. - errmsg = "can't compact a system namespace"; - return false; + CollectionPtr collection = [&]() { + if (CollectionPtr collection = CollectionPtr( + collectionCatalog->lookupCollectionByNamespace(opCtx, collectionNss))) { + return collection; + } + + // Check if this is a time-series collection. + auto bucketsNs = collectionNss.makeTimeseriesBucketsNamespace(); + if (CollectionPtr collection = CollectionPtr( + collectionCatalog->lookupCollectionByNamespace(opCtx, bucketsNs))) { + return collection; + } + + return CollectionPtr(); + }(); + + if (!collection) { + std::shared_ptr<const ViewDefinition> view = + collectionCatalog->lookupView(opCtx, collectionNss); + uassert(ErrorCodes::CommandNotSupportedOnView, "can't compact a view", !view); + uasserted(ErrorCodes::NamespaceNotFound, "collection does not exist"); } - // This command is internal to the storage engine and should not block oplog application. - ShouldNotConflictWithSecondaryBatchApplicationBlock noPBWMBlock(opCtx->lockState()); + AutoStatsTracker statsTracker(opCtx, + collectionNss, + Top::LockType::NotLocked, + AutoStatsTracker::LogMode::kUpdateTopAndCurOp, + collectionCatalog->getDatabaseProfileLevel(dbName)); + + StatusWith<int64_t> status = compactCollection(opCtx, collection); - StatusWith<int64_t> status = compactCollection(opCtx, nss); uassertStatusOK(status.getStatus()); int64_t bytesFreed = status.getValue(); if (bytesFreed < 0) { - // When compacting a collection that is actively being written to, it is possible that - // the collection is larger at the completion of compaction than when it started. + // When compacting a collection that is actively being written to, it is possible + // that the collection is larger at the completion of compaction than when it + // started. bytesFreed = 0; } |
