v1-0003-wip-Split-SnapshotData-into-multiple-structs.patch
text/x-patch
Filename: v1-0003-wip-Split-SnapshotData-into-multiple-structs.patch
Type: text/x-patch
Part: 2
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-0003
Subject: wip: Split SnapshotData into multiple structs
| File | + | − |
|---|---|---|
| contrib/amcheck/verify_nbtree.c | 3 | 3 |
| contrib/pgrowlocks/pgrowlocks.c | 1 | 1 |
| src/backend/access/brin/brin.c | 1 | 1 |
| src/backend/access/heap/heapam.c | 2 | 1 |
| src/backend/access/heap/heapam_handler.c | 8 | 8 |
| src/backend/access/heap/heapam_visibility.c | 10 | 10 |
| src/backend/access/index/genam.c | 2 | 2 |
| src/backend/access/index/indexam.c | 5 | 8 |
| src/backend/access/nbtree/nbtinsert.c | 3 | 3 |
| src/backend/access/nbtree/nbtsort.c | 1 | 1 |
| src/backend/access/table/tableam.c | 6 | 5 |
| src/backend/access/transam/parallel.c | 4 | 4 |
| src/backend/catalog/index.c | 1 | 1 |
| src/backend/catalog/pg_inherits.c | 1 | 1 |
| src/backend/catalog/pg_largeobject.c | 1 | 1 |
| src/backend/commands/async.c | 4 | 4 |
| src/backend/commands/copyto.c | 2 | 2 |
| src/backend/commands/createas.c | 1 | 1 |
| src/backend/commands/dbcommands.c | 2 | 2 |
| src/backend/commands/explain.c | 1 | 1 |
| src/backend/commands/indexcmds.c | 8 | 8 |
| src/backend/commands/matview.c | 1 | 1 |
| src/backend/commands/tablecmds.c | 3 | 3 |
| src/backend/commands/trigger.c | 1 | 1 |
| src/backend/commands/typecmds.c | 2 | 2 |
| src/backend/executor/execIndexing.c | 6 | 6 |
| src/backend/executor/execMain.c | 4 | 4 |
| src/backend/executor/execParallel.c | 1 | 1 |
| src/backend/executor/execReplication.c | 9 | 9 |
| src/backend/executor/execUtils.c | 2 | 2 |
| src/backend/executor/functions.c | 1 | 1 |
| src/backend/executor/nodeBitmapHeapscan.c | 1 | 1 |
| src/backend/executor/nodeBitmapIndexscan.c | 1 | 1 |
| src/backend/executor/nodeIndexonlyscan.c | 2 | 2 |
| src/backend/executor/nodeIndexscan.c | 2 | 2 |
| src/backend/executor/nodeLockRows.c | 1 | 1 |
| src/backend/executor/nodeModifyTable.c | 9 | 9 |
| src/backend/executor/nodeSamplescan.c | 1 | 1 |
| src/backend/executor/nodeSeqscan.c | 3 | 3 |
| src/backend/executor/nodeTidrangescan.c | 1 | 1 |
| src/backend/executor/nodeTidscan.c | 2 | 2 |
| src/backend/executor/spi.c | 32 | 32 |
| src/backend/libpq/be-fsstubs.c | 1 | 1 |
| src/backend/partitioning/partbounds.c | 1 | 1 |
| src/backend/partitioning/partdesc.c | 1 | 1 |
| src/backend/replication/logical/decode.c | 1 | 1 |
| src/backend/replication/logical/reorderbuffer.c | 38 | 38 |
| src/backend/replication/logical/snapbuild.c | 51 | 48 |
| src/backend/replication/walsender.c | 1 | 1 |
| src/backend/storage/ipc/procarray.c | 3 | 3 |
| src/backend/storage/large_object/inv_api.c | 8 | 8 |
| src/backend/storage/lmgr/predicate.c | 15 | 15 |
| src/backend/tcop/postgres.c | 2 | 2 |
| src/backend/tcop/pquery.c | 13 | 13 |
| src/backend/utils/adt/acl.c | 1 | 1 |
| src/backend/utils/adt/ri_triggers.c | 6 | 6 |
| src/backend/utils/adt/ruleutils.c | 1 | 1 |
| src/backend/utils/adt/tid.c | 1 | 1 |
| src/backend/utils/adt/xid8funcs.c | 1 | 1 |
| src/backend/utils/init/postinit.c | 1 | 1 |
| src/backend/utils/mmgr/portalmem.c | 2 | 2 |
| src/backend/utils/time/snapmgr.c | 113 | 84 |
| src/include/access/genam.h | 2 | 2 |
| src/include/access/heapam.h | 1 | 1 |
| src/include/access/relscan.h | 3 | 3 |
| src/include/executor/execdesc.h | 4 | 4 |
| src/include/executor/spi.h | 2 | 2 |
| src/include/nodes/execnodes.h | 2 | 2 |
| src/include/replication/reorderbuffer.h | 6 | 6 |
| src/include/replication/snapbuild.h | 3 | 3 |
| src/include/replication/snapbuild_internal.h | 1 | 1 |
| src/include/storage/large_object.h | 1 | 1 |
| src/include/storage/predicate.h | 2 | 2 |
| src/include/storage/procarray.h | 1 | 1 |
| src/include/tcop/pquery.h | 1 | 1 |
| src/include/utils/portal.h | 2 | 2 |
| src/include/utils/snapmgr.h | 17 | 16 |
| src/include/utils/snapshot.h | 113 | 48 |
| src/tools/pgindent/typedefs.list | 4 | 0 |
From 5b48cf9bec8a9f1b0bacde30acf9b28e7e9d34e5 Mon Sep 17 00:00:00 2001
From: Heikki Linnakangas <heikki.linnakangas@iki.fi>
Date: Mon, 6 Jan 2025 23:29:41 +0200
Subject: [PATCH v1 3/3] wip: Split SnapshotData into multiple structs
---
contrib/amcheck/verify_nbtree.c | 6 +-
contrib/pgrowlocks/pgrowlocks.c | 2 +-
src/backend/access/brin/brin.c | 2 +-
src/backend/access/heap/heapam.c | 3 +-
src/backend/access/heap/heapam_handler.c | 16 +-
src/backend/access/heap/heapam_visibility.c | 20 +-
src/backend/access/index/genam.c | 4 +-
src/backend/access/index/indexam.c | 13 +-
src/backend/access/nbtree/nbtinsert.c | 6 +-
src/backend/access/nbtree/nbtsort.c | 2 +-
src/backend/access/table/tableam.c | 11 +-
src/backend/access/transam/parallel.c | 8 +-
src/backend/catalog/index.c | 2 +-
src/backend/catalog/pg_inherits.c | 2 +-
src/backend/catalog/pg_largeobject.c | 2 +-
src/backend/commands/async.c | 8 +-
src/backend/commands/copyto.c | 4 +-
src/backend/commands/createas.c | 2 +-
src/backend/commands/dbcommands.c | 4 +-
src/backend/commands/explain.c | 2 +-
src/backend/commands/indexcmds.c | 16 +-
src/backend/commands/matview.c | 2 +-
src/backend/commands/tablecmds.c | 6 +-
src/backend/commands/trigger.c | 2 +-
src/backend/commands/typecmds.c | 4 +-
src/backend/executor/execIndexing.c | 12 +-
src/backend/executor/execMain.c | 8 +-
src/backend/executor/execParallel.c | 2 +-
src/backend/executor/execReplication.c | 18 +-
src/backend/executor/execUtils.c | 4 +-
src/backend/executor/functions.c | 2 +-
src/backend/executor/nodeBitmapHeapscan.c | 2 +-
src/backend/executor/nodeBitmapIndexscan.c | 2 +-
src/backend/executor/nodeIndexonlyscan.c | 4 +-
src/backend/executor/nodeIndexscan.c | 4 +-
src/backend/executor/nodeLockRows.c | 2 +-
src/backend/executor/nodeModifyTable.c | 18 +-
src/backend/executor/nodeSamplescan.c | 2 +-
src/backend/executor/nodeSeqscan.c | 6 +-
src/backend/executor/nodeTidrangescan.c | 2 +-
src/backend/executor/nodeTidscan.c | 4 +-
src/backend/executor/spi.c | 64 +++---
src/backend/libpq/be-fsstubs.c | 2 +-
src/backend/partitioning/partbounds.c | 2 +-
src/backend/partitioning/partdesc.c | 2 +-
src/backend/replication/logical/decode.c | 2 +-
.../replication/logical/reorderbuffer.c | 76 +++----
src/backend/replication/logical/snapbuild.c | 99 ++++-----
src/backend/replication/walsender.c | 2 +-
src/backend/storage/ipc/procarray.c | 6 +-
src/backend/storage/large_object/inv_api.c | 16 +-
src/backend/storage/lmgr/predicate.c | 30 +--
src/backend/tcop/postgres.c | 4 +-
src/backend/tcop/pquery.c | 26 +--
src/backend/utils/adt/acl.c | 2 +-
src/backend/utils/adt/ri_triggers.c | 12 +-
src/backend/utils/adt/ruleutils.c | 2 +-
src/backend/utils/adt/tid.c | 2 +-
src/backend/utils/adt/xid8funcs.c | 2 +-
src/backend/utils/init/postinit.c | 2 +-
src/backend/utils/mmgr/portalmem.c | 4 +-
src/backend/utils/time/snapmgr.c | 197 ++++++++++--------
src/include/access/genam.h | 4 +-
src/include/access/heapam.h | 2 +-
src/include/access/relscan.h | 6 +-
src/include/executor/execdesc.h | 8 +-
src/include/executor/spi.h | 4 +-
src/include/nodes/execnodes.h | 4 +-
src/include/replication/reorderbuffer.h | 12 +-
src/include/replication/snapbuild.h | 6 +-
src/include/replication/snapbuild_internal.h | 2 +-
src/include/storage/large_object.h | 2 +-
src/include/storage/predicate.h | 4 +-
src/include/storage/procarray.h | 2 +-
src/include/tcop/pquery.h | 2 +-
src/include/utils/portal.h | 4 +-
src/include/utils/snapmgr.h | 33 +--
src/include/utils/snapshot.h | 161 +++++++++-----
src/tools/pgindent/typedefs.list | 4 +
79 files changed, 578 insertions(+), 477 deletions(-)
diff --git a/contrib/amcheck/verify_nbtree.c b/contrib/amcheck/verify_nbtree.c
index 7f7b55d902a..2bf9c3aa903 100644
--- a/contrib/amcheck/verify_nbtree.c
+++ b/contrib/amcheck/verify_nbtree.c
@@ -565,7 +565,7 @@ bt_check_every_level(Relation rel, Relation heaprel, bool heapkeyspace,
*/
if (!state->readonly)
{
- snapshot = RegisterSnapshot(GetTransactionSnapshot());
+ snapshot = (Snapshot) RegisterSnapshot(GetTransactionSnapshot());
/*
* GetTransactionSnapshot() always acquires a new MVCC snapshot in
@@ -582,7 +582,7 @@ bt_check_every_level(Relation rel, Relation heaprel, bool heapkeyspace,
*/
if (IsolationUsesXactSnapshot() && rel->rd_index->indcheckxmin &&
!TransactionIdPrecedes(HeapTupleHeaderGetXmin(rel->rd_indextuple->t_data),
- snapshot->xmin))
+ snapshot->mvcc.xmin))
ereport(ERROR,
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
errmsg("index \"%s\" cannot be verified using transaction snapshot",
@@ -603,7 +603,7 @@ bt_check_every_level(Relation rel, Relation heaprel, bool heapkeyspace,
if (snapshot != SnapshotAny)
state->snapshot = snapshot;
else
- state->snapshot = RegisterSnapshot(GetTransactionSnapshot());
+ state->snapshot = (Snapshot) RegisterSnapshot(GetTransactionSnapshot());
}
}
diff --git a/contrib/pgrowlocks/pgrowlocks.c b/contrib/pgrowlocks/pgrowlocks.c
index 7e40ab21dda..2c5d2964a55 100644
--- a/contrib/pgrowlocks/pgrowlocks.c
+++ b/contrib/pgrowlocks/pgrowlocks.c
@@ -111,7 +111,7 @@ pgrowlocks(PG_FUNCTION_ARGS)
RelationGetRelationName(rel));
/* Scan the relation */
- scan = table_beginscan(rel, GetActiveSnapshot(), 0, NULL);
+ scan = table_beginscan(rel, (Snapshot) GetActiveSnapshot(), 0, NULL);
hscan = (HeapScanDesc) scan;
attinmeta = TupleDescGetAttInMetadata(rsinfo->setDesc);
diff --git a/src/backend/access/brin/brin.c b/src/backend/access/brin/brin.c
index 9a984547578..47dd092fc41 100644
--- a/src/backend/access/brin/brin.c
+++ b/src/backend/access/brin/brin.c
@@ -2393,7 +2393,7 @@ _brin_begin_parallel(BrinBuildState *buildstate, Relation heap, Relation index,
if (!isconcurrent)
snapshot = SnapshotAny;
else
- snapshot = RegisterSnapshot(GetTransactionSnapshot());
+ snapshot = (Snapshot) RegisterSnapshot(GetTransactionSnapshot());
/*
* Estimate size for our own PARALLEL_KEY_BRIN_SHARED workspace.
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 485525f4d64..ab3f07b7ffc 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -536,7 +536,8 @@ heap_prepare_pagescan(TableScanDesc sscan)
* full page write. Until we can prove that beyond doubt, let's check each
* tuple for visibility the hard way.
*/
- all_visible = PageIsAllVisible(page) && !snapshot->takenDuringRecovery;
+ all_visible = PageIsAllVisible(page) &&
+ (snapshot->snapshot_type != SNAPSHOT_MVCC || !snapshot->mvcc.takenDuringRecovery);
check_serializable =
CheckForSerializableConflictOutNeeded(scan->rs_base.rs_rd, snapshot);
diff --git a/src/backend/access/heap/heapam_handler.c b/src/backend/access/heap/heapam_handler.c
index e817f8f8f84..6d537fa6ab8 100644
--- a/src/backend/access/heap/heapam_handler.c
+++ b/src/backend/access/heap/heapam_handler.c
@@ -431,11 +431,11 @@ tuple_lock_retry:
}
/* otherwise xmin should not be dirty... */
- if (TransactionIdIsValid(SnapshotDirty.xmin))
+ if (TransactionIdIsValid(SnapshotDirty.dirty.xmin))
ereport(ERROR,
(errcode(ERRCODE_DATA_CORRUPTED),
errmsg_internal("t_xmin %u is uncommitted in tuple (%u,%u) to be updated in table \"%s\"",
- SnapshotDirty.xmin,
+ SnapshotDirty.dirty.xmin,
ItemPointerGetBlockNumber(&tuple->t_self),
ItemPointerGetOffsetNumber(&tuple->t_self),
RelationGetRelationName(relation))));
@@ -444,23 +444,23 @@ tuple_lock_retry:
* If tuple is being updated by other transaction then we
* have to wait for its commit/abort, or die trying.
*/
- if (TransactionIdIsValid(SnapshotDirty.xmax))
+ if (TransactionIdIsValid(SnapshotDirty.dirty.xmax))
{
ReleaseBuffer(buffer);
switch (wait_policy)
{
case LockWaitBlock:
- XactLockTableWait(SnapshotDirty.xmax,
+ XactLockTableWait(SnapshotDirty.dirty.xmax,
relation, &tuple->t_self,
XLTW_FetchUpdated);
break;
case LockWaitSkip:
- if (!ConditionalXactLockTableWait(SnapshotDirty.xmax))
+ if (!ConditionalXactLockTableWait(SnapshotDirty.dirty.xmax))
/* skip instead of waiting */
return TM_WouldBlock;
break;
case LockWaitError:
- if (!ConditionalXactLockTableWait(SnapshotDirty.xmax))
+ if (!ConditionalXactLockTableWait(SnapshotDirty.dirty.xmax))
ereport(ERROR,
(errcode(ERRCODE_LOCK_NOT_AVAILABLE),
errmsg("could not obtain lock on row in relation \"%s\"",
@@ -1250,7 +1250,7 @@ heapam_index_build_range_scan(Relation heapRelation,
*/
if (!TransactionIdIsValid(OldestXmin))
{
- snapshot = RegisterSnapshot(GetTransactionSnapshot());
+ snapshot = (Snapshot) RegisterSnapshot(GetTransactionSnapshot());
need_unregister_snapshot = true;
}
else
@@ -2440,7 +2440,7 @@ heapam_scan_sample_next_tuple(TableScanDesc scan, SampleScanState *scanstate,
page = (Page) BufferGetPage(hscan->rs_cbuf);
all_visible = PageIsAllVisible(page) &&
- !scan->rs_snapshot->takenDuringRecovery;
+ (scan->rs_snapshot->snapshot_type != SNAPSHOT_MVCC || !scan->rs_snapshot->mvcc.takenDuringRecovery);
maxoffset = PageGetMaxOffsetNumber(page);
for (;;)
diff --git a/src/backend/access/heap/heapam_visibility.c b/src/backend/access/heap/heapam_visibility.c
index e146605bd57..9d7d1abd929 100644
--- a/src/backend/access/heap/heapam_visibility.c
+++ b/src/backend/access/heap/heapam_visibility.c
@@ -740,7 +740,7 @@ HeapTupleSatisfiesUpdate(HeapTuple htup, CommandId curcid,
* token is also returned in snapshot->speculativeToken.
*/
static bool
-HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot,
+HeapTupleSatisfiesDirty(HeapTuple htup, DirtySnapshotData *snapshot,
Buffer buffer)
{
HeapTupleHeader tuple = htup->t_data;
@@ -957,7 +957,7 @@ HeapTupleSatisfiesDirty(HeapTuple htup, Snapshot snapshot,
* and more contention on ProcArrayLock.
*/
static bool
-HeapTupleSatisfiesMVCC(HeapTuple htup, Snapshot snapshot,
+HeapTupleSatisfiesMVCC(HeapTuple htup, MVCCSnapshot snapshot,
Buffer buffer)
{
HeapTupleHeader tuple = htup->t_data;
@@ -1426,7 +1426,7 @@ HeapTupleSatisfiesVacuumHorizon(HeapTuple htup, Buffer buffer, TransactionId *de
* snapshot->vistest must have been set up with the horizon to use.
*/
static bool
-HeapTupleSatisfiesNonVacuumable(HeapTuple htup, Snapshot snapshot,
+HeapTupleSatisfiesNonVacuumable(HeapTuple htup, NonVacuumableSnapshotData *snapshot,
Buffer buffer)
{
TransactionId dead_after = InvalidTransactionId;
@@ -1584,7 +1584,7 @@ TransactionIdInArray(TransactionId xid, TransactionId *xip, Size num)
* complicated than when dealing "only" with the present.
*/
static bool
-HeapTupleSatisfiesHistoricMVCC(HeapTuple htup, Snapshot snapshot,
+HeapTupleSatisfiesHistoricMVCC(HeapTuple htup, HistoricMVCCSnapshot snapshot,
Buffer buffer)
{
HeapTupleHeader tuple = htup->t_data;
@@ -1660,7 +1660,7 @@ HeapTupleSatisfiesHistoricMVCC(HeapTuple htup, Snapshot snapshot,
return false;
}
/* check if it's a committed transaction in [xmin, xmax) */
- else if (TransactionIdInArray(xmin, snapshot->xip, snapshot->xcnt))
+ else if (TransactionIdInArray(xmin, snapshot->committed_xids, snapshot->xcnt))
{
/* fall through */
}
@@ -1746,7 +1746,7 @@ HeapTupleSatisfiesHistoricMVCC(HeapTuple htup, Snapshot snapshot,
else if (TransactionIdFollowsOrEquals(xmax, snapshot->xmax))
return true;
/* xmax is between [xmin, xmax), check known committed array */
- else if (TransactionIdInArray(xmax, snapshot->xip, snapshot->xcnt))
+ else if (TransactionIdInArray(xmax, snapshot->committed_xids, snapshot->xcnt))
return false;
/* xmax is between [xmin, xmax), but known not to have committed yet */
else
@@ -1769,7 +1769,7 @@ HeapTupleSatisfiesVisibility(HeapTuple htup, Snapshot snapshot, Buffer buffer)
switch (snapshot->snapshot_type)
{
case SNAPSHOT_MVCC:
- return HeapTupleSatisfiesMVCC(htup, snapshot, buffer);
+ return HeapTupleSatisfiesMVCC(htup, &snapshot->mvcc, buffer);
case SNAPSHOT_SELF:
return HeapTupleSatisfiesSelf(htup, snapshot, buffer);
case SNAPSHOT_ANY:
@@ -1777,11 +1777,11 @@ HeapTupleSatisfiesVisibility(HeapTuple htup, Snapshot snapshot, Buffer buffer)
case SNAPSHOT_TOAST:
return HeapTupleSatisfiesToast(htup, snapshot, buffer);
case SNAPSHOT_DIRTY:
- return HeapTupleSatisfiesDirty(htup, snapshot, buffer);
+ return HeapTupleSatisfiesDirty(htup, &snapshot->dirty, buffer);
case SNAPSHOT_HISTORIC_MVCC:
- return HeapTupleSatisfiesHistoricMVCC(htup, snapshot, buffer);
+ return HeapTupleSatisfiesHistoricMVCC(htup, &snapshot->historic_mvcc, buffer);
case SNAPSHOT_NON_VACUUMABLE:
- return HeapTupleSatisfiesNonVacuumable(htup, snapshot, buffer);
+ return HeapTupleSatisfiesNonVacuumable(htup, &snapshot->nonvacuumable, buffer);
}
return false; /* keep compiler quiet */
diff --git a/src/backend/access/index/genam.c b/src/backend/access/index/genam.c
index 07bae342e25..9d1312abbd0 100644
--- a/src/backend/access/index/genam.c
+++ b/src/backend/access/index/genam.c
@@ -410,7 +410,7 @@ systable_beginscan(Relation heapRelation,
{
Oid relid = RelationGetRelid(heapRelation);
- snapshot = RegisterSnapshot(GetCatalogSnapshot(relid));
+ snapshot = RegisterCatalogSnapshot(GetCatalogSnapshot(relid));
sysscan->snapshot = snapshot;
}
else
@@ -680,7 +680,7 @@ systable_beginscan_ordered(Relation heapRelation,
{
Oid relid = RelationGetRelid(heapRelation);
- snapshot = RegisterSnapshot(GetCatalogSnapshot(relid));
+ snapshot = RegisterCatalogSnapshot(GetCatalogSnapshot(relid));
sysscan->snapshot = snapshot;
}
else
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index 8b1f555435b..0bcf06ea68b 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -451,12 +451,10 @@ index_restrpos(IndexScanDesc scan)
*/
Size
index_parallelscan_estimate(Relation indexRelation, int nkeys, int norderbys,
- Snapshot snapshot)
+ MVCCSnapshot snapshot)
{
Size nbytes;
- Assert(snapshot != InvalidSnapshot);
-
RELATION_CHECKS;
nbytes = offsetof(ParallelIndexScanDescData, ps_snapshot_data);
@@ -488,12 +486,10 @@ index_parallelscan_estimate(Relation indexRelation, int nkeys, int norderbys,
*/
void
index_parallelscan_initialize(Relation heapRelation, Relation indexRelation,
- Snapshot snapshot, ParallelIndexScanDesc target)
+ MVCCSnapshot snapshot, ParallelIndexScanDesc target)
{
Size offset;
- Assert(snapshot != InvalidSnapshot);
-
RELATION_CHECKS;
offset = add_size(offsetof(ParallelIndexScanDescData, ps_snapshot_data),
@@ -541,14 +537,15 @@ IndexScanDesc
index_beginscan_parallel(Relation heaprel, Relation indexrel, int nkeys,
int norderbys, ParallelIndexScanDesc pscan)
{
+ MVCCSnapshot mvccsnapshot;
Snapshot snapshot;
IndexScanDesc scan;
Assert(RelFileLocatorEquals(heaprel->rd_locator, pscan->ps_locator));
Assert(RelFileLocatorEquals(indexrel->rd_locator, pscan->ps_indexlocator));
- snapshot = RestoreSnapshot(pscan->ps_snapshot_data);
- RegisterSnapshot(snapshot);
+ mvccsnapshot = RestoreSnapshot(pscan->ps_snapshot_data);
+ snapshot = (Snapshot) RegisterSnapshot(mvccsnapshot);
scan = index_beginscan_internal(indexrel, nkeys, norderbys, snapshot,
pscan, true);
diff --git a/src/backend/access/nbtree/nbtinsert.c b/src/backend/access/nbtree/nbtinsert.c
index 3eddbcf3a82..d8b26072012 100644
--- a/src/backend/access/nbtree/nbtinsert.c
+++ b/src/backend/access/nbtree/nbtinsert.c
@@ -583,15 +583,15 @@ _bt_check_unique(Relation rel, BTInsertState insertstate, Relation heapRel,
* If this tuple is being updated by other transaction
* then we have to wait for its commit/abort.
*/
- xwait = (TransactionIdIsValid(SnapshotDirty.xmin)) ?
- SnapshotDirty.xmin : SnapshotDirty.xmax;
+ xwait = (TransactionIdIsValid(SnapshotDirty.dirty.xmin)) ?
+ SnapshotDirty.dirty.xmin : SnapshotDirty.dirty.xmax;
if (TransactionIdIsValid(xwait))
{
if (nbuf != InvalidBuffer)
_bt_relbuf(rel, nbuf);
/* Tell _bt_doinsert to wait... */
- *speculativeToken = SnapshotDirty.speculativeToken;
+ *speculativeToken = SnapshotDirty.dirty.speculativeToken;
/* Caller releases lock on buf immediately */
insertstate->bounds_valid = false;
return xwait;
diff --git a/src/backend/access/nbtree/nbtsort.c b/src/backend/access/nbtree/nbtsort.c
index 7aba852db90..956d073988c 100644
--- a/src/backend/access/nbtree/nbtsort.c
+++ b/src/backend/access/nbtree/nbtsort.c
@@ -1437,7 +1437,7 @@ _bt_begin_parallel(BTBuildState *buildstate, bool isconcurrent, int request)
if (!isconcurrent)
snapshot = SnapshotAny;
else
- snapshot = RegisterSnapshot(GetTransactionSnapshot());
+ snapshot = (Snapshot) RegisterSnapshot(GetTransactionSnapshot());
/*
* Estimate size for our own PARALLEL_KEY_BTREE_SHARED workspace, and
diff --git a/src/backend/access/table/tableam.c b/src/backend/access/table/tableam.c
index e18a8f8250f..a4175ec7c88 100644
--- a/src/backend/access/table/tableam.c
+++ b/src/backend/access/table/tableam.c
@@ -114,7 +114,7 @@ table_beginscan_catalog(Relation relation, int nkeys, struct ScanKeyData *key)
uint32 flags = SO_TYPE_SEQSCAN |
SO_ALLOW_STRAT | SO_ALLOW_SYNC | SO_ALLOW_PAGEMODE | SO_TEMP_SNAPSHOT;
Oid relid = RelationGetRelid(relation);
- Snapshot snapshot = RegisterSnapshot(GetCatalogSnapshot(relid));
+ Snapshot snapshot = RegisterCatalogSnapshot(GetCatalogSnapshot(relid));
return relation->rd_tableam->scan_begin(relation, snapshot, nkeys, key,
NULL, flags);
@@ -132,7 +132,7 @@ table_parallelscan_estimate(Relation rel, Snapshot snapshot)
Size sz = 0;
if (IsMVCCSnapshot(snapshot))
- sz = add_size(sz, EstimateSnapshotSpace(snapshot));
+ sz = add_size(sz, EstimateSnapshotSpace(&snapshot->mvcc));
else
Assert(snapshot == SnapshotAny);
@@ -151,7 +151,7 @@ table_parallelscan_initialize(Relation rel, ParallelTableScanDesc pscan,
if (IsMVCCSnapshot(snapshot))
{
- SerializeSnapshot(snapshot, (char *) pscan + pscan->phs_snapshot_off);
+ SerializeSnapshot(&snapshot->mvcc, (char *) pscan + pscan->phs_snapshot_off);
pscan->phs_snapshot_any = false;
}
else
@@ -164,6 +164,7 @@ table_parallelscan_initialize(Relation rel, ParallelTableScanDesc pscan,
TableScanDesc
table_beginscan_parallel(Relation relation, ParallelTableScanDesc pscan)
{
+ MVCCSnapshot mvccsnapshot;
Snapshot snapshot;
uint32 flags = SO_TYPE_SEQSCAN |
SO_ALLOW_STRAT | SO_ALLOW_SYNC | SO_ALLOW_PAGEMODE;
@@ -173,8 +174,8 @@ table_beginscan_parallel(Relation relation, ParallelTableScanDesc pscan)
if (!pscan->phs_snapshot_any)
{
/* Snapshot was serialized -- restore it */
- snapshot = RestoreSnapshot((char *) pscan + pscan->phs_snapshot_off);
- RegisterSnapshot(snapshot);
+ mvccsnapshot = RestoreSnapshot((char *) pscan + pscan->phs_snapshot_off);
+ snapshot = (Snapshot) RegisterSnapshot(mvccsnapshot);
flags |= SO_TEMP_SNAPSHOT;
}
else
diff --git a/src/backend/access/transam/parallel.c b/src/backend/access/transam/parallel.c
index 7817bedc2ef..fa0cb9d7543 100644
--- a/src/backend/access/transam/parallel.c
+++ b/src/backend/access/transam/parallel.c
@@ -222,8 +222,8 @@ InitializeParallelDSM(ParallelContext *pcxt)
int i;
FixedParallelState *fps;
dsm_handle session_dsm_handle = DSM_HANDLE_INVALID;
- Snapshot transaction_snapshot = GetTransactionSnapshot();
- Snapshot active_snapshot = GetActiveSnapshot();
+ MVCCSnapshot transaction_snapshot = GetTransactionSnapshot();
+ MVCCSnapshot active_snapshot = GetActiveSnapshot();
/* We might be running in a very short-lived memory context. */
oldcontext = MemoryContextSwitchTo(TopTransactionContext);
@@ -1309,8 +1309,8 @@ ParallelWorkerMain(Datum main_arg)
char *uncommittedenumsspace;
char *clientconninfospace;
char *session_dsm_handle_space;
- Snapshot tsnapshot;
- Snapshot asnapshot;
+ MVCCSnapshot tsnapshot;
+ MVCCSnapshot asnapshot;
/* Set flag to indicate that we're initializing a parallel worker. */
InitializingParallelWorker = true;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 221fbb4e286..5b11109e332 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -3200,7 +3200,7 @@ IndexCheckExclusion(Relation heapRelation,
/*
* Scan all live tuples in the base relation.
*/
- snapshot = RegisterSnapshot(GetLatestSnapshot());
+ snapshot = (Snapshot) RegisterSnapshot(GetLatestSnapshot());
scan = table_beginscan_strat(heapRelation, /* relation */
snapshot, /* snapshot */
0, /* number of keys */
diff --git a/src/backend/catalog/pg_inherits.c b/src/backend/catalog/pg_inherits.c
index 929bb53b620..af5876c8608 100644
--- a/src/backend/catalog/pg_inherits.c
+++ b/src/backend/catalog/pg_inherits.c
@@ -143,7 +143,7 @@ find_inheritance_children_extended(Oid parentrelId, bool omit_detached,
if (omit_detached && ActiveSnapshotSet())
{
TransactionId xmin;
- Snapshot snap;
+ MVCCSnapshot snap;
xmin = HeapTupleHeaderGetXmin(inheritsTuple->t_data);
snap = GetActiveSnapshot();
diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c
index 0a477a8e8a9..a082796c0c7 100644
--- a/src/backend/catalog/pg_largeobject.c
+++ b/src/backend/catalog/pg_largeobject.c
@@ -177,7 +177,7 @@ LargeObjectExistsWithSnapshot(Oid loid, Snapshot snapshot)
sd = systable_beginscan(pg_lo_meta,
LargeObjectMetadataOidIndexId, true,
- snapshot, 1, skey);
+ (Snapshot) snapshot, 1, skey);
tuple = systable_getnext(sd);
if (HeapTupleIsValid(tuple))
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index 4bd37d5beb5..b6489c19681 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -449,7 +449,7 @@ static void asyncQueueReadAllNotifications(void);
static bool asyncQueueProcessPageEntries(volatile QueuePosition *current,
QueuePosition stop,
char *page_buffer,
- Snapshot snapshot);
+ MVCCSnapshot snapshot);
static void asyncQueueAdvanceTail(void);
static void ProcessIncomingNotify(bool flush);
static bool AsyncExistsPendingNotify(Notification *n);
@@ -1852,7 +1852,7 @@ asyncQueueReadAllNotifications(void)
{
volatile QueuePosition pos;
QueuePosition head;
- Snapshot snapshot;
+ MVCCSnapshot snapshot;
/* page_buffer must be adequately aligned, so use a union */
union
@@ -1993,7 +1993,7 @@ asyncQueueReadAllNotifications(void)
PG_END_TRY();
/* Done with snapshot */
- UnregisterSnapshot(snapshot);
+ UnregisterSnapshot((Snapshot) snapshot);
}
/*
@@ -2016,7 +2016,7 @@ static bool
asyncQueueProcessPageEntries(volatile QueuePosition *current,
QueuePosition stop,
char *page_buffer,
- Snapshot snapshot)
+ MVCCSnapshot snapshot)
{
bool reachedStop = false;
bool reachedEndOfPage;
diff --git a/src/backend/commands/copyto.c b/src/backend/commands/copyto.c
index 99cb23cb347..3b74cbcb432 100644
--- a/src/backend/commands/copyto.c
+++ b/src/backend/commands/copyto.c
@@ -558,7 +558,7 @@ BeginCopyTo(ParseState *pstate,
/* Create a QueryDesc requesting no output */
cstate->queryDesc = CreateQueryDesc(plan, pstate->p_sourcetext,
GetActiveSnapshot(),
- InvalidSnapshot,
+ InvalidMVCCSnapshot,
dest, NULL, NULL, 0);
/*
@@ -852,7 +852,7 @@ DoCopyTo(CopyToState cstate)
TupleTableSlot *slot;
TableScanDesc scandesc;
- scandesc = table_beginscan(cstate->rel, GetActiveSnapshot(), 0, NULL);
+ scandesc = table_beginscan(cstate->rel, (Snapshot) GetActiveSnapshot(), 0, NULL);
slot = table_slot_create(cstate->rel, NULL);
processed = 0;
diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c
index 23cecd99c9e..74d6caaa4a6 100644
--- a/src/backend/commands/createas.c
+++ b/src/backend/commands/createas.c
@@ -333,7 +333,7 @@ ExecCreateTableAs(ParseState *pstate, CreateTableAsStmt *stmt,
/* Create a QueryDesc, redirecting output to our tuple receiver */
queryDesc = CreateQueryDesc(plan, pstate->p_sourcetext,
- GetActiveSnapshot(), InvalidSnapshot,
+ GetActiveSnapshot(), InvalidMVCCSnapshot,
dest, params, queryEnv, 0);
/* call ExecutorStart to prepare the plan for execution */
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 46310add459..35ad13af985 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -257,7 +257,7 @@ ScanSourceDatabasePgClass(Oid tbid, Oid dbid, char *srcpath)
Page page;
List *rlocatorlist = NIL;
LockRelId relid;
- Snapshot snapshot;
+ MVCCSnapshot snapshot;
SMgrRelation smgr;
BufferAccessStrategy bstrategy;
@@ -309,7 +309,7 @@ ScanSourceDatabasePgClass(Oid tbid, Oid dbid, char *srcpath)
/* Append relevant pg_class tuples for current page to rlocatorlist. */
rlocatorlist = ScanSourceDatabasePgClassPage(page, buf, tbid, dbid,
srcpath, rlocatorlist,
- snapshot);
+ (Snapshot) snapshot);
UnlockReleaseBuffer(buf);
}
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index c24e66f82e1..d77e1e5c04b 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -698,7 +698,7 @@ ExplainOnePlan(PlannedStmt *plannedstmt, IntoClause *into, ExplainState *es,
/* Create a QueryDesc for the query */
queryDesc = CreateQueryDesc(plannedstmt, queryString,
- GetActiveSnapshot(), InvalidSnapshot,
+ GetActiveSnapshot(), InvalidMVCCSnapshot,
dest, params, queryEnv, instrument_option);
/* Select execution options */
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index d6e23caef17..c5f23ced82d 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -587,7 +587,7 @@ DefineIndex(Oid tableId,
LockRelId heaprelid;
LOCKTAG heaplocktag;
LOCKMODE lockmode;
- Snapshot snapshot;
+ MVCCSnapshot snapshot;
Oid root_save_userid;
int root_save_sec_context;
int root_save_nestlevel;
@@ -1722,13 +1722,13 @@ DefineIndex(Oid tableId,
* We also set ActiveSnapshot to this snap, since functions in indexes may
* need a snapshot.
*/
- snapshot = RegisterSnapshot(GetTransactionSnapshot());
+ snapshot = (MVCCSnapshot) RegisterSnapshot(GetTransactionSnapshot());
PushActiveSnapshot(snapshot);
/*
* Scan the index and the heap, insert any missing index entries.
*/
- validate_index(tableId, indexRelationId, snapshot);
+ validate_index(tableId, indexRelationId, (Snapshot) snapshot);
/*
* Drop the reference snapshot. We must do this before waiting out other
@@ -1740,7 +1740,7 @@ DefineIndex(Oid tableId,
limitXmin = snapshot->xmin;
PopActiveSnapshot();
- UnregisterSnapshot(snapshot);
+ UnregisterSnapshot((Snapshot) snapshot);
/*
* The snapshot subsystem could still contain registered snapshots that
@@ -4128,7 +4128,7 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
{
ReindexIndexInfo *newidx = lfirst(lc);
TransactionId limitXmin;
- Snapshot snapshot;
+ MVCCSnapshot snapshot;
StartTransactionCommand();
@@ -4147,7 +4147,7 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
* Take the "reference snapshot" that will be used by validate_index()
* to filter candidate tuples.
*/
- snapshot = RegisterSnapshot(GetTransactionSnapshot());
+ snapshot = (MVCCSnapshot) RegisterSnapshot(GetTransactionSnapshot());
PushActiveSnapshot(snapshot);
/*
@@ -4161,7 +4161,7 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
progress_vals[3] = newidx->amId;
pgstat_progress_update_multi_param(4, progress_index, progress_vals);
- validate_index(newidx->tableId, newidx->indexId, snapshot);
+ validate_index(newidx->tableId, newidx->indexId, (Snapshot) snapshot);
/*
* We can now do away with our active snapshot, we still need to save
@@ -4170,7 +4170,7 @@ ReindexRelationConcurrently(const ReindexStmt *stmt, Oid relationOid, const Rein
limitXmin = snapshot->xmin;
PopActiveSnapshot();
- UnregisterSnapshot(snapshot);
+ UnregisterSnapshot((Snapshot) snapshot);
/*
* To ensure no deadlocks, we must commit and start yet another
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index 4b3d4822872..33783cf6050 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -439,7 +439,7 @@ refresh_matview_datafill(DestReceiver *dest, Query *query,
/* Create a QueryDesc, redirecting output to our tuple receiver */
queryDesc = CreateQueryDesc(plan, queryString,
- GetActiveSnapshot(), InvalidSnapshot,
+ GetActiveSnapshot(), InvalidMVCCSnapshot,
dest, NULL, NULL, 0);
/* call ExecutorStart to prepare the plan for execution */
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 33ea619224b..2f7e87ab111 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -6222,7 +6222,7 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
* Scan through the rows, generating a new row if needed and then
* checking all the constraints.
*/
- snapshot = RegisterSnapshot(GetLatestSnapshot());
+ snapshot = (Snapshot) RegisterSnapshot(GetLatestSnapshot());
scan = table_beginscan(oldrel, snapshot, 0, NULL);
/*
@@ -12565,7 +12565,7 @@ validateForeignKeyConstraint(char *conname,
* if that tuple had just been inserted. If any of those fail, it should
* ereport(ERROR) and that's that.
*/
- snapshot = RegisterSnapshot(GetLatestSnapshot());
+ snapshot = (Snapshot) RegisterSnapshot(GetLatestSnapshot());
slot = table_slot_create(rel, NULL);
scan = table_beginscan(rel, snapshot, 0, NULL);
@@ -20132,7 +20132,7 @@ ATExecDetachPartitionFinalize(Relation rel, RangeVar *name)
{
Relation partRel;
ObjectAddress address;
- Snapshot snap = GetActiveSnapshot();
+ MVCCSnapshot snap = GetActiveSnapshot();
partRel = table_openrv(name, AccessExclusiveLock);
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 32f25f4d911..709b1feb178 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -3312,7 +3312,7 @@ GetTupleForTrigger(EState *estate,
*/
if (!IsolationUsesXactSnapshot())
lockflags |= TUPLE_LOCK_FLAG_FIND_LAST_VERSION;
- test = table_tuple_lock(relation, tid, estate->es_snapshot, oldslot,
+ test = table_tuple_lock(relation, tid, (Snapshot) estate->es_snapshot, oldslot,
estate->es_output_cid,
lockmode, LockWaitBlock,
lockflags,
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 6b1d2383514..beb459c6dd0 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -3171,7 +3171,7 @@ validateDomainNotNullConstraint(Oid domainoid)
Snapshot snapshot;
/* Scan all tuples in this relation */
- snapshot = RegisterSnapshot(GetLatestSnapshot());
+ snapshot = (Snapshot) RegisterSnapshot(GetLatestSnapshot());
scan = table_beginscan(testrel, snapshot, 0, NULL);
slot = table_slot_create(testrel, NULL);
while (table_scan_getnextslot(scan, ForwardScanDirection, slot))
@@ -3247,7 +3247,7 @@ validateDomainCheckConstraint(Oid domainoid, const char *ccbin)
Snapshot snapshot;
/* Scan all tuples in this relation */
- snapshot = RegisterSnapshot(GetLatestSnapshot());
+ snapshot = (Snapshot) RegisterSnapshot(GetLatestSnapshot());
scan = table_beginscan(testrel, snapshot, 0, NULL);
slot = table_slot_create(testrel, NULL);
while (table_scan_getnextslot(scan, ForwardScanDirection, slot))
diff --git a/src/backend/executor/execIndexing.c b/src/backend/executor/execIndexing.c
index 7c87f012c30..6942b148dd8 100644
--- a/src/backend/executor/execIndexing.c
+++ b/src/backend/executor/execIndexing.c
@@ -863,21 +863,21 @@ retry:
* happen often enough to be worth trying harder, and anyway we don't
* want to hold any index internal locks while waiting.
*/
- xwait = TransactionIdIsValid(DirtySnapshot.xmin) ?
- DirtySnapshot.xmin : DirtySnapshot.xmax;
+ xwait = TransactionIdIsValid(DirtySnapshot.dirty.xmin) ?
+ DirtySnapshot.dirty.xmin : DirtySnapshot.dirty.xmax;
if (TransactionIdIsValid(xwait) &&
(waitMode == CEOUC_WAIT ||
(waitMode == CEOUC_LIVELOCK_PREVENTING_WAIT &&
- DirtySnapshot.speculativeToken &&
+ DirtySnapshot.dirty.speculativeToken &&
TransactionIdPrecedes(GetCurrentTransactionId(), xwait))))
{
reason_wait = indexInfo->ii_ExclusionOps ?
XLTW_RecheckExclusionConstr : XLTW_InsertIndex;
index_endscan(index_scan);
- if (DirtySnapshot.speculativeToken)
- SpeculativeInsertionWait(DirtySnapshot.xmin,
- DirtySnapshot.speculativeToken);
+ if (DirtySnapshot.dirty.speculativeToken)
+ SpeculativeInsertionWait(DirtySnapshot.dirty.xmin,
+ DirtySnapshot.dirty.speculativeToken);
else
XactLockTableWait(xwait, heap,
&existing_slot->tts_tid, reason_wait);
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index a06295b6ba7..613a545d0a0 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -239,8 +239,8 @@ standard_ExecutorStart(QueryDesc *queryDesc, int eflags)
/*
* Copy other important information into the EState
*/
- estate->es_snapshot = RegisterSnapshot(queryDesc->snapshot);
- estate->es_crosscheck_snapshot = RegisterSnapshot(queryDesc->crosscheck_snapshot);
+ estate->es_snapshot = (MVCCSnapshot) RegisterSnapshot(queryDesc->snapshot);
+ estate->es_crosscheck_snapshot = (MVCCSnapshot) RegisterSnapshot(queryDesc->crosscheck_snapshot);
estate->es_top_eflags = eflags;
estate->es_instrument = queryDesc->instrument_options;
estate->es_jit_flags = queryDesc->plannedstmt->jitFlags;
@@ -501,8 +501,8 @@ standard_ExecutorEnd(QueryDesc *queryDesc)
ExecEndPlan(queryDesc->planstate, estate);
/* do away with our snapshots */
- UnregisterSnapshot(estate->es_snapshot);
- UnregisterSnapshot(estate->es_crosscheck_snapshot);
+ UnregisterSnapshot((Snapshot) estate->es_snapshot);
+ UnregisterSnapshot((Snapshot) estate->es_crosscheck_snapshot);
/*
* Must switch out of context before destroying it
diff --git a/src/backend/executor/execParallel.c b/src/backend/executor/execParallel.c
index ff4d9dd1bb3..3683aa3c232 100644
--- a/src/backend/executor/execParallel.c
+++ b/src/backend/executor/execParallel.c
@@ -1259,7 +1259,7 @@ ExecParallelGetQueryDesc(shm_toc *toc, DestReceiver *receiver,
/* Create a QueryDesc for the query. */
return CreateQueryDesc(pstmt,
queryString,
- GetActiveSnapshot(), InvalidSnapshot,
+ GetActiveSnapshot(), InvalidMVCCSnapshot,
receiver, paramLI, NULL, instrument_options);
}
diff --git a/src/backend/executor/execReplication.c b/src/backend/executor/execReplication.c
index e3e4e41ac38..45eacdad96f 100644
--- a/src/backend/executor/execReplication.c
+++ b/src/backend/executor/execReplication.c
@@ -259,8 +259,8 @@ retry:
ExecMaterializeSlot(outslot);
- xwait = TransactionIdIsValid(snap.xmin) ?
- snap.xmin : snap.xmax;
+ xwait = TransactionIdIsValid(snap.dirty.xmin) ?
+ snap.dirty.xmin : snap.dirty.xmax;
/*
* If the tuple is locked, wait for locking transaction to finish and
@@ -285,7 +285,7 @@ retry:
PushActiveSnapshot(GetLatestSnapshot());
- res = table_tuple_lock(rel, &(outslot->tts_tid), GetLatestSnapshot(),
+ res = table_tuple_lock(rel, &(outslot->tts_tid), (Snapshot) GetActiveSnapshot(),
outslot,
GetCurrentCommandId(false),
lockmode,
@@ -418,8 +418,8 @@ retry:
found = true;
ExecCopySlot(outslot, scanslot);
- xwait = TransactionIdIsValid(snap.xmin) ?
- snap.xmin : snap.xmax;
+ xwait = TransactionIdIsValid(snap.dirty.xmin) ?
+ snap.dirty.xmin : snap.dirty.xmax;
/*
* If the tuple is locked, wait for locking transaction to finish and
@@ -443,7 +443,7 @@ retry:
PushActiveSnapshot(GetLatestSnapshot());
- res = table_tuple_lock(rel, &(outslot->tts_tid), GetLatestSnapshot(),
+ res = table_tuple_lock(rel, &(outslot->tts_tid), (Snapshot) GetLatestSnapshot(),
outslot,
GetCurrentCommandId(false),
lockmode,
@@ -500,7 +500,7 @@ retry:
PushActiveSnapshot(GetLatestSnapshot());
- res = table_tuple_lock(rel, &conflictTid, GetLatestSnapshot(),
+ res = table_tuple_lock(rel, &conflictTid, (Snapshot) GetLatestSnapshot(),
*conflictslot,
GetCurrentCommandId(false),
LockTupleShare,
@@ -687,7 +687,7 @@ ExecSimpleRelationUpdate(ResultRelInfo *resultRelInfo,
if (rel->rd_rel->relispartition)
ExecPartitionCheck(resultRelInfo, slot, estate, true);
- simple_table_tuple_update(rel, tid, slot, estate->es_snapshot,
+ simple_table_tuple_update(rel, tid, slot, (Snapshot) estate->es_snapshot,
&update_indexes);
conflictindexes = resultRelInfo->ri_onConflictArbiterIndexes;
@@ -746,7 +746,7 @@ ExecSimpleRelationDelete(ResultRelInfo *resultRelInfo,
if (!skip_tuple)
{
/* OK, delete the tuple */
- simple_table_tuple_delete(rel, tid, estate->es_snapshot);
+ simple_table_tuple_delete(rel, tid, (Snapshot) estate->es_snapshot);
/* AFTER ROW DELETE Triggers */
ExecARDeleteTriggers(estate, resultRelInfo,
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index f71899463b8..494dfbc015d 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -110,8 +110,8 @@ CreateExecutorState(void)
* Initialize all fields of the Executor State structure
*/
estate->es_direction = ForwardScanDirection;
- estate->es_snapshot = InvalidSnapshot; /* caller must initialize this */
- estate->es_crosscheck_snapshot = InvalidSnapshot; /* no crosscheck */
+ estate->es_snapshot = InvalidMVCCSnapshot; /* caller must initialize this */
+ estate->es_crosscheck_snapshot = InvalidMVCCSnapshot; /* no crosscheck */
estate->es_range_table = NIL;
estate->es_range_table_size = 0;
estate->es_relations = NULL;
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index 757f8068e21..6733f06b3fe 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -842,7 +842,7 @@ postquel_start(execution_state *es, SQLFunctionCachePtr fcache)
es->qd = CreateQueryDesc(es->stmt,
fcache->src,
GetActiveSnapshot(),
- InvalidSnapshot,
+ InvalidMVCCSnapshot,
dest,
fcache->paramLI,
es->qd ? es->qd->queryEnv : NULL,
diff --git a/src/backend/executor/nodeBitmapHeapscan.c b/src/backend/executor/nodeBitmapHeapscan.c
index be616683f98..f8b20c12bb8 100644
--- a/src/backend/executor/nodeBitmapHeapscan.c
+++ b/src/backend/executor/nodeBitmapHeapscan.c
@@ -172,7 +172,7 @@ BitmapHeapNext(BitmapHeapScanState *node)
node->ss.ps.plan->targetlist != NIL);
scan = table_beginscan_bm(node->ss.ss_currentRelation,
- node->ss.ps.state->es_snapshot,
+ (Snapshot) node->ss.ps.state->es_snapshot,
0,
NULL,
need_tuples);
diff --git a/src/backend/executor/nodeBitmapIndexscan.c b/src/backend/executor/nodeBitmapIndexscan.c
index d3ef5a00040..54def3c4c94 100644
--- a/src/backend/executor/nodeBitmapIndexscan.c
+++ b/src/backend/executor/nodeBitmapIndexscan.c
@@ -301,7 +301,7 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate, int eflags)
*/
indexstate->biss_ScanDesc =
index_beginscan_bitmap(indexstate->biss_RelationDesc,
- estate->es_snapshot,
+ (Snapshot) estate->es_snapshot,
indexstate->biss_NumScanKeys);
/*
diff --git a/src/backend/executor/nodeIndexonlyscan.c b/src/backend/executor/nodeIndexonlyscan.c
index e6635233155..1809571e3f6 100644
--- a/src/backend/executor/nodeIndexonlyscan.c
+++ b/src/backend/executor/nodeIndexonlyscan.c
@@ -91,7 +91,7 @@ IndexOnlyNext(IndexOnlyScanState *node)
*/
scandesc = index_beginscan(node->ss.ss_currentRelation,
node->ioss_RelationDesc,
- estate->es_snapshot,
+ (Snapshot) estate->es_snapshot,
node->ioss_NumScanKeys,
node->ioss_NumOrderByKeys);
@@ -245,7 +245,7 @@ IndexOnlyNext(IndexOnlyScanState *node)
if (!tuple_from_heap)
PredicateLockPage(scandesc->heapRelation,
ItemPointerGetBlockNumber(tid),
- estate->es_snapshot);
+ (Snapshot) estate->es_snapshot);
return slot;
}
diff --git a/src/backend/executor/nodeIndexscan.c b/src/backend/executor/nodeIndexscan.c
index 865aba08e8a..39d1da8cb57 100644
--- a/src/backend/executor/nodeIndexscan.c
+++ b/src/backend/executor/nodeIndexscan.c
@@ -108,7 +108,7 @@ IndexNext(IndexScanState *node)
*/
scandesc = index_beginscan(node->ss.ss_currentRelation,
node->iss_RelationDesc,
- estate->es_snapshot,
+ (Snapshot) estate->es_snapshot,
node->iss_NumScanKeys,
node->iss_NumOrderByKeys);
@@ -203,7 +203,7 @@ IndexNextWithReorder(IndexScanState *node)
*/
scandesc = index_beginscan(node->ss.ss_currentRelation,
node->iss_RelationDesc,
- estate->es_snapshot,
+ (Snapshot) estate->es_snapshot,
node->iss_NumScanKeys,
node->iss_NumOrderByKeys);
diff --git a/src/backend/executor/nodeLockRows.c b/src/backend/executor/nodeLockRows.c
index 4e4e3db0b38..02e98660df6 100644
--- a/src/backend/executor/nodeLockRows.c
+++ b/src/backend/executor/nodeLockRows.c
@@ -182,7 +182,7 @@ lnext:
if (!IsolationUsesXactSnapshot())
lockflags |= TUPLE_LOCK_FLAG_FIND_LAST_VERSION;
- test = table_tuple_lock(erm->relation, &tid, estate->es_snapshot,
+ test = table_tuple_lock(erm->relation, &tid, (Snapshot) estate->es_snapshot,
markSlot, estate->es_output_cid,
lockmode, erm->waitPolicy,
lockflags,
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index 1af8c9caf6c..bd0fa98564b 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -292,7 +292,7 @@ ExecCheckTupleVisible(EState *estate,
if (!IsolationUsesXactSnapshot())
return;
- if (!table_tuple_satisfies_snapshot(rel, slot, estate->es_snapshot))
+ if (!table_tuple_satisfies_snapshot(rel, slot, (Snapshot) estate->es_snapshot))
{
Datum xminDatum;
TransactionId xmin;
@@ -1354,8 +1354,8 @@ ExecDeleteAct(ModifyTableContext *context, ResultRelInfo *resultRelInfo,
return table_tuple_delete(resultRelInfo->ri_RelationDesc, tupleid,
estate->es_output_cid,
- estate->es_snapshot,
- estate->es_crosscheck_snapshot,
+ (Snapshot) estate->es_snapshot,
+ (Snapshot) estate->es_crosscheck_snapshot,
true /* wait for commit */ ,
&context->tmfd,
changingPart);
@@ -1568,7 +1568,7 @@ ldelete:
resultRelInfo->ri_RangeTableIndex);
result = table_tuple_lock(resultRelationDesc, tupleid,
- estate->es_snapshot,
+ (Snapshot) estate->es_snapshot,
inputslot, estate->es_output_cid,
LockTupleExclusive, LockWaitBlock,
TUPLE_LOCK_FLAG_FIND_LAST_VERSION,
@@ -2114,8 +2114,8 @@ lreplace:
*/
result = table_tuple_update(resultRelationDesc, tupleid, slot,
estate->es_output_cid,
- estate->es_snapshot,
- estate->es_crosscheck_snapshot,
+ (Snapshot) estate->es_snapshot,
+ (Snapshot) estate->es_crosscheck_snapshot,
true /* wait for commit */ ,
&context->tmfd, &updateCxt->lockmode,
&updateCxt->updateIndexes);
@@ -2404,7 +2404,7 @@ redo_act:
resultRelInfo->ri_RangeTableIndex);
result = table_tuple_lock(resultRelationDesc, tupleid,
- estate->es_snapshot,
+ (Snapshot) estate->es_snapshot,
inputslot, estate->es_output_cid,
updateCxt.lockmode, LockWaitBlock,
TUPLE_LOCK_FLAG_FIND_LAST_VERSION,
@@ -2558,7 +2558,7 @@ ExecOnConflictUpdate(ModifyTableContext *context,
* true anymore.
*/
test = table_tuple_lock(relation, conflictTid,
- context->estate->es_snapshot,
+ (Snapshot) context->estate->es_snapshot,
existing, context->estate->es_output_cid,
lockmode, LockWaitBlock, 0,
&tmfd);
@@ -3188,7 +3188,7 @@ lmerge_matched:
inputslot = resultRelInfo->ri_oldTupleSlot;
result = table_tuple_lock(resultRelationDesc, tupleid,
- estate->es_snapshot,
+ (Snapshot) estate->es_snapshot,
inputslot, estate->es_output_cid,
lockmode, LockWaitBlock,
TUPLE_LOCK_FLAG_FIND_LAST_VERSION,
diff --git a/src/backend/executor/nodeSamplescan.c b/src/backend/executor/nodeSamplescan.c
index 6b3db7548ed..9e19bbd11a9 100644
--- a/src/backend/executor/nodeSamplescan.c
+++ b/src/backend/executor/nodeSamplescan.c
@@ -293,7 +293,7 @@ tablesample_init(SampleScanState *scanstate)
{
scanstate->ss.ss_currentScanDesc =
table_beginscan_sampling(scanstate->ss.ss_currentRelation,
- scanstate->ss.ps.state->es_snapshot,
+ (Snapshot) scanstate->ss.ps.state->es_snapshot,
0, NULL,
scanstate->use_bulkread,
allow_sync,
diff --git a/src/backend/executor/nodeSeqscan.c b/src/backend/executor/nodeSeqscan.c
index fa2d522b25f..8112bd621ab 100644
--- a/src/backend/executor/nodeSeqscan.c
+++ b/src/backend/executor/nodeSeqscan.c
@@ -69,7 +69,7 @@ SeqNext(SeqScanState *node)
* executing a scan that was planned to be parallel.
*/
scandesc = table_beginscan(node->ss.ss_currentRelation,
- estate->es_snapshot,
+ (Snapshot) estate->es_snapshot,
0, NULL);
node->ss.ss_currentScanDesc = scandesc;
}
@@ -241,7 +241,7 @@ ExecSeqScanEstimate(SeqScanState *node,
EState *estate = node->ss.ps.state;
node->pscan_len = table_parallelscan_estimate(node->ss.ss_currentRelation,
- estate->es_snapshot);
+ (Snapshot) estate->es_snapshot);
shm_toc_estimate_chunk(&pcxt->estimator, node->pscan_len);
shm_toc_estimate_keys(&pcxt->estimator, 1);
}
@@ -262,7 +262,7 @@ ExecSeqScanInitializeDSM(SeqScanState *node,
pscan = shm_toc_allocate(pcxt->toc, node->pscan_len);
table_parallelscan_initialize(node->ss.ss_currentRelation,
pscan,
- estate->es_snapshot);
+ (Snapshot) estate->es_snapshot);
shm_toc_insert(pcxt->toc, node->ss.ps.plan->plan_node_id, pscan);
node->ss.ss_currentScanDesc =
table_beginscan_parallel(node->ss.ss_currentRelation, pscan);
diff --git a/src/backend/executor/nodeTidrangescan.c b/src/backend/executor/nodeTidrangescan.c
index ab2eab9596e..626ad9fd6b9 100644
--- a/src/backend/executor/nodeTidrangescan.c
+++ b/src/backend/executor/nodeTidrangescan.c
@@ -241,7 +241,7 @@ TidRangeNext(TidRangeScanState *node)
if (scandesc == NULL)
{
scandesc = table_beginscan_tidrange(node->ss.ss_currentRelation,
- estate->es_snapshot,
+ (Snapshot) estate->es_snapshot,
&node->trss_mintid,
&node->trss_maxtid);
node->ss.ss_currentScanDesc = scandesc;
diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c
index 5e56e29a15f..cf4a15eae31 100644
--- a/src/backend/executor/nodeTidscan.c
+++ b/src/backend/executor/nodeTidscan.c
@@ -148,7 +148,7 @@ TidListEval(TidScanState *tidstate)
if (tidstate->ss.ss_currentScanDesc == NULL)
tidstate->ss.ss_currentScanDesc =
table_beginscan_tid(tidstate->ss.ss_currentRelation,
- tidstate->ss.ps.state->es_snapshot);
+ (Snapshot) tidstate->ss.ps.state->es_snapshot);
scan = tidstate->ss.ss_currentScanDesc;
/*
@@ -326,7 +326,7 @@ TidNext(TidScanState *node)
*/
estate = node->ss.ps.state;
direction = estate->es_direction;
- snapshot = estate->es_snapshot;
+ snapshot = (Snapshot) estate->es_snapshot;
heapRelation = node->ss.ss_currentRelation;
slot = node->ss.ss_ScanTupleSlot;
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index ecb2e4ccaa1..7ac1da62ef8 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -64,7 +64,7 @@ static void _SPI_prepare_plan(const char *src, SPIPlanPtr plan);
static void _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan);
static int _SPI_execute_plan(SPIPlanPtr plan, const SPIExecuteOptions *options,
- Snapshot snapshot, Snapshot crosscheck_snapshot,
+ MVCCSnapshot snapshot, MVCCSnapshot crosscheck_snapshot,
bool fire_triggers);
static ParamListInfo _SPI_convert_params(int nargs, Oid *argtypes,
@@ -618,7 +618,7 @@ SPI_execute(const char *src, bool read_only, long tcount)
options.tcount = tcount;
res = _SPI_execute_plan(&plan, &options,
- InvalidSnapshot, InvalidSnapshot,
+ InvalidMVCCSnapshot, InvalidMVCCSnapshot,
true);
_SPI_end_call(true);
@@ -660,7 +660,7 @@ SPI_execute_extended(const char *src,
_SPI_prepare_oneshot_plan(src, &plan);
res = _SPI_execute_plan(&plan, options,
- InvalidSnapshot, InvalidSnapshot,
+ InvalidMVCCSnapshot, InvalidMVCCSnapshot,
true);
_SPI_end_call(true);
@@ -692,7 +692,7 @@ SPI_execute_plan(SPIPlanPtr plan, Datum *Values, const char *Nulls,
options.tcount = tcount;
res = _SPI_execute_plan(plan, &options,
- InvalidSnapshot, InvalidSnapshot,
+ InvalidMVCCSnapshot, InvalidMVCCSnapshot,
true);
_SPI_end_call(true);
@@ -721,7 +721,7 @@ SPI_execute_plan_extended(SPIPlanPtr plan,
return res;
res = _SPI_execute_plan(plan, options,
- InvalidSnapshot, InvalidSnapshot,
+ InvalidMVCCSnapshot, InvalidMVCCSnapshot,
true);
_SPI_end_call(true);
@@ -749,7 +749,7 @@ SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params,
options.tcount = tcount;
res = _SPI_execute_plan(plan, &options,
- InvalidSnapshot, InvalidSnapshot,
+ InvalidMVCCSnapshot, InvalidMVCCSnapshot,
true);
_SPI_end_call(true);
@@ -766,13 +766,13 @@ SPI_execute_plan_with_paramlist(SPIPlanPtr plan, ParamListInfo params,
* This is currently not documented in spi.sgml because it is only intended
* for use by RI triggers.
*
- * Passing snapshot == InvalidSnapshot will select the normal behavior of
+ * Passing snapshot == InvalidMVCCSnapshot will select the normal behavior of
* fetching a new snapshot for each query.
*/
int
SPI_execute_snapshot(SPIPlanPtr plan,
Datum *Values, const char *Nulls,
- Snapshot snapshot, Snapshot crosscheck_snapshot,
+ MVCCSnapshot snapshot, MVCCSnapshot crosscheck_snapshot,
bool read_only, bool fire_triggers, long tcount)
{
SPIExecuteOptions options;
@@ -849,7 +849,7 @@ SPI_execute_with_args(const char *src,
options.tcount = tcount;
res = _SPI_execute_plan(&plan, &options,
- InvalidSnapshot, InvalidSnapshot,
+ InvalidMVCCSnapshot, InvalidMVCCSnapshot,
true);
_SPI_end_call(true);
@@ -1581,7 +1581,7 @@ SPI_cursor_open_internal(const char *name, SPIPlanPtr plan,
CachedPlan *cplan;
List *stmt_list;
char *query_string;
- Snapshot snapshot;
+ MVCCSnapshot snapshot;
MemoryContext oldcontext;
Portal portal;
SPICallbackArg spicallbackarg;
@@ -2389,15 +2389,15 @@ _SPI_prepare_oneshot_plan(const char *src, SPIPlanPtr plan)
* if NULL, CurrentResourceOwner is used (ignored for non-saved plan)
*
* Additional, only-internally-accessible options:
- * snapshot: query snapshot to use, or InvalidSnapshot for the normal
+ * snapshot: query snapshot to use, or InvalidMVCCSnapshot for the normal
* behavior of taking a new snapshot for each query.
- * crosscheck_snapshot: for RI use, all others pass InvalidSnapshot
+ * crosscheck_snapshot: for RI use, all others pass InvalidMVCCSnapshot
* fire_triggers: true to fire AFTER triggers at end of query (normal case);
* false means any AFTER triggers are postponed to end of outer query
*/
static int
_SPI_execute_plan(SPIPlanPtr plan, const SPIExecuteOptions *options,
- Snapshot snapshot, Snapshot crosscheck_snapshot,
+ MVCCSnapshot snapshot, MVCCSnapshot crosscheck_snapshot,
bool fire_triggers)
{
int my_res = 0;
@@ -2434,31 +2434,31 @@ _SPI_execute_plan(SPIPlanPtr plan, const SPIExecuteOptions *options,
/*
* We support four distinct snapshot management behaviors:
*
- * snapshot != InvalidSnapshot, read_only = true: use exactly the given
- * snapshot.
+ * snapshot != InvalidMVCCSnapshot, read_only = true: use exactly the
+ * given snapshot.
*
- * snapshot != InvalidSnapshot, read_only = false: use the given snapshot,
- * modified by advancing its command ID before each querytree.
+ * snapshot != InvalidMVCCSnapshot, read_only = false: use the given
+ * snapshot, modified by advancing its command ID before each querytree.
*
- * snapshot == InvalidSnapshot, read_only = true: do nothing for queries
- * that require no snapshot. For those that do, ensure that a Portal
- * snapshot exists; then use that, or use the entry-time ActiveSnapshot if
- * that exists and is different.
+ * snapshot == InvalidMVCCSnapshot, read_only = true: do nothing for
+ * queries that require no snapshot. For those that do, ensure that a
+ * Portal snapshot exists; then use that, or use the entry-time
+ * ActiveSnapshot if that exists and is different.
*
- * snapshot == InvalidSnapshot, read_only = false: do nothing for queries
- * that require no snapshot. For those that do, ensure that a Portal
- * snapshot exists; then, in atomic execution (!allow_nonatomic) take a
- * full new snapshot for each user command, and advance its command ID
- * before each querytree within the command. In allow_nonatomic mode we
- * just use the Portal snapshot unmodified.
+ * snapshot == InvalidMVCCSnapshot, read_only = false: do nothing for
+ * queries that require no snapshot. For those that do, ensure that a
+ * Portal snapshot exists; then, in atomic execution (!allow_nonatomic)
+ * take a full new snapshot for each user command, and advance its command
+ * ID before each querytree within the command. In allow_nonatomic mode
+ * we just use the Portal snapshot unmodified.
*
* In the first two cases, we can just push the snap onto the stack once
* for the whole plan list.
*
- * Note that snapshot != InvalidSnapshot implies an atomic execution
+ * Note that snapshot != InvalidMVCCSnapshot implies an atomic execution
* context.
*/
- if (snapshot != InvalidSnapshot)
+ if (snapshot != InvalidMVCCSnapshot)
{
/* this intentionally tests the options field not the derived value */
Assert(!options->allow_nonatomic);
@@ -2583,7 +2583,7 @@ _SPI_execute_plan(SPIPlanPtr plan, const SPIExecuteOptions *options,
* If we weren't given a specific snapshot to use, and the statement
* list requires a snapshot, set that up.
*/
- if (snapshot == InvalidSnapshot &&
+ if (snapshot == InvalidMVCCSnapshot &&
(list_length(stmt_list) > 1 ||
(list_length(stmt_list) == 1 &&
PlannedStmtRequiresSnapshot(linitial_node(PlannedStmt,
@@ -2682,12 +2682,12 @@ _SPI_execute_plan(SPIPlanPtr plan, const SPIExecuteOptions *options,
if (stmt->utilityStmt == NULL)
{
QueryDesc *qdesc;
- Snapshot snap;
+ MVCCSnapshot snap;
if (ActiveSnapshotSet())
snap = GetActiveSnapshot();
else
- snap = InvalidSnapshot;
+ snap = InvalidMVCCSnapshot;
qdesc = CreateQueryDesc(stmt,
plansource->query_string,
diff --git a/src/backend/libpq/be-fsstubs.c b/src/backend/libpq/be-fsstubs.c
index a272e82b850..12273a8b8d3 100644
--- a/src/backend/libpq/be-fsstubs.c
+++ b/src/backend/libpq/be-fsstubs.c
@@ -725,7 +725,7 @@ closeLOfd(int fd)
cookies[fd] = NULL;
if (lobj->snapshot)
- UnregisterSnapshotFromOwner(lobj->snapshot,
+ UnregisterSnapshotFromOwner((Snapshot) lobj->snapshot,
TopTransactionResourceOwner);
inv_close(lobj);
}
diff --git a/src/backend/partitioning/partbounds.c b/src/backend/partitioning/partbounds.c
index 4bdc2941efb..4c1795cda05 100644
--- a/src/backend/partitioning/partbounds.c
+++ b/src/backend/partitioning/partbounds.c
@@ -3367,7 +3367,7 @@ check_default_partition_contents(Relation parent, Relation default_rel,
partqualstate = ExecPrepareExpr(partition_constraint, estate);
econtext = GetPerTupleExprContext(estate);
- snapshot = RegisterSnapshot(GetLatestSnapshot());
+ snapshot = (Snapshot) RegisterSnapshot(GetLatestSnapshot());
tupslot = table_slot_create(part_rel, &estate->es_tupleTable);
scan = table_beginscan(part_rel, snapshot, 0, NULL);
diff --git a/src/backend/partitioning/partdesc.c b/src/backend/partitioning/partdesc.c
index 328b4d450e4..d2047f4037e 100644
--- a/src/backend/partitioning/partdesc.c
+++ b/src/backend/partitioning/partdesc.c
@@ -97,7 +97,7 @@ RelationGetPartitionDesc(Relation rel, bool omit_detached)
rel->rd_partdesc_nodetached &&
ActiveSnapshotSet())
{
- Snapshot activesnap;
+ MVCCSnapshot activesnap;
Assert(TransactionIdIsValid(rel->rd_partdesc_nodetached_xmin));
activesnap = GetActiveSnapshot();
diff --git a/src/backend/replication/logical/decode.c b/src/backend/replication/logical/decode.c
index 0bff0f10652..aa69cd06fec 100644
--- a/src/backend/replication/logical/decode.c
+++ b/src/backend/replication/logical/decode.c
@@ -586,7 +586,7 @@ logicalmsg_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
TransactionId xid = XLogRecGetXid(r);
uint8 info = XLogRecGetInfo(r) & ~XLR_INFO_MASK;
RepOriginId origin_id = XLogRecGetOrigin(r);
- Snapshot snapshot = NULL;
+ HistoricMVCCSnapshot snapshot = NULL;
xl_logical_message *message;
if (info != XLOG_LOGICAL_MESSAGE)
diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c
index 79b60df7cf0..f16ac73e9f5 100644
--- a/src/backend/replication/logical/reorderbuffer.c
+++ b/src/backend/replication/logical/reorderbuffer.c
@@ -265,9 +265,9 @@ static void ReorderBufferSerializedPath(char *path, ReplicationSlot *slot,
TransactionId xid, XLogSegNo segno);
static int ReorderBufferTXNSizeCompare(const pairingheap_node *a, const pairingheap_node *b, void *arg);
-static void ReorderBufferFreeSnap(ReorderBuffer *rb, Snapshot snap);
-static Snapshot ReorderBufferCopySnap(ReorderBuffer *rb, Snapshot orig_snap,
- ReorderBufferTXN *txn, CommandId cid);
+static void ReorderBufferFreeSnap(ReorderBuffer *rb, HistoricMVCCSnapshot snap);
+static HistoricMVCCSnapshot ReorderBufferCopySnap(ReorderBuffer *rb, HistoricMVCCSnapshot orig_snap,
+ ReorderBufferTXN *txn, CommandId cid);
/*
* ---------------------------------------
@@ -849,7 +849,7 @@ ReorderBufferQueueChange(ReorderBuffer *rb, TransactionId xid, XLogRecPtr lsn,
*/
void
ReorderBufferQueueMessage(ReorderBuffer *rb, TransactionId xid,
- Snapshot snap, XLogRecPtr lsn,
+ HistoricMVCCSnapshot snap, XLogRecPtr lsn,
bool transactional, const char *prefix,
Size message_size, const char *message)
{
@@ -883,7 +883,7 @@ ReorderBufferQueueMessage(ReorderBuffer *rb, TransactionId xid,
else
{
ReorderBufferTXN *txn = NULL;
- volatile Snapshot snapshot_now = snap;
+ volatile HistoricMVCCSnapshot snapshot_now = snap;
/* Non-transactional changes require a valid snapshot. */
Assert(snapshot_now);
@@ -1829,35 +1829,35 @@ ReorderBufferBuildTupleCidHash(ReorderBuffer *rb, ReorderBufferTXN *txn)
* that catalog modifying transactions can look into intermediate catalog
* states.
*/
-static Snapshot
-ReorderBufferCopySnap(ReorderBuffer *rb, Snapshot orig_snap,
+static HistoricMVCCSnapshot
+ReorderBufferCopySnap(ReorderBuffer *rb, HistoricMVCCSnapshot orig_snap,
ReorderBufferTXN *txn, CommandId cid)
{
- Snapshot snap;
+ HistoricMVCCSnapshot snap;
dlist_iter iter;
int i = 0;
Size size;
- size = sizeof(SnapshotData) +
+ size = sizeof(HistoricMVCCSnapshotData) +
sizeof(TransactionId) * orig_snap->xcnt +
sizeof(TransactionId) * (txn->nsubtxns + 1);
snap = MemoryContextAllocZero(rb->context, size);
- memcpy(snap, orig_snap, sizeof(SnapshotData));
+ memcpy(snap, orig_snap, sizeof(HistoricMVCCSnapshotData));
snap->copied = true;
- snap->active_count = 1; /* mark as active so nobody frees it */
+ snap->refcount = 1; /* mark as active so nobody frees it */
snap->regd_count = 0;
- snap->xip = (TransactionId *) (snap + 1);
+ snap->committed_xids = (TransactionId *) (snap + 1);
- memcpy(snap->xip, orig_snap->xip, sizeof(TransactionId) * snap->xcnt);
+ memcpy(snap->committed_xids, orig_snap->committed_xids, sizeof(TransactionId) * snap->xcnt);
/*
* snap->subxip contains all txids that belong to our transaction which we
* need to check via cmin/cmax. That's why we store the toplevel
* transaction in there as well.
*/
- snap->subxip = snap->xip + snap->xcnt;
+ snap->subxip = snap->committed_xids + snap->xcnt;
snap->subxip[i++] = txn->xid;
/*
@@ -1889,7 +1889,7 @@ ReorderBufferCopySnap(ReorderBuffer *rb, Snapshot orig_snap,
* Free a previously ReorderBufferCopySnap'ed snapshot
*/
static void
-ReorderBufferFreeSnap(ReorderBuffer *rb, Snapshot snap)
+ReorderBufferFreeSnap(ReorderBuffer *rb, HistoricMVCCSnapshot snap)
{
if (snap->copied)
pfree(snap);
@@ -2040,7 +2040,7 @@ ReorderBufferApplyMessage(ReorderBuffer *rb, ReorderBufferTXN *txn,
*/
static inline void
ReorderBufferSaveTXNSnapshot(ReorderBuffer *rb, ReorderBufferTXN *txn,
- Snapshot snapshot_now, CommandId command_id)
+ HistoricMVCCSnapshot snapshot_now, CommandId command_id)
{
txn->command_id = command_id;
@@ -2061,7 +2061,7 @@ ReorderBufferSaveTXNSnapshot(ReorderBuffer *rb, ReorderBufferTXN *txn,
*/
static void
ReorderBufferResetTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
- Snapshot snapshot_now,
+ HistoricMVCCSnapshot snapshot_now,
CommandId command_id,
XLogRecPtr last_lsn,
ReorderBufferChange *specinsert)
@@ -2108,7 +2108,7 @@ ReorderBufferResetTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
static void
ReorderBufferProcessTXN(ReorderBuffer *rb, ReorderBufferTXN *txn,
XLogRecPtr commit_lsn,
- volatile Snapshot snapshot_now,
+ volatile HistoricMVCCSnapshot snapshot_now,
volatile CommandId command_id,
bool streaming)
{
@@ -2682,7 +2682,7 @@ ReorderBufferReplay(ReorderBufferTXN *txn,
TimestampTz commit_time,
RepOriginId origin_id, XLogRecPtr origin_lsn)
{
- Snapshot snapshot_now;
+ HistoricMVCCSnapshot snapshot_now;
CommandId command_id = FirstCommandId;
txn->final_lsn = commit_lsn;
@@ -3142,7 +3142,7 @@ ReorderBufferProcessXid(ReorderBuffer *rb, TransactionId xid, XLogRecPtr lsn)
*/
void
ReorderBufferAddSnapshot(ReorderBuffer *rb, TransactionId xid,
- XLogRecPtr lsn, Snapshot snap)
+ XLogRecPtr lsn, HistoricMVCCSnapshot snap)
{
ReorderBufferChange *change = ReorderBufferGetChange(rb);
@@ -3160,7 +3160,7 @@ ReorderBufferAddSnapshot(ReorderBuffer *rb, TransactionId xid,
*/
void
ReorderBufferSetBaseSnapshot(ReorderBuffer *rb, TransactionId xid,
- XLogRecPtr lsn, Snapshot snap)
+ XLogRecPtr lsn, HistoricMVCCSnapshot snap)
{
ReorderBufferTXN *txn;
bool is_new;
@@ -3920,12 +3920,12 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
}
case REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT:
{
- Snapshot snap;
+ HistoricMVCCSnapshot snap;
char *data;
snap = change->data.snapshot;
- sz += sizeof(SnapshotData) +
+ sz += sizeof(HistoricMVCCSnapshotData) +
sizeof(TransactionId) * snap->xcnt +
sizeof(TransactionId) * snap->subxcnt;
@@ -3935,12 +3935,12 @@ ReorderBufferSerializeChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
/* might have been reallocated above */
ondisk = (ReorderBufferDiskChange *) rb->outbuf;
- memcpy(data, snap, sizeof(SnapshotData));
- data += sizeof(SnapshotData);
+ memcpy(data, snap, sizeof(HistoricMVCCSnapshotData));
+ data += sizeof(HistoricMVCCSnapshotData);
if (snap->xcnt)
{
- memcpy(data, snap->xip,
+ memcpy(data, snap->committed_xids,
sizeof(TransactionId) * snap->xcnt);
data += sizeof(TransactionId) * snap->xcnt;
}
@@ -4054,7 +4054,7 @@ ReorderBufferCanStartStreaming(ReorderBuffer *rb)
static void
ReorderBufferStreamTXN(ReorderBuffer *rb, ReorderBufferTXN *txn)
{
- Snapshot snapshot_now;
+ HistoricMVCCSnapshot snapshot_now;
CommandId command_id;
Size stream_bytes;
bool txn_is_streamed;
@@ -4222,11 +4222,11 @@ ReorderBufferChangeSize(ReorderBufferChange *change)
}
case REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT:
{
- Snapshot snap;
+ HistoricMVCCSnapshot snap;
snap = change->data.snapshot;
- sz += sizeof(SnapshotData) +
+ sz += sizeof(HistoricMVCCSnapshotData) +
sizeof(TransactionId) * snap->xcnt +
sizeof(TransactionId) * snap->subxcnt;
@@ -4506,13 +4506,13 @@ ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
}
case REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT:
{
- Snapshot oldsnap;
- Snapshot newsnap;
+ HistoricMVCCSnapshot oldsnap;
+ HistoricMVCCSnapshot newsnap;
Size size;
- oldsnap = (Snapshot) data;
+ oldsnap = (HistoricMVCCSnapshot) data;
- size = sizeof(SnapshotData) +
+ size = sizeof(HistoricMVCCSnapshotData) +
sizeof(TransactionId) * oldsnap->xcnt +
sizeof(TransactionId) * (oldsnap->subxcnt + 0);
@@ -4521,9 +4521,9 @@ ReorderBufferRestoreChange(ReorderBuffer *rb, ReorderBufferTXN *txn,
newsnap = change->data.snapshot;
memcpy(newsnap, data, size);
- newsnap->xip = (TransactionId *)
- (((char *) newsnap) + sizeof(SnapshotData));
- newsnap->subxip = newsnap->xip + newsnap->xcnt;
+ newsnap->committed_xids = (TransactionId *)
+ (((char *) newsnap) + sizeof(HistoricMVCCSnapshotData));
+ newsnap->subxip = newsnap->committed_xids + newsnap->xcnt;
newsnap->copied = true;
break;
}
@@ -5194,7 +5194,7 @@ file_sort_by_lsn(const ListCell *a_p, const ListCell *b_p)
* transaction for relid.
*/
static void
-UpdateLogicalMappings(HTAB *tuplecid_data, Oid relid, Snapshot snapshot)
+UpdateLogicalMappings(HTAB *tuplecid_data, Oid relid, HistoricMVCCSnapshot snapshot)
{
DIR *mapping_dir;
struct dirent *mapping_de;
@@ -5273,7 +5273,7 @@ UpdateLogicalMappings(HTAB *tuplecid_data, Oid relid, Snapshot snapshot)
*/
bool
ResolveCminCmaxDuringDecoding(HTAB *tuplecid_data,
- Snapshot snapshot,
+ HistoricMVCCSnapshot snapshot,
HeapTuple htup, Buffer buffer,
CommandId *cmin, CommandId *cmax)
{
diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c
index bbedd3de318..f2fc352c634 100644
--- a/src/backend/replication/logical/snapbuild.c
+++ b/src/backend/replication/logical/snapbuild.c
@@ -155,11 +155,11 @@ static bool ExportInProgress = false;
static void SnapBuildPurgeOlderTxn(SnapBuild *builder);
/* snapshot building/manipulation/distribution functions */
-static Snapshot SnapBuildBuildSnapshot(SnapBuild *builder);
+static HistoricMVCCSnapshot SnapBuildBuildSnapshot(SnapBuild *builder);
-static void SnapBuildFreeSnapshot(Snapshot snap);
+static void SnapBuildFreeSnapshot(HistoricMVCCSnapshot snap);
-static void SnapBuildSnapIncRefcount(Snapshot snap);
+static void SnapBuildSnapIncRefcount(HistoricMVCCSnapshot snap);
static void SnapBuildDistributeNewCatalogSnapshot(SnapBuild *builder, XLogRecPtr lsn);
@@ -249,23 +249,21 @@ FreeSnapshotBuilder(SnapBuild *builder)
* Free an unreferenced snapshot that has previously been built by us.
*/
static void
-SnapBuildFreeSnapshot(Snapshot snap)
+SnapBuildFreeSnapshot(HistoricMVCCSnapshot snap)
{
/* make sure we don't get passed an external snapshot */
Assert(snap->snapshot_type == SNAPSHOT_HISTORIC_MVCC);
/* make sure nobody modified our snapshot */
Assert(snap->curcid == FirstCommandId);
- Assert(!snap->suboverflowed);
- Assert(!snap->takenDuringRecovery);
Assert(snap->regd_count == 0);
/* slightly more likely, so it's checked even without c-asserts */
if (snap->copied)
elog(ERROR, "cannot free a copied snapshot");
- if (snap->active_count)
- elog(ERROR, "cannot free an active snapshot");
+ if (snap->refcount)
+ elog(ERROR, "cannot free a snapshot that's in use");
pfree(snap);
}
@@ -313,9 +311,9 @@ SnapBuildXactNeedsSkip(SnapBuild *builder, XLogRecPtr ptr)
* adding a Snapshot as builder->snapshot.
*/
static void
-SnapBuildSnapIncRefcount(Snapshot snap)
+SnapBuildSnapIncRefcount(HistoricMVCCSnapshot snap)
{
- snap->active_count++;
+ snap->refcount++;
}
/*
@@ -325,26 +323,23 @@ SnapBuildSnapIncRefcount(Snapshot snap)
* IncRef'ed Snapshot can adjust its refcount easily.
*/
void
-SnapBuildSnapDecRefcount(Snapshot snap)
+SnapBuildSnapDecRefcount(HistoricMVCCSnapshot snap)
{
/* make sure we don't get passed an external snapshot */
Assert(snap->snapshot_type == SNAPSHOT_HISTORIC_MVCC);
/* make sure nobody modified our snapshot */
Assert(snap->curcid == FirstCommandId);
- Assert(!snap->suboverflowed);
- Assert(!snap->takenDuringRecovery);
+ Assert(snap->refcount > 0);
Assert(snap->regd_count == 0);
- Assert(snap->active_count > 0);
-
/* slightly more likely, so it's checked even without casserts */
if (snap->copied)
elog(ERROR, "cannot free a copied snapshot");
- snap->active_count--;
- if (snap->active_count == 0)
+ snap->refcount--;
+ if (snap->refcount == 0)
SnapBuildFreeSnapshot(snap);
}
@@ -356,15 +351,15 @@ SnapBuildSnapDecRefcount(Snapshot snap)
* these snapshots; they have to copy them and fill in appropriate ->curcid
* and ->subxip/subxcnt values.
*/
-static Snapshot
+static HistoricMVCCSnapshot
SnapBuildBuildSnapshot(SnapBuild *builder)
{
- Snapshot snapshot;
+ HistoricMVCCSnapshot snapshot;
Size ssize;
Assert(builder->state >= SNAPBUILD_FULL_SNAPSHOT);
- ssize = sizeof(SnapshotData)
+ ssize = sizeof(HistoricMVCCSnapshotData)
+ sizeof(TransactionId) * builder->committed.xcnt
+ sizeof(TransactionId) * 1 /* toplevel xid */ ;
@@ -400,15 +395,15 @@ SnapBuildBuildSnapshot(SnapBuild *builder)
snapshot->xmax = builder->xmax;
/* store all transactions to be treated as committed by this snapshot */
- snapshot->xip =
- (TransactionId *) ((char *) snapshot + sizeof(SnapshotData));
+ snapshot->committed_xids =
+ (TransactionId *) ((char *) snapshot + sizeof(HistoricMVCCSnapshotData));
snapshot->xcnt = builder->committed.xcnt;
- memcpy(snapshot->xip,
+ memcpy(snapshot->committed_xids,
builder->committed.xip,
builder->committed.xcnt * sizeof(TransactionId));
/* sort so we can bsearch() */
- qsort(snapshot->xip, snapshot->xcnt, sizeof(TransactionId), xidComparator);
+ qsort(snapshot->committed_xids, snapshot->xcnt, sizeof(TransactionId), xidComparator);
/*
* Initially, subxip is empty, i.e. it's a snapshot to be used by
@@ -418,13 +413,10 @@ SnapBuildBuildSnapshot(SnapBuild *builder)
snapshot->subxcnt = 0;
snapshot->subxip = NULL;
- snapshot->suboverflowed = false;
- snapshot->takenDuringRecovery = false;
snapshot->copied = false;
snapshot->curcid = FirstCommandId;
- snapshot->active_count = 0;
+ snapshot->refcount = 0;
snapshot->regd_count = 0;
- snapshot->snapXactCompletionCount = 0;
return snapshot;
}
@@ -436,13 +428,13 @@ SnapBuildBuildSnapshot(SnapBuild *builder)
* The snapshot will be usable directly in current transaction or exported
* for loading in different transaction.
*/
-Snapshot
+MVCCSnapshot
SnapBuildInitialSnapshot(SnapBuild *builder)
{
- Snapshot snap;
+ HistoricMVCCSnapshot historicsnap;
+ MVCCSnapshot mvccsnap;
TransactionId xid;
TransactionId safeXid;
- TransactionId *newxip;
int newxcnt = 0;
Assert(XactIsoLevel == XACT_REPEATABLE_READ);
@@ -464,10 +456,10 @@ SnapBuildInitialSnapshot(SnapBuild *builder)
if (TransactionIdIsValid(MyProc->xmin))
elog(ERROR, "cannot build an initial slot snapshot when MyProc->xmin already is valid");
- snap = SnapBuildBuildSnapshot(builder);
+ historicsnap = SnapBuildBuildSnapshot(builder);
/*
- * We know that snap->xmin is alive, enforced by the logical xmin
+ * We know that historicsnap->xmin is alive, enforced by the logical xmin
* mechanism. Due to that we can do this without locks, we're only
* changing our own value.
*
@@ -479,15 +471,18 @@ SnapBuildInitialSnapshot(SnapBuild *builder)
safeXid = GetOldestSafeDecodingTransactionId(false);
LWLockRelease(ProcArrayLock);
- if (TransactionIdFollows(safeXid, snap->xmin))
+ if (TransactionIdFollows(safeXid, historicsnap->xmin))
elog(ERROR, "cannot build an initial slot snapshot as oldest safe xid %u follows snapshot's xmin %u",
- safeXid, snap->xmin);
+ safeXid, historicsnap->xmin);
- MyProc->xmin = snap->xmin;
+ MyProc->xmin = historicsnap->xmin;
/* allocate in transaction context */
- newxip = (TransactionId *)
- palloc(sizeof(TransactionId) * GetMaxSnapshotXidCount());
+ mvccsnap = palloc(sizeof(MVCCSnapshotData) + sizeof(TransactionId) * GetMaxSnapshotXidCount());
+ mvccsnap->snapshot_type = SNAPSHOT_MVCC;
+ mvccsnap->xmin = historicsnap->xmin;
+ mvccsnap->xmax = historicsnap->xmax;
+ mvccsnap->xip = (TransactionId *) ((char *) mvccsnap + sizeof(MVCCSnapshotData));
/*
* snapbuild.c builds transactions in an "inverted" manner, which means it
@@ -495,7 +490,7 @@ SnapBuildInitialSnapshot(SnapBuild *builder)
* classical snapshot by marking all non-committed transactions as
* in-progress. This can be expensive.
*/
- for (xid = snap->xmin; NormalTransactionIdPrecedes(xid, snap->xmax);)
+ for (xid = historicsnap->xmin; NormalTransactionIdPrecedes(xid, historicsnap->xmax);)
{
void *test;
@@ -503,7 +498,7 @@ SnapBuildInitialSnapshot(SnapBuild *builder)
* Check whether transaction committed using the decoding snapshot
* meaning of ->xip.
*/
- test = bsearch(&xid, snap->xip, snap->xcnt,
+ test = bsearch(&xid, historicsnap->committed_xids, historicsnap->xcnt,
sizeof(TransactionId), xidComparator);
if (test == NULL)
@@ -513,18 +508,26 @@ SnapBuildInitialSnapshot(SnapBuild *builder)
(errcode(ERRCODE_T_R_SERIALIZATION_FAILURE),
errmsg("initial slot snapshot too large")));
- newxip[newxcnt++] = xid;
+ mvccsnap->xip[newxcnt++] = xid;
}
TransactionIdAdvance(xid);
}
/* adjust remaining snapshot fields as needed */
- snap->snapshot_type = SNAPSHOT_MVCC;
- snap->xcnt = newxcnt;
- snap->xip = newxip;
-
- return snap;
+ mvccsnap->xcnt = newxcnt;
+
+ mvccsnap->subxip = NULL;
+ mvccsnap->subxcnt = 0;
+ mvccsnap->suboverflowed = false;
+ mvccsnap->takenDuringRecovery = false;
+ mvccsnap->copied = false;
+ mvccsnap->curcid = FirstCommandId;
+ mvccsnap->active_count = 0;
+ mvccsnap->regd_count = 0;
+ mvccsnap->snapXactCompletionCount = 0;
+
+ return mvccsnap;
}
/*
@@ -538,7 +541,7 @@ SnapBuildInitialSnapshot(SnapBuild *builder)
const char *
SnapBuildExportSnapshot(SnapBuild *builder)
{
- Snapshot snap;
+ MVCCSnapshot snap;
char *snapname;
if (IsTransactionOrTransactionBlock())
@@ -575,7 +578,7 @@ SnapBuildExportSnapshot(SnapBuild *builder)
/*
* Ensure there is a snapshot and if not build one for current transaction.
*/
-Snapshot
+HistoricMVCCSnapshot
SnapBuildGetOrBuildSnapshot(SnapBuild *builder)
{
Assert(builder->state == SNAPBUILD_CONSISTENT);
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index a0782b1bbf6..7e208e34784 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -1305,7 +1305,7 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd)
}
else if (snapshot_action == CRS_USE_SNAPSHOT)
{
- Snapshot snap;
+ MVCCSnapshot snap;
snap = SnapBuildInitialSnapshot(ctx->snapshot_builder);
RestoreTransactionSnapshot(snap, MyProc);
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c
index 2e54c11f880..b2751dfa63b 100644
--- a/src/backend/storage/ipc/procarray.c
+++ b/src/backend/storage/ipc/procarray.c
@@ -2092,7 +2092,7 @@ GetMaxSnapshotSubxidCount(void)
* least in the case we already hold a snapshot), but that's for another day.
*/
static bool
-GetSnapshotDataReuse(Snapshot snapshot)
+GetSnapshotDataReuse(MVCCSnapshot snapshot)
{
uint64 curXactCompletionCount;
@@ -2171,8 +2171,8 @@ GetSnapshotDataReuse(Snapshot snapshot)
* Note: this function should probably not be called with an argument that's
* not statically allocated (see xip allocation below).
*/
-Snapshot
-GetSnapshotData(Snapshot snapshot)
+MVCCSnapshot
+GetSnapshotData(MVCCSnapshot snapshot)
{
ProcArrayStruct *arrayP = procArray;
TransactionId *other_xids = ProcGlobal->xids;
diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c
index 68b76f2cc18..5bbfd0abb65 100644
--- a/src/backend/storage/large_object/inv_api.c
+++ b/src/backend/storage/large_object/inv_api.c
@@ -215,7 +215,7 @@ LargeObjectDesc *
inv_open(Oid lobjId, int flags, MemoryContext mcxt)
{
LargeObjectDesc *retval;
- Snapshot snapshot = NULL;
+ MVCCSnapshot snapshot = NULL;
int descflags = 0;
/*
@@ -241,7 +241,7 @@ inv_open(Oid lobjId, int flags, MemoryContext mcxt)
snapshot = GetActiveSnapshot();
/* Can't use LargeObjectExists here because we need to specify snapshot */
- if (!LargeObjectExistsWithSnapshot(lobjId, snapshot))
+ if (!LargeObjectExistsWithSnapshot(lobjId, (Snapshot) snapshot))
ereport(ERROR,
(errcode(ERRCODE_UNDEFINED_OBJECT),
errmsg("large object %u does not exist", lobjId)));
@@ -253,7 +253,7 @@ inv_open(Oid lobjId, int flags, MemoryContext mcxt)
pg_largeobject_aclcheck_snapshot(lobjId,
GetUserId(),
ACL_SELECT,
- snapshot) != ACLCHECK_OK)
+ (Snapshot) snapshot) != ACLCHECK_OK)
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied for large object %u",
@@ -265,7 +265,7 @@ inv_open(Oid lobjId, int flags, MemoryContext mcxt)
pg_largeobject_aclcheck_snapshot(lobjId,
GetUserId(),
ACL_UPDATE,
- snapshot) != ACLCHECK_OK)
+ (Snapshot) snapshot) != ACLCHECK_OK)
ereport(ERROR,
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
errmsg("permission denied for large object %u",
@@ -354,7 +354,7 @@ inv_getsize(LargeObjectDesc *obj_desc)
ObjectIdGetDatum(obj_desc->id));
sd = systable_beginscan_ordered(lo_heap_r, lo_index_r,
- obj_desc->snapshot, 1, skey);
+ (Snapshot) obj_desc->snapshot, 1, skey);
/*
* Because the pg_largeobject index is on both loid and pageno, but we
@@ -484,7 +484,7 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
Int32GetDatum(pageno));
sd = systable_beginscan_ordered(lo_heap_r, lo_index_r,
- obj_desc->snapshot, 2, skey);
+ (Snapshot) obj_desc->snapshot, 2, skey);
while ((tuple = systable_getnext_ordered(sd, ForwardScanDirection)) != NULL)
{
@@ -604,7 +604,7 @@ inv_write(LargeObjectDesc *obj_desc, const char *buf, int nbytes)
Int32GetDatum(pageno));
sd = systable_beginscan_ordered(lo_heap_r, lo_index_r,
- obj_desc->snapshot, 2, skey);
+ (Snapshot) obj_desc->snapshot, 2, skey);
oldtuple = NULL;
olddata = NULL;
@@ -797,7 +797,7 @@ inv_truncate(LargeObjectDesc *obj_desc, int64 len)
Int32GetDatum(pageno));
sd = systable_beginscan_ordered(lo_heap_r, lo_index_r,
- obj_desc->snapshot, 2, skey);
+ (Snapshot) obj_desc->snapshot, 2, skey);
/*
* If possible, get the page the truncation point is in. The truncation
diff --git a/src/backend/storage/lmgr/predicate.c b/src/backend/storage/lmgr/predicate.c
index 5b21a053981..5adf0b1ffe9 100644
--- a/src/backend/storage/lmgr/predicate.c
+++ b/src/backend/storage/lmgr/predicate.c
@@ -449,10 +449,10 @@ static void SerialSetActiveSerXmin(TransactionId xid);
static uint32 predicatelock_hash(const void *key, Size keysize);
static void SummarizeOldestCommittedSxact(void);
-static Snapshot GetSafeSnapshot(Snapshot origSnapshot);
-static Snapshot GetSerializableTransactionSnapshotInt(Snapshot snapshot,
- VirtualTransactionId *sourcevxid,
- int sourcepid);
+static MVCCSnapshot GetSafeSnapshot(MVCCSnapshot origSnapshot);
+static MVCCSnapshot GetSerializableTransactionSnapshotInt(MVCCSnapshot snapshot,
+ VirtualTransactionId *sourcevxid,
+ int sourcepid);
static bool PredicateLockExists(const PREDICATELOCKTARGETTAG *targettag);
static bool GetParentPredicateLockTag(const PREDICATELOCKTARGETTAG *tag,
PREDICATELOCKTARGETTAG *parent);
@@ -1544,10 +1544,10 @@ SummarizeOldestCommittedSxact(void)
* for), the passed-in Snapshot pointer should reference a static data
* area that can safely be passed to GetSnapshotData.
*/
-static Snapshot
-GetSafeSnapshot(Snapshot origSnapshot)
+static MVCCSnapshot
+GetSafeSnapshot(MVCCSnapshot origSnapshot)
{
- Snapshot snapshot;
+ MVCCSnapshot snapshot;
Assert(XactReadOnly && XactDeferrable);
@@ -1668,8 +1668,8 @@ GetSafeSnapshotBlockingPids(int blocked_pid, int *output, int output_size)
* always this same pointer; no new snapshot data structure is allocated
* within this function.
*/
-Snapshot
-GetSerializableTransactionSnapshot(Snapshot snapshot)
+MVCCSnapshot
+GetSerializableTransactionSnapshot(MVCCSnapshot snapshot)
{
Assert(IsolationIsSerializable());
@@ -1709,7 +1709,7 @@ GetSerializableTransactionSnapshot(Snapshot snapshot)
* read-only.
*/
void
-SetSerializableTransactionSnapshot(Snapshot snapshot,
+SetSerializableTransactionSnapshot(MVCCSnapshot snapshot,
VirtualTransactionId *sourcevxid,
int sourcepid)
{
@@ -1750,8 +1750,8 @@ SetSerializableTransactionSnapshot(Snapshot snapshot,
* source xact is still running after we acquire SerializableXactHashLock.
* We do that by calling ProcArrayInstallImportedXmin.
*/
-static Snapshot
-GetSerializableTransactionSnapshotInt(Snapshot snapshot,
+static MVCCSnapshot
+GetSerializableTransactionSnapshotInt(MVCCSnapshot snapshot,
VirtualTransactionId *sourcevxid,
int sourcepid)
{
@@ -3961,7 +3961,7 @@ ReleaseOneSerializableXact(SERIALIZABLEXACT *sxact, bool partial,
static bool
XidIsConcurrent(TransactionId xid)
{
- Snapshot snap;
+ MVCCSnapshot snap;
Assert(TransactionIdIsValid(xid));
Assert(!TransactionIdEquals(xid, GetTopTransactionIdIfAny()));
@@ -4214,7 +4214,7 @@ CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag)
}
else if (!SxactIsDoomed(sxact)
&& (!SxactIsCommitted(sxact)
- || TransactionIdPrecedes(GetTransactionSnapshot()->xmin,
+ || TransactionIdPrecedes(TransactionXmin,
sxact->finishedBefore))
&& !RWConflictExists(sxact, MySerializableXact))
{
@@ -4227,7 +4227,7 @@ CheckTargetForConflictsIn(PREDICATELOCKTARGETTAG *targettag)
*/
if (!SxactIsDoomed(sxact)
&& (!SxactIsCommitted(sxact)
- || TransactionIdPrecedes(GetTransactionSnapshot()->xmin,
+ || TransactionIdPrecedes(TransactionXmin,
sxact->finishedBefore))
&& !RWConflictExists(sxact, MySerializableXact))
{
diff --git a/src/backend/tcop/postgres.c b/src/backend/tcop/postgres.c
index c01cff9d650..939a402540c 100644
--- a/src/backend/tcop/postgres.c
+++ b/src/backend/tcop/postgres.c
@@ -1229,7 +1229,7 @@ exec_simple_query(const char *query_string)
/*
* Start the portal. No parameters here.
*/
- PortalStart(portal, NULL, 0, InvalidSnapshot);
+ PortalStart(portal, NULL, 0, InvalidMVCCSnapshot);
/*
* Select the appropriate output format: text unless we are doing a
@@ -2034,7 +2034,7 @@ exec_bind_message(StringInfo input_message)
/*
* And we're ready to start portal execution.
*/
- PortalStart(portal, params, 0, InvalidSnapshot);
+ PortalStart(portal, params, 0, InvalidMVCCSnapshot);
/*
* Apply the result format requests to the portal.
diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c
index 6f22496305a..2a4142d65ea 100644
--- a/src/backend/tcop/pquery.c
+++ b/src/backend/tcop/pquery.c
@@ -66,8 +66,8 @@ static void DoPortalRewind(Portal portal);
QueryDesc *
CreateQueryDesc(PlannedStmt *plannedstmt,
const char *sourceText,
- Snapshot snapshot,
- Snapshot crosscheck_snapshot,
+ MVCCSnapshot snapshot,
+ MVCCSnapshot crosscheck_snapshot,
DestReceiver *dest,
ParamListInfo params,
QueryEnvironment *queryEnv,
@@ -78,9 +78,9 @@ CreateQueryDesc(PlannedStmt *plannedstmt,
qd->operation = plannedstmt->commandType; /* operation */
qd->plannedstmt = plannedstmt; /* plan */
qd->sourceText = sourceText; /* query text */
- qd->snapshot = RegisterSnapshot(snapshot); /* snapshot */
+ qd->snapshot = (MVCCSnapshot) RegisterSnapshot(snapshot); /* snapshot */
/* RI check snapshot */
- qd->crosscheck_snapshot = RegisterSnapshot(crosscheck_snapshot);
+ qd->crosscheck_snapshot = (MVCCSnapshot) RegisterSnapshot(crosscheck_snapshot);
qd->dest = dest; /* output dest */
qd->params = params; /* parameter values passed into query */
qd->queryEnv = queryEnv;
@@ -108,8 +108,8 @@ FreeQueryDesc(QueryDesc *qdesc)
Assert(qdesc->estate == NULL);
/* forget our snapshots */
- UnregisterSnapshot(qdesc->snapshot);
- UnregisterSnapshot(qdesc->crosscheck_snapshot);
+ UnregisterSnapshot((Snapshot) qdesc->snapshot);
+ UnregisterSnapshot((Snapshot) qdesc->crosscheck_snapshot);
/* Only the QueryDesc itself need be freed */
pfree(qdesc);
@@ -146,7 +146,7 @@ ProcessQuery(PlannedStmt *plan,
* Create the QueryDesc object
*/
queryDesc = CreateQueryDesc(plan, sourceText,
- GetActiveSnapshot(), InvalidSnapshot,
+ GetActiveSnapshot(), InvalidMVCCSnapshot,
dest, params, queryEnv, 0);
/*
@@ -431,7 +431,7 @@ FetchStatementTargetList(Node *stmt)
*/
void
PortalStart(Portal portal, ParamListInfo params,
- int eflags, Snapshot snapshot)
+ int eflags, MVCCSnapshot snapshot)
{
Portal saveActivePortal;
ResourceOwner saveResourceOwner;
@@ -495,7 +495,7 @@ PortalStart(Portal portal, ParamListInfo params,
queryDesc = CreateQueryDesc(linitial_node(PlannedStmt, portal->stmts),
portal->sourceText,
GetActiveSnapshot(),
- InvalidSnapshot,
+ InvalidMVCCSnapshot,
None_Receiver,
params,
portal->queryEnv,
@@ -1127,12 +1127,12 @@ PortalRunUtility(Portal portal, PlannedStmt *pstmt,
*/
if (PlannedStmtRequiresSnapshot(pstmt))
{
- Snapshot snapshot = GetTransactionSnapshot();
+ MVCCSnapshot snapshot = GetTransactionSnapshot();
/* If told to, register the snapshot we're using and save in portal */
if (setHoldSnapshot)
{
- snapshot = RegisterSnapshot(snapshot);
+ snapshot = (MVCCSnapshot) RegisterSnapshot(snapshot);
portal->holdSnapshot = snapshot;
}
@@ -1235,12 +1235,12 @@ PortalRunMulti(Portal portal,
*/
if (!active_snapshot_set)
{
- Snapshot snapshot = GetTransactionSnapshot();
+ MVCCSnapshot snapshot = GetTransactionSnapshot();
/* If told to, register the snapshot and save in portal */
if (setHoldSnapshot)
{
- snapshot = RegisterSnapshot(snapshot);
+ snapshot = (MVCCSnapshot) RegisterSnapshot(snapshot);
portal->holdSnapshot = snapshot;
}
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index 6a76550a5e2..ac253f7330c 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -4692,7 +4692,7 @@ has_lo_priv_byid(Oid roleid, Oid lobjId, AclMode priv, bool *is_missing)
if (priv & ACL_UPDATE)
snapshot = NULL;
else
- snapshot = GetActiveSnapshot();
+ snapshot = (Snapshot) GetActiveSnapshot();
if (!LargeObjectExistsWithSnapshot(lobjId, snapshot))
{
diff --git a/src/backend/utils/adt/ri_triggers.c b/src/backend/utils/adt/ri_triggers.c
index 0d8b53d1b75..cab86849a13 100644
--- a/src/backend/utils/adt/ri_triggers.c
+++ b/src/backend/utils/adt/ri_triggers.c
@@ -1639,7 +1639,7 @@ RI_Initial_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
spi_result = SPI_execute_snapshot(qplan,
NULL, NULL,
GetLatestSnapshot(),
- InvalidSnapshot,
+ InvalidMVCCSnapshot,
true, false, 1);
/* Check result */
@@ -1878,7 +1878,7 @@ RI_PartitionRemove_Check(Trigger *trigger, Relation fk_rel, Relation pk_rel)
spi_result = SPI_execute_snapshot(qplan,
NULL, NULL,
GetLatestSnapshot(),
- InvalidSnapshot,
+ InvalidMVCCSnapshot,
true, false, 1);
/* Check result */
@@ -2400,8 +2400,8 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo,
Relation query_rel,
source_rel;
bool source_is_pk;
- Snapshot test_snapshot;
- Snapshot crosscheck_snapshot;
+ MVCCSnapshot test_snapshot;
+ MVCCSnapshot crosscheck_snapshot;
int limit;
int spi_result;
Oid save_userid;
@@ -2471,8 +2471,8 @@ ri_PerformCheck(const RI_ConstraintInfo *riinfo,
else
{
/* the default SPI behavior is okay */
- test_snapshot = InvalidSnapshot;
- crosscheck_snapshot = InvalidSnapshot;
+ test_snapshot = InvalidMVCCSnapshot;
+ crosscheck_snapshot = InvalidMVCCSnapshot;
}
/*
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 2089b52d575..e4e5cdb7cae 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -2192,7 +2192,7 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
StringInfoData buf;
SysScanDesc scandesc;
ScanKeyData scankey[1];
- Snapshot snapshot = RegisterSnapshot(GetTransactionSnapshot());
+ Snapshot snapshot = (Snapshot) RegisterSnapshot(GetTransactionSnapshot());
Relation relation = table_open(ConstraintRelationId, AccessShareLock);
ScanKeyInit(&scankey[0],
diff --git a/src/backend/utils/adt/tid.c b/src/backend/utils/adt/tid.c
index 1b0df111717..de2ded46a1e 100644
--- a/src/backend/utils/adt/tid.c
+++ b/src/backend/utils/adt/tid.c
@@ -320,7 +320,7 @@ currtid_internal(Relation rel, ItemPointer tid)
ItemPointerCopy(tid, result);
- snapshot = RegisterSnapshot(GetLatestSnapshot());
+ snapshot = (Snapshot) RegisterSnapshot(GetLatestSnapshot());
scan = table_beginscan_tid(rel, snapshot);
table_tuple_get_latest_tid(scan, result);
table_endscan(scan);
diff --git a/src/backend/utils/adt/xid8funcs.c b/src/backend/utils/adt/xid8funcs.c
index 4736755b298..4303acbc664 100644
--- a/src/backend/utils/adt/xid8funcs.c
+++ b/src/backend/utils/adt/xid8funcs.c
@@ -409,7 +409,7 @@ pg_current_snapshot(PG_FUNCTION_ARGS)
pg_snapshot *snap;
uint32 nxip,
i;
- Snapshot cur;
+ MVCCSnapshot cur;
FullTransactionId next_fxid = ReadNextFullTransactionId();
cur = GetActiveSnapshot();
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 01bb6a410cb..ea1a548d573 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -1286,7 +1286,7 @@ process_settings(Oid databaseid, Oid roleid)
relsetting = table_open(DbRoleSettingRelationId, AccessShareLock);
/* read all the settings under the same snapshot for efficiency */
- snapshot = RegisterSnapshot(GetCatalogSnapshot(DbRoleSettingRelationId));
+ snapshot = RegisterCatalogSnapshot(GetCatalogSnapshot(DbRoleSettingRelationId));
/* Later settings are ignored if set earlier. */
ApplySetting(snapshot, databaseid, roleid, relsetting, PGC_S_DATABASE_USER);
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index 0be1c2b0fff..d4e10a74c79 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -526,7 +526,7 @@ PortalDrop(Portal portal, bool isTopCommit)
if (portal->holdSnapshot)
{
if (portal->resowner)
- UnregisterSnapshotFromOwner(portal->holdSnapshot,
+ UnregisterSnapshotFromOwner((Snapshot) portal->holdSnapshot,
portal->resowner);
portal->holdSnapshot = NULL;
}
@@ -709,7 +709,7 @@ PreCommit_Portals(bool isPrepare)
if (portal->holdSnapshot)
{
if (portal->resowner)
- UnregisterSnapshotFromOwner(portal->holdSnapshot,
+ UnregisterSnapshotFromOwner((Snapshot) portal->holdSnapshot,
portal->resowner);
portal->holdSnapshot = NULL;
}
diff --git a/src/backend/utils/time/snapmgr.c b/src/backend/utils/time/snapmgr.c
index 76992eb094f..6ffe5ebc459 100644
--- a/src/backend/utils/time/snapmgr.c
+++ b/src/backend/utils/time/snapmgr.c
@@ -133,18 +133,18 @@
* These SnapshotData structs are static to simplify memory allocation
* (see the hack in GetSnapshotData to avoid repeated malloc/free).
*/
-static SnapshotData CurrentSnapshotData = {SNAPSHOT_MVCC};
-static SnapshotData SecondarySnapshotData = {SNAPSHOT_MVCC};
-static SnapshotData CatalogSnapshotData = {SNAPSHOT_MVCC};
+static MVCCSnapshotData CurrentSnapshotData = {SNAPSHOT_MVCC};
+static MVCCSnapshotData SecondarySnapshotData = {SNAPSHOT_MVCC};
+static MVCCSnapshotData CatalogSnapshotData = {SNAPSHOT_MVCC};
SnapshotData SnapshotSelfData = {SNAPSHOT_SELF};
SnapshotData SnapshotAnyData = {SNAPSHOT_ANY};
SnapshotData SnapshotToastData = {SNAPSHOT_TOAST};
/* Pointers to valid snapshots */
-static Snapshot CurrentSnapshot = NULL;
-static Snapshot SecondarySnapshot = NULL;
-static Snapshot CatalogSnapshot = NULL;
-static Snapshot HistoricSnapshot = NULL;
+static MVCCSnapshot CurrentSnapshot = NULL;
+static MVCCSnapshot SecondarySnapshot = NULL;
+static MVCCSnapshot CatalogSnapshot = NULL;
+static HistoricMVCCSnapshot HistoricSnapshot = NULL;
/*
* These are updated by GetSnapshotData. We initialize them this way
@@ -167,7 +167,7 @@ static HTAB *tuplecid_data = NULL;
*/
typedef struct ActiveSnapshotElt
{
- Snapshot as_snap;
+ MVCCSnapshot as_snap;
int as_level;
struct ActiveSnapshotElt *as_next;
} ActiveSnapshotElt;
@@ -192,7 +192,7 @@ bool FirstSnapshotSet = false;
* FirstSnapshotSet in combination with IsolationUsesXactSnapshot(), because
* GUC may be reset before us, changing the value of IsolationUsesXactSnapshot.
*/
-static Snapshot FirstXactSnapshot = NULL;
+static MVCCSnapshot FirstXactSnapshot = NULL;
/* Define pathname of exported-snapshot files */
#define SNAPSHOT_EXPORT_DIR "pg_snapshots"
@@ -201,16 +201,16 @@ static Snapshot FirstXactSnapshot = NULL;
typedef struct ExportedSnapshot
{
char *snapfile;
- Snapshot snapshot;
+ MVCCSnapshot snapshot;
} ExportedSnapshot;
/* Current xact's exported snapshots (a list of ExportedSnapshot structs) */
static List *exportedSnapshots = NIL;
/* Prototypes for local functions */
-static Snapshot CopySnapshot(Snapshot snapshot);
+static MVCCSnapshot CopyMVCCSnapshot(MVCCSnapshot snapshot);
static void UnregisterSnapshotNoOwner(Snapshot snapshot);
-static void FreeSnapshot(Snapshot snapshot);
+static void FreeMVCCSnapshot(MVCCSnapshot snapshot);
static void SnapshotResetXmin(void);
/* ResourceOwner callbacks to track snapshot references */
@@ -263,7 +263,7 @@ typedef struct SerializedSnapshotData
* RegisterSnapshot or PushActiveSnapshot on the returned snap if it is to be
* used very long.
*/
-Snapshot
+MVCCSnapshot
GetTransactionSnapshot(void)
{
/*
@@ -304,8 +304,9 @@ GetTransactionSnapshot(void)
CurrentSnapshot = GetSerializableTransactionSnapshot(&CurrentSnapshotData);
else
CurrentSnapshot = GetSnapshotData(&CurrentSnapshotData);
+
/* Make a saved copy */
- CurrentSnapshot = CopySnapshot(CurrentSnapshot);
+ CurrentSnapshot = CopyMVCCSnapshot(CurrentSnapshot);
FirstXactSnapshot = CurrentSnapshot;
/* Mark it as "registered" in FirstXactSnapshot */
FirstXactSnapshot->regd_count++;
@@ -334,7 +335,7 @@ GetTransactionSnapshot(void)
* Get a snapshot that is up-to-date as of the current instant,
* even if we are executing in transaction-snapshot mode.
*/
-Snapshot
+MVCCSnapshot
GetLatestSnapshot(void)
{
/*
@@ -376,7 +377,7 @@ GetCatalogSnapshot(Oid relid)
* finishing decoding.
*/
if (HistoricSnapshotActive())
- return HistoricSnapshot;
+ return (Snapshot) HistoricSnapshot;
return GetNonHistoricCatalogSnapshot(relid);
}
@@ -422,7 +423,7 @@ GetNonHistoricCatalogSnapshot(Oid relid)
pairingheap_add(&RegisteredSnapshots, &CatalogSnapshot->ph_node);
}
- return CatalogSnapshot;
+ return (Snapshot) CatalogSnapshot;
}
/*
@@ -491,7 +492,7 @@ SnapshotSetCommandId(CommandId curcid)
* in GetTransactionSnapshot.
*/
static void
-SetTransactionSnapshot(Snapshot sourcesnap, VirtualTransactionId *sourcevxid,
+SetTransactionSnapshot(MVCCSnapshot sourcesnap, VirtualTransactionId *sourcevxid,
int sourcepid, PGPROC *sourceproc)
{
/* Caller should have checked this already */
@@ -570,7 +571,7 @@ SetTransactionSnapshot(Snapshot sourcesnap, VirtualTransactionId *sourcevxid,
SetSerializableTransactionSnapshot(CurrentSnapshot, sourcevxid,
sourcepid);
/* Make a saved copy */
- CurrentSnapshot = CopySnapshot(CurrentSnapshot);
+ CurrentSnapshot = CopyMVCCSnapshot(CurrentSnapshot);
FirstXactSnapshot = CurrentSnapshot;
/* Mark it as "registered" in FirstXactSnapshot */
FirstXactSnapshot->regd_count++;
@@ -581,30 +582,27 @@ SetTransactionSnapshot(Snapshot sourcesnap, VirtualTransactionId *sourcevxid,
}
/*
- * CopySnapshot
+ * CopyMVCCSnapshot
* Copy the given snapshot.
*
* The copy is palloc'd in TopTransactionContext and has initial refcounts set
* to 0. The returned snapshot has the copied flag set.
*/
-static Snapshot
-CopySnapshot(Snapshot snapshot)
+static MVCCSnapshot
+CopyMVCCSnapshot(MVCCSnapshot snapshot)
{
- Snapshot newsnap;
+ MVCCSnapshot newsnap;
Size subxipoff;
Size size;
- Assert(snapshot != InvalidSnapshot);
- Assert(snapshot->snapshot_type == SNAPSHOT_MVCC || snapshot->snapshot_type == SNAPSHOT_HISTORIC_MVCC);
-
/* We allocate any XID arrays needed in the same palloc block. */
- size = subxipoff = sizeof(SnapshotData) +
+ size = subxipoff = sizeof(MVCCSnapshotData) +
snapshot->xcnt * sizeof(TransactionId);
if (snapshot->subxcnt > 0)
size += snapshot->subxcnt * sizeof(TransactionId);
- newsnap = (Snapshot) MemoryContextAlloc(TopTransactionContext, size);
- memcpy(newsnap, snapshot, sizeof(SnapshotData));
+ newsnap = (MVCCSnapshot) MemoryContextAlloc(TopTransactionContext, size);
+ memcpy(newsnap, snapshot, sizeof(MVCCSnapshotData));
newsnap->regd_count = 0;
newsnap->active_count = 0;
@@ -641,11 +639,11 @@ CopySnapshot(Snapshot snapshot)
}
/*
- * FreeSnapshot
+ * FreeMVCCSnapshot
* Free the memory associated with a snapshot.
*/
static void
-FreeSnapshot(Snapshot snapshot)
+FreeMVCCSnapshot(MVCCSnapshot snapshot)
{
Assert(snapshot->regd_count == 0);
Assert(snapshot->active_count == 0);
@@ -663,7 +661,7 @@ FreeSnapshot(Snapshot snapshot)
* with active refcount=1. Otherwise, only increment the refcount.
*/
void
-PushActiveSnapshot(Snapshot snapshot)
+PushActiveSnapshot(MVCCSnapshot snapshot)
{
PushActiveSnapshotWithLevel(snapshot, GetCurrentTransactionNestLevel());
}
@@ -677,13 +675,12 @@ PushActiveSnapshot(Snapshot snapshot)
* must not be deeper than the current top of the snapshot stack.
*/
void
-PushActiveSnapshotWithLevel(Snapshot snapshot, int snap_level)
+PushActiveSnapshotWithLevel(MVCCSnapshot snapshot, int snap_level)
{
ActiveSnapshotElt *newactive;
Assert(snapshot->snapshot_type == SNAPSHOT_MVCC);
- Assert(snapshot != InvalidSnapshot);
Assert(ActiveSnapshot == NULL || snap_level >= ActiveSnapshot->as_level);
newactive = MemoryContextAlloc(TopTransactionContext, sizeof(ActiveSnapshotElt));
@@ -694,7 +691,7 @@ PushActiveSnapshotWithLevel(Snapshot snapshot, int snap_level)
*/
if (snapshot == CurrentSnapshot || snapshot == SecondarySnapshot ||
!snapshot->copied)
- newactive->as_snap = CopySnapshot(snapshot);
+ newactive->as_snap = CopyMVCCSnapshot(snapshot);
else
newactive->as_snap = snapshot;
@@ -715,9 +712,9 @@ PushActiveSnapshotWithLevel(Snapshot snapshot, int snap_level)
* The new snapshot will be released when popped from the stack.
*/
void
-PushCopiedSnapshot(Snapshot snapshot)
+PushCopiedSnapshot(MVCCSnapshot snapshot)
{
- PushActiveSnapshot(CopySnapshot(snapshot));
+ PushActiveSnapshot(CopyMVCCSnapshot(snapshot));
}
/*
@@ -770,7 +767,7 @@ PopActiveSnapshot(void)
if (ActiveSnapshot->as_snap->active_count == 0 &&
ActiveSnapshot->as_snap->regd_count == 0)
- FreeSnapshot(ActiveSnapshot->as_snap);
+ FreeMVCCSnapshot(ActiveSnapshot->as_snap);
pfree(ActiveSnapshot);
ActiveSnapshot = newstack;
@@ -782,7 +779,7 @@ PopActiveSnapshot(void)
* GetActiveSnapshot
* Return the topmost snapshot in the Active stack.
*/
-Snapshot
+MVCCSnapshot
GetActiveSnapshot(void)
{
Assert(ActiveSnapshot != NULL);
@@ -806,11 +803,11 @@ ActiveSnapshotSet(void)
*
* If InvalidSnapshot is passed, it is not registered.
*/
-Snapshot
-RegisterSnapshot(Snapshot snapshot)
+MVCCSnapshot
+RegisterSnapshot(MVCCSnapshot snapshot)
{
- if (snapshot == InvalidSnapshot)
- return InvalidSnapshot;
+ if (snapshot == InvalidMVCCSnapshot)
+ return InvalidMVCCSnapshot;
return RegisterSnapshotOnOwner(snapshot, CurrentResourceOwner);
}
@@ -819,28 +816,47 @@ RegisterSnapshot(Snapshot snapshot)
* RegisterSnapshotOnOwner
* As above, but use the specified resource owner
*/
-Snapshot
-RegisterSnapshotOnOwner(Snapshot snapshot, ResourceOwner owner)
+MVCCSnapshot
+RegisterSnapshotOnOwner(MVCCSnapshot snapshot, ResourceOwner owner)
{
- Snapshot snap;
-
- if (snapshot == InvalidSnapshot)
- return InvalidSnapshot;
-
- Assert(snapshot->snapshot_type == SNAPSHOT_MVCC || snapshot->snapshot_type == SNAPSHOT_HISTORIC_MVCC);
+ if (snapshot == InvalidMVCCSnapshot)
+ return InvalidMVCCSnapshot;
/* Static snapshot? Create a persistent copy */
- snap = snapshot->copied ? snapshot : CopySnapshot(snapshot);
+ snapshot = snapshot->copied ? snapshot : CopyMVCCSnapshot(snapshot);
/* and tell resowner.c about it */
ResourceOwnerEnlarge(owner);
- snap->regd_count++;
- ResourceOwnerRememberSnapshot(owner, snap);
+ snapshot->regd_count++;
+ ResourceOwnerRememberSnapshot(owner, (Snapshot) snapshot);
+
+ if (snapshot->regd_count == 1)
+ pairingheap_add(&RegisteredSnapshots, &snapshot->ph_node);
+
+ return snapshot;
+}
+
+/*
+ * RegisterCatalogSnapshot
+ * Like RegisterSnapshot(), but also works for historic snapshots
+ */
+Snapshot
+RegisterCatalogSnapshot(Snapshot snapshot)
+{
+ if (snapshot->snapshot_type == SNAPSHOT_MVCC)
+ return (Snapshot) RegisterSnapshot(&snapshot->mvcc);
+ else if (snapshot->snapshot_type == SNAPSHOT_HISTORIC_MVCC)
+ {
+ HistoricMVCCSnapshot historicsnap = &snapshot->historic_mvcc;
- if (snap->regd_count == 1)
- pairingheap_add(&RegisteredSnapshots, &snap->ph_node);
+ ResourceOwnerEnlarge(CurrentResourceOwner);
+ historicsnap->regd_count++;
+ ResourceOwnerRememberSnapshot(CurrentResourceOwner, (Snapshot) historicsnap);
- return snap;
+ return (Snapshot) historicsnap;
+ }
+ else
+ elog(ERROR, "cannot register non-MVCC snapshot");
}
/*
@@ -876,18 +892,32 @@ UnregisterSnapshotFromOwner(Snapshot snapshot, ResourceOwner owner)
static void
UnregisterSnapshotNoOwner(Snapshot snapshot)
{
- Assert(snapshot->regd_count > 0);
- Assert(!pairingheap_is_empty(&RegisteredSnapshots));
+ if (snapshot->snapshot_type == SNAPSHOT_MVCC)
+ {
+ MVCCSnapshot mvccsnap = &snapshot->mvcc;
+
+ Assert(mvccsnap->regd_count > 0);
+ Assert(!pairingheap_is_empty(&RegisteredSnapshots));
- snapshot->regd_count--;
- if (snapshot->regd_count == 0)
- pairingheap_remove(&RegisteredSnapshots, &snapshot->ph_node);
+ mvccsnap->regd_count--;
+ if (mvccsnap->regd_count == 0)
+ pairingheap_remove(&RegisteredSnapshots, &mvccsnap->ph_node);
- if (snapshot->regd_count == 0 && snapshot->active_count == 0)
+ if (mvccsnap->regd_count == 0 && mvccsnap->active_count == 0)
+ {
+ FreeMVCCSnapshot(mvccsnap);
+ SnapshotResetXmin();
+ }
+ }
+ else if (snapshot->snapshot_type == SNAPSHOT_HISTORIC_MVCC)
{
- FreeSnapshot(snapshot);
- SnapshotResetXmin();
+ HistoricMVCCSnapshot historicsnap = &snapshot->historic_mvcc;
+
+ Assert(historicsnap->regd_count > 0);
+ historicsnap->regd_count--;
}
+ else
+ elog(ERROR, "registered snapshot has unexpected type");
}
/*
@@ -897,8 +927,8 @@ UnregisterSnapshotNoOwner(Snapshot snapshot)
static int
xmin_cmp(const pairingheap_node *a, const pairingheap_node *b, void *arg)
{
- const SnapshotData *asnap = pairingheap_const_container(SnapshotData, ph_node, a);
- const SnapshotData *bsnap = pairingheap_const_container(SnapshotData, ph_node, b);
+ const MVCCSnapshotData *asnap = pairingheap_const_container(MVCCSnapshotData, ph_node, a);
+ const MVCCSnapshotData *bsnap = pairingheap_const_container(MVCCSnapshotData, ph_node, b);
if (TransactionIdPrecedes(asnap->xmin, bsnap->xmin))
return 1;
@@ -924,7 +954,7 @@ xmin_cmp(const pairingheap_node *a, const pairingheap_node *b, void *arg)
static void
SnapshotResetXmin(void)
{
- Snapshot minSnapshot;
+ MVCCSnapshot minSnapshot;
if (ActiveSnapshot != NULL)
return;
@@ -935,7 +965,7 @@ SnapshotResetXmin(void)
return;
}
- minSnapshot = pairingheap_container(SnapshotData, ph_node,
+ minSnapshot = pairingheap_container(MVCCSnapshotData, ph_node,
pairingheap_first(&RegisteredSnapshots));
if (TransactionIdPrecedes(MyProc->xmin, minSnapshot->xmin))
@@ -985,7 +1015,7 @@ AtSubAbort_Snapshot(int level)
if (ActiveSnapshot->as_snap->active_count == 0 &&
ActiveSnapshot->as_snap->regd_count == 0)
- FreeSnapshot(ActiveSnapshot->as_snap);
+ FreeMVCCSnapshot(ActiveSnapshot->as_snap);
/* and free the stack element */
pfree(ActiveSnapshot);
@@ -1007,7 +1037,7 @@ AtEOXact_Snapshot(bool isCommit, bool resetXmin)
* In transaction-snapshot mode we must release our privately-managed
* reference to the transaction snapshot. We must remove it from
* RegisteredSnapshots to keep the check below happy. But we don't bother
- * to do FreeSnapshot, for two reasons: the memory will go away with
+ * to do FreeMVCCSnapshot, for two reasons: the memory will go away with
* TopTransactionContext anyway, and if someone has left the snapshot
* stacked as active, we don't want the code below to be chasing through a
* dangling pointer.
@@ -1100,7 +1130,7 @@ AtEOXact_Snapshot(bool isCommit, bool resetXmin)
* snapshot.
*/
char *
-ExportSnapshot(Snapshot snapshot)
+ExportSnapshot(MVCCSnapshot snapshot)
{
TransactionId topXid;
TransactionId *children;
@@ -1164,7 +1194,7 @@ ExportSnapshot(Snapshot snapshot)
* ensure that the snapshot's xmin is honored for the rest of the
* transaction.
*/
- snapshot = CopySnapshot(snapshot);
+ snapshot = CopyMVCCSnapshot(snapshot);
oldcxt = MemoryContextSwitchTo(TopTransactionContext);
esnap = (ExportedSnapshot *) palloc(sizeof(ExportedSnapshot));
@@ -1385,7 +1415,7 @@ ImportSnapshot(const char *idstr)
Oid src_dbid;
int src_isolevel;
bool src_readonly;
- SnapshotData snapshot;
+ MVCCSnapshotData snapshot;
/*
* Must be at top level of a fresh transaction. Note in particular that
@@ -1654,7 +1684,7 @@ HaveRegisteredOrActiveSnapshot(void)
* Needed for logical decoding.
*/
void
-SetupHistoricSnapshot(Snapshot historic_snapshot, HTAB *tuplecids)
+SetupHistoricSnapshot(HistoricMVCCSnapshot historic_snapshot, HTAB *tuplecids)
{
Assert(historic_snapshot != NULL);
@@ -1697,11 +1727,10 @@ HistoricSnapshotGetTupleCids(void)
* SerializedSnapshotData.
*/
Size
-EstimateSnapshotSpace(Snapshot snapshot)
+EstimateSnapshotSpace(MVCCSnapshot snapshot)
{
Size size;
- Assert(snapshot != InvalidSnapshot);
Assert(snapshot->snapshot_type == SNAPSHOT_MVCC);
/* We allocate any XID arrays needed in the same palloc block. */
@@ -1721,7 +1750,7 @@ EstimateSnapshotSpace(Snapshot snapshot)
* memory location at start_address.
*/
void
-SerializeSnapshot(Snapshot snapshot, char *start_address)
+SerializeSnapshot(MVCCSnapshot snapshot, char *start_address)
{
SerializedSnapshotData serialized_snapshot;
@@ -1777,12 +1806,12 @@ SerializeSnapshot(Snapshot snapshot, char *start_address)
* The copy is palloc'd in TopTransactionContext and has initial refcounts set
* to 0. The returned snapshot has the copied flag set.
*/
-Snapshot
+MVCCSnapshot
RestoreSnapshot(char *start_address)
{
SerializedSnapshotData serialized_snapshot;
Size size;
- Snapshot snapshot;
+ MVCCSnapshot snapshot;
TransactionId *serialized_xids;
memcpy(&serialized_snapshot, start_address,
@@ -1791,12 +1820,12 @@ RestoreSnapshot(char *start_address)
(start_address + sizeof(SerializedSnapshotData));
/* We allocate any XID arrays needed in the same palloc block. */
- size = sizeof(SnapshotData)
+ size = sizeof(MVCCSnapshotData)
+ serialized_snapshot.xcnt * sizeof(TransactionId)
+ serialized_snapshot.subxcnt * sizeof(TransactionId);
/* Copy all required fields */
- snapshot = (Snapshot) MemoryContextAlloc(TopTransactionContext, size);
+ snapshot = (MVCCSnapshot) MemoryContextAlloc(TopTransactionContext, size);
snapshot->snapshot_type = SNAPSHOT_MVCC;
snapshot->xmin = serialized_snapshot.xmin;
snapshot->xmax = serialized_snapshot.xmax;
@@ -1841,7 +1870,7 @@ RestoreSnapshot(char *start_address)
* the declaration for PGPROC.
*/
void
-RestoreTransactionSnapshot(Snapshot snapshot, void *source_pgproc)
+RestoreTransactionSnapshot(MVCCSnapshot snapshot, void *source_pgproc)
{
SetTransactionSnapshot(snapshot, NULL, InvalidPid, source_pgproc);
}
@@ -1857,7 +1886,7 @@ RestoreTransactionSnapshot(Snapshot snapshot, void *source_pgproc)
* XID could not be ours anyway.
*/
bool
-XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot)
+XidInMVCCSnapshot(TransactionId xid, MVCCSnapshot snapshot)
{
/*
* Make a quick range check to eliminate most XIDs without looking at the
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index 1be8739573f..a39f5c90538 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -168,9 +168,9 @@ extern void index_endscan(IndexScanDesc scan);
extern void index_markpos(IndexScanDesc scan);
extern void index_restrpos(IndexScanDesc scan);
extern Size index_parallelscan_estimate(Relation indexRelation,
- int nkeys, int norderbys, Snapshot snapshot);
+ int nkeys, int norderbys, MVCCSnapshot snapshot);
extern void index_parallelscan_initialize(Relation heapRelation,
- Relation indexRelation, Snapshot snapshot,
+ Relation indexRelation, MVCCSnapshot snapshot,
ParallelIndexScanDesc target);
extern void index_parallelrescan(IndexScanDesc scan);
extern IndexScanDesc index_beginscan_parallel(Relation heaprel,
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index 7d06dad83fc..650c77eaea2 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -423,7 +423,7 @@ extern bool HeapTupleIsSurelyDead(HeapTuple htup,
*/
struct HTAB;
extern bool ResolveCminCmaxDuringDecoding(struct HTAB *tuplecid_data,
- Snapshot snapshot,
+ HistoricMVCCSnapshot snapshot,
HeapTuple htup,
Buffer buffer,
CommandId *cmin, CommandId *cmax);
diff --git a/src/include/access/relscan.h b/src/include/access/relscan.h
index dc6e0184284..1c098f75e5b 100644
--- a/src/include/access/relscan.h
+++ b/src/include/access/relscan.h
@@ -34,7 +34,7 @@ typedef struct TableScanDescData
{
/* scan parameters */
Relation rs_rd; /* heap relation descriptor */
- struct SnapshotData *rs_snapshot; /* snapshot to see */
+ union SnapshotData *rs_snapshot; /* snapshot to see */
int rs_nkeys; /* number of scan keys */
struct ScanKeyData *rs_key; /* array of scan key descriptors */
@@ -133,7 +133,7 @@ typedef struct IndexScanDescData
/* scan parameters */
Relation heapRelation; /* heap relation descriptor, or NULL */
Relation indexRelation; /* index relation descriptor */
- struct SnapshotData *xs_snapshot; /* snapshot to see */
+ union SnapshotData *xs_snapshot; /* snapshot to see */
int numberOfKeys; /* number of index qualifier conditions */
int numberOfOrderBys; /* number of ordering operators */
struct ScanKeyData *keyData; /* array of index qualifier descriptors */
@@ -201,7 +201,7 @@ typedef struct SysScanDescData
Relation irel; /* NULL if doing heap scan */
struct TableScanDescData *scan; /* only valid in storage-scan case */
struct IndexScanDescData *iscan; /* only valid in index-scan case */
- struct SnapshotData *snapshot; /* snapshot to unregister at end of scan */
+ union SnapshotData *snapshot; /* snapshot to unregister at end of scan */
struct TupleTableSlot *slot;
} SysScanDescData;
diff --git a/src/include/executor/execdesc.h b/src/include/executor/execdesc.h
index 86db3dc8d0d..2ce0b23ba49 100644
--- a/src/include/executor/execdesc.h
+++ b/src/include/executor/execdesc.h
@@ -36,8 +36,8 @@ typedef struct QueryDesc
CmdType operation; /* CMD_SELECT, CMD_UPDATE, etc. */
PlannedStmt *plannedstmt; /* planner's output (could be utility, too) */
const char *sourceText; /* source text of the query */
- Snapshot snapshot; /* snapshot to use for query */
- Snapshot crosscheck_snapshot; /* crosscheck for RI update/delete */
+ MVCCSnapshot snapshot; /* snapshot to use for query */
+ MVCCSnapshot crosscheck_snapshot; /* crosscheck for RI update/delete */
DestReceiver *dest; /* the destination for tuple output */
ParamListInfo params; /* param values being passed in */
QueryEnvironment *queryEnv; /* query environment passed in */
@@ -58,8 +58,8 @@ typedef struct QueryDesc
/* in pquery.c */
extern QueryDesc *CreateQueryDesc(PlannedStmt *plannedstmt,
const char *sourceText,
- Snapshot snapshot,
- Snapshot crosscheck_snapshot,
+ MVCCSnapshot snapshot,
+ MVCCSnapshot crosscheck_snapshot,
DestReceiver *dest,
ParamListInfo params,
QueryEnvironment *queryEnv,
diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h
index d064d1a9b76..eb804f7c3e4 100644
--- a/src/include/executor/spi.h
+++ b/src/include/executor/spi.h
@@ -123,8 +123,8 @@ extern int SPI_execp(SPIPlanPtr plan, Datum *Values, const char *Nulls,
long tcount);
extern int SPI_execute_snapshot(SPIPlanPtr plan,
Datum *Values, const char *Nulls,
- Snapshot snapshot,
- Snapshot crosscheck_snapshot,
+ MVCCSnapshot snapshot,
+ MVCCSnapshot crosscheck_snapshot,
bool read_only, bool fire_triggers, long tcount);
extern int SPI_execute_with_args(const char *src,
int nargs, Oid *argtypes,
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 29127416076..5ff7f394973 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -629,8 +629,8 @@ typedef struct EState
/* Basic state for all query types: */
ScanDirection es_direction; /* current scan direction */
- Snapshot es_snapshot; /* time qual to use */
- Snapshot es_crosscheck_snapshot; /* crosscheck time qual for RI */
+ MVCCSnapshot es_snapshot; /* time qual to use */
+ MVCCSnapshot es_crosscheck_snapshot; /* crosscheck time qual for RI */
List *es_range_table; /* List of RangeTblEntry */
Index es_range_table_size; /* size of the range table arrays */
Relation *es_relations; /* Array of per-range-table-entry Relation
diff --git a/src/include/replication/reorderbuffer.h b/src/include/replication/reorderbuffer.h
index a669658b3f1..1dd4e2f7527 100644
--- a/src/include/replication/reorderbuffer.h
+++ b/src/include/replication/reorderbuffer.h
@@ -127,7 +127,7 @@ typedef struct ReorderBufferChange
} msg;
/* New snapshot, set when action == *_INTERNAL_SNAPSHOT */
- Snapshot snapshot;
+ HistoricMVCCSnapshot snapshot;
/*
* New command id for existing snapshot in a catalog changing tx. Set
@@ -330,7 +330,7 @@ typedef struct ReorderBufferTXN
* transaction modifies the catalog, or another catalog-modifying
* transaction commits.
*/
- Snapshot base_snapshot;
+ HistoricMVCCSnapshot base_snapshot;
XLogRecPtr base_snapshot_lsn;
dlist_node base_snapshot_node; /* link in txns_by_base_snapshot_lsn */
@@ -338,7 +338,7 @@ typedef struct ReorderBufferTXN
* Snapshot/CID from the previous streaming run. Only valid for already
* streamed transactions (NULL/InvalidCommandId otherwise).
*/
- Snapshot snapshot_now;
+ HistoricMVCCSnapshot snapshot_now;
CommandId command_id;
/*
@@ -678,7 +678,7 @@ extern void ReorderBufferQueueChange(ReorderBuffer *rb, TransactionId xid,
XLogRecPtr lsn, ReorderBufferChange *change,
bool toast_insert);
extern void ReorderBufferQueueMessage(ReorderBuffer *rb, TransactionId xid,
- Snapshot snap, XLogRecPtr lsn,
+ HistoricMVCCSnapshot snap, XLogRecPtr lsn,
bool transactional, const char *prefix,
Size message_size, const char *message);
extern void ReorderBufferCommit(ReorderBuffer *rb, TransactionId xid,
@@ -702,9 +702,9 @@ extern void ReorderBufferForget(ReorderBuffer *rb, TransactionId xid, XLogRecPtr
extern void ReorderBufferInvalidate(ReorderBuffer *rb, TransactionId xid, XLogRecPtr lsn);
extern void ReorderBufferSetBaseSnapshot(ReorderBuffer *rb, TransactionId xid,
- XLogRecPtr lsn, Snapshot snap);
+ XLogRecPtr lsn, HistoricMVCCSnapshot snap);
extern void ReorderBufferAddSnapshot(ReorderBuffer *rb, TransactionId xid,
- XLogRecPtr lsn, Snapshot snap);
+ XLogRecPtr lsn, HistoricMVCCSnapshot snap);
extern void ReorderBufferAddNewCommandId(ReorderBuffer *rb, TransactionId xid,
XLogRecPtr lsn, CommandId cid);
extern void ReorderBufferAddNewTupleCids(ReorderBuffer *rb, TransactionId xid,
diff --git a/src/include/replication/snapbuild.h b/src/include/replication/snapbuild.h
index 44031dcf6e3..5930ffb55a8 100644
--- a/src/include/replication/snapbuild.h
+++ b/src/include/replication/snapbuild.h
@@ -70,15 +70,15 @@ extern SnapBuild *AllocateSnapshotBuilder(struct ReorderBuffer *reorder,
XLogRecPtr two_phase_at);
extern void FreeSnapshotBuilder(SnapBuild *builder);
-extern void SnapBuildSnapDecRefcount(Snapshot snap);
+extern void SnapBuildSnapDecRefcount(HistoricMVCCSnapshot snap);
-extern Snapshot SnapBuildInitialSnapshot(SnapBuild *builder);
+extern MVCCSnapshot SnapBuildInitialSnapshot(SnapBuild *builder);
extern const char *SnapBuildExportSnapshot(SnapBuild *builder);
extern void SnapBuildClearExportedSnapshot(void);
extern void SnapBuildResetExportedSnapshotState(void);
extern SnapBuildState SnapBuildCurrentState(SnapBuild *builder);
-extern Snapshot SnapBuildGetOrBuildSnapshot(SnapBuild *builder);
+extern HistoricMVCCSnapshot SnapBuildGetOrBuildSnapshot(SnapBuild *builder);
extern bool SnapBuildXactNeedsSkip(SnapBuild *builder, XLogRecPtr ptr);
extern XLogRecPtr SnapBuildGetTwoPhaseAt(SnapBuild *builder);
diff --git a/src/include/replication/snapbuild_internal.h b/src/include/replication/snapbuild_internal.h
index 081b01b890a..ef00d125155 100644
--- a/src/include/replication/snapbuild_internal.h
+++ b/src/include/replication/snapbuild_internal.h
@@ -74,7 +74,7 @@ struct SnapBuild
/*
* Snapshot that's valid to see the catalog state seen at this moment.
*/
- Snapshot snapshot;
+ HistoricMVCCSnapshot snapshot;
/*
* LSN of the last location we are sure a snapshot has been serialized to.
diff --git a/src/include/storage/large_object.h b/src/include/storage/large_object.h
index 6fecf442446..5cb3ebb6a9f 100644
--- a/src/include/storage/large_object.h
+++ b/src/include/storage/large_object.h
@@ -39,7 +39,7 @@
typedef struct LargeObjectDesc
{
Oid id; /* LO's identifier */
- Snapshot snapshot; /* snapshot to use */
+ MVCCSnapshot snapshot; /* snapshot to use */
SubTransactionId subid; /* owning subtransaction ID */
uint64 offset; /* current seek pointer */
int flags; /* see flag bits below */
diff --git a/src/include/storage/predicate.h b/src/include/storage/predicate.h
index 267d5d90e94..6a78dfeac96 100644
--- a/src/include/storage/predicate.h
+++ b/src/include/storage/predicate.h
@@ -47,8 +47,8 @@ extern void CheckPointPredicate(void);
extern bool PageIsPredicateLocked(Relation relation, BlockNumber blkno);
/* predicate lock maintenance */
-extern Snapshot GetSerializableTransactionSnapshot(Snapshot snapshot);
-extern void SetSerializableTransactionSnapshot(Snapshot snapshot,
+extern MVCCSnapshot GetSerializableTransactionSnapshot(MVCCSnapshot snapshot);
+extern void SetSerializableTransactionSnapshot(MVCCSnapshot snapshot,
VirtualTransactionId *sourcevxid,
int sourcepid);
extern void RegisterPredicateLockingXid(TransactionId xid);
diff --git a/src/include/storage/procarray.h b/src/include/storage/procarray.h
index ef0b733ebe8..7f5727c2586 100644
--- a/src/include/storage/procarray.h
+++ b/src/include/storage/procarray.h
@@ -44,7 +44,7 @@ extern void KnownAssignedTransactionIdsIdleMaintenance(void);
extern int GetMaxSnapshotXidCount(void);
extern int GetMaxSnapshotSubxidCount(void);
-extern Snapshot GetSnapshotData(Snapshot snapshot);
+extern MVCCSnapshot GetSnapshotData(MVCCSnapshot snapshot);
extern bool ProcArrayInstallImportedXmin(TransactionId xmin,
VirtualTransactionId *sourcevxid);
diff --git a/src/include/tcop/pquery.h b/src/include/tcop/pquery.h
index fa3cc5f2dfc..1e85e09cec9 100644
--- a/src/include/tcop/pquery.h
+++ b/src/include/tcop/pquery.h
@@ -30,7 +30,7 @@ extern List *FetchPortalTargetList(Portal portal);
extern List *FetchStatementTargetList(Node *stmt);
extern void PortalStart(Portal portal, ParamListInfo params,
- int eflags, Snapshot snapshot);
+ int eflags, MVCCSnapshot snapshot);
extern void PortalSetResultFormat(Portal portal, int nFormats,
int16 *formats);
diff --git a/src/include/utils/portal.h b/src/include/utils/portal.h
index 0b62143af8b..dd27de9139d 100644
--- a/src/include/utils/portal.h
+++ b/src/include/utils/portal.h
@@ -166,7 +166,7 @@ typedef struct PortalData
* This ensures that TOAST references in query results can be detoasted,
* and helps to reduce thrashing of the process's exposed xmin.
*/
- Snapshot portalSnapshot; /* active snapshot, or NULL if none */
+ MVCCSnapshot portalSnapshot; /* active snapshot, or NULL if none */
/*
* Where we store tuples for a held cursor or a PORTAL_ONE_RETURNING,
@@ -184,7 +184,7 @@ typedef struct PortalData
* belonging to them. In the case of a held cursor, we avoid needing to
* keep such a snapshot by forcibly detoasting the data.
*/
- Snapshot holdSnapshot; /* registered snapshot, or NULL if none */
+ MVCCSnapshot holdSnapshot; /* registered snapshot, or NULL if none */
/*
* atStart, atEnd and portalPos indicate the current cursor position.
diff --git a/src/include/utils/snapmgr.h b/src/include/utils/snapmgr.h
index d346be71642..9ee9acf3d50 100644
--- a/src/include/utils/snapmgr.h
+++ b/src/include/utils/snapmgr.h
@@ -49,15 +49,15 @@ extern PGDLLIMPORT SnapshotData SnapshotToastData;
*/
#define InitNonVacuumableSnapshot(snapshotdata, vistestp) \
((snapshotdata).snapshot_type = SNAPSHOT_NON_VACUUMABLE, \
- (snapshotdata).vistest = (vistestp))
+ (snapshotdata).nonvacuumable.vistest = (vistestp))
/* This macro encodes the knowledge of which snapshots are MVCC-safe */
#define IsMVCCSnapshot(snapshot) \
((snapshot)->snapshot_type == SNAPSHOT_MVCC || \
(snapshot)->snapshot_type == SNAPSHOT_HISTORIC_MVCC)
-extern Snapshot GetTransactionSnapshot(void);
-extern Snapshot GetLatestSnapshot(void);
+extern MVCCSnapshot GetTransactionSnapshot(void);
+extern MVCCSnapshot GetLatestSnapshot(void);
extern void SnapshotSetCommandId(CommandId curcid);
extern Snapshot GetCatalogSnapshot(Oid relid);
@@ -65,17 +65,18 @@ extern Snapshot GetNonHistoricCatalogSnapshot(Oid relid);
extern void InvalidateCatalogSnapshot(void);
extern void InvalidateCatalogSnapshotConditionally(void);
-extern void PushActiveSnapshot(Snapshot snapshot);
-extern void PushActiveSnapshotWithLevel(Snapshot snapshot, int snap_level);
-extern void PushCopiedSnapshot(Snapshot snapshot);
+extern void PushActiveSnapshot(MVCCSnapshot snapshot);
+extern void PushActiveSnapshotWithLevel(MVCCSnapshot snapshot, int snap_level);
+extern void PushCopiedSnapshot(MVCCSnapshot snapshot);
extern void UpdateActiveSnapshotCommandId(void);
extern void PopActiveSnapshot(void);
-extern Snapshot GetActiveSnapshot(void);
+extern MVCCSnapshot GetActiveSnapshot(void);
extern bool ActiveSnapshotSet(void);
-extern Snapshot RegisterSnapshot(Snapshot snapshot);
+extern MVCCSnapshot RegisterSnapshot(MVCCSnapshot snapshot);
+extern Snapshot RegisterCatalogSnapshot(Snapshot snapshot);
extern void UnregisterSnapshot(Snapshot snapshot);
-extern Snapshot RegisterSnapshotOnOwner(Snapshot snapshot, ResourceOwner owner);
+extern MVCCSnapshot RegisterSnapshotOnOwner(MVCCSnapshot snapshot, ResourceOwner owner);
extern void UnregisterSnapshotFromOwner(Snapshot snapshot, ResourceOwner owner);
extern void AtSubCommit_Snapshot(int level);
@@ -89,7 +90,7 @@ extern void WaitForOlderSnapshots(TransactionId limitXmin, bool progress);
extern bool ThereAreNoPriorRegisteredSnapshots(void);
extern bool HaveRegisteredOrActiveSnapshot(void);
-extern char *ExportSnapshot(Snapshot snapshot);
+extern char *ExportSnapshot(MVCCSnapshot snapshot);
/*
* These live in procarray.c because they're intimately linked to the
@@ -105,18 +106,18 @@ extern bool GlobalVisCheckRemovableFullXid(Relation rel, FullTransactionId fxid)
/*
* Utility functions for implementing visibility routines in table AMs.
*/
-extern bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot);
+extern bool XidInMVCCSnapshot(TransactionId xid, MVCCSnapshot snapshot);
/* Support for catalog timetravel for logical decoding */
struct HTAB;
extern struct HTAB *HistoricSnapshotGetTupleCids(void);
-extern void SetupHistoricSnapshot(Snapshot historic_snapshot, struct HTAB *tuplecids);
+extern void SetupHistoricSnapshot(HistoricMVCCSnapshot historic_snapshot, struct HTAB *tuplecids);
extern void TeardownHistoricSnapshot(bool is_error);
extern bool HistoricSnapshotActive(void);
-extern Size EstimateSnapshotSpace(Snapshot snapshot);
-extern void SerializeSnapshot(Snapshot snapshot, char *start_address);
-extern Snapshot RestoreSnapshot(char *start_address);
-extern void RestoreTransactionSnapshot(Snapshot snapshot, void *source_pgproc);
+extern Size EstimateSnapshotSpace(MVCCSnapshot snapshot);
+extern void SerializeSnapshot(MVCCSnapshot snapshot, char *start_address);
+extern MVCCSnapshot RestoreSnapshot(char *start_address);
+extern void RestoreTransactionSnapshot(MVCCSnapshot snapshot, void *source_pgproc);
#endif /* SNAPMGR_H */
diff --git a/src/include/utils/snapshot.h b/src/include/utils/snapshot.h
index 0e546ec1497..19af828ea45 100644
--- a/src/include/utils/snapshot.h
+++ b/src/include/utils/snapshot.h
@@ -17,8 +17,8 @@
/*
- * The different snapshot types. We use SnapshotData structures to represent
- * both "regular" (MVCC) snapshots and "special" snapshots that have non-MVCC
+ * The different snapshot types. We use SnapshotData union to represent both
+ * "regular" (MVCC) snapshots and "special" snapshots that have non-MVCC
* semantics. The specific semantics of a snapshot are encoded by its type.
*
* The behaviour of each type of snapshot should be documented alongside its
@@ -27,6 +27,9 @@
* The reason the snapshot type rather than a callback as it used to be is
* that that allows to use the same snapshot for different table AMs without
* having one callback per AM.
+ *
+ * The executor uses MVCC snapshots, and hence use MVCCSnapshot directly. The
+ * table AM APIs also support the special snapshots.
*/
typedef enum SnapshotType
{
@@ -100,7 +103,9 @@ typedef enum SnapshotType
/*
* A tuple is visible iff it follows the rules of SNAPSHOT_MVCC, but
* supports being called in timetravel context (for decoding catalog
- * contents in the context of logical decoding).
+ * contents in the context of logical decoding). A historic MVCC snapshot
+ * should only be used on catalog tables, as we only track XIDs that
+ * modify catalogs during logical decoding.
*/
SNAPSHOT_HISTORIC_MVCC,
@@ -114,37 +119,18 @@ typedef enum SnapshotType
SNAPSHOT_NON_VACUUMABLE,
} SnapshotType;
-typedef struct SnapshotData *Snapshot;
-
-#define InvalidSnapshot ((Snapshot) NULL)
-
/*
- * Struct representing all kind of possible snapshots.
+ * Struct representing a normal MVCC snapshot.
*
- * There are several different kinds of snapshots:
- * * Normal MVCC snapshots
- * * MVCC snapshots taken during recovery (in Hot-Standby mode)
- * * Historic MVCC snapshots used during logical decoding
- * * snapshots passed to HeapTupleSatisfiesDirty()
- * * snapshots passed to HeapTupleSatisfiesNonVacuumable()
- * * snapshots used for SatisfiesAny, Toast, Self where no members are
- * accessed.
- *
- * TODO: It's probably a good idea to split this struct using a NodeTag
- * similar to how parser and executor nodes are handled, with one type for
- * each different kind of snapshot to avoid overloading the meaning of
- * individual fields.
+ * MVCC snapshots come in two variants: those taken during recovery in hot
+ * standby mode, and "normal" MVCC snapshots. They are distinguished by
+ * takenDuringRecovery.
*/
-typedef struct SnapshotData
+typedef struct MVCCSnapshotData
{
- SnapshotType snapshot_type; /* type of snapshot */
+ SnapshotType snapshot_type; /* type of snapshot, must be first */
/*
- * The remaining fields are used only for MVCC snapshots, and are normally
- * just zeroes in special snapshots. (But xmin and xmax are used
- * specially by HeapTupleSatisfiesDirty, and xmin is used specially by
- * HeapTupleSatisfiesNonVacuumable.)
- *
* An MVCC snapshot can never see the effects of XIDs >= xmax. It can see
* the effects of all older XIDs except those listed in the snapshot. xmin
* is stored as an optimization to avoid needing to search the XID arrays
@@ -154,10 +140,8 @@ typedef struct SnapshotData
TransactionId xmax; /* all XID >= xmax are invisible to me */
/*
- * For normal MVCC snapshot this contains the all xact IDs that are in
- * progress, unless the snapshot was taken during recovery in which case
- * it's empty. For historic MVCC snapshots, the meaning is inverted, i.e.
- * it contains *committed* transactions between xmin and xmax.
+ * xip contains the all xact IDs that are in progress, unless the snapshot
+ * was taken during recovery in which case it's empty.
*
* note: all ids in xip[] satisfy xmin <= xip[i] < xmax
*/
@@ -165,10 +149,8 @@ typedef struct SnapshotData
uint32 xcnt; /* # of xact ids in xip[] */
/*
- * For non-historic MVCC snapshots, this contains subxact IDs that are in
- * progress (and other transactions that are in progress if taken during
- * recovery). For historic snapshot it contains *all* xids assigned to the
- * replayed transaction, including the toplevel xid.
+ * This contains subxact IDs that are in progress (and other transactions
+ * that are in progress if taken during recovery).
*
* note: all ids in subxip[] are >= xmin, but we don't bother filtering
* out any that are >= xmax
@@ -182,18 +164,6 @@ typedef struct SnapshotData
CommandId curcid; /* in my xact, CID < curcid are visible */
- /*
- * An extra return value for HeapTupleSatisfiesDirty, not used in MVCC
- * snapshots.
- */
- uint32 speculativeToken;
-
- /*
- * For SNAPSHOT_NON_VACUUMABLE (and hopefully more in the future) this is
- * used to determine whether row could be vacuumed.
- */
- struct GlobalVisState *vistest;
-
/*
* Book-keeping information, used by the snapshot manager
*/
@@ -207,6 +177,101 @@ typedef struct SnapshotData
* transactions completed since the last GetSnapshotData().
*/
uint64 snapXactCompletionCount;
+} MVCCSnapshotData;
+
+typedef struct MVCCSnapshotData *MVCCSnapshot;
+
+#define InvalidMVCCSnapshot ((MVCCSnapshot) NULL)
+
+/*
+ * Struct representing a "historic" MVCC snapshot during logical decoding.
+ * These are constructed by src/replication/logical/snapbuild.c.
+ */
+typedef struct HistoricMVCCSnapshotData
+{
+ SnapshotType snapshot_type; /* type of snapshot, must be first */
+
+ /*
+ * xmin and xmax like in a normal MVCC snapshot.
+ */
+ TransactionId xmin; /* all XID < xmin are visible to me */
+ TransactionId xmax; /* all XID >= xmax are invisible to me */
+
+ /*
+ * committed_xids contains *committed* transactions between xmin and xmax.
+ * (This is the inverse of 'xip' in normal MVCC snapshots, which contains
+ * all non-committed transactions.) The array is sorted by XID to allow
+ * binary search.
+ *
+ * note: all ids in committed_xids[] satisfy xmin <= committed_xids[i] <
+ * xmax
+ */
+ TransactionId *committed_xids;
+ uint32 xcnt; /* # of xact ids in committed_xids[] */
+
+ /*
+ * subxip contains *all* xids assigned to the replayed transaction,
+ * including the toplevel xid. (This is different from the subxip in a
+ * normal MVCC snapshot, where it doesn't include the top-level xid. Also,
+ * there's no 'suboverflowed')
+ *
+ * note: all ids in subxip[] are >= xmin, but we don't bother filtering
+ * out any that are >= xmax. FIXME: is that true for historic snapshots?
+ */
+ TransactionId *subxip;
+ int32 subxcnt; /* # of xact ids in subxip[] */
+
+ CommandId curcid; /* in my xact, CID < curcid are visible */
+
+ bool copied; /* false if it's a static snapshot */
+
+ uint32 refcount; /* refcount managed by snapbuild.c */
+ uint32 regd_count; /* refcount registered with resource owners */
+
+} HistoricMVCCSnapshotData;
+
+typedef struct HistoricMVCCSnapshotData *HistoricMVCCSnapshot;
+
+/*
+ * Struct representing a special "snapshot" which sees all tuples as visible
+ * if they are visible to anyone, i.e. if they are not vacuumable.
+ * i.e. SNAPSHOT_NON_VACUUMABLE.
+ */
+typedef struct NonVacuumableSnapshotData
+{
+ SnapshotType snapshot_type; /* type of snapshot, must be first */
+
+ /* This is used to determine whether row could be vacuumed. */
+ struct GlobalVisState *vistest;
+} NonVacuumableSnapshotData;
+
+/*
+ * Return values to the caller of HeapTupleSatisfyDirty.
+ */
+typedef struct DirtySnapshotData
+{
+ SnapshotType snapshot_type; /* type of snapshot, must be first */
+
+ TransactionId xmin;
+ TransactionId xmax;
+ uint32 speculativeToken;
+} DirtySnapshotData;
+
+/*
+ * Generic union representing all kind of possible snapshots. Some have
+ * type-specific structs.
+ */
+typedef union SnapshotData
+{
+ SnapshotType snapshot_type; /* type of snapshot */
+ struct MVCCSnapshotData mvcc;
+ struct DirtySnapshotData dirty;
+ struct HistoricMVCCSnapshotData historic_mvcc;
+ struct NonVacuumableSnapshotData nonvacuumable;
} SnapshotData;
+typedef union SnapshotData *Snapshot;
+
+#define InvalidSnapshot ((Snapshot) NULL)
+
#endif /* SNAPSHOT_H */
diff --git a/src/tools/pgindent/typedefs.list b/src/tools/pgindent/typedefs.list
index e1c4f913f84..a28e6817270 100644
--- a/src/tools/pgindent/typedefs.list
+++ b/src/tools/pgindent/typedefs.list
@@ -617,6 +617,7 @@ DictThesaurus
DimensionInfo
DirectoryMethodData
DirectoryMethodFile
+DirtySnapshotData
DisableTimeoutParams
DiscardMode
DiscardStmt
@@ -1159,6 +1160,7 @@ HeapTupleFreeze
HeapTupleHeader
HeapTupleHeaderData
HeapTupleTableSlot
+HistoricMVCCSnapshotData
HistControl
HotStandbyState
I32
@@ -1605,6 +1607,7 @@ MINIDUMPWRITEDUMP
MINIDUMP_TYPE
MJEvalResult
MTTargetRelLookup
+MVCCSnapshotData
MVDependencies
MVDependency
MVNDistinct
@@ -1703,6 +1706,7 @@ NextValueExpr
Node
NodeTag
NonEmptyRange
+NonVacuumableSnapshotData
Notification
NotificationList
NotifyStmt
--
2.39.5