diff options
Diffstat (limited to 'src/mongo/db/commands')
-rw-r--r-- | src/mongo/db/commands/fle2_compact.cpp | 487 | ||||
-rw-r--r-- | src/mongo/db/commands/fle2_compact.h | 33 | ||||
-rw-r--r-- | src/mongo/db/commands/fle2_compact_cmd.cpp | 51 | ||||
-rw-r--r-- | src/mongo/db/commands/fle2_get_count_info_command.cpp | 4 | ||||
-rw-r--r-- | src/mongo/db/commands/fle_compact_test.cpp | 52 | ||||
-rw-r--r-- | src/mongo/db/commands/set_feature_compatibility_version_command.cpp | 10 |
6 files changed, 18 insertions, 619 deletions
diff --git a/src/mongo/db/commands/fle2_compact.cpp b/src/mongo/db/commands/fle2_compact.cpp index d1f00e68113..f637e1c8dc8 100644 --- a/src/mongo/db/commands/fle2_compact.cpp +++ b/src/mongo/db/commands/fle2_compact.cpp @@ -52,11 +52,6 @@ MONGO_FAIL_POINT_DEFINE(fleCompactFailBeforeECOCRead); MONGO_FAIL_POINT_DEFINE(fleCompactHangBeforeESCAnchorInsert); -// TODO: SERVER-73303 delete the below failpoints when v2 is enabled by default -MONGO_FAIL_POINT_DEFINE(fleCompactHangBeforeESCPlaceholderInsert); -MONGO_FAIL_POINT_DEFINE(fleCompactHangAfterESCPlaceholderInsert); -MONGO_FAIL_POINT_DEFINE(fleCompactHangBeforeECCPlaceholderInsert); -MONGO_FAIL_POINT_DEFINE(fleCompactHangAfterECCPlaceholderInsert); namespace mongo { namespace { @@ -138,300 +133,6 @@ private: const NamespaceString& _nss; mutable CompactStatsCounter<StatsType> _stats; }; - -// TODO: SERVER-73303 delete when v2 is enabled by default -/** - * Deletes an entry at the given position from FLECollection, using - * the TagToken to generate the _id value for the delete query. - */ -template <typename FLECollection, typename TagToken> -void deleteDocumentByPos(FLEQueryInterface* queryImpl, - const NamespaceString& nss, - uint64_t pos, - const TagToken& tagToken, - ECStats* stats) { - CompactStatsCounter<ECStats> statsCtr(stats); - - write_ops::DeleteOpEntry deleteEntry; - auto block = FLECollection::generateId(tagToken, pos); - deleteEntry.setMulti(false); - deleteEntry.setQ(BSON("_id" << BSONBinData(block.data(), block.size(), BinDataGeneral))); - write_ops::DeleteCommandRequest deleteRequest(nss, {std::move(deleteEntry)}); - auto [deleteReply, deletedDoc] = - queryImpl->deleteWithPreimage(nss, EncryptionInformation(BSONObj()), deleteRequest); - - if (deletedDoc.isEmpty()) { - // nothing was deleted - return; - } - checkWriteErrors(deleteReply); - statsCtr.addDeletes(1); -} - -// TODO: SERVER-73303 delete when v2 is enabled by default -/** - * Inserts or updates a null document in FLECollection. - * The newNullDoc must contain the _id of the null document to update. - */ -void upsertNullDocument(FLEQueryInterface* queryImpl, - bool hasNullDoc, - BSONObj newNullDoc, - const NamespaceString& nss, - ECStats* stats) { - CompactStatsCounter<ECStats> statsCtr(stats); - if (hasNullDoc) { - // update the null doc with a replacement modification - write_ops::UpdateOpEntry updateEntry; - updateEntry.setMulti(false); - updateEntry.setUpsert(false); - updateEntry.setQ(newNullDoc.getField("_id").wrap()); - updateEntry.setU(mongo::write_ops::UpdateModification( - newNullDoc, write_ops::UpdateModification::ReplacementTag{})); - write_ops::UpdateCommandRequest updateRequest(nss, {std::move(updateEntry)}); - auto [reply, originalDoc] = - queryImpl->updateWithPreimage(nss, EncryptionInformation(BSONObj()), updateRequest); - checkWriteErrors(reply); - if (!originalDoc.isEmpty()) { - statsCtr.addUpdates(1); - } - } else { - // insert the null doc; translate duplicate key error to a FLE contention error - StmtId stmtId = kUninitializedStmtId; - auto reply = uassertStatusOK(queryImpl->insertDocuments(nss, {newNullDoc}, &stmtId, true)); - checkWriteErrors(reply); - statsCtr.addInserts(1); - } -} - -// TODO: SERVER-73303 delete when v2 is enabled by default -/** - * Deletes a document at the specified position from the ESC - */ -void deleteESCDocument(FLEQueryInterface* queryImpl, - const NamespaceString& nss, - uint64_t pos, - const ESCTwiceDerivedTagToken& tagToken, - ECStats* escStats) { - deleteDocumentByPos<ESCCollection, ESCTwiceDerivedTagToken>( - queryImpl, nss, pos, tagToken, escStats); -} - -// TODO: SERVER-73303 delete when v2 is enabled by default -/** - * Deletes a document at the specified position from the ECC - */ -void deleteECCDocument(FLEQueryInterface* queryImpl, - const NamespaceString& nss, - uint64_t pos, - const ECCTwiceDerivedTagToken& tagToken, - ECStats* eccStats) { - deleteDocumentByPos<ECCCollection, ECCTwiceDerivedTagToken>( - queryImpl, nss, pos, tagToken, eccStats); -} - -// TODO: SERVER-73303 delete when v2 is enabled by default -/** - * Result of preparing the ESC collection for a single field/value pair - * before compaction. - */ -struct ESCPreCompactState { - // total insertions of this field/value pair into EDC - uint64_t count{0}; - // position of the lowest entry - uint64_t ipos{0}; - // position of the highest entry - uint64_t pos{0}; -}; - -// TODO: SERVER-73303 delete when v2 is enabled by default -/** - * Finds the upper and lower bound positions, and the current counter - * value from the ESC collection for the given twice-derived tokens, - * and inserts the compaction placeholder document. - */ -ESCPreCompactState prepareESCForCompaction(FLEQueryInterface* queryImpl, - const NamespaceString& nssEsc, - const ESCTwiceDerivedTagToken& tagToken, - const ESCTwiceDerivedValueToken& valueToken, - ECStats* escStats) { - CompactStatsCounter<ECStats> stats(escStats); - - TxnCollectionReaderForCompact reader(queryImpl, nssEsc, escStats); - - // get the upper bound index 'pos' using binary search - // get the lower bound index 'ipos' from the null doc, if it exists, otherwise 1 - ESCPreCompactState state; - - auto alpha = ESCCollection::emuBinary(reader, tagToken, valueToken); - if (alpha.has_value() && alpha.value() == 0) { - // No null doc & no entries found for this field/value pair so nothing to compact. - // This can happen if the tag and value tokens were derived from a bogus ECOC - // document, or from an ECOC document decrypted with bogus compaction tokens. - // Skip inserting the compaction placeholder. - return state; - } else if (!alpha.has_value()) { - // only the null doc exists - auto block = ESCCollection::generateId(tagToken, boost::none); - auto r_esc = reader.getById(block); - uassert(6346802, "ESC null document not found", !r_esc.isEmpty()); - - auto nullDoc = uassertStatusOK(ESCCollection::decryptNullDocument(valueToken, r_esc)); - - // +2 to skip over index of placeholder doc from previous compaction - state.pos = nullDoc.position + 2; - state.ipos = state.pos; - state.count = nullDoc.count; - } else { - // one or more entries exist for this field/value pair - auto block = ESCCollection::generateId(tagToken, alpha); - auto r_esc = reader.getById(block); - uassert(6346803, "ESC document not found", !r_esc.isEmpty()); - - auto escDoc = uassertStatusOK(ESCCollection::decryptDocument(valueToken, r_esc)); - - state.pos = alpha.value() + 1; - state.count = escDoc.count; - - // null doc may or may not yet exist - block = ESCCollection::generateId(tagToken, boost::none); - r_esc = reader.getById(block); - if (r_esc.isEmpty()) { - state.ipos = 1; - } else { - auto nullDoc = uassertStatusOK(ESCCollection::decryptNullDocument(valueToken, r_esc)); - state.ipos = nullDoc.position + 2; - } - } - - uassert(6346804, "Invalid position range for ESC compact", state.ipos <= state.pos); - uassert(6346805, "Invalid counter value for ESC compact", state.count > 0); - - // Insert a placeholder at the next ESC position; this is deleted later in compact. - // This serves to trigger a write conflict if another write transaction is - // committed before the current compact transaction commits - if (MONGO_unlikely(fleCompactHangBeforeESCPlaceholderInsert.shouldFail())) { - LOGV2(6548301, "Hanging due to fleCompactHangBeforeESCPlaceholderInsert fail point"); - fleCompactHangBeforeESCPlaceholderInsert.pauseWhileSet(); - } - - auto placeholder = ESCCollection::generateCompactionPlaceholderDocument( - tagToken, valueToken, state.pos, state.count); - StmtId stmtId = kUninitializedStmtId; - auto insertReply = - uassertStatusOK(queryImpl->insertDocuments(nssEsc, {placeholder}, &stmtId, true)); - checkWriteErrors(insertReply); - stats.addInserts(1); - - if (MONGO_unlikely(fleCompactHangAfterESCPlaceholderInsert.shouldFail())) { - LOGV2(6548302, "Hanging due to fleCompactHangAfterESCPlaceholderInsert fail point"); - fleCompactHangAfterESCPlaceholderInsert.pauseWhileSet(); - } - return state; -} - -// TODO: SERVER-73303 delete when v2 is enabled by default -/** - * Result of preparing the ECC collection for a single field/value pair - * before compaction. - */ -struct ECCPreCompactState { - // total deletions of this field/value pair from EDC - uint64_t count{0}; - // position of the lowest entry - uint64_t ipos{0}; - // position of the highest entry - uint64_t pos{0}; - // result of merging all ECC entries for this field/value pair - std::vector<ECCDocument> g_prime; - // whether the merge reduced the number of ECC entries - bool merged{false}; -}; - -// TODO: SERVER-73303 delete when v2 is enabled by default -ECCPreCompactState prepareECCForCompaction(FLEQueryInterface* queryImpl, - const NamespaceString& nssEcc, - const ECCTwiceDerivedTagToken& tagToken, - const ECCTwiceDerivedValueToken& valueToken, - ECStats* eccStats) { - CompactStatsCounter<ECStats> stats(eccStats); - - TxnCollectionReaderForCompact reader(queryImpl, nssEcc, eccStats); - - ECCPreCompactState state; - bool flag = true; - std::vector<ECCDocument> g; - - // find the null doc - auto block = ECCCollection::generateId(tagToken, boost::none); - auto r_ecc = reader.getById(block); - if (r_ecc.isEmpty()) { - state.pos = 1; - } else { - auto nullDoc = uassertStatusOK(ECCCollection::decryptNullDocument(valueToken, r_ecc)); - state.pos = nullDoc.position + 2; - } - - // get all documents starting from ipos; set pos to one after position of last document found - state.ipos = state.pos; - while (flag) { - block = ECCCollection::generateId(tagToken, state.pos); - r_ecc = reader.getById(block); - if (!r_ecc.isEmpty()) { - auto doc = uassertStatusOK(ECCCollection::decryptDocument(valueToken, r_ecc)); - g.push_back(std::move(doc)); - state.pos += 1; - } else { - flag = false; - } - } - - if (g.empty()) { - // if there are no entries, there must not be a null doc and ipos must be 1 - uassert(6346901, "Found ECC null doc, but no ECC entries", state.ipos == 1); - - // no null doc & no entries found, so nothing to compact - state.pos = 0; - state.ipos = 0; - state.count = 0; - return state; - } - - // merge 'g' - state.g_prime = CompactionHelpers::mergeECCDocuments(g); - dassert(std::is_sorted(g.begin(), g.end())); - dassert(std::is_sorted(state.g_prime.begin(), state.g_prime.end())); - state.merged = (state.g_prime != g); - state.count = CompactionHelpers::countDeleted(state.g_prime); - - if (state.merged) { - // Insert a placeholder at the next ECC position; this is deleted later in compact. - // This serves to trigger a write conflict if another write transaction is - // committed before the current compact transaction commits - auto placeholder = - ECCCollection::generateCompactionDocument(tagToken, valueToken, state.pos); - StmtId stmtId = kUninitializedStmtId; - - if (MONGO_unlikely(fleCompactHangBeforeECCPlaceholderInsert.shouldFail())) { - LOGV2(6548303, "Hanging due to fleCompactHangBeforeECCPlaceholderInsert fail point"); - fleCompactHangBeforeECCPlaceholderInsert.pauseWhileSet(); - } - auto insertReply = - uassertStatusOK(queryImpl->insertDocuments(nssEcc, {placeholder}, &stmtId, true)); - checkWriteErrors(insertReply); - stats.addInserts(1); - - if (MONGO_unlikely(fleCompactHangAfterECCPlaceholderInsert.shouldFail())) { - LOGV2(6548304, "Hanging due to fleCompactHangAfterECCPlaceholderInsert fail point"); - fleCompactHangAfterECCPlaceholderInsert.pauseWhileSet(); - } - } else { - // adjust pos back to the last document found - state.pos -= 1; - } - - return state; -} - } // namespace @@ -457,12 +158,6 @@ EncryptedStateCollectionsNamespaces::createFromDataCollection(const Collection& namespaces.escNss = NamespaceString(db, cfg.getEscCollection().value_or_eval([&f]() { return f("state"_sd); })); - // TODO SERVER-73303 remove when feature flag is enabled. - if (!gFeatureFlagFLE2ProtocolVersion2.isEnabled(serverGlobalParams.featureCompatibility)) { - namespaces.eccNss = NamespaceString( - db, cfg.getEccCollection().value_or_eval([&f]() { return f("cache"_sd); })); - } - namespaces.ecocNss = NamespaceString( db, cfg.getEcocCollection().value_or_eval([&f]() { return f("compaction"_sd); })); @@ -484,38 +179,6 @@ EncryptedStateCollectionsNamespaces::createFromDataCollection(const Collection& * that have been encrypted with that token. All entries are returned * in a set in their decrypted form. */ -stdx::unordered_set<ECOCCompactionDocument> getUniqueCompactionDocuments( - FLEQueryInterface* queryImpl, - const CompactStructuredEncryptionData& request, - const NamespaceString& ecocNss, - ECOCStats* ecocStats) { - - CompactStatsCounter<ECOCStats> stats(ecocStats); - - // Initialize a set 'C' and for each compaction token, find all entries - // in ECOC with matching field name. Decrypt entries and add to set 'C'. - stdx::unordered_set<ECOCCompactionDocument> c; - auto compactionTokens = CompactionHelpers::parseCompactionTokens(request.getCompactionTokens()); - - for (auto& compactionToken : compactionTokens) { - auto docs = queryImpl->findDocuments( - ecocNss, BSON(EcocDocument::kFieldNameFieldName << compactionToken.fieldPathName)); - stats.addReads(docs.size()); - - for (auto& doc : docs) { - auto ecocDoc = ECOCCollection::parseAndDecrypt(doc, compactionToken.token); - c.insert(std::move(ecocDoc)); - } - } - return c; -} - -/** - * Parses the compaction tokens from the compact request, and - * for each one, retrieves the unique entries in the ECOC collection - * that have been encrypted with that token. All entries are returned - * in a set in their decrypted form. - */ stdx::unordered_set<ECOCCompactionDocumentV2> getUniqueCompactionDocumentsV2( FLEQueryInterface* queryImpl, const CompactStructuredEncryptionData& request, @@ -542,80 +205,6 @@ stdx::unordered_set<ECOCCompactionDocumentV2> getUniqueCompactionDocumentsV2( return c; } -void compactOneFieldValuePair(FLEQueryInterface* queryImpl, - const ECOCCompactionDocument& ecocDoc, - const EncryptedStateCollectionsNamespaces& namespaces, - ECStats* escStats, - ECStats* eccStats) { - // PART 1 - // prepare the ESC, and get back the highest counter value before the placeholder - // document, ipos, and pos - auto escTagToken = FLETwiceDerivedTokenGenerator::generateESCTwiceDerivedTagToken(ecocDoc.esc); - auto escValueToken = - FLETwiceDerivedTokenGenerator::generateESCTwiceDerivedValueToken(ecocDoc.esc); - auto escState = - prepareESCForCompaction(queryImpl, namespaces.escNss, escTagToken, escValueToken, escStats); - - // PART 2 - // prepare the ECC, and get back the merged set 'g_prime', whether (g_prime != g), - // ipos_prime, and pos_prime - auto eccTagToken = FLETwiceDerivedTokenGenerator::generateECCTwiceDerivedTagToken(ecocDoc.ecc); - auto eccValueToken = - FLETwiceDerivedTokenGenerator::generateECCTwiceDerivedValueToken(ecocDoc.ecc); - auto eccState = - prepareECCForCompaction(queryImpl, namespaces.eccNss, eccTagToken, eccValueToken, eccStats); - - // PART 3 - // A. compact the ECC - StmtId stmtId = kUninitializedStmtId; - - if (eccState.count != 0) { - if (eccState.merged) { - CompactStatsCounter<ECStats> stats(eccStats); - - // a. for each entry in g_prime at index k, insert - // {_id: F(eccTagToken, pos'+ k), value: Enc(eccValueToken, g_prime[k])} - for (auto k = eccState.g_prime.size(); k > 0; k--) { - const auto& range = eccState.g_prime[k - 1]; - auto insertReply = uassertStatusOK(queryImpl->insertDocuments( - namespaces.eccNss, - {ECCCollection::generateDocument( - eccTagToken, eccValueToken, eccState.pos + k, range.start, range.end)}, - &stmtId, - true)); - checkWriteErrors(insertReply); - stats.addInserts(1); - } - - // b & c. update or insert the ECC null doc - bool hasNullDoc = (eccState.ipos > 1); - auto newNullDoc = - ECCCollection::generateNullDocument(eccTagToken, eccValueToken, eccState.pos - 1); - upsertNullDocument(queryImpl, hasNullDoc, newNullDoc, namespaces.eccNss, eccStats); - - // d. delete entries between ipos' and pos', inclusive - for (auto k = eccState.ipos; k <= eccState.pos; k++) { - deleteECCDocument(queryImpl, namespaces.eccNss, k, eccTagToken, eccStats); - } - } - } - - // B. compact the ESC - if (escState.count != 0) { - // Delete ESC entries between ipos and pos, inclusive. - // The compaction placeholder is at index pos, so it will be deleted as well. - for (auto k = escState.ipos; k <= escState.pos; k++) { - deleteESCDocument(queryImpl, namespaces.escNss, k, escTagToken, escStats); - } - - // update or insert the ESC null doc - bool hasNullDoc = (escState.ipos > 1); - auto newNullDoc = ESCCollection::generateNullDocument( - escTagToken, escValueToken, escState.pos - 1, escState.count); - upsertNullDocument(queryImpl, hasNullDoc, newNullDoc, namespaces.escNss, escStats); - } -} - void compactOneFieldValuePairV2(FLEQueryInterface* queryImpl, const ECOCCompactionDocumentV2& ecocDoc, const NamespaceString& escNss, @@ -674,82 +263,6 @@ void compactOneFieldValuePairV2(FLEQueryInterface* queryImpl, stats.addInserts(1); } -CompactStats processFLECompact(OperationContext* opCtx, - const CompactStructuredEncryptionData& request, - GetTxnCallback getTxn, - const EncryptedStateCollectionsNamespaces& namespaces) { - auto ecocStats = std::make_shared<ECOCStats>(); - auto escStats = std::make_shared<ECStats>(); - auto eccStats = std::make_shared<ECStats>(); - auto c = std::make_shared<stdx::unordered_set<ECOCCompactionDocument>>(); - - if (MONGO_unlikely(fleCompactFailBeforeECOCRead.shouldFail())) { - uasserted(6599901, "Failed compact due to fleCompactFailBeforeECOCRead fail point"); - } - - // Read the ECOC documents in a transaction - { - std::shared_ptr<txn_api::SyncTransactionWithRetries> trun = getTxn(opCtx); - - // The function that handles the transaction may outlive this function so we need to use - // shared_ptrs - auto argsBlock = std::make_tuple(request, namespaces); - auto sharedBlock = std::make_shared<decltype(argsBlock)>(argsBlock); - - auto swResult = trun->runNoThrow( - opCtx, - [sharedBlock, c, ecocStats](const txn_api::TransactionClient& txnClient, - ExecutorPtr txnExec) { - FLEQueryInterfaceImpl queryImpl(txnClient, getGlobalServiceContext()); - - auto [request2, namespaces2] = *sharedBlock.get(); - - *c = getUniqueCompactionDocuments( - &queryImpl, request2, namespaces2.ecocRenameNss, ecocStats.get()); - - return SemiFuture<void>::makeReady(); - }); - - uassertStatusOK(swResult); - uassertStatusOK(swResult.getValue().getEffectiveStatus()); - } - - // Each entry in 'C' represents a unique field/value pair. For each field/value pair, - // compact the ESC & ECC entries for that field/value pair in one transaction. - for (auto& ecocDoc : *c) { - // start a new transaction - std::shared_ptr<txn_api::SyncTransactionWithRetries> trun = getTxn(opCtx); - - // The function that handles the transaction may outlive this function so we need to use - // shared_ptrs - auto argsBlock = std::make_tuple(ecocDoc, namespaces); - auto sharedBlock = std::make_shared<decltype(argsBlock)>(argsBlock); - - auto swResult = trun->runNoThrow( - opCtx, - [sharedBlock, escStats, eccStats](const txn_api::TransactionClient& txnClient, - ExecutorPtr txnExec) { - FLEQueryInterfaceImpl queryImpl(txnClient, getGlobalServiceContext()); - - auto [ecocDoc2, namespaces2] = *sharedBlock.get(); - - compactOneFieldValuePair( - &queryImpl, ecocDoc2, namespaces2, escStats.get(), eccStats.get()); - - return SemiFuture<void>::makeReady(); - }); - - uassertStatusOK(swResult); - uassertStatusOK(swResult.getValue().getEffectiveStatus()); - } - - CompactStats stats(*ecocStats, *escStats); - stats.setEcc(*eccStats); - FLEStatusSection::get().updateCompactionStats(stats); - - return stats; -} - void processFLECompactV2(OperationContext* opCtx, const CompactStructuredEncryptionData& request, GetTxnCallback getTxn, diff --git a/src/mongo/db/commands/fle2_compact.h b/src/mongo/db/commands/fle2_compact.h index ff351703573..2af0e930f3a 100644 --- a/src/mongo/db/commands/fle2_compact.h +++ b/src/mongo/db/commands/fle2_compact.h @@ -44,8 +44,6 @@ struct EncryptedStateCollectionsNamespaces { NamespaceString escNss; NamespaceString ecocNss; NamespaceString ecocRenameNss; - // TODO: SERVER-73303 delete when v2 is enabled by default - NamespaceString eccNss; }; /** @@ -53,12 +51,6 @@ struct EncryptedStateCollectionsNamespaces { */ void validateCompactRequest(const CompactStructuredEncryptionData& request, const Collection& edc); -// TODO: SERVER-73303 delete when v2 is enabled by default -CompactStats processFLECompact(OperationContext* opCtx, - const CompactStructuredEncryptionData& request, - GetTxnCallback getTxn, - const EncryptedStateCollectionsNamespaces& namespaces); - void processFLECompactV2(OperationContext* opCtx, const CompactStructuredEncryptionData& request, GetTxnCallback getTxn, @@ -66,18 +58,6 @@ void processFLECompactV2(OperationContext* opCtx, ECStats* escStats, ECOCStats* ecocStats); -// TODO: SERVER-73303 delete when v2 is enabled by default -/** - * Get all unique documents in the ECOC collection in their decrypted form. - * - * Used by unit tests. - */ -stdx::unordered_set<ECOCCompactionDocument> getUniqueCompactionDocuments( - FLEQueryInterface* queryImpl, - const CompactStructuredEncryptionData& request, - const NamespaceString& ecocNss, - ECOCStats* ecocStats); - /** * Get all unique documents in the ECOC collection in their decrypted form. * @@ -90,19 +70,6 @@ stdx::unordered_set<ECOCCompactionDocumentV2> getUniqueCompactionDocumentsV2( ECOCStats* ecocStats); -// TODO: SERVER-73303 delete when v2 is enabled by default -/** - * Performs compaction of the ESC and ECC entries for the encrypted field/value pair - * whose tokens are in the provided ECOC compaction document. - * - * Used by unit tests. - */ -void compactOneFieldValuePair(FLEQueryInterface* queryImpl, - const ECOCCompactionDocument& ecocDoc, - const EncryptedStateCollectionsNamespaces& namespaces, - ECStats* escStats, - ECStats* eccStats); - /** * Performs compaction of the ESC entries for the encrypted field/value pair * whose tokens are in the provided ECOC compaction document. diff --git a/src/mongo/db/commands/fle2_compact_cmd.cpp b/src/mongo/db/commands/fle2_compact_cmd.cpp index 5fcbe58d727..e0fa4440f22 100644 --- a/src/mongo/db/commands/fle2_compact_cmd.cpp +++ b/src/mongo/db/commands/fle2_compact_cmd.cpp @@ -75,8 +75,6 @@ CompactStats compactEncryptedCompactionCollection(OperationContext* opCtx, Lock::ExclusiveLock fleCompactCommandLock(opCtx, commandMutex); const auto& edcNss = request.getNamespace(); - const bool useV1Protocol = - !gFeatureFlagFLE2ProtocolVersion2.isEnabled(serverGlobalParams.featureCompatibility); LOGV2(6319900, "Compacting the encrypted compaction collection", logAttrs(edcNss)); @@ -110,24 +108,10 @@ CompactStats compactEncryptedCompactionCollection(OperationContext* opCtx, CompactStats stats({}, {}); FLECompactESCDeleteSet escDeleteSet; - if (useV1Protocol) { - stats.setEcc({}); - } - if (!ecoc && !ecocRename) { // nothing to compact LOGV2(6548306, "Skipping compaction as there is no ECOC collection to compact"); return stats; - } else if (ecoc && !ecocRename && useV1Protocol) { - // TODO: SERVER-73303 delete this branch when v2 is enabled by default - LOGV2(6319901, - "Renaming the encrypted compaction collection", - "ecocNss"_attr = namespaces.ecocNss, - "ecocRenameNss"_attr = namespaces.ecocRenameNss); - RenameCollectionOptions renameOpts; - validateAndRunRenameCollection( - opCtx, namespaces.ecocNss, namespaces.ecocRenameNss, renameOpts); - ecoc = nullptr; } else if (ecoc && !ecocRename) { // load the random set of ESC non-anchor entries to be deleted post-compact auto memoryLimit = @@ -188,30 +172,21 @@ CompactStats compactEncryptedCompactionCollection(OperationContext* opCtx, << " no longer exists prior to compaction", tempEcocColl.getCollection()); - if (useV1Protocol) { - // TODO: SERVER-73303 delete this branch when v2 is enabled by default - stats = - processFLECompact(opCtx, request, &getTransactionWithRetriesForMongoD, namespaces); - } else { - processFLECompactV2(opCtx, - request, - &getTransactionWithRetriesForMongoD, - namespaces, - &stats.getEsc(), - &stats.getEcoc()); - } + processFLECompactV2(opCtx, + request, + &getTransactionWithRetriesForMongoD, + namespaces, + &stats.getEsc(), + &stats.getEcoc()); } - if (!useV1Protocol) { - auto tagsPerDelete = - ServerParameterSet::getClusterParameterSet() - ->get<ClusterParameterWithStorage<FLECompactionOptions>>("fleCompactionOptions") - ->getValue(boost::none) - .getMaxESCEntriesPerCompactionDelete(); - cleanupESCNonAnchors( - opCtx, namespaces.escNss, escDeleteSet, tagsPerDelete, &stats.getEsc()); - FLEStatusSection::get().updateCompactionStats(stats); - } + auto tagsPerDelete = + ServerParameterSet::getClusterParameterSet() + ->get<ClusterParameterWithStorage<FLECompactionOptions>>("fleCompactionOptions") + ->getValue(boost::none) + .getMaxESCEntriesPerCompactionDelete(); + cleanupESCNonAnchors(opCtx, namespaces.escNss, escDeleteSet, tagsPerDelete, &stats.getEsc()); + FLEStatusSection::get().updateCompactionStats(stats); if (MONGO_unlikely(fleCompactSkipECOCDropUnsharded.shouldFail())) { LOGV2(7299612, diff --git a/src/mongo/db/commands/fle2_get_count_info_command.cpp b/src/mongo/db/commands/fle2_get_count_info_command.cpp index 0ad2d793e19..fe5b82fe9b3 100644 --- a/src/mongo/db/commands/fle2_get_count_info_command.cpp +++ b/src/mongo/db/commands/fle2_get_count_info_command.cpp @@ -103,10 +103,6 @@ QECountInfosReply getTagsLocal(OperationContext* opCtx, CurOp::get(opCtx)->debug().shouldOmitDiagnosticInformation = true; - uassert(741503, - "FeatureFlagFLE2ProtocolVersion2 is not enabled", - gFeatureFlagFLE2ProtocolVersion2.isEnabled(serverGlobalParams.featureCompatibility)); - auto nestedTokens = toNestedTokens(request.getTokens()); auto countInfoSets = diff --git a/src/mongo/db/commands/fle_compact_test.cpp b/src/mongo/db/commands/fle_compact_test.cpp index 7eeba42ea14..da83ffe3436 100644 --- a/src/mongo/db/commands/fle_compact_test.cpp +++ b/src/mongo/db/commands/fle_compact_test.cpp @@ -185,10 +185,8 @@ protected: std::vector<char> generatePlaceholder(UUID keyId, BSONElement value); void doSingleInsert(int id, BSONObj encryptedFieldsObj); - void doSingleDelete(int id, BSONObj encryptedFieldsObj); void insertFieldValues(StringData fieldName, std::map<std::string, InsertionState>& values); - void deleteFieldValues(StringData fieldName, std::map<std::string, InsertionState>& values); protected: ServiceContext::UniqueOperationContext _opCtx; @@ -385,33 +383,6 @@ void FleCompactTest::doSingleInsert(int id, BSONObj encryptedFieldsObj) { _queryImpl.get(), _namespaces.edcNss, serverPayload, efc, &stmtId, result, false)); } -void FleCompactTest::doSingleDelete(int id, BSONObj encryptedFieldsObj) { - auto efc = - generateEncryptedFieldConfig(encryptedFieldsObj.getFieldNames<std::set<std::string>>()); - - auto doc = EncryptionInformationHelpers::encryptionInformationSerializeForDelete( - _namespaces.edcNss, efc, &_keyVault); - - auto ei = EncryptionInformation::parse(IDLParserContext("test"), doc); - - write_ops::DeleteOpEntry entry; - entry.setQ(BSON("_id" << id)); - entry.setMulti(false); - - write_ops::DeleteCommandRequest deleteRequest(_namespaces.edcNss); - deleteRequest.setDeletes({entry}); - deleteRequest.getWriteCommandRequestBase().setEncryptionInformation(ei); - - std::unique_ptr<CollatorInterface> collator; - auto expCtx = make_intrusive<ExpressionContext>(_opCtx.get(), - std::move(collator), - deleteRequest.getNamespace(), - deleteRequest.getLegacyRuntimeConstants(), - deleteRequest.getLet()); - - processDelete(_queryImpl.get(), expCtx, deleteRequest); -} - void FleCompactTest::insertFieldValues(StringData field, std::map<std::string, InsertionState>& values) { static int insertId = 1; @@ -429,32 +400,11 @@ void FleCompactTest::insertFieldValues(StringData field, } } -void FleCompactTest::deleteFieldValues(StringData field, - std::map<std::string, InsertionState>& values) { - for (auto& [value, state] : values) { - BSONObjBuilder builder; - builder.append(field, value); - auto entry = builder.obj(); - - for (auto& range : state.toDeleteRanges) { - for (auto ctr = range.first; ctr <= range.second; ctr++) { - if (state.insertedIds.find(ctr) == state.insertedIds.end()) { - continue; - } - doSingleDelete(state.insertedIds[ctr], entry); - state.insertedIds.erase(ctr); - } - } - } -} TEST_F(FleCompactTest, GetUniqueECOCDocsFromEmptyECOC) { ECOCStats stats; std::set<std::string> fieldSet = {"first", "ssn"}; auto cmd = generateCompactCommand(fieldSet); - auto docsV1 = getUniqueCompactionDocuments(_queryImpl.get(), cmd, _namespaces.ecocNss, &stats); - ASSERT(docsV1.empty()); - auto docs = getUniqueCompactionDocumentsV2(_queryImpl.get(), cmd, _namespaces.ecocNss, &stats); ASSERT(docs.empty()); } @@ -505,7 +455,6 @@ TEST_F(FleCompactTest, CompactValueV2_NoNonAnchors) { } TEST_F(FleCompactTest, CompactValueV2_NoNullAnchors) { - RAIIServerParameterControllerForTest controller("featureFlagFLE2ProtocolVersion2", true); ECStats escStats; std::map<std::string, InsertionState> values; constexpr auto key = "first"_sd; @@ -548,7 +497,6 @@ TEST_F(FleCompactTest, CompactValueV2_NoNullAnchors) { } TEST_F(FleCompactTest, RandomESCNonAnchorDeletions) { - RAIIServerParameterControllerForTest controller("featureFlagFLE2ProtocolVersion2", true); ECStats escStats; constexpr auto key = "first"_sd; const std::string value = "roger"; diff --git a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp index 2d9bc0d74b0..31a0757368d 100644 --- a/src/mongo/db/commands/set_feature_compatibility_version_command.cpp +++ b/src/mongo/db/commands/set_feature_compatibility_version_command.cpp @@ -346,7 +346,7 @@ public: // TODO SERVER-68373: Remove once 7.0 becomes last LTS if (serverGlobalParams.clusterRole.has(ClusterRole::ShardServer) && - gFeatureFlagFLE2ProtocolVersion2.isEnabledOnVersion(requestedVersion)) { + mongo::gFeatureFlagFLE2CompactForProtocolV2.isEnabledOnVersion(requestedVersion)) { ShardingDDLCoordinatorService::getService(opCtx) ->waitForCoordinatorsOfGivenTypeToComplete( opCtx, @@ -559,8 +559,8 @@ public: // TODO SERVER-68373: Remove once 7.0 becomes last LTS if (serverGlobalParams.clusterRole.has(ClusterRole::ShardServer) && requestedVersion > actualVersion && - gFeatureFlagFLE2ProtocolVersion2.isEnabledOnTargetFCVButDisabledOnOriginalFCV( - requestedVersion, actualVersion)) { + mongo::gFeatureFlagFLE2CompactForProtocolV2 + .isEnabledOnTargetFCVButDisabledOnOriginalFCV(requestedVersion, actualVersion)) { ShardingDDLCoordinatorService::getService(opCtx) ->waitForCoordinatorsOfGivenTypeToComplete( opCtx, DDLCoordinatorTypeEnum::kCompactStructuredEncryptionDataPre70Compatible); @@ -639,8 +639,8 @@ private: // TODO SERVER-68373 remove once 7.0 becomes last LTS if (isDowngrading && - gFeatureFlagFLE2ProtocolVersion2.isDisabledOnTargetFCVButEnabledOnOriginalFCV( - requestedVersion, originalVersion)) { + mongo::gFeatureFlagFLE2CompactForProtocolV2 + .isDisabledOnTargetFCVButEnabledOnOriginalFCV(requestedVersion, originalVersion)) { // Drain the QE compact coordinator because it persists state that is // not backwards compatible with earlier versions. ShardingDDLCoordinatorService::getService(opCtx) |