SERVER-120515 Change isReplicatedFastCountEnabled() to use "or" operator (#48834)

GitOrigin-RevId: 11f203ec52741ae4db7d69c57d9ab75d422b3590
This commit is contained in:
Cedric Sirianni 2026-03-09 15:51:03 -04:00 committed by MongoDB Bot
parent 023c472351
commit 311d8a7f51
12 changed files with 63 additions and 77 deletions

View File

@ -4,9 +4,6 @@
*
* @tags: [
* requires_wiredtiger,
* # TODO SERVER-120515: Re-enable this test because the size storer can coexist with the
* # replicated fast count collection.
* featureFlagReplicatedFastCount_incompatible,
* ]
*/
@ -17,6 +14,7 @@ import {
getUriForIndex,
startMongodOnExistingPath,
} from "jstests/disk/libs/wt_file_helper.js";
import {FeatureFlagUtil} from "jstests/libs/feature_flag_util.js";
const baseName = "wt_repair_missing_files";
const collName = "test";
@ -52,7 +50,10 @@ testColl = mongod.getDB(baseName)[collName];
assert.eq(testCollUri, getUriForColl(testColl));
assert.eq(testColl.find({}).itcount(), 0);
assert.eq(testColl.count(), 0);
// TODO SERVER-117520: Check this is correct after implementing repair.
if (!FeatureFlagUtil.isPresentAndEnabled(mongod, "featureFlagReplicatedFastCount")) {
assert.eq(testColl.count(), 0);
}
/**
* Test 2. Delete an index file. Verify that repair rebuilds and allows MongoDB to start up
@ -82,7 +83,10 @@ assert.neq(indexUri, getUriForIndex(testColl, indexName));
assertQueryUsesIndex(testColl, doc, indexName);
assert.eq(testColl.find(doc).itcount(), 1);
assert.eq(testColl.count(), 1);
// TODO SERVER-117520: Check this is correct after implementing repair.
if (!FeatureFlagUtil.isPresentAndEnabled(mongod, "featureFlagReplicatedFastCount")) {
assert.eq(testColl.count(), 1);
}
MongoRunner.stopMongod(mongod);
@ -100,7 +104,10 @@ mongod = startMongodOnExistingPath(dbpath);
testColl = mongod.getDB(baseName)[collName];
assert.eq(testColl.find(doc).itcount(), 1);
assert.eq(testColl.count(), 1);
// TODO SERVER-117520: Check this is correct after implementing repair.
if (!FeatureFlagUtil.isPresentAndEnabled(mongod, "featureFlagReplicatedFastCount")) {
assert.eq(testColl.count(), 1);
}
MongoRunner.stopMongod(mongod);
/**
@ -119,7 +126,10 @@ testColl = mongod.getDB(baseName)[collName];
assert.isnull(testColl.exists());
assert.eq(testColl.find(doc).itcount(), 0);
assert.eq(testColl.count(), 0);
// TODO SERVER-117520: Check this is correct after implementing repair.
if (!FeatureFlagUtil.isPresentAndEnabled(mongod, "featureFlagReplicatedFastCount")) {
assert.eq(testColl.count(), 0);
}
/**
* Test 5. Verify that using repair with --directoryperdb creates a missing directory and its
@ -149,7 +159,10 @@ testColl = mongod.getDB(baseName)[collName];
assert.eq(testCollUri, getUriForColl(testColl));
assert.eq(testColl.find({}).itcount(), 0);
assert.eq(testColl.count(), 0);
// TODO SERVER-117520: Check this is correct after implementing repair.
if (!FeatureFlagUtil.isPresentAndEnabled(mongod, "featureFlagReplicatedFastCount")) {
assert.eq(testColl.count(), 0);
}
MongoRunner.stopMongod(mongod);
resetDbpath(dbpath);
@ -174,6 +187,9 @@ mongod = startMongodOnExistingPath(dbpath);
testColl = mongod.getDB(baseName)[collName];
assert.eq(testColl.find(doc).itcount(), 1);
assert.eq(testColl.count(), 1);
// TODO SERVER-117520: Check this is correct after implementing repair.
if (!FeatureFlagUtil.isPresentAndEnabled(mongod, "featureFlagReplicatedFastCount")) {
assert.eq(testColl.count(), 1);
}
MongoRunner.stopMongod(mongod);

View File

@ -5,14 +5,12 @@
* @tags: [
* requires_replication,
* requires_wiredtiger,
* # TODO SERVER-120515: Re-enable this test because the size storer can coexist with the
* # replicated fast count collection.
* featureFlagReplicatedFastCount_incompatible,
* ]
*/
import {getUriForColl, getUriForIndex, runWiredTigerTool} from "jstests/disk/libs/wt_file_helper.js";
import {ReplSetTest} from "jstests/libs/replsettest.js";
import {FeatureFlagUtil} from "jstests/libs/feature_flag_util.js";
const replTest = new ReplSetTest({nodes: 1});
replTest.startSet();
@ -55,7 +53,11 @@ primary = replTest.getPrimary();
const collIdent = getUriForColl(coll());
const indexIdent = getUriForIndex(coll(), "_id_");
assert.eq(coll().count(), 1);
// TODO SERVER-120753: Re-enable this test when replicated fast count is correctly persisted on step
// down.
if (!FeatureFlagUtil.isPresentAndEnabled(primary, "featureFlagReplicatedFastCount")) {
assert.eq(coll().count(), 1);
}
assert(coll().drop());
assert.commandWorked(primary.adminCommand({appendOplogNote: 1, data: {msg: "advance timestamp"}}));
assert.commandWorked(primary.adminCommand({fsync: 1}));

View File

@ -4,9 +4,6 @@
*
* @tags: [
* requires_wiredtiger,
* # TODO SERVER-120515: Re-enable this test because the size storer can coexist with the
* # replicated fast count collection.
* featureFlagReplicatedFastCount_incompatible,
* ]
*/

View File

@ -57,7 +57,10 @@ function checkOplogMetrics(db, changeStream, previousMetrics, expectedDocsReturn
assert.gte(newMetrics.document.returned, newMetrics.oplogStats.document.returned);
assert.gte(newMetrics.queryExecutor.scannedObjects, newMetrics.oplogStats.queryExecutor.scannedObjects);
assert.eq(expectedDocsReturned, oplogDocsReturned);
assert.eq(expectedDocsScanned, oplogDocsScanned);
// Since the oplog can be written to in the background (for example, for internal replicated
// collections), we can only guarantee that there are *at least* the expected number of
// documents scanned.
assert.lte(expectedDocsScanned, oplogDocsScanned);
// Check oplog stats are added to total stats.
assert.eq(oplogDocsReturned, newMetrics.document.returned - previousMetrics.document.returned);
assert.eq(oplogDocsScanned, newMetrics.queryExecutor.scannedObjects - previousMetrics.queryExecutor.scannedObjects);

View File

@ -4,8 +4,8 @@
*/
import {afterEach, beforeEach, describe, it} from "jstests/libs/mochalite.js";
import {FeatureFlagUtil} from "jstests/libs/feature_flag_util.js";
const internalFastCountCollectionName = "fast_count_metadata_store";
const collName = jsTestName() + "_coll";
function initializeMongod(ctx) {
@ -22,43 +22,20 @@ describe("FastCount validation", function () {
initializeMongod(this);
});
it("detects legacy WiredTiger size storer table", function () {
for (const flag of [
it("detects correct FastCountType", function () {
const enforceFlagCombinations = [
{enforceFastCount: false, enforceFastSize: false},
{enforceFastCount: true},
{enforceFastSize: true},
{enforceFastCount: true, enforceFastSize: true},
]) {
];
const featureFlagEnabled = FeatureFlagUtil.isPresentAndEnabled(this.db, "featureFlagReplicatedFastCount");
const expectedFastCountType = featureFlagEnabled ? "both" : "legacySizeStorer";
for (const flag of enforceFlagCombinations) {
const result = assert.commandWorked(this.db.runCommand(Object.assign({validate: collName}, flag)));
assert(result.valid, result);
assert(result.fastCountType == "legacySizeStorer", result);
}
});
afterEach(function () {
MongoRunner.stopMongod(this.conn);
});
});
describe("FastCount validation without shutdown validation", function () {
beforeEach(function () {
initializeMongod(this);
});
it("detects both after creating replicated collection", function () {
assert.commandWorked(this.configDb.createCollection(internalFastCountCollectionName));
const resultWithoutEnforce = assert.commandWorked(this.db.runCommand({validate: collName}));
assert(resultWithoutEnforce.valid, resultWithoutEnforce);
assert(resultWithoutEnforce.fastCountType == "both", resultWithoutEnforce);
for (const flag of [
{enforceFastCount: true},
{enforceFastSize: true},
{enforceFastCount: true, enforceFastSize: true},
]) {
const result = assert.commandWorked(this.db.runCommand(Object.assign({validate: collName}, flag)));
assert(!result.valid, result);
assert(result.fastCountType == "both", result);
assert.eq(result.fastCountType, expectedFastCountType, result);
// The keysPerIndex values are populated by _validateIndexes(), which runs after traverseRecordStore(), so a
// non-zero key count for the _id index confirms the fast count error did not stop validation early. The
@ -80,8 +57,6 @@ describe("FastCount validation without shutdown validation", function () {
// behavior is not tested here.
afterEach(function () {
// We must skip validation during shutdown because creating the `fast_count_metadata_store`
// causes the shutdown validation result to be invalid.
MongoRunner.stopMongod(this.conn, null, {skipValidation: true});
MongoRunner.stopMongod(this.conn);
});
});

View File

@ -35,6 +35,7 @@
#include "mongo/db/namespace_string.h"
#include "mongo/db/op_observer/op_observer.h"
#include "mongo/db/op_observer/op_observer_util.h"
#include "mongo/db/replicated_fast_count/replicated_fast_count_enabled.h"
#include "mongo/db/replicated_fast_count/replicated_fast_count_uncommitted_changes.h"
#include "mongo/db/server_feature_flags_gen.h"
#include "mongo/db/service_context.h"
@ -206,9 +207,7 @@ void cappedDeleteUntilBelowConfiguredMaximum(OperationContext* opCtx,
serviceOpCounters(opCtx).gotDelete();
}
if (gFeatureFlagReplicatedFastCount.isEnabledUseLatestFCVWhenUninitialized(
VersionContext::getDecoration(opCtx),
serverGlobalParams.featureCompatibility.acquireFCVSnapshot())) {
if (isReplicatedFastCountEnabled(opCtx)) {
UncommittedFastCountChange::getForWrite(opCtx).record(
collection->uuid(), -docsRemoved, -sizeSaved);
}

View File

@ -40,7 +40,7 @@ bool isReplicatedFastCountEnabled(OperationContext* opCtx) {
// TODO(SERVER-117326): Remove feature flag check.
return gFeatureFlagReplicatedFastCount.isEnabledUseLatestFCVWhenUninitialized(
VersionContext::getDecoration(opCtx),
serverGlobalParams.featureCompatibility.acquireFCVSnapshot()) &&
serverGlobalParams.featureCompatibility.acquireFCVSnapshot()) ||
rss::ReplicatedStorageService::get(opCtx)
.getPersistenceProvider()
.shouldUseReplicatedFastCount();

View File

@ -54,12 +54,12 @@ TEST_F(IsReplicatedFastCountEnabledTest, DisabledWhenFeatureFlagOff) {
TEST_F(IsReplicatedFastCountEnabledTest, DisabledWhenProviderReturnsFalse) {
RAIIServerParameterControllerForTest featureFlag("featureFlagReplicatedFastCount", true);
ASSERT_FALSE(isReplicatedFastCountEnabled(operationContext()));
ASSERT_TRUE(isReplicatedFastCountEnabled(operationContext()));
}
TEST_F(IsReplicatedFastCountEnabledWithProviderTest, DisabledWhenFeatureFlagOff) {
RAIIServerParameterControllerForTest featureFlag("featureFlagReplicatedFastCount", false);
ASSERT_FALSE(isReplicatedFastCountEnabled(operationContext()));
ASSERT_TRUE(isReplicatedFastCountEnabled(operationContext()));
}
TEST_F(IsReplicatedFastCountEnabledWithProviderTest, EnabledWhenBothFlagAndProviderOn) {

View File

@ -35,6 +35,7 @@
#include "mongo/bson/timestamp.h"
#include "mongo/db/client.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/replicated_fast_count/replicated_fast_count_enabled.h"
#include "mongo/db/replicated_fast_count/replicated_fast_count_manager.h"
#include "mongo/db/server_feature_flags_gen.h"
#include "mongo/db/service_context.h"
@ -134,9 +135,7 @@ void Checkpointer::run() {
const Date_t startTime = Date_t::now();
opCtx->getServiceContext()->getStorageEngine()->checkpoint();
if (gFeatureFlagReplicatedFastCount.isEnabledUseLatestFCVWhenUninitialized(
VersionContext::getDecoration(opCtx.get()),
serverGlobalParams.featureCompatibility.acquireFCVSnapshot())) {
if (isReplicatedFastCountEnabled(opCtx.get())) {
ReplicatedFastCountManager::get(opCtx->getServiceContext()).flushAsync();
}

View File

@ -38,6 +38,7 @@
#include "mongo/db/client.h"
#include "mongo/db/commands/server_status/server_status_metric.h"
#include "mongo/db/index_names.h"
#include "mongo/db/replicated_fast_count/replicated_fast_count_enabled.h"
#include "mongo/db/replicated_fast_count/replicated_fast_count_manager.h"
#include "mongo/db/rss/replicated_storage_service.h"
#include "mongo/db/server_feature_flags_gen.h"
@ -1154,9 +1155,7 @@ void WiredTigerKVEngine::flushAllFiles(OperationContext* opCtx, bool callerHolds
// Immediately flush the size storer information to disk. When the node is fsync locked for
// operations such as backup, it's imperative that we copy the most up-to-date data files.
if (!_sizeStorer) {
if (gFeatureFlagReplicatedFastCount.isEnabledUseLastLTSFCVWhenUninitialized(
VersionContext::getDecoration(opCtx),
serverGlobalParams.featureCompatibility.acquireFCVSnapshot())) {
if (isReplicatedFastCountEnabled(opCtx)) {
// TODO(SERVER-101413): Remove this once checkpointing and recovery is functional.
ReplicatedFastCountManager::get(opCtx->getServiceContext()).flushAsync();
}

View File

@ -960,14 +960,12 @@ Status validate(OperationContext* opCtx,
const FastCountType fastCountType = validateState.getDetectedFastCountType(opCtx);
results->setFastCountType({fastCountType});
if (validateState.enforceFastCountRequested() || validateState.enforceFastSizeRequested()) {
if (fastCountType == FastCountType::both) {
LOGV2_ERROR(ErrorCodes::InvalidOptions, "Both FastCount tables found");
results->addError("Both FastCount tables found", false);
} else if (fastCountType == FastCountType::neither) {
LOGV2_ERROR(ErrorCodes::InvalidOptions, "Neither FastCount table found");
results->addError("Neither FastCount table found", false);
}
const bool shouldEnforceFastCountOrSize =
validateState.enforceFastCountRequested() || validateState.enforceFastSizeRequested();
if (shouldEnforceFastCountOrSize && fastCountType == FastCountType::neither) {
LOGV2_ERROR(ErrorCodes::InvalidOptions, "Neither FastCount table found");
results->addError("Neither FastCount table found", false);
}
_validateCatalogEntry(opCtx, &validateState, results);

View File

@ -35,6 +35,7 @@
#include "mongo/db/index_names.h"
#include "mongo/db/operation_context.h"
#include "mongo/db/repl/intent_registry.h"
#include "mongo/db/replicated_fast_count/replicated_fast_count_enabled.h"
#include "mongo/db/server_feature_flags_gen.h"
#include "mongo/db/service_context.h"
#include "mongo/db/shard_role/shard_catalog/collection.h"
@ -182,10 +183,7 @@ bool ValidateState::shouldEnforceFastCount(OperationContext* opCtx) const {
// size storer counts for the 'config.image_collection' collection. We therefore do not
// enforce fast count on it.
return false;
} else if (gFeatureFlagReplicatedFastCount.isEnabledUseLatestFCVWhenUninitialized(
VersionContext::getDecoration(opCtx),
serverGlobalParams.featureCompatibility.acquireFCVSnapshot()) &&
_nss.isOnInternalDb()) {
} else if (isReplicatedFastCountEnabled(opCtx) && _nss.isOnInternalDb()) {
// SERVER-119984 TODO: Revisit this, enforce if possible.
return false;
}