• Meir Shpilraien (Spielrein)'s avatar
    Avoid saving module aux on RDB if no aux data was saved by the module. (#11374) · b43f2548
    Meir Shpilraien (Spielrein) authored
    ### Background
    
    The issue is that when saving an RDB with module AUX data, the module AUX metadata
    (moduleid, when, ...) is saved to the RDB even though the module did not saved any actual data.
    This prevent loading the RDB in the absence of the module (although there is no actual data in
    the RDB that requires the module to be loaded).
    
    ### Solution
    
    The solution suggested in this PR is that module AUX will be saved on the RDB only if the module
    actually saved something during `aux_save` function.
    
    To support backward compatibility, we introduce `aux_save2` callback that acts the same as
    `aux_save` with the tiny change of avoid saving the aux field if no data was actually saved by
    the module. Modules can use the new API to make sure that if they have no data to save,
    then it will be possible to load the created RDB even without the module.
    
    ### Concerns
    
    A module may register for the aux load and save hooks just in order to be notified when
    saving or loading starts or completed (there are better ways to do that, but it still possible
    that someone used it).
    
    However, if a module didn't save a single field in the save callback, it means it's not allowed
    to read in the read callback, since it has no way to distinguish between empty and non-empty
    payloads. furthermore, it means that if the module did that, it must never change it, since it'll
    break compatibility with it's old RDB files, so this is really not a valid use case.
    
    Since some modules (ones who currently save one field indicating an empty payload), need
    to know if saving an empty payload is valid, and if Redis is gonna ignore an empty payload
    or store it, we opted to add a new API (rather than change behavior of an existing API and
    expect modules to check the redis version)
    
    ### Technical Details
    
    To avoid saving AUX data on RDB, we change the code to first save the AUX metadata
    (moduleid, when, ...) into a temporary buffer. The buffer is then flushed to the rio at the first
    time the module makes a write operation inside the `aux_save` function. If the module saves
    nothing (and `aux_save2` was used), the entire temporary buffer is simply dropped and no
    data about this AUX field is saved to the RDB. This make it possible to load the RDB even in
    the absence of the module.
    
    Test was added to verify the fix.
    b43f2548
rdb.c 134 KB