• T
    Fix CLUSTER/VACUUM FULL for toast values owned by recently-updated rows. · 21b446dd
    Tom Lane 提交于
    In commit 7b0d0e93, I made CLUSTER and
    VACUUM FULL try to preserve toast value OIDs from the original toast table
    to the new one.  However, if we have to copy both live and recently-dead
    versions of a row that has a toasted column, those versions may well
    reference the same toast value with the same OID.  The patch then led to
    duplicate-key failures as we tried to insert the toast value twice with the
    same OID.  (The previous behavior was not very desirable either, since it
    would have silently inserted the same value twice with different OIDs.
    That wastes space, but what's worse is that the toast values inserted for
    already-dead heap rows would not be reclaimed by subsequent ordinary
    VACUUMs, since they go into the new toast table marked live not deleted.)
    
    To fix, check if the copied OID already exists in the new toast table, and
    if so, assume that it stores the desired value.  This is reasonably safe
    since the only case where we will copy an OID from a previous toast pointer
    is when toast_insert_or_update was given that toast pointer and so we just
    pulled the data from the old table; if we got two different values that way
    then we have big problems anyway.  We do have to assume that no other
    backend is inserting items into the new toast table concurrently, but
    that's surely safe for CLUSTER and VACUUM FULL.
    
    Per bug #6393 from Maxim Boguk.  Back-patch to 9.0, same as the previous
    patch.
    21b446dd
cluster.c 50.0 KB