Skip to content

Commit 53d44f0

Browse files
authored
Merge pull request #19352 from ajaysundark/migrate-experimental-snapshot-catch-up-entries
migrate experimental-snapshot-catchup-entries flag to snapshot-catchup-entries
2 parents f197f44 + 5802231 commit 53d44f0

File tree

7 files changed

+127
-11
lines changed

7 files changed

+127
-11
lines changed

server/embed/config.go

+28-5
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ var (
156156
"experimental-bootstrap-defrag-threshold-megabytes": "bootstrap-defrag-threshold-megabytes",
157157
"experimental-max-learners": "max-learners",
158158
"experimental-memory-mlock": "memory-mlock",
159+
"experimental-snapshot-catchup-entries": "snapshot-catchup-entries",
159160
"experimental-compaction-sleep-interval": "compaction-sleep-interval",
160161
"experimental-downgrade-check-time": "downgrade-check-time",
161162
"experimental-peer-skip-client-san-verification": "peer-skip-client-san-verification",
@@ -199,12 +200,23 @@ type Config struct {
199200
// TODO: remove it in 3.7.
200201
SnapshotCount uint64 `json:"snapshot-count"`
201202

202-
// SnapshotCatchUpEntries is the number of entries for a slow follower
203+
// ExperimentalSnapshotCatchUpEntries is the number of entries for a slow follower
203204
// to catch-up after compacting the raft storage entries.
204205
// We expect the follower has a millisecond level latency with the leader.
205206
// The max throughput is around 10K. Keep a 5K entries is enough for helping
206207
// follower to catch up.
207-
SnapshotCatchUpEntries uint64 `json:"experimental-snapshot-catch-up-entries"`
208+
// Deprecated in v3.6 and will be removed in v3.7.
209+
// TODO: remove in v3.7.
210+
// Note we made a mistake in https://github.com/etcd-io/etcd/pull/15033. The json tag
211+
// `*-catch-up-*` isn't consistent with the command line flag `*-catchup-*`.
212+
ExperimentalSnapshotCatchUpEntries uint64 `json:"experimental-snapshot-catch-up-entries"`
213+
214+
// SnapshotCatchUpEntries is the number of entires for a slow follower
215+
// to catch-up after compacting the raft storage entries.
216+
// We expect the follower has a millisecond level latency with the leader.
217+
// The max throughput is around 10K. Keep a 5K entries is enough for helping
218+
// follower to catch up.
219+
SnapshotCatchUpEntries uint64 `json:"snapshot-catchup-entries"`
208220

209221
// MaxSnapFiles is deprecated in v3.6 and will be decommissioned in v3.7.
210222
// TODO: remove it in 3.7.
@@ -631,8 +643,9 @@ func NewConfig() *Config {
631643

632644
Name: DefaultName,
633645

634-
SnapshotCount: etcdserver.DefaultSnapshotCount,
635-
SnapshotCatchUpEntries: etcdserver.DefaultSnapshotCatchUpEntries,
646+
SnapshotCount: etcdserver.DefaultSnapshotCount,
647+
ExperimentalSnapshotCatchUpEntries: etcdserver.DefaultSnapshotCatchUpEntries,
648+
SnapshotCatchUpEntries: etcdserver.DefaultSnapshotCatchUpEntries,
636649

637650
MaxTxnOps: DefaultMaxTxnOps,
638651
MaxRequestBytes: DefaultMaxRequestBytes,
@@ -935,7 +948,8 @@ func (cfg *Config) AddFlags(fs *flag.FlagSet) {
935948
// TODO: delete in v3.7
936949
fs.IntVar(&cfg.ExperimentalMaxLearners, "experimental-max-learners", membership.DefaultMaxLearners, "Sets the maximum number of learners that can be available in the cluster membership. Deprecated in v3.6 and will be decommissioned in v3.7. Use --max-learners instead.")
937950
fs.IntVar(&cfg.MaxLearners, "max-learners", membership.DefaultMaxLearners, "Sets the maximum number of learners that can be available in the cluster membership.")
938-
fs.Uint64Var(&cfg.SnapshotCatchUpEntries, "experimental-snapshot-catchup-entries", cfg.SnapshotCatchUpEntries, "Number of entries for a slow follower to catch up after compacting the raft storage entries.")
951+
fs.Uint64Var(&cfg.ExperimentalSnapshotCatchUpEntries, "experimental-snapshot-catchup-entries", cfg.ExperimentalSnapshotCatchUpEntries, "Number of entries for a slow follower to catch up after compacting the raft storage entries. Deprecated in v3.6 and will be decommissioned in v3.7. Use --snapshot-catchup-entries instead.")
952+
fs.Uint64Var(&cfg.SnapshotCatchUpEntries, "snapshot-catchup-entries", cfg.SnapshotCatchUpEntries, "Number of entries for a slow follower to catch up after compacting the raft storage entries.")
939953

940954
// unsafe
941955
fs.BoolVar(&cfg.UnsafeNoFsync, "unsafe-no-fsync", false, "Disables fsync, unsafe, will cause data loss.")
@@ -994,6 +1008,15 @@ func (cfg *configYAML) configFromFile(path string) error {
9941008
}
9951009
}
9961010

1011+
// attempt to fix a bug introduced in https://github.com/etcd-io/etcd/pull/15033
1012+
// both `experimental-snapshot-catch-up-entries` and `experimental-snapshot-catchup-entries` refer to the same field,
1013+
// map the YAML field "experimental-snapshot-catch-up-entries" to the flag "experimental-snapshot-catchup-entries".
1014+
if val, ok := cfgMap["experimental-snapshot-catch-up-entries"]; ok {
1015+
cfgMap["experimental-snapshot-catchup-entries"] = val
1016+
cfg.ExperimentalSnapshotCatchUpEntries = uint64(val.(float64))
1017+
cfg.FlagsExplicitlySet["experimental-snapshot-catchup-entries"] = true
1018+
}
1019+
9971020
getBoolFlagVal := func(flagName string) *bool {
9981021
flagVal, ok := cfgMap[flagName]
9991022
if !ok {

server/etcdmain/config.go

+5
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ var (
7272
"experimental-bootstrap-defrag-threshold-megabytes": "--experimental-bootstrap-defrag-threshold-megabytes is deprecated in v3.6 and will be decommissioned in v3.7. Use '--bootstrap-defrag-threshold-megabytes' instead.",
7373
"experimental-max-learners": "--experimental-max-learners is deprecated in v3.6 and will be decommissioned in v3.7. Use '--max-learners' instead.",
7474
"experimental-memory-mlock": "--experimental-memory-mlock is deprecated in v3.6 and will be decommissioned in v3.7. Use '--memory-mlock' instead.",
75+
"experimental-snapshot-catchup-entries": "--experimental-snapshot-catchup-entries is deprecated in v3.6 and will be decommissioned in v3.7. Use '--snapshot-catchup-entries' instead.",
7576
"experimental-compaction-sleep-interval": "--experimental-compaction-sleep-interval is deprecated in v3.6 and will be decommissioned in v3.7. Use 'compaction-sleep-interval' instead.",
7677
"experimental-downgrade-check-time": "--experimental-downgrade-check-time is deprecated in v3.6 and will be decommissioned in v3.7. Use '--downgrade-check-time' instead.",
7778
"experimental-enable-distributed-tracing": "--experimental-enable-distributed-tracing is deprecated in 3.6 and will be decommissioned in 3.7. Use --enable-distributed-tracing instead.",
@@ -219,6 +220,10 @@ func (cfg *config) parse(arguments []string) error {
219220
cfg.ec.MemoryMlock = cfg.ec.ExperimentalMemoryMlock
220221
}
221222

223+
if cfg.ec.FlagsExplicitlySet["experimental-snapshot-catchup-entries"] {
224+
cfg.ec.SnapshotCatchUpEntries = cfg.ec.ExperimentalSnapshotCatchUpEntries
225+
}
226+
222227
if cfg.ec.FlagsExplicitlySet["experimental-compaction-sleep-interval"] {
223228
cfg.ec.CompactionSleepInterval = cfg.ec.ExperimentalCompactionSleepInterval
224229
}

server/etcdmain/config_test.go

+72-1
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import (
3333
"go.etcd.io/etcd/pkg/v3/featuregate"
3434
"go.etcd.io/etcd/pkg/v3/flags"
3535
"go.etcd.io/etcd/server/v3/embed"
36+
"go.etcd.io/etcd/server/v3/etcdserver"
3637
"go.etcd.io/etcd/server/v3/features"
3738
)
3839

@@ -67,7 +68,7 @@ func TestConfigFileMemberFields(t *testing.T) {
6768
MaxWALFiles uint `json:"max-wals"`
6869
Name string `json:"name"`
6970
SnapshotCount uint64 `json:"snapshot-count"`
70-
SnapshotCatchUpEntries uint64 `json:"experimental-snapshot-catch-up-entries"`
71+
SnapshotCatchUpEntries uint64 `json:"snapshot-catchup-entries"`
7172
ListenPeerURLs string `json:"listen-peer-urls"`
7273
ListenClientURLs string `json:"listen-client-urls"`
7374
ListenClientHTTPURLs string `json:"listen-client-http-urls"`
@@ -321,6 +322,73 @@ func TestConfigParsingMissedAdvertiseClientURLsFlag(t *testing.T) {
321322
}
322323
}
323324

325+
// TestExperimentalSnapshotCatchUpEntriesFlagMigration tests the migration from
326+
// --experimental-snapshot-catch-up-entries to --snapshot-catch-up-entries
327+
func TestExperimentalSnapshotCatchUpEntriesFlagMigration(t *testing.T) {
328+
testCases := []struct {
329+
name string
330+
snapshotCatchUpEntries uint64
331+
experimentalSnapshotCatchUpEntries uint64
332+
wantErr bool
333+
wantConfig uint64
334+
}{
335+
{
336+
name: "default",
337+
wantConfig: etcdserver.DefaultSnapshotCatchUpEntries,
338+
},
339+
{
340+
name: "cannot set both experimental flag and non experimental flag",
341+
experimentalSnapshotCatchUpEntries: 1000,
342+
snapshotCatchUpEntries: 2000,
343+
wantErr: true,
344+
},
345+
{
346+
name: "can set experimental flag",
347+
experimentalSnapshotCatchUpEntries: 1000,
348+
wantConfig: 1000,
349+
},
350+
{
351+
name: "can set non-experimental flag",
352+
snapshotCatchUpEntries: 2000,
353+
wantConfig: 2000,
354+
},
355+
}
356+
for _, tc := range testCases {
357+
t.Run(tc.name, func(t *testing.T) {
358+
cmdLineArgs := []string{}
359+
yc := struct {
360+
ExperimentalSnapshotCatchUpEntries uint64 `json:"experimental-snapshot-catch-up-entries,omitempty"`
361+
SnapshotCatchUpEntries uint64 `json:"snapshot-catchup-entries,omitempty"`
362+
}{}
363+
364+
if tc.snapshotCatchUpEntries > 0 {
365+
cmdLineArgs = append(cmdLineArgs, fmt.Sprintf("--snapshot-catchup-entries=%d", tc.snapshotCatchUpEntries))
366+
yc.SnapshotCatchUpEntries = tc.snapshotCatchUpEntries
367+
}
368+
369+
if tc.experimentalSnapshotCatchUpEntries > 0 {
370+
cmdLineArgs = append(cmdLineArgs, fmt.Sprintf("--experimental-snapshot-catchup-entries=%d", tc.experimentalSnapshotCatchUpEntries))
371+
yc.ExperimentalSnapshotCatchUpEntries = tc.experimentalSnapshotCatchUpEntries
372+
}
373+
374+
cfgFromCmdLine, errFromCmdLine, cfgFromFile, errFromFile := generateCfgsFromFileAndCmdLine(t, yc, cmdLineArgs)
375+
376+
if tc.wantErr {
377+
if errFromCmdLine == nil || errFromFile == nil {
378+
t.Fatal("expect parse error")
379+
}
380+
return
381+
}
382+
if errFromCmdLine != nil || errFromFile != nil {
383+
t.Fatal("error parsing config")
384+
}
385+
386+
require.Equal(t, tc.wantConfig, cfgFromCmdLine.ec.SnapshotCatchUpEntries)
387+
require.Equal(t, tc.wantConfig, cfgFromFile.ec.SnapshotCatchUpEntries)
388+
})
389+
}
390+
}
391+
324392
func TestConfigIsNewCluster(t *testing.T) {
325393
tests := []struct {
326394
state string
@@ -1274,6 +1342,7 @@ func TestConfigFileDeprecatedOptions(t *testing.T) {
12741342
ExperimentalWarningApplyDuration time.Duration `json:"experimental-warning-apply-duration,omitempty"`
12751343
ExperimentalBootstrapDefragThresholdMegabytes uint `json:"experimental-bootstrap-defrag-threshold-megabytes,omitempty"`
12761344
ExperimentalMaxLearners int `json:"experimental-max-learners,omitempty"`
1345+
ExperimentalSnapshotCatchUpEntries uint64 `json:"experimental-snapshot-catch-up-entries,omitempty"`
12771346
ExperimentalCompactionSleepInterval time.Duration `json:"experimental-compaction-sleep-interval,omitempty"`
12781347
ExperimentalDowngradeCheckTime time.Duration `json:"experimental-downgrade-check-time,omitempty"`
12791348
}
@@ -1300,6 +1369,7 @@ func TestConfigFileDeprecatedOptions(t *testing.T) {
13001369
ExperimentalWarningApplyDuration: 3 * time.Minute,
13011370
ExperimentalBootstrapDefragThresholdMegabytes: 100,
13021371
ExperimentalMaxLearners: 1,
1372+
ExperimentalSnapshotCatchUpEntries: 1000,
13031373
ExperimentalCompactionSleepInterval: 30 * time.Second,
13041374
ExperimentalDowngradeCheckTime: 1 * time.Minute,
13051375
},
@@ -1312,6 +1382,7 @@ func TestConfigFileDeprecatedOptions(t *testing.T) {
13121382
"experimental-warning-apply-duration": {},
13131383
"experimental-bootstrap-defrag-threshold-megabytes": {},
13141384
"experimental-max-learners": {},
1385+
"experimental-snapshot-catchup-entries": {},
13151386
"experimental-compaction-sleep-interval": {},
13161387
"experimental-downgrade-check-time": {},
13171388
},

server/etcdmain/help.go

+2
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,8 @@ Experimental feature:
342342
--experimental-memory-mlock
343343
Enable to enforce etcd pages (in particular bbolt) to stay in RAM. Deprecated in v3.6 and will be decommissioned in v3.7. Use '--memory-mlock' instead.
344344
--experimental-snapshot-catchup-entries
345+
Number of entries for a slow follower to catch up after compacting the raft storage entries. Deprecated in v3.6 and will be decommissioned in v3.7. Use '--snapshot-catchup-entries' instead.
346+
--snapshot-catchup-entries
345347
Number of entries for a slow follower to catch up after compacting the raft storage entries.
346348
--experimental-stop-grpc-service-on-defrag
347349
Enable etcd gRPC service to stop serving client requests on defragmentation. It's deprecated, and will be decommissioned in v3.7. Use '--feature-gates=StopGRPCServiceOnDefrag=true' instead.

tests/framework/e2e/cluster.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -229,7 +229,9 @@ func WithSnapshotCount(count uint64) EPClusterOption {
229229
}
230230

231231
func WithSnapshotCatchUpEntries(count uint64) EPClusterOption {
232-
return func(c *EtcdProcessClusterConfig) { c.ServerConfig.SnapshotCatchUpEntries = count }
232+
return func(c *EtcdProcessClusterConfig) {
233+
c.ServerConfig.SnapshotCatchUpEntries = count
234+
}
233235
}
234236

235237
func WithClusterSize(size int) EPClusterOption {
@@ -455,6 +457,10 @@ func InitEtcdProcessCluster(t testing.TB, cfg *EtcdProcessClusterConfig) (*EtcdP
455457
if cfg.Version == LastVersion && !CouldSetSnapshotCatchupEntries(BinPath.EtcdLastRelease) {
456458
return nil, fmt.Errorf("cannot set SnapshotCatchUpEntries for last etcd version: %s", BinPath.EtcdLastRelease)
457459
}
460+
if cfg.Version != CurrentVersion && UsesExperimentalSnapshotCatchupEntriesFlag(BinPath.EtcdLastRelease) {
461+
cfg.ServerConfig.ExperimentalSnapshotCatchUpEntries = cfg.ServerConfig.SnapshotCatchUpEntries
462+
cfg.ServerConfig.SnapshotCatchUpEntries = etcdserver.DefaultSnapshotCatchUpEntries
463+
}
458464
}
459465

460466
etcdCfgs := cfg.EtcdAllServerProcessConfigs(t)
@@ -661,7 +667,7 @@ func (cfg *EtcdProcessClusterConfig) EtcdServerProcessConfig(tb testing.TB, i in
661667
if defaultValue := defaultValues[flag]; value == "" || value == defaultValue {
662668
continue
663669
}
664-
if flag == "experimental-snapshot-catchup-entries" && !CouldSetSnapshotCatchupEntries(execPath) {
670+
if strings.HasSuffix(flag, "snapshot-catchup-entries") && !CouldSetSnapshotCatchupEntries(execPath) {
665671
continue
666672
}
667673
args = append(args, fmt.Sprintf("--%s=%s", flag, value))

tests/framework/e2e/cluster_test.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -81,22 +81,22 @@ func TestEtcdServerProcessConfig(t *testing.T) {
8181
name: "CatchUpEntries",
8282
config: NewConfig(WithSnapshotCatchUpEntries(100)),
8383
expectArgsContain: []string{
84-
"--experimental-snapshot-catchup-entries=100",
84+
"--snapshot-catchup-entries=100",
8585
},
8686
mockBinaryVersion: &v3_5_14,
8787
},
8888
{
8989
name: "CatchUpEntriesNoVersion",
9090
config: NewConfig(WithSnapshotCatchUpEntries(100), WithVersion(LastVersion)),
9191
expectArgsNotContain: []string{
92-
"--experimental-snapshot-catchup-entries=100",
92+
"--snapshot-catchup-entries=100",
9393
},
9494
},
9595
{
9696
name: "CatchUpEntriesOldVersion",
9797
config: NewConfig(WithSnapshotCatchUpEntries(100), WithVersion(LastVersion)),
9898
expectArgsNotContain: []string{
99-
"--experimental-snapshot-catchup-entries=100",
99+
"--snapshot-catchup-entries=100",
100100
},
101101
mockBinaryVersion: &v3_5_12,
102102
},

tests/framework/e2e/etcd_process.go

+9
Original file line numberDiff line numberDiff line change
@@ -531,3 +531,12 @@ func CouldSetSnapshotCatchupEntries(execPath string) bool {
531531
v3_5_14 := semver.Version{Major: 3, Minor: 5, Patch: 14}
532532
return v.Compare(v3_5_14) >= 0
533533
}
534+
535+
func UsesExperimentalSnapshotCatchupEntriesFlag(execPath string) bool {
536+
v, err := GetVersionFromBinary(execPath)
537+
if err != nil {
538+
return false
539+
}
540+
v3_6 := semver.Version{Major: 3, Minor: 6}
541+
return v.LessThan(v3_6)
542+
}

0 commit comments

Comments
 (0)