Fix XSETID with max_deleted_entry_id issue (#11444)

Resolve an edge case where the ID of a stream is updated retroactively
to an ID lower than the already set max_deleted_entry_id.

Currently, if we have command as below:
**xsetid mystream 1-1 MAXDELETEDID 1-2**
Then we will get the following error:
**(error) ERR The ID specified in XSETID is smaller than the provided max_deleted_entry_id**
Becuase the provided MAXDELETEDID 1-2 is greated than input last-id: 1-1

Then we could assume there is a similar situation:
step 1: we add three items in the mystream

**127.0.0.1:6381> xadd mystream 1-1 a 1
"1-1"
127.0.0.1:6381> xadd mystream 1-2 b 2
"1-2"
127.0.0.1:6381> xadd mystream 1-3 c 3
"1-3"**

step 2: we could check the mystream infomation as below:
**127.0.0.1:6381> xinfo stream mystream
 1) "length"
 2) (integer) 3
 7) "last-generated-id"
 8) "1-3"
 9) "max-deleted-entry-id"
10) "0-0"

step 3: we delete the item id 1-2 and 1-3 as below:
**127.0.0.1:6381> xdel mystream 1-2
(integer) 1
127.0.0.1:6381> xdel mystream 1-3
(integer) 1**

step 4: we check the mystream information:
127.0.0.1:6381> xinfo stream mystream
 1) "length"
 2) (integer) 1
 7) "last-generated-id"
 8) "1-3"
 9) "max-deleted-entry-id"
10) "1-3"

we could notice that the **max-deleted-entry-id update to 1-3**, so right now, if we just run:
**xsetid mystream 1-2** 
the above command has the same effect with **xsetid mystream 1-2  MAXDELETEDID 1-3**

So we should return an error to the client that **(error) ERR The ID specified in XSETID is smaller than current max_deleted_entry_id**
This commit is contained in:
Wen Hui 2022-11-02 10:16:16 -04:00 committed by GitHub
parent fea9bbbe0f
commit 7395e370e6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 0 deletions

View File

@ -2778,6 +2778,11 @@ void xsetidCommand(client *c) {
if (o == NULL || checkType(c,o,OBJ_STREAM)) return;
stream *s = o->ptr;
if (streamCompareID(&id,&s->max_deleted_entry_id) < 0) {
addReplyError(c,"The ID specified in XSETID is smaller than current max_deleted_entry_id");
return;
}
/* If the stream has at least one item, we want to check that the user
* is setting a last ID that is equal or greater than the current top
* item, otherwise the fundamental ID monotonicity assumption is violated. */

View File

@ -823,6 +823,19 @@ start_server {tags {"stream"}} {
r XADD mystream MAXLEN 0 * a b
set err
} {ERR *smaller*}
test {XSETID cannot set smaller ID than current MAXDELETEDID} {
r DEL x
r XADD x 1-1 a 1
r XADD x 1-2 b 2
r XADD x 1-3 c 3
r XDEL x 1-2
r XDEL x 1-3
set reply [r XINFO stream x]
assert_equal [dict get $reply max-deleted-entry-id] "1-3"
catch {r XSETID x "1-2" } err
set err
} {ERR *smaller*}
}
start_server {tags {"stream"}} {