• Alvaro Herrera's avatar
    Make XactLockTableWait work for transactions that are not yet self-locked · 3c27944f
    Alvaro Herrera authored
    XactLockTableWait assumed that its xid argument has already added itself
    to the lock table.  That assumption led to another assumption that if
    locking the xid has succeeded but the xid is reported as still in
    progress, then the input xid must have been a subtransaction.
    
    These assumptions hold true for the original uses of this code in
    locking related to on-disk tuples, but they break down in logical
    replication slot snapshot building -- in particular, when a standby
    snapshot logged contains an xid that's already in ProcArray but not yet
    in the lock table.  This leads to assertion failures that can be
    reproduced all the way back to 9.4, when logical decoding was
    introduced.
    
    To fix, change SubTransGetParent to SubTransGetTopmostTransaction which
    has a slightly different API: it returns the argument Xid if there is no
    parent, and it goes all the way to the top instead of moving up the
    levels one by one.  Also, to avoid busy-waiting, add a 1ms sleep to give
    the other process time to register itself in the lock table.
    
    For consistency, change ConditionalXactLockTableWait the same way.
    
    Author: Petr Jelínek
    Discussion: https://postgr.es/m/1B3E32D8-FCF4-40B4-AEF9-5C0E3AC57969@postgrespro.ru
    Reported-by: Konstantin Knizhnik
    Diagnosed-by: Stas Kelvich, Petr Jelínek
    Reviewed-by: Andres Freund, Robert Haas
    3c27944f
lmgr.c 25.7 KB