aboutsummaryrefslogtreecommitdiff
path: root/src/backend/access/spgist/spgutils.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/access/spgist/spgutils.c')
-rw-r--r--src/backend/access/spgist/spgutils.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/backend/access/spgist/spgutils.c b/src/backend/access/spgist/spgutils.c
index 3f793125f74..76b80146ff0 100644
--- a/src/backend/access/spgist/spgutils.c
+++ b/src/backend/access/spgist/spgutils.c
@@ -358,8 +358,19 @@ initSpGistState(SpGistState *state, Relation index)
/* Make workspace for constructing dead tuples */
state->deadTupleStorage = palloc0(SGDTSIZE);
- /* Set XID to use in redirection tuples */
- state->myXid = GetTopTransactionIdIfAny();
+ /*
+ * Set horizon XID to use in redirection tuples. Use our own XID if we
+ * have one, else use InvalidTransactionId. The latter case can happen in
+ * VACUUM or REINDEX CONCURRENTLY, and in neither case would it be okay to
+ * force an XID to be assigned. VACUUM won't create any redirection
+ * tuples anyway, but REINDEX CONCURRENTLY can. Fortunately, REINDEX
+ * CONCURRENTLY doesn't mark the index valid until the end, so there could
+ * never be any concurrent scans "in flight" to a redirection tuple it has
+ * inserted. And it locks out VACUUM until the end, too. So it's okay
+ * for VACUUM to immediately expire a redirection tuple that contains an
+ * invalid xid.
+ */
+ state->redirectXid = GetTopTransactionIdIfAny();
/* Assume we're not in an index build (spgbuild will override) */
state->isBuild = false;
@@ -1075,8 +1086,7 @@ spgFormDeadTuple(SpGistState *state, int tupstate,
if (tupstate == SPGIST_REDIRECT)
{
ItemPointerSet(&tuple->pointer, blkno, offnum);
- Assert(TransactionIdIsValid(state->myXid));
- tuple->xid = state->myXid;
+ tuple->xid = state->redirectXid;
}
else
{