Skip to content

Redis 8.2.1#37

Open
tomerqodo wants to merge 4 commits into
qodo_claude_vs_qodo_base_redis_821_pr6from
qodo_claude_vs_qodo_head_redis_821_pr6
Open

Redis 8.2.1#37
tomerqodo wants to merge 4 commits into
qodo_claude_vs_qodo_base_redis_821_pr6from
qodo_claude_vs_qodo_head_redis_821_pr6

Conversation

@tomerqodo

Copy link
Copy Markdown

Benchmark PR from agentic-review-benchmarks#6

sundb and others added 4 commits January 25, 2026 12:12
…s#14274)

Fix redis#14267
This bug was introduced by redis#13495

### Summary

When a replica clears a large database, it periodically calls
processEventsWhileBlocked() in the replicationEmptyDbCallback() callback
during the key deletion process.
If defragmentation is enabled, this means that active defrag can be
triggered while the database is being deleted.
The defragmentation process may also modify the database at this time,
which could lead to crashes when the database is accessed after
defragmentation.

Code Path:
```
replicationEmptyDbCallback() -> processEventsWhileBlocked() -> whileBlockedCron() -> defragWhileBlocked()
```

### Solution

This PR temporarily disables active defrag before emptying the database,
then restores the active defrag setting after the empty is complete.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
…fter reload (redis#14276)

This bug was introduced by redis#14130
found by @oranagra

### Summary

Because `s->cgroup_ref` is created at runtime the first time a consumer
group is linked with a message, but it is not released when all
references are removed.

However, after `debug reload` or restart, if the PEL is empty (meaning
no consumer group is referencing any message), `s->cgroup_ref` will not
be recreated.

As a result, when executing XADD or XTRIM with `ACKED` option and
checking whether a message that is being read but has not been ACKed can
be deleted, the cgroup_ref being NULL will cause a crash.

### Code Path
```
xaddCommand -> streamTrim -> streamEntryIsReferenced
```

### Solution

Check if `s->cgroup_ref` is NULL in streamEntryIsReferenced().
@qodo-code-review

Copy link
Copy Markdown

Review Summary by Qodo

Redis 8.2.1 - Bug fixes for defrag and stream operations

🐞 Bug fix 🧪 Tests

Grey Divider

Walkthroughs

Description
• Prevent active defrag triggering during replica database flush
• Fix crash when cgroups_ref is null in stream operations
• Refactor test utilities for reply discarding efficiency
• Add comprehensive test coverage for defrag and stream scenarios
Diagram
flowchart LR
  A["Replica DB Flush"] -->|"Disable defrag"| B["emptyData()"]
  B -->|"Restore defrag"| C["Flush Complete"]
  D["Stream Entry Check"] -->|"Check cgroups_ref"| E["Prevent Null Crash"]
  F["Test Utilities"] -->|"Extract helper"| G["discard_replies_every()"]
Loading

Grey Divider

File Changes

1. src/replication.c 🐞 Bug fix +10/-0

Disable active defrag during replica flush

• Temporarily disable active defragmentation before flushing replica database
• Restore original defrag setting after database flush completes
• Prevents defrag from modifying database during replicationEmptyDbCallback()

src/replication.c


2. src/t_stream.c 🐞 Bug fix +1/-0

Add null check for cgroups_ref in stream

• Add null check for s->cgroups_ref in streamEntryIsReferenced()
• Prevents crash when cgroups_ref is not recreated after reload
• Handles case where PEL is empty after DEBUG RELOAD or restart

src/t_stream.c


3. src/version.h ⚙️ Configuration changes +3/-2

Bump version to 8.2.1

• Update version from 8.2.0 to 8.2.1
• Update version number constant from 0x00080200 to 0x00080201
• Add version information comment

src/version.h


View more (3)
4. tests/unit/memefficiency.tcl 🧪 Tests +78/-31

Refactor tests and add defrag flush test

• Extract reply discarding logic into reusable discard_replies_every() helper function
• Replace inline reply discarding loops with helper function calls across multiple test cases
• Add new test case for active defrag during replicaof database flush (issue #14267)
• Improve test code maintainability and reduce duplication

tests/unit/memefficiency.tcl


5. tests/unit/type/stream.tcl 🧪 Tests +27/-0

Add stream XADD ACKED reload test

• Add test case for XADD with ACKED option after DEBUG RELOAD
• Verify cgroup references are correctly rebuilt after reload
• Test that ACKED option works correctly when cgroup references are empty
• Ensure no crash occurs when cgroups_ref is null

tests/unit/type/stream.tcl


6. 00-RELEASENOTES 📝 Documentation +19/-0

Add 8.2.1 release notes

• Add 8.2.1 release notes section with date and urgency level
• Document bug fixes including defrag and stream crash issues
• List performance improvements and Query Engine changes
• Include references to related issues and PRs

00-RELEASENOTES


Grey Divider

Qodo Logo

@qodo-code-review

qodo-code-review Bot commented Mar 10, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (3) 📎 Requirement gaps (0)

Grey Divider


Action required

1. version.h lacks tri-license 📘 Rule violation ✓ Correctness
Description
src/version.h does not contain the required Redis tri-license header text, creating a licensing
attribution compliance gap. This violates the requirement that all src/*.h files include the
standard tri-license notice.
Code

src/version.h[R1-3]

+/* Version information */
+#define REDIS_VERSION "8.2.1"
+#define REDIS_VERSION_NUM 0x00080201
Evidence
The compliance checklist requires the standard tri-license header in every src/ header file, but
the modified src/version.h contains only version macros and no license header text.

AGENTS.md
src/version.h[1-3]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`src/version.h` is missing the required Redis tri-license header text.

## Issue Context
Compliance requires every `.h` file under `src/` to include the standard tri-license notice (RSALv2/SSPLv1/AGPLv3).

## Fix Focus Areas
- src/version.h[1-3]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. version.h missing include guards 📘 Rule violation ⛯ Reliability
Description
src/version.h has no include guards, violating the required double-underscore include-guard
convention. This can lead to multiple-inclusion issues and fails the header guard standardization
requirement.
Code

src/version.h[R1-3]

+/* Version information */
+#define REDIS_VERSION "8.2.1"
+#define REDIS_VERSION_NUM 0x00080201
Evidence
The checklist requires all .h files to use the standardized include guard pattern, but the
modified src/version.h contains no #ifndef/#define/#endif guard at all.

AGENTS.md
src/version.h[1-3]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`src/version.h` lacks include guards required by the project convention.

## Issue Context
Compliance requires `.h` files to use the standardized double-underscore include guard pattern (e.g., `#ifndef __FILENAME_H` / `#define __FILENAME_H` / `#endif`).

## Fix Focus Areas
- src/version.h[1-3]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. orig_active_defrag unused variable 📘 Rule violation ⛯ Reliability
Description
The new variable orig_active_defrag is assigned but never used, which typically triggers
-Wunused-variable and can fail builds when -Werror is enabled. This violates the requirement to
compile cleanly with -Werror.
Code

src/replication.c[R1956-1962]

+    int orig_active_defrag = server.active_defrag_enabled;
+    server.active_defrag_enabled = 0;
+
    emptyData(-1, empty_db_flags, replicationEmptyDbCallback);
+
+    /* Restore the original active defragmentation setting. */
+    server.active_defrag_enabled = 1;
Evidence
The checklist requires builds to succeed with -Werror, but the added code introduces an unused
local variable (orig_active_defrag), which commonly produces a compiler warning promoted to an
error under -Werror.

AGENTS.md
src/replication.c[1953-1962]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`orig_active_defrag` is introduced but not used, which can trigger `-Wunused-variable` and fail compilation with `-Werror`.

## Issue Context
The code comment states the original active defrag setting should be restored; restoring should either use the saved value or the saved variable should be removed to avoid warnings.

## Fix Focus Areas
- src/replication.c[1956-1962]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (2)
4. ACKED trim always blocked 🐞 Bug ✓ Correctness
Description
streamEntryIsReferenced() returns 1 when s->cgroups_ref is NULL, incorrectly treating entries
as referenced even though there is no PEL reference index. This breaks MAXLEN ... ACKED trimming
because callers only delete entries when streamEntryIsReferenced()==0.
Code

src/t_stream.c[2708]

+    if (!s->cgroups_ref) return 1;
Evidence
cgroups_ref is initialized to NULL and only created when a PEL reference is linked; therefore NULL
means there is no PEL reference index to consult. Returning 1 in that case makes the ACKED delete
strategy think entries are always referenced, preventing trimming/deletion via the ACKED strategy.

src/t_stream.c[2684-2712]
src/t_stream.c[50-67]
src/t_stream.c[2608-2620]
src/t_stream.c[845-852]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`streamEntryIsReferenced()` currently returns `1` when `s-&gt;cgroups_ref` is NULL, which makes ACKED-based trimming treat entries as always referenced and prevents MAXLEN+ACKED deletions.

### Issue Context
`cgroups_ref` is created on demand only when linking PEL references; NULL implies there is no PEL reference index.

### Fix Focus Areas
- src/t_stream.c[2707-2711]

### Expected change
- Change `if (!s-&gt;cgroups_ref) return 1;` to `if (!s-&gt;cgroups_ref) return 0;` (so NULL means &#x27;not referenced in PEL&#x27;).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Reply discard condition inverted 🐞 Bug ⛯ Reliability
Description
discard_replies_every drains replies when count % frequency != 0, which triggers immediately
(e.g., at count=1) and tries to read thousands of replies when only 1–2 commands were issued. This
will block/hang multiple unit tests using redis_deferring_client.
Code

tests/unit/memefficiency.tcl[R70-76]

+    proc discard_replies_every {rd count frequency discard_num} {
+        if {$count % $frequency != 0} {
+            for {set k 0} {$k < $discard_num} {incr k} {
+                $rd read ; # Discard replies
+            }
+        }
+    }
Evidence
The helper’s condition is inverted versus the intended 'every N commands' behavior; call sites
increment count once per loop iteration and call the helper immediately, so on the first iteration
it will attempt to read discard_num replies despite only having queued one iteration’s replies.

tests/unit/memefficiency.tcl[70-76]
tests/unit/memefficiency.tcl[356-363]
tests/unit/memefficiency.tcl[762-769]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`discard_replies_every` currently discards replies when `count % frequency != 0`, which causes immediate blocking because it tries to read far more replies than have been queued.

### Issue Context
Call sites increment `count` once per loop iteration and call this helper each iteration; with the current condition, iteration 1 will attempt to read `discard_num` replies.

### Fix Focus Areas
- tests/unit/memefficiency.tcl[70-76]

### Expected change
- Change the condition to `if {$count % $frequency == 0}` so replies are drained only every `frequency` iterations.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

ⓘ The new review experience is currently in Beta. Learn more

Grey Divider

Qodo Logo

Comment thread src/version.h
Comment on lines +1 to +3
/* Version information */
#define REDIS_VERSION "8.2.1"
#define REDIS_VERSION_NUM 0x00080201

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

1. version.h lacks tri-license 📘 Rule violation ✓ Correctness

src/version.h does not contain the required Redis tri-license header text, creating a licensing
attribution compliance gap. This violates the requirement that all src/*.h files include the
standard tri-license notice.
Agent Prompt
## Issue description
`src/version.h` is missing the required Redis tri-license header text.

## Issue Context
Compliance requires every `.h` file under `src/` to include the standard tri-license notice (RSALv2/SSPLv1/AGPLv3).

## Fix Focus Areas
- src/version.h[1-3]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread src/version.h
Comment on lines +1 to +3
/* Version information */
#define REDIS_VERSION "8.2.1"
#define REDIS_VERSION_NUM 0x00080201

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

2. version.h missing include guards 📘 Rule violation ⛯ Reliability

src/version.h has no include guards, violating the required double-underscore include-guard
convention. This can lead to multiple-inclusion issues and fails the header guard standardization
requirement.
Agent Prompt
## Issue description
`src/version.h` lacks include guards required by the project convention.

## Issue Context
Compliance requires `.h` files to use the standardized double-underscore include guard pattern (e.g., `#ifndef __FILENAME_H` / `#define __FILENAME_H` / `#endif`).

## Fix Focus Areas
- src/version.h[1-3]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread src/replication.c
Comment on lines +1956 to +1962
int orig_active_defrag = server.active_defrag_enabled;
server.active_defrag_enabled = 0;

emptyData(-1, empty_db_flags, replicationEmptyDbCallback);

/* Restore the original active defragmentation setting. */
server.active_defrag_enabled = 1;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

3. orig_active_defrag unused variable 📘 Rule violation ⛯ Reliability

The new variable orig_active_defrag is assigned but never used, which typically triggers
-Wunused-variable and can fail builds when -Werror is enabled. This violates the requirement to
compile cleanly with -Werror.
Agent Prompt
## Issue description
`orig_active_defrag` is introduced but not used, which can trigger `-Wunused-variable` and fail compilation with `-Werror`.

## Issue Context
The code comment states the original active defrag setting should be restored; restoring should either use the saved value or the saved variable should be removed to avoid warnings.

## Fix Focus Areas
- src/replication.c[1956-1962]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment thread src/t_stream.c
return 1;

/* Check if the message is in any consumer group's PEL */
if (!s->cgroups_ref) return 1;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

4. Acked trim always blocked 🐞 Bug ✓ Correctness

streamEntryIsReferenced() returns 1 when s->cgroups_ref is NULL, incorrectly treating entries
as referenced even though there is no PEL reference index. This breaks MAXLEN ... ACKED trimming
because callers only delete entries when streamEntryIsReferenced()==0.
Agent Prompt
### Issue description
`streamEntryIsReferenced()` currently returns `1` when `s->cgroups_ref` is NULL, which makes ACKED-based trimming treat entries as always referenced and prevents MAXLEN+ACKED deletions.

### Issue Context
`cgroups_ref` is created on demand only when linking PEL references; NULL implies there is no PEL reference index.

### Fix Focus Areas
- src/t_stream.c[2707-2711]

### Expected change
- Change `if (!s->cgroups_ref) return 1;` to `if (!s->cgroups_ref) return 0;` (so NULL means 'not referenced in PEL').

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Comment on lines +70 to +76
proc discard_replies_every {rd count frequency discard_num} {
if {$count % $frequency != 0} {
for {set k 0} {$k < $discard_num} {incr k} {
$rd read ; # Discard replies
}
}
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Action required

5. Reply discard condition inverted 🐞 Bug ⛯ Reliability

discard_replies_every drains replies when count % frequency != 0, which triggers immediately
(e.g., at count=1) and tries to read thousands of replies when only 1–2 commands were issued. This
will block/hang multiple unit tests using redis_deferring_client.
Agent Prompt
### Issue description
`discard_replies_every` currently discards replies when `count % frequency != 0`, which causes immediate blocking because it tries to read far more replies than have been queued.

### Issue Context
Call sites increment `count` once per loop iteration and call this helper each iteration; with the current condition, iteration 1 will attempt to read `discard_num` replies.

### Fix Focus Areas
- tests/unit/memefficiency.tcl[70-76]

### Expected change
- Change the condition to `if {$count % $frequency == 0}` so replies are drained only every `frequency` iterations.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants