• Alvaro Herrera's avatar
    Fix concurrent locking of tuple update chain · 459c64d3
    Alvaro Herrera authored
    If several sessions are concurrently locking a tuple update chain with
    nonconflicting lock modes using an old snapshot, and they all succeed,
    it may happen that some of them fail because of restarting the loop (due
    to a concurrent Xmax change) and getting an error in the subsequent pass
    while trying to obtain a tuple lock that they already have in some tuple
    version.
    
    This can only happen with very high concurrency (where a row is being
    both updated and FK-checked by multiple transactions concurrently), but
    it's been observed in the field and can have unpleasant consequences
    such as an FK check failing to see a tuple that definitely exists:
        ERROR:  insert or update on table "child_table" violates foreign key constraint "fk_constraint_name"
        DETAIL:  Key (keyid)=(123456) is not present in table "parent_table".
    (where the key is observably present in the table).
    
    Discussion: https://postgr.es/m/20170714210011.r25mrff4nxjhmf3g@alvherre.pgsql
    459c64d3
heapam.c 274 KB