• sundb's avatar
    Fix abnormal compression due to out-of-control recompress (#9849) · 494ee2f1
    sundb authored
    This pr is following #9779 .
    
    ## Describe of feature
    Now when we turn on the `list-compress-depth` configuration, the list will compress
    the ziplist between `[list-compress-depth, -list-compress-depth]`.
    When we need to use the compressed data, we will first decompress it, then use it,
    and finally compress it again.
    It's controlled by `quicklistNode->recompress`, which is designed to avoid the need to
    re-traverse the entire quicklist for compression after each decompression, we only need
    to recompress the quicklsitNode being used.
    In order to ensure the correctness of recompressing, we should normally let
    quicklistDecompressNodeForUse and quicklistCompress appear in pairs, otherwise,
    it may lead to the head and tail being compressed or the middle ziplist not being
    compressed correctly, which is exactly the problem this pr needs to solve.
    
    ## Solution
    1. Reset `quicklistIter` after insert and replace.
        The quicklist node will be compressed in `quicklistInsertAfter`, `quicklistInsertBefore`,
       `quicklistReplaceAtIndex`, so we can safely reset the quicklistIter to avoid it being used again
    2. `quicklistIndex` will return an iterator that can be used to recompress the current node after use.
        
    ## Test
    1. In the `Stress Tester for #3343-Similar Errors` test, when the server crashes or when
       `valgrind` or `asan` error is detected, print violating commands.
    2. Add a crash test due to wrongly recompressing after `lrem`.
    3. Remove `insert before with 0 elements` and `insert after with 0 elements`,
       Now we forbid any operation on an NULL quicklistIter.
    494ee2f1
t_list.c 41.3 KB