• Tom Lane's avatar
    Do not select new object OIDs that match recently-dead entries. · 0408e1ed
    Tom Lane authored
    When selecting a new OID, we take care to avoid picking one that's already
    in use in the target table, so as not to create duplicates after the OID
    counter has wrapped around.  However, up to now we used SnapshotDirty when
    scanning for pre-existing entries.  That ignores committed-dead rows, so
    that we could select an OID matching a deleted-but-not-yet-vacuumed row.
    While that mostly worked, it has two problems:
    
    * If recently deleted, the dead row might still be visible to MVCC
    snapshots, creating a risk for duplicate OIDs when examining the catalogs
    within our own transaction.  Such duplication couldn't be visible outside
    the object-creating transaction, though, and we've heard few if any field
    reports corresponding to such a symptom.
    
    * When selecting a TOAST OID, deleted toast rows definitely *are* visible
    to SnapshotToast, and will remain so until vacuumed away.  This leads to
    a conflict that will manifest in errors like "unexpected chunk number 0
    (expected 1) for toast value nnnnn".  We've been seeing reports of such
    errors from the field for years, but the cause was unclear before.
    
    The fix is simple: just use SnapshotAny to search for conflicting rows.
    This results in a slightly longer window before object OIDs can be
    recycled, but that seems unlikely to create any large problems.
    
    Pavan Deolasee
    
    Discussion: https://postgr.es/m/CABOikdOgWT2hHkYG3Wwo2cyZJq2zfs1FH0FgX-=h4OLosXHf9w@mail.gmail.com
    0408e1ed
tuptoaster.c 64.1 KB