Skip to content

Fix slot-migration-max-failover-repl-bytes unable to accept -1#3443

Merged
enjoy-binbin merged 4 commits intovalkey-io:unstablefrom
enjoy-binbin:slot-migration-max-failover-repl-bytes
Apr 8, 2026
Merged

Fix slot-migration-max-failover-repl-bytes unable to accept -1#3443
enjoy-binbin merged 4 commits intovalkey-io:unstablefrom
enjoy-binbin:slot-migration-max-failover-repl-bytes

Conversation

@enjoy-binbin
Copy link
Copy Markdown
Member

In valkey.conf, slot-migration-max-failover-repl-bytes allows setting
to -1 to disable the limit.

Setting this to -1 will disable this limit

But slot-migration-max-failover-repl-bytes is defined as MEMORY_CONFIG
and memtoull() rejects negative inputs, making it impossible to set the
value to -1 via config file or CONFIG SET.

>>> 'slot-migration-max-failover-repl-bytes "-1"'
argument must be a memory value

Introduce SIGNED_MEMORY_CONFIG flag for memory configs that also accept
plain negative number. When memtoull() fails and this flag is set, fall
back to string2ll() for parsing. Use ll2string() for CONFIG GET and
rewriteConfigNumericalOption() for CONFIG REWRITE when the value is
negative.

Add a serverAssert in initConfigValues() to enforce that PERCENT_CONFIG
and SIGNED_MEMORY_CONFIG are never combined on the same config, since
both use negative values with different semantics.

This means we have had this issue since it was introduced in #1949.

In valkey.conf, slot-migration-max-failover-repl-bytes allows setting
to -1 to disable the limit.
```
Setting this to -1 will disable this limit
```

But slot-migration-max-failover-repl-bytes is defined as MEMORY_CONFIG
and memtoull() rejects negative inputs, making it impossible to set the
value to -1 via config file or CONFIG SET.
```
>>> 'slot-migration-max-failover-repl-bytes "-1"'
argument must be a memory value
```

Introduce SIGNED_MEMORY_CONFIG flag for memory configs that also accept
plain negative number. When memtoull() fails and this flag is set, fall
back to string2ll() for parsing. Use ll2string() for CONFIG GET and
rewriteConfigNumericalOption() for CONFIG REWRITE when the value is
negative.

Add a serverAssert in initConfigValues() to enforce that PERCENT_CONFIG
and SIGNED_MEMORY_CONFIG are never combined on the same config, since
both use negative values with different semantics.

This means we have had this issue since it was introduced in valkey-io#1949.

Signed-off-by: Binbin <binloveplay1314@qq.com>
@enjoy-binbin enjoy-binbin requested a review from zuiderkwast April 4, 2026 17:40
@enjoy-binbin enjoy-binbin moved this to To be backported in Valkey 9.0 Apr 4, 2026
@enjoy-binbin enjoy-binbin moved this to To be backported in Valkey 9.1 Apr 4, 2026
Copy link
Copy Markdown
Contributor

@murphyjacob4 murphyjacob4 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense! Thanks for the fix

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 4, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76.52%. Comparing base (e8ca6c0) to head (442125d).
⚠️ Report is 8 commits behind head on unstable.

Additional details and impacted files
@@             Coverage Diff              @@
##           unstable    #3443      +/-   ##
============================================
- Coverage     76.52%   76.52%   -0.01%     
============================================
  Files           157      157              
  Lines         79025    79035      +10     
============================================
+ Hits          60477    60479       +2     
- Misses        18548    18556       +8     
Files with missing lines Coverage Δ
src/cluster_migrateslots.c 91.87% <ø> (-0.39%) ⬇️
src/config.c 78.02% <100.00%> (+0.31%) ⬆️
src/server.h 100.00% <ø> (ø)

... and 25 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@zuiderkwast
Copy link
Copy Markdown
Contributor

Great!

So was slot-migration-max-failover-repl-bytes -1 not tested before?

Signed-off-by: Binbin <binloveplay1314@qq.com>
@enjoy-binbin
Copy link
Copy Markdown
Member Author

So was slot-migration-max-failover-repl-bytes -1 not tested before?

Yes, i added a test, this require a log change.

@zuiderkwast
Copy link
Copy Markdown
Contributor

zuiderkwast commented Apr 7, 2026

The failing test case "Main db not affected when fail to diskless load" has this pattern of writing many commands in a pipeline and reading the replies only afterwards:

    set num 10000
    set value [string repeat A 1024]
    set rd [valkey_deferring_client valkey $master_id]
    for {set j 0} {$j < $num} {incr j} {
        $rd set $j $value
    }
    for {set j 0} {$j < $num} {incr j} {
        $rd read
    }

