Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

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#15489
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

@pjs7678 pjs7678 commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Fixes #15488

Problem

XSETID key <id> ENTRIESADDED n lowers a stream's entries_added counter,
validating only n >= stream length. It never reconciles n with the consumer
groups' entries_read, so after XTRIM a group can end up with
entries_read > entries_added.

That violates the entries_read <= entries_added invariant and causes:

  1. XINFO GROUPS reporting a negative lag (lag = entries_added - entries_read).
  2. An RDB that saves fine but fails to load — the loader's consistency
    check in rdb.c rejects it ("Stream cgroup entries_read inconsistent with
    entries_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 CREATE and
XGROUP SETID clamp entries_read down to entries_added, and the RDB loader
rejects payloads that break it. Only XSETID was missing the guard.

Fix

When XSETID lowers entries_added, clamp every consumer group's
entries_read down to the new entries_added (skipping groups whose counter is
SCG_INVALID_ENTRIES_READ), exactly as XGROUP CREATE/SETID already do.

Reproduction

XADD st * f v        # x10
XGROUP CREATE st g 0
XREADGROUP GROUP g c COUNT 10 STREAMS st >
XTRIM st MAXLEN 2
XSETID st <last-generated-id> ENTRIESADDED 2
XINFO GROUPS st      # lag => -8   (before the fix)
SAVE                 # OK, but restart fails to load the dump before the fix

Tests

Added three cases to tests/unit/type/stream-cgroups.tcl:

  • XSETID ENTRIESADDED clamps entries_read and never yields a negative lag.
  • The resulting state survives DEBUG RELOAD (no unloadable RDB).
  • XSETID raising entries_added leaves a group's entries_read untouched
    (no over-eager clamping).

Verified the new tests fail without the fix and pass with it; the full
unit/type/stream-cgroups suite 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 ... ENTRIESADDED can now lower a stream’s entries_added without leaving consumer groups with entries_read above that value—a gap that caused negative XINFO GROUPS lag and RDB loads to fail on consistency checks.

When entries_added is reduced, the handler walks all consumer groups and clamps each valid entries_read down to the new entries_added, mirroring XGROUP CREATE / SETID. If entries_added is only raised or unchanged, groups are left alone.

New stream-cgroup tests cover clamping and non-negative lag after trim + XSETID, DEBUG RELOAD on that state, and unchanged entries_read when entries_added is increased.

Reviewed by Cursor Bugbot for commit 4c84f23. Bugbot is set up for automated code reviews on this repo. Configure here.

@pjs7678
pjs7678 force-pushed the fix-xsetid-entriesadded-negative-lag branch from f0e0527 to 3716586 Compare July 20, 2026 01:16
@sundb
sundb requested a review from sggeorgiev July 20, 2026 02:47
@sundb

sundb commented Jul 20, 2026

Copy link
Copy Markdown
Collaborator

This issue was introduced since #15308

@fcostaoliveira

Copy link
Copy Markdown
Collaborator

This change touches performance-sensitive code paths. Adding the action:run-benchmark label will trigger the CE Performance suite so we can see the impact before merge.

Comment thread src/t_stream.c
@pjs7678
pjs7678 force-pushed the fix-xsetid-entriesadded-negative-lag branch from 3716586 to 95145b7 Compare July 22, 2026 11:40
@sundb sundb added this to Redis 8.10 Jul 23, 2026
Comment thread tests/unit/type/stream-cgroups.tcl Outdated
assert_equal [dict get $ginfo lag] 97
}
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Remove this blank trailing line.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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
pjs7678 force-pushed the fix-xsetid-entriesadded-negative-lag branch from 95145b7 to 4c84f23 Compare July 24, 2026 21:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

[BUG] XSETID ... ENTRIESADDED can create a negative consumer-group lag and an unloadable RDB

4 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.