• Michael Paquier's avatar
    Make release of 2PC identifier and locks consistent in COMMIT PREPARED · effe7d95
    Michael Paquier authored
    When preparing a transaction in two-phase commit, a dummy PGPROC entry
    holding the GID used for the transaction is registered, which gets
    released once COMMIT PREPARED is run.  Prior releasing its shared memory
    state, all the locks taken in the prepared transaction are released
    using a dedicated set of callbacks (pgstat and multixact having similar
    callbacks), which may cause the locks to be released before the GID is
    set free.
    
    Hence, there is a small window where lock conflicts could happen, for
    example:
    - Transaction A releases its locks, still holding its GID in shared
    memory.
    - Transaction B held a lock which conflicted with locks of transaction
    A.
    - Transaction B continues its processing, reusing the same GID as
    transaction A.
    - Transaction B fails because of a conflicting GID, already in use by
    transaction A.
    
    This commit changes the shared memory state release so as post-commit
    callbacks and predicate lock cleanup happen consistently with the shared
    memory state cleanup for the dummy PGPROC entry.  The race window is
    small and 2PC had this issue from the start, so no backpatch is done.
    On top if that fixes discussed involved ABI breakages, which are not
    welcome in stable branches.
    
    Reported-by: Oleksii Kliukin, Ildar Musin
    Diagnosed-by: Oleksii Kliukin, Ildar Musin
    Author: Michael Paquier
    Reviewed-by: Masahiko Sawada, Oleksii Kliukin
    Discussion: https://postgr.es/m/BF9B38A4-2BFF-46E8-BA87-A2D00A8047A6@hintbits.com
    effe7d95
lock.c 134 KB