fix_hang_15.patch
text/x-patch
Filename: fix_hang_15.patch
Type: text/x-patch
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v1
Subject: fix
| File | + | − |
|---|---|---|
| src/backend/access/heap/pruneheap.c | 25 | 11 |
| src/backend/access/heap/vacuumlazy.c | 1 | 1 |
| src/include/access/heapam.h | 1 | 0 |
From eb5ed39ee00430755c45e4ed55ba1cde4c6fd79f Mon Sep 17 00:00:00 2001
From: Melanie Plageman <melanieplageman@gmail.com>
Date: Tue, 14 May 2024 10:35:14 -0400
Subject: [PATCH v1] fix
---
src/backend/access/heap/pruneheap.c | 36 +++++++++++++++++++---------
src/backend/access/heap/vacuumlazy.c | 2 +-
src/include/access/heapam.h | 1 +
3 files changed, 27 insertions(+), 12 deletions(-)
diff --git a/src/backend/access/heap/pruneheap.c b/src/backend/access/heap/pruneheap.c
index 9f43bbe25f5..65d409e8b12 100644
--- a/src/backend/access/heap/pruneheap.c
+++ b/src/backend/access/heap/pruneheap.c
@@ -36,6 +36,12 @@ typedef struct
/* tuple visibility test, initialized for the relation */
GlobalVisState *vistest;
+ /*
+ * Used only by vacuum. The oldest xmin at the beginning of vacuuming the
+ * relation.
+ */
+ TransactionId oldest_xmin;
+
/*
* Thresholds set by TransactionIdLimitedForOldSnapshots() if they have
* been computed (done on demand, and only if
@@ -206,8 +212,8 @@ heap_page_prune_opt(Relation relation, Buffer buffer)
int ndeleted,
nnewlpdead;
- ndeleted = heap_page_prune(relation, buffer, vistest, limited_xmin,
- limited_ts, &nnewlpdead, NULL);
+ ndeleted = heap_page_prune(relation, buffer, vistest, InvalidTransactionId,
+ limited_xmin, limited_ts, &nnewlpdead, NULL);
/*
* Report the number of tuples reclaimed to pgstats. This is
@@ -248,11 +254,14 @@ heap_page_prune_opt(Relation relation, Buffer buffer)
* also need to account for a reduction in the length of the line pointer
* array following array truncation by us.
*
- * vistest is used to distinguish whether tuples are DEAD or RECENTLY_DEAD
- * (see heap_prune_satisfies_vacuum and
- * HeapTupleSatisfiesVacuum). old_snap_xmin / old_snap_ts need to
- * either have been set by TransactionIdLimitedForOldSnapshots, or
- * InvalidTransactionId/0 respectively.
+ * vistest is used to distinguish whether tuples are DEAD or RECENTLY_DEAD (see
+ * heap_prune_satisfies_vacuum and HeapTupleSatisfiesVacuum).
+ *
+ * oldest_xmin is only set to a valid TransactionId by vacuum. It is the oldest
+ * removable TransactionId at the beginning of vacuuming the relation.
+ *
+ * old_snap_xmin / old_snap_ts need to either have been set by
+ * TransactionIdLimitedForOldSnapshots, or InvalidTransactionId/0 respectively.
*
* Sets *nnewlpdead for caller, indicating the number of items that were
* newly set LP_DEAD during prune operation.
@@ -265,6 +274,7 @@ heap_page_prune_opt(Relation relation, Buffer buffer)
int
heap_page_prune(Relation relation, Buffer buffer,
GlobalVisState *vistest,
+ TransactionId oldest_xmin,
TransactionId old_snap_xmin,
TimestampTz old_snap_ts,
int *nnewlpdead,
@@ -292,6 +302,7 @@ heap_page_prune(Relation relation, Buffer buffer,
prstate.new_prune_xid = InvalidTransactionId;
prstate.rel = relation;
prstate.vistest = vistest;
+ prstate.oldest_xmin = oldest_xmin;
prstate.old_snap_xmin = old_snap_xmin;
prstate.old_snap_ts = old_snap_ts;
prstate.old_snap_used = false;
@@ -520,11 +531,14 @@ heap_prune_satisfies_vacuum(PruneState *prstate, HeapTuple tup, Buffer buffer)
}
/*
- * First check if GlobalVisTestIsRemovableXid() is sufficient to find the
- * row dead. If not, and old_snapshot_threshold is enabled, try to use the
- * lowered horizon.
+ * First check if oldest_xmin or GlobalVisTestIsRemovableXid() is
+ * sufficient to find the row dead. If not, and old_snapshot_threshold is
+ * enabled, try to use the lowered horizon.
*/
- if (GlobalVisTestIsRemovableXid(prstate->vistest, dead_after))
+ if (TransactionIdIsValid(prstate->oldest_xmin) &&
+ NormalTransactionIdPrecedes(dead_after, prstate->oldest_xmin))
+ res = HEAPTUPLE_DEAD;
+ else if (GlobalVisTestIsRemovableXid(prstate->vistest, dead_after))
res = HEAPTUPLE_DEAD;
else if (OldSnapshotThresholdActive())
{
diff --git a/src/backend/access/heap/vacuumlazy.c b/src/backend/access/heap/vacuumlazy.c
index 2e61e2f20b4..a027458cf69 100644
--- a/src/backend/access/heap/vacuumlazy.c
+++ b/src/backend/access/heap/vacuumlazy.c
@@ -1585,7 +1585,7 @@ retry:
* lpdead_items's final value can be thought of as the number of tuples
* that were deleted from indexes.
*/
- tuples_deleted = heap_page_prune(rel, buf, vacrel->vistest,
+ tuples_deleted = heap_page_prune(rel, buf, vacrel->vistest, vacrel->OldestXmin,
InvalidTransactionId, 0, &nnewlpdead,
&vacrel->offnum);
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index abf62d9df79..e39fa14c1b2 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -186,6 +186,7 @@ struct GlobalVisState;
extern void heap_page_prune_opt(Relation relation, Buffer buffer);
extern int heap_page_prune(Relation relation, Buffer buffer,
struct GlobalVisState *vistest,
+ TransactionId oldest_xmin,
TransactionId old_snap_xmin,
TimestampTz old_snap_ts_ts,
int *nnewlpdead,
--
2.34.1