[redis]github-87 Report

https://github.com/antirez/redis/issues/87

1. Symptom

BRPOPLPUSH doesn’t behave correctly when blocked on empty list. It will return wrong result.

Client A blocks on 'BRPOPLPUSH a b 0'

Client B runs 'LPUSH a data1 data2 data3'

The correct result should be A returns with “a” = [data1 data2] and “b” = [data3], but the wrong result was ‘a’ empty and ‘b’ = [data1]

1.1 Severity

Critical

1.2 Was there exception thrown?

No

1.2.1 Were there multiple exceptions?

No

1.4 Scope of the failure

Single client

2. How to reproduce this failure

2.0 Version

2.4.unstable

2.1 Configuration

standard

2.2 Reproduction procedure

Client A blocks on 'BRPOPLPUSH a b 0'

Client B runs 'LPUSH a data1 data2 data3'

2.2.1 Timing order

in this order

2.2.2 Events order externally controllable?

Yes

2.3 Can the logs tell how to reproduce the failure?

Yes. client log

2.4 How many machines needed?

3

3. Diagnosis procedure

3.1 Detailed Symptom (where you start)

Wrong result.

4. Root cause

The reason is that rpoplpushHandlePush calls rewriteClientCommandVector when the first item is pushed to 'a' and that interferes with the pushing of the other items. Even if pushGenericCommand was changed so that it would push all the items regardless (using a local copy of them), the replication and AOF would only register one of the items. This seems to require some minor redesign to fix it.

4.1 Category:

Semantic

4.2 Are there multiple fault?

No