summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHuayu Ouyang <huayu.ouyang@mongodb.com>2023-04-27 14:49:46 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2023-04-27 15:59:11 +0000
commita1716c08fff135e860cb629b60cc1c023410bff1 (patch)
tree859eb3ddfe559d4be1e528d985cc922c595e47d7
parentb62a4d9aec355679098f803dd97b0fda2cf0bcdb (diff)
downloadmongo-a1716c08fff135e860cb629b60cc1c023410bff1.tar.gz
SERVER-68151 Add a required feature flag IDL parameter of shouldBeFCVGated
-rw-r--r--buildscripts/idl/idl/binder.py13
-rw-r--r--buildscripts/idl/idl/errors.py15
-rw-r--r--buildscripts/idl/idl/parser.py3
-rw-r--r--buildscripts/idl/idl/syntax.py2
-rw-r--r--buildscripts/idl/tests/test_binder.py57
-rw-r--r--buildscripts/idl/tests/test_parser.py11
-rw-r--r--src/mongo/crypto/encryption_fields.idl2
-rw-r--r--src/mongo/db/catalog_shard_feature_flag.idl2
-rw-r--r--src/mongo/db/feature_flag.cpp28
-rw-r--r--src/mongo/db/feature_flag.h3
-rw-r--r--src/mongo/db/feature_flag_test.idl.tpl10
-rw-r--r--src/mongo/db/internal_transactions_feature_flag.idl3
-rw-r--r--src/mongo/db/process_health/health_monitoring.idl1
-rw-r--r--src/mongo/db/query/query_feature_flags.idl16
-rw-r--r--src/mongo/db/repl/FCV_AND_FEATURE_FLAG_README.md15
-rw-r--r--src/mongo/db/repl/repl_server_parameters.idl5
-rw-r--r--src/mongo/db/server_feature_flags.idl12
-rw-r--r--src/mongo/db/storage/storage_engine_feature_flags.idl2
-rw-r--r--src/mongo/db/storage/storage_parameters.idl12
-rw-r--r--src/mongo/executor/network_interface_tl.idl1
-rw-r--r--src/mongo/idl/cluster_server_parameter.idl2
-rw-r--r--src/mongo/idl/feature_flag_test.cpp23
-rw-r--r--src/mongo/s/analyze_shard_key_feature_flag.idl1
-rw-r--r--src/mongo/s/move_primary/move_primary_feature_flag.idl1
-rw-r--r--src/mongo/s/resharding/resharding_feature_flag.idl1
-rw-r--r--src/mongo/s/sharding_feature_flags.idl14
26 files changed, 239 insertions, 16 deletions
diff --git a/buildscripts/idl/idl/binder.py b/buildscripts/idl/idl/binder.py
index 51db4476b22..47ef2c02d40 100644
--- a/buildscripts/idl/idl/binder.py
+++ b/buildscripts/idl/idl/binder.py
@@ -1476,13 +1476,20 @@ def _bind_feature_flags(ctxt, param):
ctxt.add_feature_flag_default_false_has_version(param)
return None
- # Feature flags that default to true are required to have a version
- if param.default.literal == "true" and not param.version:
+ # Feature flags that default to true and should be FCV gated are required to have a version
+ if param.default.literal == "true" and param.shouldBeFCVGated.literal == "true" and not param.version:
ctxt.add_feature_flag_default_true_missing_version(param)
return None
+ # Feature flags that should not be FCV gated must not have a version
+ if param.shouldBeFCVGated.literal == "false" and param.version:
+ ctxt.add_feature_flag_fcv_gated_false_has_version(param)
+ return None
+
expr = syntax.Expression(param.default.file_name, param.default.line, param.default.column)
- expr.expr = '%s, "%s"_sd' % (param.default.literal, param.version if param.version else '')
+ expr.expr = '%s, "%s"_sd, %s' % (param.default.literal, param.version if
+ (param.shouldBeFCVGated.literal == "true"
+ and param.version) else '', param.shouldBeFCVGated.literal)
ast_param.default = _bind_expression(expr)
ast_param.default.export = False
diff --git a/buildscripts/idl/idl/errors.py b/buildscripts/idl/idl/errors.py
index c3b870e8fd7..677cf9eca8f 100644
--- a/buildscripts/idl/idl/errors.py
+++ b/buildscripts/idl/idl/errors.py
@@ -137,6 +137,7 @@ ERROR_ID_CANNOT_BE_LITERAL_AND_FIELDPATH = "ID0097"
ERROR_ID_QUERY_SHAPE_FIELDPATH_CANNOT_BE_FALSE = "ID0098"
ERROR_ID_STRICT_AND_DISABLE_CHECK_NOT_ALLOWED = "ID0099"
ERROR_ID_INHERITANCE_AND_DISABLE_CHECK_NOT_ALLOWED = "ID0100"
+ERROR_ID_FEATURE_FLAG_SHOULD_BE_FCV_GATED_FALSE_HAS_VERSION = "ID0101"
class IDLError(Exception):
@@ -843,9 +844,10 @@ class ParserContext(object):
def add_feature_flag_default_true_missing_version(self, location):
# type: (common.SourceLocation) -> None
- """Add an error about a default flag with a default value of true but no version."""
- self._add_error(location, ERROR_ID_FEATURE_FLAG_DEFAULT_TRUE_MISSING_VERSION,
- ("Missing 'version' required for feature flag that defaults to true"))
+ """Add an error about a default flag with a default value of true and should be FCV gated but no version."""
+ self._add_error(location, ERROR_ID_FEATURE_FLAG_DEFAULT_TRUE_MISSING_VERSION, (
+ "Missing 'version' required for feature flag that defaults to true and should be FCV gated"
+ ))
def add_feature_flag_default_false_has_version(self, location):
# type: (common.SourceLocation) -> None
@@ -854,6 +856,13 @@ class ParserContext(object):
location, ERROR_ID_FEATURE_FLAG_DEFAULT_FALSE_HAS_VERSION,
("The 'version' attribute is not allowed for feature flag that defaults to false"))
+ def add_feature_flag_fcv_gated_false_has_version(self, location):
+ # type: (common.SourceLocation) -> None
+ """Add an error about a feature flag that should not be FCV gated but has a version."""
+ self._add_error(
+ location, ERROR_ID_FEATURE_FLAG_SHOULD_BE_FCV_GATED_FALSE_HAS_VERSION,
+ ("The 'version' attribute is not allowed for feature flag that should be FCV gated"))
+
def add_reply_type_invalid_type(self, location, command_name, reply_type_name):
# type: (common.SourceLocation, str, str) -> None
"""Add an error about a command whose reply_type refers to an unknown type."""
diff --git a/buildscripts/idl/idl/parser.py b/buildscripts/idl/idl/parser.py
index 3393d6681e7..349ef8ff64a 100644
--- a/buildscripts/idl/idl/parser.py
+++ b/buildscripts/idl/idl/parser.py
@@ -986,6 +986,9 @@ def _parse_feature_flag(ctxt, spec, name, node):
mapping_parser_func=_parse_expression),
"version":
_RuleDesc('scalar'),
+ "shouldBeFCVGated":
+ _RuleDesc('scalar_or_mapping', _RuleDesc.REQUIRED,
+ mapping_parser_func=_parse_expression),
})
spec.feature_flags.append(param)
diff --git a/buildscripts/idl/idl/syntax.py b/buildscripts/idl/idl/syntax.py
index 21f2e252ec8..cf23b4931c5 100644
--- a/buildscripts/idl/idl/syntax.py
+++ b/buildscripts/idl/idl/syntax.py
@@ -886,6 +886,8 @@ class FeatureFlag(common.SourceLocation):
self.cpp_varname = None # type: str
self.default = None # type: Expression
self.version = None # type: str
+ # pylint: disable=C0103
+ self.shouldBeFCVGated = None # type: Expression
super(FeatureFlag, self).__init__(file_name, line, column)
diff --git a/buildscripts/idl/tests/test_binder.py b/buildscripts/idl/tests/test_binder.py
index 8cf23521b0f..0118f38c7b9 100644
--- a/buildscripts/idl/tests/test_binder.py
+++ b/buildscripts/idl/tests/test_binder.py
@@ -2335,7 +2335,7 @@ class TestBinder(testcase.IDLTestcase):
# type: () -> None
"""Test feature flag checks around version."""
- # feature flag can default to false without a version
+ # feature flag can default to false without a version (shouldBeFCVGated can be true or false)
self.assert_bind(
textwrap.dedent("""
feature_flags:
@@ -2343,9 +2343,20 @@ class TestBinder(testcase.IDLTestcase):
description: "Make toast"
cpp_varname: gToaster
default: false
+ shouldBeFCVGated: false
"""))
- # feature flag can default to true with a version
+ self.assert_bind(
+ textwrap.dedent("""
+ feature_flags:
+ featureFlagToaster:
+ description: "Make toast"
+ cpp_varname: gToaster
+ default: false
+ shouldBeFCVGated: true
+ """))
+
+ # if shouldBeFCVGated: true, feature flag can default to true with a version
self.assert_bind(
textwrap.dedent("""
feature_flags:
@@ -2354,9 +2365,21 @@ class TestBinder(testcase.IDLTestcase):
cpp_varname: gToaster
default: true
version: 123
+ shouldBeFCVGated: true
"""))
- # true is only allowed with a version
+ # if shouldBeFCVGated: false, we do not need a version
+ self.assert_bind(
+ textwrap.dedent("""
+ feature_flags:
+ featureFlagToaster:
+ description: "Make toast"
+ cpp_varname: gToaster
+ default: true
+ shouldBeFCVGated: false
+ """))
+
+ # if shouldBeFCVGated: true and default: true, a version is required
self.assert_bind_fail(
textwrap.dedent("""
feature_flags:
@@ -2364,9 +2387,10 @@ class TestBinder(testcase.IDLTestcase):
description: "Make toast"
cpp_varname: gToaster
default: true
+ shouldBeFCVGated: true
"""), idl.errors.ERROR_ID_FEATURE_FLAG_DEFAULT_TRUE_MISSING_VERSION)
- # false is not allowed with a version
+ # false is not allowed with a version and shouldBeFCVGated: true
self.assert_bind_fail(
textwrap.dedent("""
feature_flags:
@@ -2375,8 +2399,33 @@ class TestBinder(testcase.IDLTestcase):
cpp_varname: gToaster
default: false
version: 123
+ shouldBeFCVGated: true
"""), idl.errors.ERROR_ID_FEATURE_FLAG_DEFAULT_FALSE_HAS_VERSION)
+ # false is not allowed with a version and shouldBeFCVGated: false
+ self.assert_bind_fail(
+ textwrap.dedent("""
+ feature_flags:
+ featureFlagToaster:
+ description: "Make toast"
+ cpp_varname: gToaster
+ default: false
+ version: 123
+ shouldBeFCVGated: false
+ """), idl.errors.ERROR_ID_FEATURE_FLAG_DEFAULT_FALSE_HAS_VERSION)
+
+ # if shouldBeFCVGated is false, a version is not allowed
+ self.assert_bind_fail(
+ textwrap.dedent("""
+ feature_flags:
+ featureFlagToaster:
+ description: "Make toast"
+ cpp_varname: gToaster
+ default: true
+ version: 123
+ shouldBeFCVGated: false
+ """), idl.errors.ERROR_ID_FEATURE_FLAG_SHOULD_BE_FCV_GATED_FALSE_HAS_VERSION)
+
def test_access_check(self):
# type: () -> None
"""Test access check."""
diff --git a/buildscripts/idl/tests/test_parser.py b/buildscripts/idl/tests/test_parser.py
index 305d5fbbafd..91aa7d4ce2a 100644
--- a/buildscripts/idl/tests/test_parser.py
+++ b/buildscripts/idl/tests/test_parser.py
@@ -1591,6 +1591,17 @@ class TestParser(testcase.IDLTestcase):
featureFlagToaster:
description: "Make toast"
cpp_varname: gToaster
+ shouldBeFCVGated: true
+ """), idl.errors.ERROR_ID_MISSING_REQUIRED_FIELD)
+
+ # Missing shouldBeFCVGated
+ self.assert_parse_fail(
+ textwrap.dedent("""
+ feature_flags:
+ featureFlagToaster:
+ description: "Make toast"
+ cpp_varname: gToaster
+ default: false
"""), idl.errors.ERROR_ID_MISSING_REQUIRED_FIELD)
def _test_field_list(self, field_list_name, should_forward_name):
diff --git a/src/mongo/crypto/encryption_fields.idl b/src/mongo/crypto/encryption_fields.idl
index 85b2ac77ebb..ef48242d030 100644
--- a/src/mongo/crypto/encryption_fields.idl
+++ b/src/mongo/crypto/encryption_fields.idl
@@ -61,10 +61,12 @@ feature_flags:
version: 7.0
cpp_varname: gFeatureFlagFLE2CompactForProtocolV2
default: true
+ shouldBeFCVGated: true
featureFlagFLE2CleanupCommand:
description: "Enable support for the Cleanup Structured Encryption Data command"
cpp_varname: gFeatureFlagFLE2CleanupCommand
default: false
+ shouldBeFCVGated: true
structs:
diff --git a/src/mongo/db/catalog_shard_feature_flag.idl b/src/mongo/db/catalog_shard_feature_flag.idl
index bcbef0063fd..e43d755c675 100644
--- a/src/mongo/db/catalog_shard_feature_flag.idl
+++ b/src/mongo/db/catalog_shard_feature_flag.idl
@@ -35,9 +35,11 @@ feature_flags:
cpp_varname: gFeatureFlagCatalogShard
default: true
version: 7.0
+ shouldBeFCVGated: true
featureFlagTransitionToCatalogShard:
description: "Feature flag for transitioning a config server in and out of config shard mode"
cpp_varname: gFeatureFlagTransitionToCatalogShard
default: true
version: 7.0
+ shouldBeFCVGated: true
diff --git a/src/mongo/db/feature_flag.cpp b/src/mongo/db/feature_flag.cpp
index b75892a9408..818df3bfdcc 100644
--- a/src/mongo/db/feature_flag.cpp
+++ b/src/mongo/db/feature_flag.cpp
@@ -35,8 +35,10 @@
namespace mongo {
// (Generic FCV reference): feature flag support
-FeatureFlag::FeatureFlag(bool enabled, StringData versionString)
- : _enabled(enabled), _version(multiversion::GenericFCV::kLatest) {
+FeatureFlag::FeatureFlag(bool enabled, StringData versionString, bool shouldBeFCVGated)
+ : _enabled(enabled),
+ _version(multiversion::GenericFCV::kLatest),
+ _shouldBeFCVGated(shouldBeFCVGated) {
// Verify the feature flag invariants. IDL binder verifies these hold but we add these checks to
// prevent incorrect direct instantiation.
@@ -44,7 +46,7 @@ FeatureFlag::FeatureFlag(bool enabled, StringData versionString)
// If default is true, then version should be present.
// If default is false, then no version is allowed.
if (kDebugBuild) {
- if (enabled) {
+ if (enabled && shouldBeFCVGated) {
dassert(!versionString.empty());
} else {
dassert(versionString.empty());
@@ -57,6 +59,12 @@ FeatureFlag::FeatureFlag(bool enabled, StringData versionString)
}
bool FeatureFlag::isEnabled(const ServerGlobalParams::FeatureCompatibility& fcv) const {
+ // If the feature flag is not FCV gated, return whether it is enabled.
+ if (!_shouldBeFCVGated) {
+ return _enabled;
+ }
+
+
// If the FCV is not initialized yet, we check whether the feature flag is enabled on the last
// LTS FCV, which is the lowest FCV we can have on this server. Because the version of a feature
// flag is not supposed to change, we are sure that if the feature flag is enabled on the last
@@ -70,13 +78,27 @@ bool FeatureFlag::isEnabled(const ServerGlobalParams::FeatureCompatibility& fcv)
return false;
}
+ // If the feature flag is enabled, return whether the server's FCV is >= to the version the
+ // feature flag was enabled on.
return fcv.isGreaterThanOrEqualTo(_version);
}
+// isEnabledAndIgnoreFCVUnsafe should NOT be used in general, as it checks if the feature flag is
+// turned on, regardless of which FCV we are on. It can result in unsafe scenarios
+// where we enable a feature on an FCV where it is not supported or where the feature has not been
+// fully implemented yet. In order to use isEnabledAndIgnoreFCVUnsafe, you **must** add a comment
+// above that line starting with "(Ignore FCV check):" describing why we can safely ignore checking
+// the FCV here.
+// Note that if the feature flag does not have any upgrade/downgrade concerns, then shouldBeFCVGated
+// should be set to false and FeatureFlag::isEnabled() should be used instead of this function.
bool FeatureFlag::isEnabledAndIgnoreFCVUnsafe() const {
return _enabled;
}
+// isEnabledAndIgnoreFCVUnsafeAtStartup should only be used on startup, if we want to check if the
+// feature flag if the feature flag is turned on, regardless of which FCV we are on.
+// Note that if the feature flag does not have any upgrade/downgrade concerns, then shouldBeFCVGated
+// should be set to false and FeatureFlag::isEnabled() should be used instead of this function.
bool FeatureFlag::isEnabledAndIgnoreFCVUnsafeAtStartup() const {
return _enabled;
}
diff --git a/src/mongo/db/feature_flag.h b/src/mongo/db/feature_flag.h
index 746f14e41c5..d59407c2c2e 100644
--- a/src/mongo/db/feature_flag.h
+++ b/src/mongo/db/feature_flag.h
@@ -52,7 +52,7 @@ class FeatureFlag {
friend class FeatureFlagServerParameter;
public:
- FeatureFlag(bool enabled, StringData versionString);
+ FeatureFlag(bool enabled, StringData versionString, bool shouldBeFCVGated);
/**
* Returns true if the flag is set to true and enabled for this FCV version.
@@ -126,6 +126,7 @@ private:
private:
bool _enabled;
multiversion::FeatureCompatibilityVersion _version;
+ bool _shouldBeFCVGated;
};
/**
diff --git a/src/mongo/db/feature_flag_test.idl.tpl b/src/mongo/db/feature_flag_test.idl.tpl
index d83d2316aaf..5b5d6e8a0ed 100644
--- a/src/mongo/db/feature_flag_test.idl.tpl
+++ b/src/mongo/db/feature_flag_test.idl.tpl
@@ -42,11 +42,19 @@ feature_flags:
description: "Create a feature flag"
cpp_varname: gFeatureFlagToaster
default: false
+ shouldBeFCVGated: true
featureFlagFryer:
description: "Create a feature flag"
cpp_varname: gFeatureFlagFryer
default: false
+ shouldBeFCVGated: true
+
+ featureFlagFork:
+ description: "Create a feature flag that should not be FCV gated"
+ cpp_varname: gFeatureFlagFork
+ default: true
+ shouldBeFCVGated: false
#def $ver_str(v): ${'{}.{}'.format(v.major, v.minor)}
featureFlagBlender:
@@ -56,6 +64,7 @@ feature_flags:
# The version should be a valid FCV not equal to GenericFCV::kLastLTS in
# the generated 'releases.h' file.
version: $ver_str(latest)
+ shouldBeFCVGated: true
featureFlagSpoon:
description: "Create a feature flag"
@@ -63,6 +72,7 @@ feature_flags:
default: true
# The version should match GenericFCV::kLastLTS in the generated 'releases.h' file.
version: $ver_str(last_lts)
+ shouldBeFCVGated: true
server_parameters:
spTestNeedsFeatureFlagToaster:
diff --git a/src/mongo/db/internal_transactions_feature_flag.idl b/src/mongo/db/internal_transactions_feature_flag.idl
index 97b0bcd927a..9a38ed96d7f 100644
--- a/src/mongo/db/internal_transactions_feature_flag.idl
+++ b/src/mongo/db/internal_transactions_feature_flag.idl
@@ -39,13 +39,16 @@ feature_flags:
description: Feature flag to enable always creating the config.transactions partial index on step up to primary even if the collection is not empty.
cpp_varname: gFeatureFlagAlwaysCreateConfigTransactionsPartialIndexOnStepUp
default: false
+ shouldBeFCVGated: true
featureFlagUpdateDocumentShardKeyUsingTransactionApi:
description: Feature flag to enable usage of the transaction api for update findAndModify and update commands that change a document's shard key.
cpp_varname: gFeatureFlagUpdateDocumentShardKeyUsingTransactionApi
default: false
+ shouldBeFCVGated: true
featureFlagUpdateOneWithoutShardKey:
description: Feature flag to enable updateOne, deleteOne, and findAndModify without a shard key or _id equality in their filter against a sharded collection.
cpp_varname: gFeatureFlagUpdateOneWithoutShardKey
default: false
+ shouldBeFCVGated: true
diff --git a/src/mongo/db/process_health/health_monitoring.idl b/src/mongo/db/process_health/health_monitoring.idl
index 88837981d8c..5c9a23e5bc5 100644
--- a/src/mongo/db/process_health/health_monitoring.idl
+++ b/src/mongo/db/process_health/health_monitoring.idl
@@ -40,3 +40,4 @@ feature_flags:
cpp_varname: gFeatureFlagHealthMonitoring
default: true
version: 5.3
+ shouldBeFCVGated: true
diff --git a/src/mongo/db/query/query_feature_flags.idl b/src/mongo/db/query/query_feature_flags.idl
index 86d0622d385..c99596755a9 100644
--- a/src/mongo/db/query/query_feature_flags.idl
+++ b/src/mongo/db/query/query_feature_flags.idl
@@ -35,88 +35,104 @@ feature_flags:
cpp_varname: gFeatureFlagChangeStreamsRewrite
default: true
version: 5.1
+ shouldBeFCVGated: true
featureFlagShardedTimeSeries:
description: "Feature flag for allowing sharding a Time Series collection"
cpp_varname: gFeatureFlagShardedTimeSeries
default: true
version: 5.1
+ shouldBeFCVGated: true
featureFlagShardedTimeSeriesUpdateDelete:
description: "Feature flag for allowing update and delete operations on a sharded Time Series collection"
cpp_varname: gFeatureFlagShardedTimeSeriesUpdateDelete
default: true
version: 5.1
+ shouldBeFCVGated: true
featureFlagChangeStreamsFurtherEnrichedEvents:
description: "Feature flag for enabling the reshardCollection and refineCollectionShardKey events, as well as enhancements to the updateDescription field for update events"
cpp_varname: gFeatureFlagChangeStreamsFurtherEnrichedEvents
default: true
version: 6.1
+ shouldBeFCVGated: true
featureFlagCommonQueryFramework:
description: "Feature flag for allowing use of Cascades-based query optimizer"
cpp_varname: gFeatureFlagCommonQueryFramework
default: false
+ shouldBeFCVGated: true
featureFlagBucketUnpackWithSort:
description: "Enables a time-series optimization that allows for partially-blocking sort on time"
cpp_varname: gFeatureFlagBucketUnpackWithSort
default: true
version: 6.0
+ shouldBeFCVGated: true
featureFlagColumnstoreIndexes:
description: "Enables creation of a new columnstore index type"
cpp_varname: gFeatureFlagColumnstoreIndexes
default: false
+ shouldBeFCVGated: true
featureFlagServerlessChangeStreams:
description: "Feature flag to enable reading change events from the change collection rather than the oplog"
cpp_varname: gFeatureFlagServerlessChangeStreams
default: false
+ shouldBeFCVGated: true
featureFlagSbeFull:
description: "Feature flag for SBE behaviors, features, or extensions that are not yet enabled
by default"
cpp_varname: gFeatureFlagSbeFull
default: false
+ shouldBeFCVGated: true
featureFlagTelemetry:
description: "Feature flag for enabling the telemetry store."
cpp_varname: gFeatureFlagTelemetry
default: false
+ shouldBeFCVGated: true
featureFlagBitwiseAggOperators:
description: "Feature flag for enabling support for bitwise operators in the aggregation language."
cpp_varname: gFeatureFlagBitwise
default: true
version: 6.3
+ shouldBeFCVGated: true
featureFlagCompoundWildcardIndexes:
description: "Feature flag to enable compound wildcard indexes."
cpp_varname: gFeatureFlagCompoundWildcardIndexes
default: true
version: 7.0
+ shouldBeFCVGated: true
featureFlagShardedSearchCustomSort:
description: "Feature flag to enable user specified sort for sharded $search queries."
cpp_varname: gFeatureFlagShardedSearchCustomSort
default: true
version: 7.0
+ shouldBeFCVGated: true
featureFlagUserRoles:
description: "Feature flag to enable usage of $$USER_ROLES."
cpp_varname: gFeatureFlagUserRoles
default: true
version: 7.0
+ shouldBeFCVGated: true
featureFlagApproxPercentiles:
description: "Feature flag to enable approximate $percentile accumulator/expression."
cpp_varname: gFeatureFlagApproxPercentiles
default: true
version: 7.0
+ shouldBeFCVGated: true
featureFlagSearchBatchSizeLimit:
description: "Feature flag to enable the search batchsize and limit optimization."
cpp_varname: gFeatureFlagSearchBatchSizeLimit
default: false
+ shouldBeFCVGated: true
diff --git a/src/mongo/db/repl/FCV_AND_FEATURE_FLAG_README.md b/src/mongo/db/repl/FCV_AND_FEATURE_FLAG_README.md
index b5570f5206f..97381b12223 100644
--- a/src/mongo/db/repl/FCV_AND_FEATURE_FLAG_README.md
+++ b/src/mongo/db/repl/FCV_AND_FEATURE_FLAG_README.md
@@ -544,6 +544,7 @@ Feature flags are created by adding it to an IDL file:
description: "Create a feature flag"
cpp_varname: gFeatureFlagToaster
default: false
+ shouldBeFCVGated: true
```
A feature flag has the following properties:
@@ -569,6 +570,13 @@ A feature flag has the following properties:
* Version: string - a string for the FCV version
* Required field if default is true, Must be a string acceptable to
FeatureCompatibilityVersionParser.
+* shouldBeFCVGated: boolean
+ * This should usually be true in order to gate the feature flag based on the FCV.
+ * However, some feature flags should not be FCV gated (for example, if the feature only exists
+ on mongos, which doesn't have an FCV, or if the feature doesn't have any upgrade downgrade
+ concerns and can be enabled as soon as the binary is upgraded/downgraded.
+ * When set to false, the feature flag won't require a version parameter, so it will only be
+ gated based on whether it is enabled by default on that binary version.
To turn on a feature flag for testing when starting up a server, we would use the following command
line (for the Toaster feature):
@@ -599,9 +607,12 @@ if(feature_flags::gFeatureFlagToaster.isEnabled(serverGlobalParams.featureCompat
}
```
-Note that `isEnabled` checks if the feature flag is enabled on the input FCV, which is usually
-the server's current FCV `serverGlobalParams.featureCompatibility`. If the FCV has not been
+Note that `isEnabled` checks if the feature flag is enabled on the input FCV, which is usually
+the server's current FCV `serverGlobalParams.featureCompatibility`. If the FCV has not been
initialized yet, it will check if the feature flag is enabled on the lastLTS FCV.
+If the feature flag has `shouldBeFCVGated` set to false, then `isEnabled` will simply return
+whether the feature flag is enabled.
+
There are some places where we only want to check if the feature flag is turned on, regardless of
which FCV we are on. For example, this could be the case if we need to perform the check in a spot
diff --git a/src/mongo/db/repl/repl_server_parameters.idl b/src/mongo/db/repl/repl_server_parameters.idl
index 4e2c0838e4d..620a4d08a29 100644
--- a/src/mongo/db/repl/repl_server_parameters.idl
+++ b/src/mongo/db/repl/repl_server_parameters.idl
@@ -769,17 +769,20 @@ feature_flags:
cpp_varname: feature_flags::gFeatureFlagRetryableFindAndModify
default: true
version: 5.1
+ shouldBeFCVGated: true
featureFlagShardMerge:
description: When enabled, multitenant migration uses the "shard merge" protocol.
cpp_varname: feature_flags::gShardMerge
default: false
+ shouldBeFCVGated: true
featureFlagShardSplit:
description: When enabled, multitenant migration can use the shard split commands.
cpp_varname: feature_flags::gShardSplit
default: true
version: 6.3
+ shouldBeFCVGated: true
featureFlagDowngradingToUpgrading:
description: When enabled,
@@ -787,9 +790,11 @@ feature_flags:
cpp_varname: feature_flags::gDowngradingToUpgrading
default: true
version: 7.0
+ shouldBeFCVGated: true
featureFlagApplyPreparedTxnsInParallel:
description: when enabled, secondaries will apply prepared transactions in parallel.
cpp_varname: feature_flags::gApplyPreparedTxnsInParallel
default: true
version: 7.0
+ shouldBeFCVGated: true
diff --git a/src/mongo/db/server_feature_flags.idl b/src/mongo/db/server_feature_flags.idl
index d7324158ccd..57b34e36c89 100644
--- a/src/mongo/db/server_feature_flags.idl
+++ b/src/mongo/db/server_feature_flags.idl
@@ -34,6 +34,7 @@ feature_flags:
description: "Enable parsing and handling of SecurityTokens in multitenancy mode"
cpp_varname: gFeatureFlagSecurityToken
default: false
+ shouldBeFCVGated: true
featureFlagRequireTenantID:
# Only available with the server parameter "multitenancySupport".
description: >-
@@ -41,47 +42,57 @@ feature_flags:
require tenantID to be a part of NamespaceString and TenantDatabase.
cpp_varname: gFeatureFlagRequireTenantID
default: false
+ shouldBeFCVGated: true
featureFlagConnHealthMetrics:
description: "Enable newly added cluster connection health metrics"
cpp_varname: gFeatureFlagConnHealthMetrics
default: true
version: 6.3
+ shouldBeFCVGated: true
featureFlagGlobalIndexes:
description: "Enable support for global indexes"
cpp_varname: gFeatureFlagGlobalIndexes
default: false
+ shouldBeFCVGated: true
featureFlagAdditionalParticipants:
description: "Adding additional participants to existing transactions"
cpp_varname: gFeatureFlagAdditionalParticipants
default: false
+ shouldBeFCVGated: true
featureFlagUseNewCompactStructuredEncryptionDataCoordinator:
description: "Use the new 6.1 compact structured encryption data coordinator"
cpp_varname: gFeatureFlagUseNewCompactStructuredEncryptionDataCoordinator
default: true
version: 6.1
+ shouldBeFCVGated: true
featureFlagOIDC:
description: "Feature flag for OIDC support"
cpp_varname: gFeatureFlagOIDC
default: true
version: 7.0
+ shouldBeFCVGated: true
featureFlagBulkWriteCommand:
description: "Support for bulkWrite command and one-shot transactions"
cpp_varname: gFeatureFlagBulkWriteCommand
default: false
+ shouldBeFCVGated: true
featureFlagAuditConfigClusterParameter:
description: "Enable use of new auditConfig cluster server parameter"
cpp_varname: feature_flags::gFeatureFlagAuditConfigClusterParameter
default: false
+ shouldBeFCVGated: true
featureFlagStreams:
description: "Enable support for streams"
cpp_varname: gFeatureFlagStreams
default: false
+ shouldBeFCVGated: true
featureFlagUseUnreplicatedTruncatesForDeletions:
description: "Feature flag to enable pre-image collection and change collection maintenance
using unreplicated truncates instead of normal document deletions replicated from the
primary."
cpp_varname: feature_flags::gFeatureFlagUseUnreplicatedTruncatesForDeletions
default: false
+ shouldBeFCVGated: true
featureFlagConfigurableX509ClusterAuthn:
description: >-
Enable configurable parameters for detection of peer server nodes using X.509
@@ -89,3 +100,4 @@ feature_flags:
cpp_varname: gFeatureFlagConfigurableX509ClusterAuthn
default: true
version: 7.0
+ shouldBeFCVGated: true
diff --git a/src/mongo/db/storage/storage_engine_feature_flags.idl b/src/mongo/db/storage/storage_engine_feature_flags.idl
index d2ef38f4576..26052df419b 100644
--- a/src/mongo/db/storage/storage_engine_feature_flags.idl
+++ b/src/mongo/db/storage/storage_engine_feature_flags.idl
@@ -34,8 +34,10 @@ feature_flags:
cpp_varname: feature_flags::gFeatureFlagExecutionControl
default: true
version: 7.0
+ shouldBeFCVGated: true
featureFlagDeprioritizeLowPriorityOperations:
description: Enables the deprioritization of low priority operations
cpp_varname: feature_flags::gFeatureFlagDeprioritizeLowPriorityOperations
default: true
version: 7.0
+ shouldBeFCVGated: true
diff --git a/src/mongo/db/storage/storage_parameters.idl b/src/mongo/db/storage/storage_parameters.idl
index ea461827d05..b17ad345e71 100644
--- a/src/mongo/db/storage/storage_parameters.idl
+++ b/src/mongo/db/storage/storage_parameters.idl
@@ -171,55 +171,67 @@ feature_flags:
cpp_varname: feature_flags::gTimeseriesMetricIndexes
default: true
version: 6.0
+ shouldBeFCVGated: true
featureFlagCollModIndexUnique:
description: "When enabled, collMod supports making an index unique"
cpp_varname: feature_flags::gCollModIndexUnique
default: true
version: 6.0
+ shouldBeFCVGated: true
featureFlagSelectiveBackup:
description: "When enabled, support selective backups and restores on collections"
cpp_varname: feature_flags::gSelectiveBackup
default: true
version: 6.0
+ shouldBeFCVGated: true
featureFlagBatchMultiDeletes:
description: "When enabled, support batching multi-document deletions"
cpp_varname: feature_flags::gBatchMultiDeletes
default: true
version: 6.1
+ shouldBeFCVGated: true
featureFlagDocumentSourceListCatalog:
description: "When enabled, allow the use of the $listCatalog aggregation stage"
cpp_varname: feature_flags::gDocumentSourceListCatalog
default: true
version: 6.0
+ shouldBeFCVGated: true
featureFlagDerivedMetadata:
description: "When enabled, support storing derived collection and index metadata"
cpp_varname: feature_flags::gDerivedMetadata
default: false
+ shouldBeFCVGated: true
featureFlagTimeseriesScalabilityImprovements:
description: "Enable scalability and usability improvements for time-series collections"
cpp_varname: feature_flags::gTimeseriesScalabilityImprovements
default: true
version: 6.3
+ shouldBeFCVGated: true
featureFlagExtendValidateCommand:
description: "Enable checks on more types of inconsistencies for the validate command"
cpp_varname: feature_flags::gExtendValidateCommand
default: true
version: 6.2
+ shouldBeFCVGated: true
featureFlagInternalWritesAreReplicatedTransactionally:
description: Feature flag to enable internal writes to use the transactionally replicated WriteUnitOfWork API by default.
cpp_varname: gFeatureFlagInternalWritesAreReplicatedTransactionally
default: false
+ shouldBeFCVGated: true
featureFlagTimeseriesDeletesSupport:
description: "Enable support for arbitrary deletes on time-series collections"
cpp_varname: feature_flags::gTimeseriesDeletesSupport
default: true
version: 7.0
+ shouldBeFCVGated: true
featureFlagTimeseriesUpdatesSupport:
description: "Enable support for arbitrary updates on time-series collections"
cpp_varname: feature_flags::gTimeseriesUpdatesSupport
default: false
+ shouldBeFCVGated: true
featureFlagIndexBuildGracefulErrorHandling:
description: "Enable index build error handling improvements"
cpp_varname: feature_flags::gIndexBuildGracefulErrorHandling
default: true
version: 7.1
+ shouldBeFCVGated: true
diff --git a/src/mongo/executor/network_interface_tl.idl b/src/mongo/executor/network_interface_tl.idl
index 03decc33c96..11226a554b9 100644
--- a/src/mongo/executor/network_interface_tl.idl
+++ b/src/mongo/executor/network_interface_tl.idl
@@ -34,6 +34,7 @@ feature_flags:
description: Suppress network interface transport layer exceptions
cpp_varname: gSuppressNetworkInterfaceTransportLayerExceptions
default: false
+ shouldBeFCVGated: true
server_parameters:
opportunisticSecondaryTargeting:
diff --git a/src/mongo/idl/cluster_server_parameter.idl b/src/mongo/idl/cluster_server_parameter.idl
index 8991e4f47f9..216193190c8 100644
--- a/src/mongo/idl/cluster_server_parameter.idl
+++ b/src/mongo/idl/cluster_server_parameter.idl
@@ -92,10 +92,12 @@ feature_flags:
cpp_varname: gFeatureFlagClusterWideConfigM2
default: true
version: 6.1
+ shouldBeFCVGated: true
featureFlagClusterWideToaster:
description: Feature flag for testing use of feature flags with CW server params
cpp_varname: gFeatureFlagClusterWideToaster
default: false
+ shouldBeFCVGated: true
server_parameters:
testIntClusterParameter:
diff --git a/src/mongo/idl/feature_flag_test.cpp b/src/mongo/idl/feature_flag_test.cpp
index f0b43850b78..e0636f53d75 100644
--- a/src/mongo/idl/feature_flag_test.cpp
+++ b/src/mongo/idl/feature_flag_test.cpp
@@ -51,6 +51,7 @@ protected:
protected:
ServerParameter* _featureFlagBlender{nullptr};
ServerParameter* _featureFlagSpoon{nullptr};
+ ServerParameter* _featureFlagFork{nullptr};
};
@@ -199,6 +200,28 @@ TEST_F(FeatureFlagTest, RAIIFeatureFlagController) {
feature_flags::gFeatureFlagBlender.isEnabled(serverGlobalParams.featureCompatibility));
}
+// Test feature flags that should not be FCV Gated
+TEST_F(FeatureFlagTest, ShouldBeFCVGatedFalse) {
+ // Test that feature flag that is enabled and not FCV gated will return true for isEnabled.
+ // Test newest version
+ // (Generic FCV reference): feature flag test
+ serverGlobalParams.mutableFeatureCompatibility.setVersion(multiversion::GenericFCV::kLatest);
+
+ ASSERT_TRUE(feature_flags::gFeatureFlagFork.isEnabled(serverGlobalParams.featureCompatibility));
+
+ // Test oldest version
+ // (Generic FCV reference): feature flag test
+ serverGlobalParams.mutableFeatureCompatibility.setVersion(multiversion::GenericFCV::kLastLTS);
+
+ ASSERT_TRUE(feature_flags::gFeatureFlagFork.isEnabled(serverGlobalParams.featureCompatibility));
+
+ // Test uninitialized FCV
+ serverGlobalParams.mutableFeatureCompatibility.setVersion(
+ multiversion::FeatureCompatibilityVersion::kUnsetDefaultLastLTSBehavior);
+
+ ASSERT_TRUE(feature_flags::gFeatureFlagFork.isEnabled(serverGlobalParams.featureCompatibility));
+}
+
} // namespace
} // namespace mongo
diff --git a/src/mongo/s/analyze_shard_key_feature_flag.idl b/src/mongo/s/analyze_shard_key_feature_flag.idl
index 4e92dcac667..b995fe0430f 100644
--- a/src/mongo/s/analyze_shard_key_feature_flag.idl
+++ b/src/mongo/s/analyze_shard_key_feature_flag.idl
@@ -40,3 +40,4 @@ feature_flags:
cpp_varname: gFeatureFlagAnalyzeShardKey
default: true
version: 7.0
+ shouldBeFCVGated: true
diff --git a/src/mongo/s/move_primary/move_primary_feature_flag.idl b/src/mongo/s/move_primary/move_primary_feature_flag.idl
index 61099c5cbdd..876715c7222 100644
--- a/src/mongo/s/move_primary/move_primary_feature_flag.idl
+++ b/src/mongo/s/move_primary/move_primary_feature_flag.idl
@@ -40,3 +40,4 @@ feature_flags:
cpp_varname: gFeatureFlagOnlineMovePrimaryLifecycle
default: true
version: 7.0
+ shouldBeFCVGated: true
diff --git a/src/mongo/s/resharding/resharding_feature_flag.idl b/src/mongo/s/resharding/resharding_feature_flag.idl
index afdad3d093e..551bd8dcc81 100644
--- a/src/mongo/s/resharding/resharding_feature_flag.idl
+++ b/src/mongo/s/resharding/resharding_feature_flag.idl
@@ -40,3 +40,4 @@ feature_flags:
cpp_varname: gFeatureFlagResharding
default: true
version: 5.0
+ shouldBeFCVGated: true
diff --git a/src/mongo/s/sharding_feature_flags.idl b/src/mongo/s/sharding_feature_flags.idl
index 339d9072d87..f084c5827fd 100644
--- a/src/mongo/s/sharding_feature_flags.idl
+++ b/src/mongo/s/sharding_feature_flags.idl
@@ -36,27 +36,32 @@ feature_flags:
description: "Feature flag for enabling sharding catalog features for global indexes"
cpp_varname: feature_flags::gGlobalIndexesShardingCatalog
default: false
+ shouldBeFCVGated: true
featureFlagRangeDeleterService:
description: "Feature flag protecting instantiation and usages of the range deleter service"
cpp_varname: feature_flags::gRangeDeleterService
default: true
version: 6.2
+ shouldBeFCVGated: true
featureFlagCollModCoordinatorV3:
description: "Feature for enabling new coll mod coordinator v3"
cpp_varname: feature_flags::gCollModCoordinatorV3
default: true
version: 6.1
+ shouldBeFCVGated: true
featureFlagCreateCollectionCoordinatorV3:
description: "Feature for enabling new createCollection coordinator v3"
cpp_varname: feature_flags::gCreateCollectionCoordinatorV3
default: true
version: 6.2
+ shouldBeFCVGated: true
# TODO SERVER-68217 remove once 7.0 becomes last LTS
featureFlagHistoricalPlacementShardingCatalog:
description: "Feature flag for enabling the storage and access to historical placement data at shards granularity through the Sharding Catalog"
cpp_varname: feature_flags::gHistoricalPlacementShardingCatalog
default: true
version: 7.0
+ shouldBeFCVGated: true
featureFlagImplicitDDLTimeseriesNssTranslation:
description: "When enabled, the logic to evaluate whether a DDL is targeting a Timeseries operation
will always be executed by the DDL Coordinator (VS doing the evaluation when the command is received by the primary shard).
@@ -64,40 +69,49 @@ feature_flags:
cpp_varname: feature_flags::gImplicitDDLTimeseriesNssTranslation
default: true
version: 6.1
+ shouldBeFCVGated: true
featureFlagConcurrencyInChunkMigration:
description: "Feature flag for enabling concurrency within a chunk migration"
cpp_varname: feature_flags::gConcurrencyInChunkMigration
default: true
version: 6.3
+ shouldBeFCVGated: true
featureFlagStopUsingConfigVersion:
# TODO SERVER-68889 remove once 7.0 becomes last LTS
description: "Stop using deprecated config version fields to check metadata compatibility between different version"
cpp_varname: feature_flags::gStopUsingConfigVersion
default: true
version: 6.2
+ shouldBeFCVGated: true
featureFlagAutoMerger:
description: "Feature flag for enabling auto-merging of contiguous chunks belonging to the same shard"
cpp_varname: feature_flags::gAutoMerger
default: true
version: 7.0
+ shouldBeFCVGated: true
# TODO (SERVER-70396): Remove once 7.0 becomes last LTS
featureFlagCheckMetadataConsistency:
description: "Feature flag for checking metadata consistency in the cluster, database or collection"
cpp_varname: feature_flags::gCheckMetadataConsistency
default: true
version: 7.0
+ shouldBeFCVGated: true
# TODO SERVER-73627: Remove once 7.0 becomes last LTS.
featureFlagDropCollectionHoldingCriticalSection:
description: "Feature flag for enabling the new implementation of the dropCollection DDL operation."
cpp_varname: feature_flags::gDropCollectionHoldingCriticalSection
default: true
version: 7.0
+ shouldBeFCVGated: true
+
featureFlagCheckForDirectShardOperations:
description: "Feature flag for checking for direct shard operations."
cpp_varname: feature_flags::gCheckForDirectShardOperations
default: false
+ shouldBeFCVGated: true
featureFlagClusterCardinalityParameter:
description: "Feature flag for enabling the cluster parameter tracking cluster cardinality."
cpp_varname: feature_flags::gClusterCardinalityParameter
default: true
version: 7.0
+ shouldBeFCVGated: true