summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/heap/tuptoaster.c8
-rw-r--r--src/backend/catalog/catalog.c15
2 files changed, 12 insertions, 11 deletions
diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c
index fc4702ce6f3..ade4bd142df 100644
--- a/src/backend/access/heap/tuptoaster.c
+++ b/src/backend/access/heap/tuptoaster.c
@@ -1725,7 +1725,9 @@ toast_delete_datum(Relation rel, Datum value, bool is_speculative)
/* ----------
* toastrel_valueid_exists -
*
- * Test whether a toast value with the given ID exists in the toast relation
+ * Test whether a toast value with the given ID exists in the toast relation.
+ * For safety, we consider a value to exist if there are either live or dead
+ * toast rows with that ID; see notes for GetNewOid().
* ----------
*/
static bool
@@ -1737,7 +1739,6 @@ toastrel_valueid_exists(Relation toastrel, Oid valueid)
int num_indexes;
int validIndex;
Relation *toastidxs;
- SnapshotData SnapshotToast;
/* Fetch a valid index relation */
validIndex = toast_open_indexes(toastrel,
@@ -1756,10 +1757,9 @@ toastrel_valueid_exists(Relation toastrel, Oid valueid)
/*
* Is there any such chunk?
*/
- init_toast_snapshot(&SnapshotToast);
toastscan = systable_beginscan(toastrel,
RelationGetRelid(toastidxs[validIndex]),
- true, &SnapshotToast, 1, &toastkey);
+ true, SnapshotAny, 1, &toastkey);
if (systable_getnext(toastscan) != NULL)
result = true;
diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c
index 809524819d2..b14433e1291 100644
--- a/src/backend/catalog/catalog.c
+++ b/src/backend/catalog/catalog.c
@@ -278,8 +278,12 @@ IsSharedRelation(Oid relationId)
* managed to cycle through 2^32 OIDs and generate the same OID before we
* finish inserting our row. This seems unlikely to be a problem. Note
* that if we had to *commit* the row to end the race condition, the risk
- * would be rather higher; therefore we use SnapshotDirty in the test,
- * so that we will see uncommitted rows.
+ * would be rather higher; therefore we use SnapshotAny in the test, so that
+ * we will see uncommitted rows. (We used to use SnapshotDirty, but that has
+ * the disadvantage that it ignores recently-deleted rows, creating a risk
+ * of transient conflicts for as long as our own MVCC snapshots think a
+ * recently-deleted row is live. The risk is far higher when selecting TOAST
+ * OIDs, because SnapshotToast considers dead rows as active indefinitely.)
*/
Oid
GetNewOid(Relation relation)
@@ -332,7 +336,6 @@ Oid
GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
{
Oid newOid;
- SnapshotData SnapshotDirty;
SysScanDesc scan;
ScanKeyData key;
bool collides;
@@ -345,8 +348,6 @@ GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
*/
Assert(!IsBinaryUpgrade || RelationGetRelid(relation) != TypeRelationId);
- InitDirtySnapshot(SnapshotDirty);
-
/* Generate new OIDs until we find one not in the table */
do
{
@@ -359,9 +360,9 @@ GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
BTEqualStrategyNumber, F_OIDEQ,
ObjectIdGetDatum(newOid));
- /* see notes above about using SnapshotDirty */
+ /* see notes above about using SnapshotAny */
scan = systable_beginscan(relation, indexId, true,
- &SnapshotDirty, 1, &key);
+ SnapshotAny, 1, &key);
collides = HeapTupleIsValid(systable_getnext(scan));