• Michael Paquier's avatar
    Fix corruption of toast indexes with REINDEX CONCURRENTLY · 64ab21f0
    Michael Paquier authored
    REINDEX CONCURRENTLY run on a toast index or a toast relation could
    corrupt the target indexes rebuilt, as a backend running in parallel
    that manipulates toast values would directly release the lock on the
    toast relation when its local operation is done, rather than releasing
    the lock once the transaction that manipulated the toast values
    committed.
    
    The fix done here is simple: we now hold a ROW EXCLUSIVE lock on the
    toast relation when saving or deleting a toast value until the
    transaction working on them is committed, so as a concurrent reindex
    happening in parallel would be able to wait for any activity and see any
    new rows inserted (or deleted).
    
    An isolation test is added to check after the case fixed here, which is
    a bit fancy by design as it relies on allow_system_table_mods to rename
    the toast table and its index to fixed names.  This way, it is possible
    to reindex them directly without any dependency on the OID of the
    underlying relation.  Note that this could not use a DO block either, as
    REINDEX CONCURRENTLY cannot be run in a transaction block.  The test is
    backpatched down to 13, where it is possible, thanks to c4a7a392, to use
    allow_system_table_mods in a test suite.
    
    Reported-by: Alexey Ermakov
    Analyzed-by: Andres Freund, Noah Misch
    Author: Michael Paquier
    Reviewed-by: Nathan Bossart
    Discussion: https://postgr.es/m/17268-d2fb426e0895abd4@postgresql.org
    Backpatch-through: 12
    64ab21f0
reindex-concurrently-toast.out 27.1 KB