Stream: clamp group entries_read on XSETID ... ENTRIESADDED#15489
Open
pjs7678 wants to merge 1 commit into
redis:unstableredis/redis:unstablefrom
pjs7678:fix-xsetid-entriesadded-negative-lagpjs7678/redis:fix-xsetid-entriesadded-negative-lagCopy head branch name to clipboard
Open
Stream: clamp group entries_read on XSETID ... ENTRIESADDED#15489pjs7678 wants to merge 1 commit intoredis:unstableredis/redis:unstablefrom pjs7678:fix-xsetid-entriesadded-negative-lagpjs7678/redis:fix-xsetid-entriesadded-negative-lagCopy head branch name to clipboard
pjs7678 wants to merge 1 commit into
redis:unstableredis/redis:unstablefrom
pjs7678:fix-xsetid-entriesadded-negative-lagpjs7678/redis:fix-xsetid-entriesadded-negative-lagCopy head branch name to clipboard
Conversation
pjs7678
force-pushed
the
fix-xsetid-entriesadded-negative-lag
branch
from
July 20, 2026 01:16
f0e0527 to
3716586
Compare
Collaborator
|
This issue was introduced since #15308 |
Collaborator
|
This change touches performance-sensitive code paths. Adding the |
sggeorgiev
reviewed
Jul 21, 2026
pjs7678
force-pushed
the
fix-xsetid-entriesadded-negative-lag
branch
from
July 22, 2026 11:40
3716586 to
95145b7
Compare
sggeorgiev
reviewed
Jul 23, 2026
| assert_equal [dict get $ginfo lag] 97 | ||
| } | ||
| } | ||
|
|
Collaborator
There was a problem hiding this comment.
Remove this blank trailing line.
Contributor
Author
There was a problem hiding this comment.
Done - removed the trailing blank line in the latest push. Thanks!
XSETID lets you lower a stream's entries_added counter (it only checks
that the new value is >= the stream length). It never reconciles that
value against the consumer groups' entries_read, so after XTRIM shrinks
the stream, entries_added can be set below a group's entries_read.
That breaks the invariant entries_read <= entries_added and has two
observable effects:
1. XINFO GROUPS reports a negative lag (lag = entries_added -
entries_read), which the field must never be.
2. On builds that validate this invariant on load (rdb.c), the
resulting RDB/RESTORE payload is rejected with "Stream cgroup
entries_read inconsistent with entries_added", so the primary
fails to restart, replicas fail to full-sync and backups fail to
restore.
XGROUP CREATE/SETID already clamp entries_read down to entries_added to
keep this invariant; do the same in XSETID when entries_added is lowered.
Repro:
XADD s * ... (x10); XGROUP CREATE s g 0; XREADGROUP ... COUNT 10
XTRIM s MAXLEN 2; XSETID s <top-id> ENTRIESADDED 2
XINFO GROUPS s -> lag = -8 (and SAVE + restart fails to load)
pjs7678
force-pushed
the
fix-xsetid-entriesadded-negative-lag
branch
from
July 24, 2026 21:57
95145b7 to
4c84f23
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #15488
Problem
XSETID key <id> ENTRIESADDED nlowers a stream'sentries_addedcounter,validating only
n >= stream length. It never reconcilesnwith the consumergroups'
entries_read, so afterXTRIMa group can end up withentries_read > entries_added.That violates the
entries_read <= entries_addedinvariant and causes:XINFO GROUPSreporting a negativelag(lag = entries_added - entries_read).check in
rdb.crejects it ("Stream cgroup entries_read inconsistent withentries_added"), so the primary can't restart, replicas can't full-sync and
backups can't be restored.
The same invariant is already enforced elsewhere:
XGROUP CREATEandXGROUP SETIDclampentries_readdown toentries_added, and the RDB loaderrejects payloads that break it. Only
XSETIDwas missing the guard.Fix
When
XSETIDlowersentries_added, clamp every consumer group'sentries_readdown to the newentries_added(skipping groups whose counter isSCG_INVALID_ENTRIES_READ), exactly asXGROUP CREATE/SETIDalready do.Reproduction
Tests
Added three cases to
tests/unit/type/stream-cgroups.tcl:XSETID ENTRIESADDEDclampsentries_readand never yields a negative lag.DEBUG RELOAD(no unloadable RDB).XSETIDraisingentries_addedleaves a group'sentries_readuntouched(no over-eager clamping).
Verified the new tests fail without the fix and pass with it; the full
unit/type/stream-cgroupssuite is green.Note
Medium Risk
Touches stream cgroup invariants and persistence-related consistency, but the change is narrow and aligned with existing XGROUP clamping behavior.
Overview
XSETID ... ENTRIESADDEDcan now lower a stream’sentries_addedwithout leaving consumer groups withentries_readabove that value—a gap that caused negativeXINFO GROUPSlag and RDB loads to fail on consistency checks.When
entries_addedis reduced, the handler walks all consumer groups and clamps each validentries_readdown to the newentries_added, mirroringXGROUP CREATE/SETID. Ifentries_addedis only raised or unchanged, groups are left alone.New stream-cgroup tests cover clamping and non-negative lag after trim +
XSETID,DEBUG RELOADon that state, and unchangedentries_readwhenentries_addedis increased.Reviewed by Cursor Bugbot for commit 4c84f23. Bugbot is set up for automated code reviews on this repo. Configure here.