Snapshot snapshot = SnapshotAny;
/*
- * RecentGlobalXmin assertion matches index_getnext_tid(). See note on
- * RecentGlobalXmin/B-Tree page deletion.
+ * This assertion matches the one in index_getnext_tid(). See page
+ * recycling/RecentGlobalXmin notes in nbtree README.
*/
- Assert(TransactionIdIsValid(RecentGlobalXmin));
+ Assert(SnapshotSet());
/*
* Initialize state for entire verification operation
{
HeapScanDesc scan;
+ Assert(SnapshotSet());
+
/*
* increment relation ref count while scanning relation
*
at_chain_start = first_call;
skip = !first_call;
- Assert(TransactionIdIsValid(RecentGlobalXmin));
+ Assert(SnapshotSet());
Assert(BufferGetBlockNumber(buffer) == blkno);
/* Scan through possible multiple members of HOT-chain */
* if so (vacuum can't subsequently move relfrozenxid to beyond
* TransactionXmin, so there's no race here).
*/
- Assert(TransactionIdIsValid(TransactionXmin));
+ Assert(SnapshotSet() && TransactionIdIsValid(TransactionXmin));
if (TransactionIdPrecedes(TransactionXmin, relation->rd_rel->relfrozenxid))
prune_xid = relation->rd_rel->relfrozenxid;
else
RELATION_CHECKS;
CHECK_REL_PROCEDURE(aminsert);
+ Assert(SnapshotSet());
+
if (!(indexRelation->rd_indam->ampredlocks))
CheckForSerializableConflictIn(indexRelation,
(ItemPointer) NULL,
{
IndexScanDesc scan;
+ Assert(SnapshotSet());
+
RELATION_CHECKS;
CHECK_REL_PROCEDURE(ambeginscan);
SCAN_CHECKS;
CHECK_SCAN_PROCEDURE(amgettuple);
- Assert(TransactionIdIsValid(RecentGlobalXmin));
+ Assert(SnapshotSet());
/*
* The AM's amgettuple proc finds the next index entry matching the scan
bool all_dead = false;
bool found;
+ Assert(SnapshotSet());
+
found = table_index_fetch_tuple(scan->xs_heapfetch, &scan->xs_heaptid,
scan->xs_snapshot, slot,
&scan->xs_heap_continue, &all_dead);
#include "catalog/indexing.h"
#include "executor/executor.h"
#include "utils/rel.h"
+#include "utils/snapmgr.h"
/*
{
CatalogIndexState indstate;
+ Assert(SnapshotSet());
+
indstate = CatalogOpenIndexes(heapRel);
simple_heap_insert(heapRel, tup);
CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup,
CatalogIndexState indstate)
{
+ Assert(SnapshotSet());
+
simple_heap_insert(heapRel, tup);
CatalogIndexInsert(indstate, tup);
{
CatalogIndexState indstate;
+ Assert(SnapshotSet());
+
indstate = CatalogOpenIndexes(heapRel);
simple_heap_update(heapRel, otid, tup);
CatalogTupleUpdateWithInfo(Relation heapRel, ItemPointer otid, HeapTuple tup,
CatalogIndexState indstate)
{
+ Assert(SnapshotSet());
+
simple_heap_update(heapRel, otid, tup);
CatalogIndexInsert(indstate, tup);
void
CatalogTupleDelete(Relation heapRel, ItemPointer tid)
{
+ Assert(SnapshotSet());
+
simple_heap_delete(heapRel, tid);
}
return ActiveSnapshot != NULL;
}
+/*
+ * Does this transaction have a snapshot.
+ */
+bool
+SnapshotSet(void)
+{
+ /* can't be safe, because somehow xmin is not set */
+ if (!TransactionIdIsValid(MyPgXact->xmin) && HistoricSnapshot == NULL)
+ return false;
+
+ /*
+ * Can't be safe because no snapshot being active/registered means that
+ * e.g. invalidation processing could change xmin horizon.
+ */
+ return ActiveSnapshot != NULL ||
+ !pairingheap_is_empty(&RegisteredSnapshots) ||
+ HistoricSnapshot != NULL;
+}
+
/*
* RegisterSnapshot
* Register a snapshot as being in use by the current resource owner
extern Snapshot GetActiveSnapshot(void);
extern bool ActiveSnapshotSet(void);
+extern bool SnapshotSet(void);
+
extern Snapshot RegisterSnapshot(Snapshot snapshot);
extern void UnregisterSnapshot(Snapshot snapshot);
extern Snapshot RegisterSnapshotOnOwner(Snapshot snapshot, ResourceOwner owner);