Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

migrate experimental-memory-mlock flag to feature gate #19124

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions server/embed/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ func TestConfigFileFeatureGates(t *testing.T) {
experimentalInitialCorruptCheck string
experimentalCompactHashCheckEnabled string
experimentalTxnModeWriteWithSharedBuffer string
experimentalMemoryMlock string
expectErr bool
expectedFeatures map[featuregate.Feature]bool
}{
Expand Down Expand Up @@ -130,6 +131,12 @@ func TestConfigFileFeatureGates(t *testing.T) {
experimentalTxnModeWriteWithSharedBuffer: "false",
expectErr: true,
},
{
name: "cannot set both experimental flag and feature gate flag for MemoryMlock",
serverFeatureGatesJSON: "MemoryMlock=true",
experimentalMemoryMlock: "false",
expectErr: true,
},
{
name: "ok to set different experimental flag and feature gate flag",
serverFeatureGatesJSON: "DistributedTracing=true",
Expand All @@ -138,6 +145,7 @@ func TestConfigFileFeatureGates(t *testing.T) {
features.DistributedTracing: true,
features.StopGRPCServiceOnDefrag: true,
features.InitialCorruptCheck: false,
features.MemoryMlock: false,
},
},
{
Expand All @@ -160,6 +168,7 @@ func TestConfigFileFeatureGates(t *testing.T) {
features.DistributedTracing: false,
features.InitialCorruptCheck: false,
features.TxnModeWriteWithSharedBuffer: true,
features.MemoryMlock: false,
},
},
{
Expand All @@ -170,6 +179,7 @@ func TestConfigFileFeatureGates(t *testing.T) {
features.DistributedTracing: false,
features.InitialCorruptCheck: false,
features.TxnModeWriteWithSharedBuffer: true,
features.MemoryMlock: false,
},
},
{
Expand All @@ -179,6 +189,7 @@ func TestConfigFileFeatureGates(t *testing.T) {
features.StopGRPCServiceOnDefrag: false,
features.DistributedTracing: false,
features.InitialCorruptCheck: true,
features.MemoryMlock: false,
},
},
{
Expand All @@ -188,6 +199,7 @@ func TestConfigFileFeatureGates(t *testing.T) {
features.StopGRPCServiceOnDefrag: false,
features.DistributedTracing: false,
features.InitialCorruptCheck: false,
features.MemoryMlock: false,
},
},
{
Expand All @@ -199,6 +211,7 @@ func TestConfigFileFeatureGates(t *testing.T) {
features.InitialCorruptCheck: false,
features.CompactHashCheck: false,
features.TxnModeWriteWithSharedBuffer: true,
features.MemoryMlock: false,
},
},
{
Expand All @@ -210,6 +223,7 @@ func TestConfigFileFeatureGates(t *testing.T) {
features.InitialCorruptCheck: false,
features.CompactHashCheck: false,
features.TxnModeWriteWithSharedBuffer: false,
features.MemoryMlock: false,
},
},
{
Expand All @@ -219,6 +233,7 @@ func TestConfigFileFeatureGates(t *testing.T) {
features.StopGRPCServiceOnDefrag: true,
features.DistributedTracing: false,
features.InitialCorruptCheck: false,
features.MemoryMlock: false,
},
},
{
Expand All @@ -228,6 +243,7 @@ func TestConfigFileFeatureGates(t *testing.T) {
features.StopGRPCServiceOnDefrag: false,
features.DistributedTracing: false,
features.InitialCorruptCheck: true,
features.MemoryMlock: false,
},
},
{
Expand All @@ -237,6 +253,7 @@ func TestConfigFileFeatureGates(t *testing.T) {
features.StopGRPCServiceOnDefrag: false,
features.DistributedTracing: false,
features.InitialCorruptCheck: false,
features.MemoryMlock: false,
},
},
{
Expand All @@ -247,6 +264,7 @@ func TestConfigFileFeatureGates(t *testing.T) {
features.DistributedTracing: false,
features.InitialCorruptCheck: false,
features.TxnModeWriteWithSharedBuffer: true,
features.MemoryMlock: false,
},
},
{
Expand All @@ -257,6 +275,7 @@ func TestConfigFileFeatureGates(t *testing.T) {
features.DistributedTracing: false,
features.InitialCorruptCheck: false,
features.TxnModeWriteWithSharedBuffer: false,
features.MemoryMlock: false,
},
},
{
Expand Down Expand Up @@ -292,6 +311,24 @@ func TestConfigFileFeatureGates(t *testing.T) {
features.CompactHashCheck: true,
},
},
{
name: "can set feature gate MemoryMlock to true from feature gate flag",
serverFeatureGatesJSON: "MemoryMlock=true",
expectedFeatures: map[featuregate.Feature]bool{
features.StopGRPCServiceOnDefrag: false,
features.DistributedTracing: false,
features.MemoryMlock: true,
},
},
{
name: "can set feature gate MemoryMlock to false from feature gate flag",
serverFeatureGatesJSON: "MemoryMlock=false",
expectedFeatures: map[featuregate.Feature]bool{
features.StopGRPCServiceOnDefrag: false,
features.DistributedTracing: false,
features.MemoryMlock: false,
},
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
Expand All @@ -300,6 +337,7 @@ func TestConfigFileFeatureGates(t *testing.T) {
ExperimentalInitialCorruptCheck *bool `json:"experimental-initial-corrupt-check,omitempty"`
ExperimentalCompactHashCheckEnabled *bool `json:"experimental-compact-hash-check-enabled,omitempty"`
ExperimentalTxnModeWriteWithSharedBuffer *bool `json:"experimental-txn-mode-write-with-shared-buffer,omitempty"`
ExperimentalMemoryMlock *bool `json:"experimental-memory-mlock,omitempty"`
ServerFeatureGatesJSON string `json:"feature-gates"`
}{
ServerFeatureGatesJSON: tc.serverFeatureGatesJSON,
Expand Down Expand Up @@ -337,6 +375,14 @@ func TestConfigFileFeatureGates(t *testing.T) {
yc.ExperimentalCompactHashCheckEnabled = &experimentalCompactHashCheckEnabled
}

if tc.experimentalMemoryMlock != "" {
experimentalMemoryMlock, err := strconv.ParseBool(tc.experimentalMemoryMlock)
if err != nil {
t.Fatal(err)
}
yc.ExperimentalMemoryMlock = &experimentalMemoryMlock
}

b, err := yaml.Marshal(&yc)
if err != nil {
t.Fatal(err)
Expand Down
1 change: 0 additions & 1 deletion server/embed/etcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,6 @@ func StartEtcd(inCfg *Config) (e *Etcd, err error) {
DowngradeCheckTime: cfg.ExperimentalDowngradeCheckTime,
WarningApplyDuration: cfg.ExperimentalWarningApplyDuration,
WarningUnaryRequestDuration: cfg.WarningUnaryRequestDuration,
ExperimentalMemoryMlock: cfg.ExperimentalMemoryMlock,
ExperimentalBootstrapDefragThresholdMegabytes: cfg.ExperimentalBootstrapDefragThresholdMegabytes,
ExperimentalMaxLearners: cfg.ExperimentalMaxLearners,
V2Deprecation: cfg.V2DeprecationEffective(),
Expand Down
2 changes: 1 addition & 1 deletion server/etcdmain/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ Experimental feature:
Duration of time between two downgrade status checks.
--experimental-enable-lease-checkpoint-persist 'false'
Enable persisting remainingTTL to prevent indefinite auto-renewal of long lived leases. Always enabled in v3.6. Should be used to ensure smooth upgrade from v3.5 clusters with this feature enabled. Requires experimental-enable-lease-checkpoint to be enabled.
--experimental-memory-mlock
--experimental-memory-mlock. It's deprecated, and will be decommissioned in v3.7. Use '--feature-gates=MemoryMlock=true' instead.
Enable to enforce etcd pages (in particular bbolt) to stay in RAM.
--experimental-snapshot-catchup-entries
Number of entries for a slow follower to catch up after compacting the raft storage entries.
Expand Down
7 changes: 7 additions & 0 deletions server/features/etcd_features.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ const (
// alpha: v3.6
// main PR: https://github.com/etcd-io/etcd/pull/14120
CompactHashCheck featuregate.Feature = "CompactHashCheck"
// MemoryMlock enables mlock memory to prevent etcd from being swapped to disk.
// owner: @ptabor
// alpha: v3.6
// main PR: https://github.com/etcd-io/etcd/pull/12750
MemoryMlock featuregate.Feature = "MemoryMlock"
)

var (
Expand All @@ -69,6 +74,7 @@ var (
InitialCorruptCheck: {Default: false, PreRelease: featuregate.Alpha},
CompactHashCheck: {Default: false, PreRelease: featuregate.Alpha},
TxnModeWriteWithSharedBuffer: {Default: true, PreRelease: featuregate.Beta},
MemoryMlock: {Default: false, PreRelease: featuregate.Alpha},
}
// ExperimentalFlagToFeatureMap is the map from the cmd line flags of experimental features
// to their corresponding feature gates.
Expand All @@ -78,6 +84,7 @@ var (
"experimental-initial-corrupt-check": InitialCorruptCheck,
"experimental-compact-hash-check-enabled": CompactHashCheck,
"experimental-txn-mode-write-with-shared-buffer": TxnModeWriteWithSharedBuffer,
"experimental-memory-mlock": MemoryMlock,
}
)

Expand Down
3 changes: 2 additions & 1 deletion server/storage/backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (

"go.etcd.io/etcd/server/v3/config"
"go.etcd.io/etcd/server/v3/etcdserver/api/snap"
"go.etcd.io/etcd/server/v3/features"
"go.etcd.io/etcd/server/v3/storage/backend"
"go.etcd.io/etcd/server/v3/storage/schema"
"go.etcd.io/raft/v3/raftpb"
Expand Down Expand Up @@ -50,7 +51,7 @@ func newBackend(cfg config.ServerConfig, hooks backend.Hooks) backend.Backend {
// permit 10% excess over quota for disarm
bcfg.MmapSize = uint64(cfg.QuotaBackendBytes + cfg.QuotaBackendBytes/10)
}
bcfg.Mlock = cfg.ExperimentalMemoryMlock
bcfg.Mlock = cfg.ServerFeatureGate.Enabled(features.MemoryMlock)
bcfg.Hooks = hooks
return backend.New(bcfg)
}
Expand Down