feat(anomaly): detect replica full-resync failure loop (valkey#1836) - #373
Merged
Conversation
- Extend stuck-replica module with a stateful INFO-based evaluator: link held down through 2+ full-sync attempts across a 5-minute window fires a WARNING; a single long first sync stays silent - Count failed cycles from sync_full deltas, falling back to the master_sync_in_progress flag toggling off while the link stays down - Reset on recovery, promotion, or a server-side down-counter drop (the link reached up between polls), so a later loop alerts afresh - New resync_loop metric type wired into the poll loop + dashboard label Closes #371
- Stop counting sync_full toward failed cycles: it tracks outbound full syncs this node served as a primary, so it never moves for the replica's own inbound loop, and downstream reconnects on an intermediate replica would fake failed cycles during a healthy first sync - Failed cycles now come only from master_sync_in_progress falling back to 0 while the link stays down - Accept role:replica alongside legacy role:slave, matching the rest of the service
Collaborator
Author
|
@BugBot review |
Collaborator
Author
|
@claude review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit 1ec3e30. Configure here.
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 subscribe to this conversation on GitHub.
Already have an account?
Sign in.
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.
Summary
Extends the
stuck-replicamodule with the full-resync failure-loop signature from valkey-io/valkey#1836: a replica that connects, starts a full sync, fails to load the transferred RDB (disk errors, corruption, permissions, out-of-space, a filesystem/AV layer mangling the transfer), disconnects and retries forever.master_link_statusnever leavesdown, so the replica serves stale data indefinitely while looking "merely syncing" at any single glance.Unlike the existing CLUSTER NODES snapshot detector in the module, this evaluator folds INFO replication/stats fields from the polled replica across polls, so it works in standalone and cluster mode alike.
Detection discipline (per the issue's guardrails)
sync_fulldeltas, falling back tomaster_sync_in_progresstoggling off while the link stays down (for replicas whose own counter never moves).master_link_down_since_secondsmeans the link DID reachupbetween polls (a sync completed) — the window restarts rather than firing.Wiring
RESYNC_LOOPmetric type (state-based, added toMETRICS_HANDLED_OUTSIDE_EXTRACTOR), WARNING severity, distinct message pointing at replica-side disk/permissions/RDB-integrity checks.Test plan
sync_full(fires past window + cycles), loop via the in-progress toggle, silent before the window despite cycles, recovery clears + re-alerts on a fresh loop, emit-retry/acknowledge contract, non-replica reset, and the down-counter-drop window restart.tsc --noEmitclean for api and web.Closes #371
Note
Medium Risk
New replication anomaly path on every poll for replica connections; logic is gated and well-tested, but false positives during flaky syncs could add noise until the window and cycle thresholds are met.
Overview
Adds state-based detection for replicas stuck in a full-resync failure loop (valkey#1836):
master_link_statusstays down while full-sync attempts start and fail repeatedly, so the replica can keep serving stale data.The new
evaluateResyncLooplogic instuck-replica-detectortracks INFO replication across polls (standalone or cluster). It only fires after a 5-minute continuous link-down window and ≥2 failed cycles (sync in-progress ends while the link is still down). A long first sync that never drops in-progress stays silent; a drop inmaster_link_down_since_secondsresets the window. Recovery or promotion clears state so a later loop can alert again, with the same emit-retry / acknowledge pattern as other stateful detectors.AnomalyServicewiresdetectResyncLoopon each poll (beside COB pressure), registersMetricType.RESYNC_LOOPoutside the z-score extractor, and cleans per-connection state on disconnect. The anomaly dashboard labels the metric Replica Resync Loop.Eight unit tests cover healthy long sync, genuine loops, timing gates, recovery/re-alert, acknowledge dedupe, non-replica reset, and down-counter restart. Remaining diff in the dashboard file is mostly formatting.
Reviewed by Cursor Bugbot for commit 1ec3e30. Bugbot is set up for automated code reviews on this repo. Configure here.