• antirez's avatar
    Fix script cache bug in the scripting engine. · 21e6b0fb
    antirez authored
    This commit fixes a serious Lua scripting replication issue, described
    by Github issue #1549. The root cause of the problem is that scripts
    were put inside the script cache, assuming that slaves and AOF already
    contained it, even if the scripts sometimes produced no changes in the
    data set, and were not actaully propagated to AOF/slaves.
    
    Example:
    
        eval "if tonumber(KEYS[1]) > 0 then redis.call('incr', 'x') end" 1 0
    
    Then:
    
        evalsha <sha1 step 1 script> 1 0
    
    At this step sha1 of the script is added to the replication script cache
    (the script is marked as known to the slaves) and EVALSHA command is
    transformed to EVAL. However it is not dirty (there is no changes to db),
    so it is not propagated to the slaves. Then the script is called again:
    
        evalsha <sha1 step 1 script> 1 1
    
    At this step master checks that the script already exists in the
    replication script cache and doesn't transform it to EVAL command. It is
    dirty and propagated to the slaves, but they fail to evaluate the script
    as they don't have it in the script cache.
    
    The fix is trivial and just uses the new API to force the propagation of
    the executed command regardless of the dirty state of the data set.
    
    Thank you to @minus-infinity on Github for finding the issue,
    understanding the root cause, and fixing it.
    21e6b0fb
scripting.c 37.5 KB