I have fixed similar tests before using CLIENT REPLY OFF (#3430, #2483). I think we need the same fix here.

[EDIT] Fix is here: #3452

Copy link
Copy Markdown
Contributor

@zuiderkwast zuiderkwast left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good. I found some minor ideas but nothing blocking.

I didn't review the tests very much.

Comment thread src/config.c Outdated
Comment thread src/config.c
Comment thread src/config.c Outdated
Copy link
Copy Markdown
Contributor

@sarthakaggarwal97 sarthakaggarwal97 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice fix!

Signed-off-by: Binbin <binloveplay1314@qq.com>
Comment thread src/config.c Outdated
Co-authored-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
Signed-off-by: Binbin <binloveplay1314@qq.com>
@enjoy-binbin enjoy-binbin added the release-notes This issue should get a line item in the release notes label Apr 8, 2026
@enjoy-binbin enjoy-binbin merged commit dba128f into valkey-io:unstable Apr 8, 2026
90 checks passed
@enjoy-binbin enjoy-binbin deleted the slot-migration-max-failover-repl-bytes branch April 8, 2026 08:26
enjoy-binbin added a commit that referenced this pull request Apr 9, 2026
…igs (#3440)

rewriteConfigFormatMemory() and rewriteConfigBytesOption() used long long
parameters to represent memory bytes, but configs like maxmemory are stored
as unsigned long long and allow values up to ULLONG_MAX.

When the value exceeds LLONG_MAX (e.g. 9223372036854775808), it overflows to
negative when passed as long long, causing config rewrite to produce incorrect
output like "maxmemory -8589934592gb".

Change both functions to use unsigned long long, matching the actual semantics
of memory byte values. This is consistent with how numericConfigGet() already
handles MEMORY_CONFIG using ull2string().

There are some MEMORY_CONFIG are signed and can be negative:
1. maxmemory-clients is a PERCENT_CONFIG
2. slot-migration-max-failover-repl-bytes is a SIGNED_MEMORY_CONFIG (after #3443) 

None of them were affected:
```
static void numericConfigRewrite(standardConfig *config, const char *name, struct rewriteConfigState *state) {
    ...
    if (config->data.numeric.flags & PERCENT_CONFIG && value < 0) {
        rewriteConfigPercentOption(state, name, -value, config->data.numeric.default_value);
    } else if (config->data.numeric.flags & SIGNED_MEMORY_CONFIG && value < 0) {
        rewriteConfigNumericalOption(state, name, value, config->data.numeric.default_value);
    } else if (config->data.numeric.flags & MEMORY_CONFIG) {
        rewriteConfigBytesOption(state, name, value, config->data.numeric.default_value);
    ...
```

Signed-off-by: Binbin <binloveplay1314@qq.com>
sarthakaggarwal97 pushed a commit to sarthakaggarwal97/valkey that referenced this pull request Apr 16, 2026
…y-io#3443)

In valkey.conf, slot-migration-max-failover-repl-bytes allows setting
to -1 to disable the limit.
```
Setting this to -1 will disable this limit
```

But slot-migration-max-failover-repl-bytes is defined as MEMORY_CONFIG
and memtoull() rejects negative inputs, making it impossible to set the
value to -1 via config file or CONFIG SET.
```
>>> 'slot-migration-max-failover-repl-bytes "-1"'
argument must be a memory value
```

Introduce SIGNED_MEMORY_CONFIG flag for memory configs that also accept
plain negative number. When memtoull() fails and this flag is set, fall back to string2ll()
for parsing. Use ll2string() for CONFIG GET and rewriteConfigNumericalOption() for
CONFIG REWRITE when the value is negative.

Add a serverAssert in initConfigValues() to enforce that PERCENT_CONFIG
and SIGNED_MEMORY_CONFIG are never combined on the same config, since
both use negative values with different semantics.

This means we have had this issue since it was introduced in valkey-io#1949.

Signed-off-by: Binbin <binloveplay1314@qq.com>
Co-authored-by: Viktor Söderqvist <viktor.soderqvist@est.tech>
sarthakaggarwal97 pushed a commit to sarthakaggarwal97/valkey that referenced this pull request Apr 16, 2026
…igs (valkey-io#3440)

rewriteConfigFormatMemory() and rewriteConfigBytesOption() used long long
parameters to represent memory bytes, but configs like maxmemory are stored
as unsigned long long and allow values up to ULLONG_MAX.

When the value exceeds LLONG_MAX (e.g. 9223372036854775808), it overflows to
negative when passed as long long, causing config rewrite to produce incorrect
output like "maxmemory -8589934592gb".

Change both functions to use unsigned long long, matching the actual semantics
of memory byte values. This is consistent with how numericConfigGet() already
handles MEMORY_CONFIG using ull2string().

There are some MEMORY_CONFIG are signed and can be negative:
1. maxmemory-clients is a PERCENT_CONFIG
2. slot-migration-max-failover-repl-bytes is a SIGNED_MEMORY_CONFIG (after valkey-io#3443) 

None of them were affected:
```
static void numericConfigRewrite(standardConfig *config, const char *name, struct rewriteConfigState *state) {
    ...
    if (config->data.numeric.flags & PERCENT_CONFIG && value < 0) {
        rewriteConfigPercentOption(state, name, -value, config->data.numeric.default_value);
    } else if (config->data.numeric.flags & SIGNED_MEMORY_CONFIG && value < 0) {
        rewriteConfigNumericalOption(state, name, value, config->data.numeric.default_value);
    } else if (config->data.numeric.flags & MEMORY_CONFIG) {
        rewriteConfigBytesOption(state, name, value, config->data.numeric.default_value);
    ...
```

Signed-off-by: Binbin <binloveplay1314@qq.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release-notes This issue should get a line item in the release notes

Projects

Status: To be backported
Status: To be backported

Development

Successfully merging this pull request may close these issues.

4 participants