• A
    SWAPDB command. · c7a4e694
    antirez 提交于
    This new command swaps two Redis databases, so that immediately all the
    clients connected to a given DB will see the data of the other DB, and
    the other way around. Example:
    
        SWAPDB 0 1
    
    This will swap DB 0 with DB 1. All the clients connected with DB 0 will
    immediately see the new data, exactly like all the clients connected
    with DB 1 will see the data that was formerly of DB 0.
    
    MOTIVATION AND HISTORY
    ---
    
    The command was recently demanded by Pedro Melo, but was suggested in
    the past multiple times, and always refused by me.
    
    The reason why it was asked: Imagine you have clients operating in DB 0.
    At the same time, you create a new version of the dataset in DB 1.
    When the new version of the dataset is available, you immediately want
    to swap the two views, so that the clients will transparently use the
    new version of the data. At the same time you'll likely destroy the
    DB 1 dataset (that contains the old data) and start to build a new
    version, to repeat the process.
    
    This is an interesting pattern, but the reason why I always opposed to
    implement this, was that FLUSHDB was a blocking command in Redis before
    Redis 4.0 improvements. Now we have FLUSHDB ASYNC that releases the
    old data in O(1) from the point of view of the client, to reclaim memory
    incrementally in a different thread.
    
    At this point, the pattern can really be supported without latency
    spikes, so I'm providing this implementation for the users to comment.
    In case a very compelling argument will be made against this new command
    it may be removed.
    
    BEHAVIOR WITH BLOCKING OPERATIONS
    ---
    
    If a client is blocking for a list in a given DB, after the swap it will
    still be blocked in the same DB ID, since this is the most logical thing
    to do: if I was blocked for a list push to list "foo", even after the
    swap I want still a LPUSH to reach the key "foo" in the same DB in order
    to unblock.
    
    However an interesting thing happens when a client is, for instance,
    blocked waiting for new elements in list "foo" of DB 0. Then the DB
    0 and 1 are swapped with SWAPDB. However the DB 1 happened to have
    a list called "foo" containing elements. When this happens, this
    implementation can correctly unblock the client.
    
    It is possible that there are subtle corner cases that are not covered
    in the implementation, but since the command is self-contained from the
    POV of the implementation and the Redis core, it cannot cause anything
    bad if not used.
    
    Tests and documentation are yet to be provided.
    c7a4e694
server.c 143.4 KB