diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2012-01-12 16:40:19 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2012-01-12 16:40:19 -0500 |
commit | b994c57a8032f55f816768ee55a677e03190abae (patch) | |
tree | d77f0bd155b3874c5c067ca7ec4b0add7bf87f57 /src/include | |
parent | d427e75e51d9e7d76fc2a4bc142ba7be852a1078 (diff) |
Fix CLUSTER/VACUUM FULL for toast values owned by recently-updated rows.
In commit 7b0d0e9356963d5c3e4d329a917f5fbb82a2ef05, 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.
Diffstat (limited to 'src/include')
-rw-r--r-- | src/include/utils/rel.h | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h index e2c2fa9ae45..57cdc3b9404 100644 --- a/src/include/utils/rel.h +++ b/src/include/utils/rel.h @@ -211,7 +211,8 @@ typedef struct RelationData * have the existing toast table's OID, not the OID of the transient toast * table. If rd_toastoid isn't InvalidOid, it is the OID to place in * toast pointers inserted into this rel. (Note it's set on the new - * version of the main heap, not the toast table itself.) + * version of the main heap, not the toast table itself.) This also + * causes toast_save_datum() to try to preserve toast value OIDs. */ Oid rd_toastoid; /* Real TOAST table's OID, or InvalidOid */ |