PostgreSQL Source Code git master
Loading...
Searching...
No Matches
snapmgr.h File Reference
#include "access/transam.h"
#include "utils/relcache.h"
#include "utils/resowner.h"
#include "utils/snapshot.h"
Include dependency graph for snapmgr.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Macros

#define SnapshotSelf   (&SnapshotSelfData)
 
#define SnapshotAny   (&SnapshotAnyData)
 
#define InitDirtySnapshot(snapshotdata)    ((snapshotdata).snapshot_type = SNAPSHOT_DIRTY)
 
#define InitNonVacuumableSnapshot(snapshotdata, vistestp)
 
#define IsMVCCSnapshot(snapshot)    ((snapshot)->snapshot_type == SNAPSHOT_MVCC)
 
#define IsHistoricMVCCSnapshot(snapshot)    ((snapshot)->snapshot_type == SNAPSHOT_HISTORIC_MVCC)
 
#define IsMVCCLikeSnapshot(snapshot)    (IsMVCCSnapshot(snapshot) || IsHistoricMVCCSnapshot(snapshot))
 

Typedefs

typedef struct GlobalVisState GlobalVisState
 

Functions

Snapshot GetTransactionSnapshot (void)
 
Snapshot GetLatestSnapshot (void)
 
void SnapshotSetCommandId (CommandId curcid)
 
Snapshot GetCatalogSnapshot (Oid relid)
 
Snapshot GetNonHistoricCatalogSnapshot (Oid relid)
 
void InvalidateCatalogSnapshot (void)
 
void InvalidateCatalogSnapshotConditionally (void)
 
void PushActiveSnapshot (Snapshot snapshot)
 
void PushActiveSnapshotWithLevel (Snapshot snapshot, int snap_level)
 
void PushCopiedSnapshot (Snapshot snapshot)
 
void UpdateActiveSnapshotCommandId (void)
 
void PopActiveSnapshot (void)
 
Snapshot GetActiveSnapshot (void)
 
bool ActiveSnapshotSet (void)
 
Snapshot RegisterSnapshot (Snapshot snapshot)
 
void UnregisterSnapshot (Snapshot snapshot)
 
Snapshot RegisterSnapshotOnOwner (Snapshot snapshot, ResourceOwner owner)
 
void UnregisterSnapshotFromOwner (Snapshot snapshot, ResourceOwner owner)
 
void AtSubCommit_Snapshot (int level)
 
void AtSubAbort_Snapshot (int level)
 
void AtEOXact_Snapshot (bool isCommit, bool resetXmin)
 
void ImportSnapshot (const char *idstr)
 
bool XactHasExportedSnapshots (void)
 
void DeleteAllExportedSnapshotFiles (void)
 
void WaitForOlderSnapshots (TransactionId limitXmin, bool progress)
 
bool ThereAreNoPriorRegisteredSnapshots (void)
 
bool HaveRegisteredOrActiveSnapshot (void)
 
charExportSnapshot (Snapshot snapshot)
 
GlobalVisStateGlobalVisTestFor (Relation rel)
 
bool GlobalVisTestIsRemovableXid (GlobalVisState *state, TransactionId xid, bool allow_update)
 
bool GlobalVisTestIsRemovableFullXid (GlobalVisState *state, FullTransactionId fxid, bool allow_update)
 
bool GlobalVisCheckRemovableXid (Relation rel, TransactionId xid)
 
bool GlobalVisCheckRemovableFullXid (Relation rel, FullTransactionId fxid)
 
bool GlobalVisTestXidConsideredRunning (GlobalVisState *state, TransactionId xid, bool allow_update)
 
bool XidInMVCCSnapshot (TransactionId xid, Snapshot snapshot)
 
struct HTABHistoricSnapshotGetTupleCids (void)
 
void SetupHistoricSnapshot (Snapshot historic_snapshot, struct HTAB *tuplecids)
 
void TeardownHistoricSnapshot (bool is_error)
 
bool HistoricSnapshotActive (void)
 
Size EstimateSnapshotSpace (Snapshot snapshot)
 
void SerializeSnapshot (Snapshot snapshot, char *start_address)
 
Snapshot RestoreSnapshot (char *start_address)
 
void RestoreTransactionSnapshot (Snapshot snapshot, struct PGPROC *source_pgproc)
 

Variables

PGDLLIMPORT bool FirstSnapshotSet
 
PGDLLIMPORT TransactionId TransactionXmin
 
PGDLLIMPORT TransactionId RecentXmin
 
PGDLLIMPORT SnapshotData SnapshotSelfData
 
PGDLLIMPORT SnapshotData SnapshotAnyData
 
PGDLLIMPORT SnapshotData SnapshotToastData
 

Macro Definition Documentation

◆ InitDirtySnapshot

#define InitDirtySnapshot (   snapshotdata)     ((snapshotdata).snapshot_type = SNAPSHOT_DIRTY)

Definition at line 42 of file snapmgr.h.

◆ InitNonVacuumableSnapshot

#define InitNonVacuumableSnapshot (   snapshotdata,
  vistestp 
)
Value:
((snapshotdata).snapshot_type = SNAPSHOT_NON_VACUUMABLE, \
(snapshotdata).vistest = (vistestp))
static int fb(int x)
@ SNAPSHOT_NON_VACUUMABLE
Definition snapshot.h:114

Definition at line 50 of file snapmgr.h.

◆ IsHistoricMVCCSnapshot

#define IsHistoricMVCCSnapshot (   snapshot)     ((snapshot)->snapshot_type == SNAPSHOT_HISTORIC_MVCC)

Definition at line 67 of file snapmgr.h.

◆ IsMVCCLikeSnapshot

#define IsMVCCLikeSnapshot (   snapshot)     (IsMVCCSnapshot(snapshot) || IsHistoricMVCCSnapshot(snapshot))

Definition at line 74 of file snapmgr.h.

◆ IsMVCCSnapshot

#define IsMVCCSnapshot (   snapshot)     ((snapshot)->snapshot_type == SNAPSHOT_MVCC)

Definition at line 59 of file snapmgr.h.

◆ SnapshotAny

#define SnapshotAny   (&SnapshotAnyData)

Definition at line 33 of file snapmgr.h.

◆ SnapshotSelf

#define SnapshotSelf   (&SnapshotSelfData)

Definition at line 32 of file snapmgr.h.

Typedef Documentation

◆ GlobalVisState

Definition at line 116 of file snapmgr.h.

Function Documentation

◆ ActiveSnapshotSet()

◆ AtEOXact_Snapshot()

void AtEOXact_Snapshot ( bool  isCommit,
bool  resetXmin 
)
extern

Definition at line 1016 of file snapmgr.c.

1017{
1018 /*
1019 * In transaction-snapshot mode we must release our privately-managed
1020 * reference to the transaction snapshot. We must remove it from
1021 * RegisteredSnapshots to keep the check below happy. But we don't bother
1022 * to do FreeSnapshot, for two reasons: the memory will go away with
1023 * TopTransactionContext anyway, and if someone has left the snapshot
1024 * stacked as active, we don't want the code below to be chasing through a
1025 * dangling pointer.
1026 */
1027 if (FirstXactSnapshot != NULL)
1028 {
1032 }
1034
1035 /*
1036 * If we exported any snapshots, clean them up.
1037 */
1038 if (exportedSnapshots != NIL)
1039 {
1040 ListCell *lc;
1041
1042 /*
1043 * Get rid of the files. Unlink failure is only a WARNING because (1)
1044 * it's too late to abort the transaction, and (2) leaving a leaked
1045 * file around has little real consequence anyway.
1046 *
1047 * We also need to remove the snapshots from RegisteredSnapshots to
1048 * prevent a warning below.
1049 *
1050 * As with the FirstXactSnapshot, we don't need to free resources of
1051 * the snapshot itself as it will go away with the memory context.
1052 */
1053 foreach(lc, exportedSnapshots)
1054 {
1056
1057 if (unlink(esnap->snapfile))
1058 elog(WARNING, "could not unlink file \"%s\": %m",
1059 esnap->snapfile);
1060
1062 &esnap->snapshot->ph_node);
1063 }
1064
1066 }
1067
1068 /* Drop catalog snapshot if any */
1070
1071 /* On commit, complain about leftover snapshots */
1072 if (isCommit)
1073 {
1074 ActiveSnapshotElt *active;
1075
1077 elog(WARNING, "registered snapshots seem to remain after cleanup");
1078
1079 /* complain about unpopped active snapshots */
1080 for (active = ActiveSnapshot; active != NULL; active = active->as_next)
1081 elog(WARNING, "snapshot %p still active", active);
1082 }
1083
1084 /*
1085 * And reset our state. We don't need to free the memory explicitly --
1086 * it'll go away with TopTransactionContext.
1087 */
1090
1093
1094 FirstSnapshotSet = false;
1095
1096 /*
1097 * During normal commit processing, we call ProcArrayEndTransaction() to
1098 * reset the MyProc->xmin. That call happens prior to the call to
1099 * AtEOXact_Snapshot(), so we need not touch xmin here at all.
1100 */
1101 if (resetXmin)
1103
1104 Assert(resetXmin || MyProc->xmin == 0);
1105}
#define Assert(condition)
Definition c.h:1002
#define WARNING
Definition elog.h:37
#define elog(elevel,...)
Definition elog.h:228
void pairingheap_remove(pairingheap *heap, pairingheap_node *node)
#define pairingheap_is_empty(h)
Definition pairingheap.h:99
#define pairingheap_reset(h)
Definition pairingheap.h:96
#define lfirst(lc)
Definition pg_list.h:172
#define NIL
Definition pg_list.h:68
static Snapshot FirstXactSnapshot
Definition snapmgr.c:200
static Snapshot CurrentSnapshot
Definition snapmgr.c:149
static Snapshot SecondarySnapshot
Definition snapmgr.c:150
static List * exportedSnapshots
Definition snapmgr.c:213
static pairingheap RegisteredSnapshots
Definition snapmgr.c:190
bool FirstSnapshotSet
Definition snapmgr.c:193
static void SnapshotResetXmin(void)
Definition snapmgr.c:937
void InvalidateCatalogSnapshot(void)
Definition snapmgr.c:455
PGPROC * MyProc
Definition proc.c:71
struct ActiveSnapshotElt * as_next
Definition snapmgr.c:177
TransactionId xmin
Definition proc.h:242
uint32 regd_count
Definition snapshot.h:201
pairingheap_node ph_node
Definition snapshot.h:202

References ActiveSnapshot, ActiveSnapshotElt::as_next, Assert, CurrentSnapshot, elog, exportedSnapshots, fb(), FirstSnapshotSet, FirstXactSnapshot, InvalidateCatalogSnapshot(), lfirst, MyProc, NIL, pairingheap_is_empty, pairingheap_remove(), pairingheap_reset, SnapshotData::ph_node, SnapshotData::regd_count, RegisteredSnapshots, SecondarySnapshot, SnapshotResetXmin(), WARNING, and PGPROC::xmin.

Referenced by CleanupTransaction(), CommitTransaction(), and PrepareTransaction().

◆ AtSubAbort_Snapshot()

void AtSubAbort_Snapshot ( int  level)
extern

Definition at line 982 of file snapmgr.c.

983{
984 /* Forget the active snapshots set by this subtransaction */
985 while (ActiveSnapshot && ActiveSnapshot->as_level >= level)
986 {
988
990
991 /*
992 * Decrement the snapshot's active count. If it's still registered or
993 * marked as active by an outer subtransaction, we can't free it yet.
994 */
997
1001
1002 /* and free the stack element */
1004
1006 }
1007
1009}
static int32 next
Definition blutils.c:225
void pfree(void *pointer)
Definition mcxt.c:1619
static void FreeSnapshot(Snapshot snapshot)
Definition snapmgr.c:664
Snapshot as_snap
Definition snapmgr.c:175
uint32 active_count
Definition snapshot.h:200

References SnapshotData::active_count, ActiveSnapshot, ActiveSnapshotElt::as_level, ActiveSnapshotElt::as_next, ActiveSnapshotElt::as_snap, Assert, FreeSnapshot(), next, pfree(), SnapshotData::regd_count, and SnapshotResetXmin().

Referenced by AbortSubTransaction().

◆ AtSubCommit_Snapshot()

void AtSubCommit_Snapshot ( int  level)
extern

Definition at line 961 of file snapmgr.c.

962{
963 ActiveSnapshotElt *active;
964
965 /*
966 * Relabel the active snapshots set in this subtransaction as though they
967 * are owned by the parent subxact.
968 */
969 for (active = ActiveSnapshot; active != NULL; active = active->as_next)
970 {
971 if (active->as_level < level)
972 break;
973 active->as_level = level - 1;
974 }
975}

References ActiveSnapshot, ActiveSnapshotElt::as_level, ActiveSnapshotElt::as_next, and fb().

Referenced by CommitSubTransaction().

◆ DeleteAllExportedSnapshotFiles()

void DeleteAllExportedSnapshotFiles ( void  )
extern

Definition at line 1586 of file snapmgr.c.

1587{
1588 char buf[MAXPGPATH + sizeof(SNAPSHOT_EXPORT_DIR)];
1589 DIR *s_dir;
1590 struct dirent *s_de;
1591
1592 /*
1593 * Problems in reading the directory, or unlinking files, are reported at
1594 * LOG level. Since we're running in the startup process, ERROR level
1595 * would prevent database start, and it's not important enough for that.
1596 */
1598
1600 {
1601 if (strcmp(s_de->d_name, ".") == 0 ||
1602 strcmp(s_de->d_name, "..") == 0)
1603 continue;
1604
1605 snprintf(buf, sizeof(buf), SNAPSHOT_EXPORT_DIR "/%s", s_de->d_name);
1606
1607 if (unlink(buf) != 0)
1608 ereport(LOG,
1610 errmsg("could not remove file \"%s\": %m", buf)));
1611 }
1612
1613 FreeDir(s_dir);
1614}
int errcode_for_file_access(void)
Definition elog.c:898
#define LOG
Definition elog.h:32
#define ereport(elevel,...)
Definition elog.h:152
int FreeDir(DIR *dir)
Definition fd.c:3009
struct dirent * ReadDirExtended(DIR *dir, const char *dirname, int elevel)
Definition fd.c:2972
DIR * AllocateDir(const char *dirname)
Definition fd.c:2891
static char * errmsg
#define MAXPGPATH
static char buf[DEFAULT_XLOG_SEG_SIZE]
#define snprintf
Definition port.h:261
#define SNAPSHOT_EXPORT_DIR
Definition snapmgr.c:203
Definition dirent.c:26

References AllocateDir(), buf, ereport, errcode_for_file_access(), errmsg, fb(), FreeDir(), LOG, MAXPGPATH, ReadDirExtended(), SNAPSHOT_EXPORT_DIR, and snprintf.

Referenced by StartupXLOG().

◆ EstimateSnapshotSpace()

Size EstimateSnapshotSpace ( Snapshot  snapshot)
extern

Definition at line 1711 of file snapmgr.c.

1712{
1713 Size size;
1714
1715 Assert(snapshot != InvalidSnapshot);
1716 Assert(snapshot->snapshot_type == SNAPSHOT_MVCC);
1717
1718 /* We allocate any XID arrays needed in the same palloc block. */
1719 size = add_size(sizeof(SerializedSnapshotData),
1720 mul_size(snapshot->xcnt, sizeof(TransactionId)));
1721 if (snapshot->subxcnt > 0 &&
1722 (!snapshot->suboverflowed || snapshot->takenDuringRecovery))
1723 size = add_size(size,
1724 mul_size(snapshot->subxcnt, sizeof(TransactionId)));
1725
1726 return size;
1727}
uint32 TransactionId
Definition c.h:795
size_t Size
Definition c.h:748
Size add_size(Size s1, Size s2)
Definition mcxt.c:1733
Size mul_size(Size s1, Size s2)
Definition mcxt.c:1752
@ SNAPSHOT_MVCC
Definition snapshot.h:46
#define InvalidSnapshot
Definition snapshot.h:119
int32 subxcnt
Definition snapshot.h:177
uint32 xcnt
Definition snapshot.h:165
SnapshotType snapshot_type
Definition snapshot.h:140
bool suboverflowed
Definition snapshot.h:178
bool takenDuringRecovery
Definition snapshot.h:180

References add_size(), Assert, InvalidSnapshot, mul_size(), SNAPSHOT_MVCC, SnapshotData::snapshot_type, SnapshotData::suboverflowed, SnapshotData::subxcnt, SnapshotData::takenDuringRecovery, and SnapshotData::xcnt.

Referenced by export_initial_snapshot(), index_parallelscan_estimate(), index_parallelscan_initialize(), InitializeParallelDSM(), and table_parallelscan_estimate().

◆ ExportSnapshot()

char * ExportSnapshot ( Snapshot  snapshot)
extern

Definition at line 1115 of file snapmgr.c.

1116{
1117 TransactionId topXid;
1118 TransactionId *children;
1120 int nchildren;
1121 int addTopXid;
1123 FILE *f;
1125 char path[MAXPGPATH];
1126 char pathtmp[MAXPGPATH];
1127
1128 /*
1129 * It's tempting to call RequireTransactionBlock here, since it's not very
1130 * useful to export a snapshot that will disappear immediately afterwards.
1131 * However, we haven't got enough information to do that, since we don't
1132 * know if we're at top level or not. For example, we could be inside a
1133 * plpgsql function that is going to fire off other transactions via
1134 * dblink. Rather than disallow perfectly legitimate usages, don't make a
1135 * check.
1136 *
1137 * Also note that we don't make any restriction on the transaction's
1138 * isolation level; however, importers must check the level if they are
1139 * serializable.
1140 */
1141
1142 /*
1143 * Get our transaction ID if there is one, to include in the snapshot.
1144 */
1145 topXid = GetTopTransactionIdIfAny();
1146
1147 /*
1148 * We cannot export a snapshot from a subtransaction because there's no
1149 * easy way for importers to verify that the same subtransaction is still
1150 * running.
1151 */
1152 if (IsSubTransaction())
1153 ereport(ERROR,
1155 errmsg("cannot export a snapshot from a subtransaction")));
1156
1157 /*
1158 * We do however allow previous committed subtransactions to exist.
1159 * Importers of the snapshot must see them as still running, so get their
1160 * XIDs to add them to the snapshot.
1161 */
1163
1164 /*
1165 * Generate file path for the snapshot. We start numbering of snapshots
1166 * inside the transaction from 1.
1167 */
1168 snprintf(path, sizeof(path), SNAPSHOT_EXPORT_DIR "/%08X-%08X-%d",
1171
1172 /*
1173 * Copy the snapshot into TopTransactionContext, add it to the
1174 * exportedSnapshots list, and mark it pseudo-registered. We do this to
1175 * ensure that the snapshot's xmin is honored for the rest of the
1176 * transaction.
1177 */
1178 snapshot = CopySnapshot(snapshot);
1179
1182 esnap->snapfile = pstrdup(path);
1183 esnap->snapshot = snapshot;
1186
1187 snapshot->regd_count++;
1189
1190 /*
1191 * Fill buf with a text serialization of the snapshot, plus identification
1192 * data about this transaction. The format expected by ImportSnapshot is
1193 * pretty rigid: each line must be fieldname:value.
1194 */
1196
1197 appendStringInfo(&buf, "vxid:%d/%u\n", MyProc->vxid.procNumber, MyProc->vxid.lxid);
1198 appendStringInfo(&buf, "pid:%d\n", MyProcPid);
1199 appendStringInfo(&buf, "dbid:%u\n", MyDatabaseId);
1200 appendStringInfo(&buf, "iso:%d\n", XactIsoLevel);
1201 appendStringInfo(&buf, "ro:%d\n", XactReadOnly);
1202
1203 appendStringInfo(&buf, "xmin:%u\n", snapshot->xmin);
1204 appendStringInfo(&buf, "xmax:%u\n", snapshot->xmax);
1205
1206 /*
1207 * We must include our own top transaction ID in the top-xid data, since
1208 * by definition we will still be running when the importing transaction
1209 * adopts the snapshot, but GetSnapshotData never includes our own XID in
1210 * the snapshot. (There must, therefore, be enough room to add it.)
1211 *
1212 * However, it could be that our topXid is after the xmax, in which case
1213 * we shouldn't include it because xip[] members are expected to be before
1214 * xmax. (We need not make the same check for subxip[] members, see
1215 * snapshot.h.)
1216 */
1217 addTopXid = (TransactionIdIsValid(topXid) &&
1218 TransactionIdPrecedes(topXid, snapshot->xmax)) ? 1 : 0;
1219 appendStringInfo(&buf, "xcnt:%d\n", snapshot->xcnt + addTopXid);
1220 for (uint32 i = 0; i < snapshot->xcnt; i++)
1221 appendStringInfo(&buf, "xip:%u\n", snapshot->xip[i]);
1222 if (addTopXid)
1223 appendStringInfo(&buf, "xip:%u\n", topXid);
1224
1225 /*
1226 * Similarly, we add our subcommitted child XIDs to the subxid data. Here,
1227 * we have to cope with possible overflow.
1228 */
1229 if (snapshot->suboverflowed ||
1231 appendStringInfoString(&buf, "sof:1\n");
1232 else
1233 {
1234 appendStringInfoString(&buf, "sof:0\n");
1235 appendStringInfo(&buf, "sxcnt:%d\n", snapshot->subxcnt + nchildren);
1236 for (int32 i = 0; i < snapshot->subxcnt; i++)
1237 appendStringInfo(&buf, "sxp:%u\n", snapshot->subxip[i]);
1238 for (int32 i = 0; i < nchildren; i++)
1239 appendStringInfo(&buf, "sxp:%u\n", children[i]);
1240 }
1241 appendStringInfo(&buf, "rec:%u\n", snapshot->takenDuringRecovery);
1242
1243 /*
1244 * Now write the text representation into a file. We first write to a
1245 * ".tmp" filename, and rename to final filename if no error. This
1246 * ensures that no other backend can read an incomplete file
1247 * (ImportSnapshot won't allow it because of its valid-characters check).
1248 */
1249 snprintf(pathtmp, sizeof(pathtmp), "%s.tmp", path);
1250 if (!(f = AllocateFile(pathtmp, PG_BINARY_W)))
1251 ereport(ERROR,
1253 errmsg("could not create file \"%s\": %m", pathtmp)));
1254
1255 if (fwrite(buf.data, buf.len, 1, f) != 1)
1256 ereport(ERROR,
1258 errmsg("could not write to file \"%s\": %m", pathtmp)));
1259
1260 /* no fsync() since file need not survive a system crash */
1261
1262 if (FreeFile(f))
1263 ereport(ERROR,
1265 errmsg("could not write to file \"%s\": %m", pathtmp)));
1266
1267 /*
1268 * Now that we have written everything into a .tmp file, rename the file
1269 * to remove the .tmp suffix.
1270 */
1271 if (rename(pathtmp, path) < 0)
1272 ereport(ERROR,
1274 errmsg("could not rename file \"%s\" to \"%s\": %m",
1275 pathtmp, path)));
1276
1277 /*
1278 * The basename of the file is what we return from pg_export_snapshot().
1279 * It's already in path in a textual format and we know that the path
1280 * starts with SNAPSHOT_EXPORT_DIR. Skip over the prefix and the slash
1281 * and pstrdup it so as not to return the address of a local variable.
1282 */
1283 return pstrdup(path + strlen(SNAPSHOT_EXPORT_DIR) + 1);
1284}
int32_t int32
Definition c.h:679
uint32_t uint32
Definition c.h:683
#define PG_BINARY_W
Definition c.h:1434
int errcode(int sqlerrcode)
Definition elog.c:875
#define ERROR
Definition elog.h:40
int FreeFile(FILE *file)
Definition fd.c:2827
FILE * AllocateFile(const char *name, const char *mode)
Definition fd.c:2628
#define palloc_object(type)
Definition fe_memutils.h:89
int MyProcPid
Definition globals.c:49
Oid MyDatabaseId
Definition globals.c:96
int i
Definition isn.c:77
List * lappend(List *list, void *datum)
Definition list.c:339
MemoryContext TopTransactionContext
Definition mcxt.c:172
char * pstrdup(const char *in)
Definition mcxt.c:1910
void pairingheap_add(pairingheap *heap, pairingheap_node *node)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:138
static int list_length(const List *l)
Definition pg_list.h:152
int GetMaxSnapshotSubxidCount(void)
Definition procarray.c:2019
static Snapshot CopySnapshot(Snapshot snapshot)
Definition snapmgr.c:608
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition stringinfo.c:145
void appendStringInfoString(StringInfo str, const char *s)
Definition stringinfo.c:230
void initStringInfo(StringInfo str)
Definition stringinfo.c:97
LocalTransactionId lxid
Definition proc.h:231
ProcNumber procNumber
Definition proc.h:226
struct PGPROC::@134 vxid
TransactionId xmin
Definition snapshot.h:153
TransactionId * subxip
Definition snapshot.h:176
TransactionId xmax
Definition snapshot.h:154
TransactionId * xip
Definition snapshot.h:164
#define TransactionIdIsValid(xid)
Definition transam.h:41
static bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition transam.h:263
bool XactReadOnly
Definition xact.c:84
TransactionId GetTopTransactionIdIfAny(void)
Definition xact.c:443
int XactIsoLevel
Definition xact.c:81
bool IsSubTransaction(void)
Definition xact.c:5098
int xactGetCommittedChildren(TransactionId **ptr)
Definition xact.c:5849

References AllocateFile(), appendStringInfo(), appendStringInfoString(), buf, CopySnapshot(), ereport, errcode(), errcode_for_file_access(), errmsg, ERROR, exportedSnapshots, fb(), FreeFile(), GetMaxSnapshotSubxidCount(), GetTopTransactionIdIfAny(), i, initStringInfo(), IsSubTransaction(), lappend(), list_length(), PGPROC::lxid, MAXPGPATH, MemoryContextSwitchTo(), MyDatabaseId, MyProc, MyProcPid, pairingheap_add(), palloc_object, PG_BINARY_W, SnapshotData::ph_node, PGPROC::procNumber, pstrdup(), SnapshotData::regd_count, RegisteredSnapshots, SNAPSHOT_EXPORT_DIR, snprintf, SnapshotData::suboverflowed, SnapshotData::subxcnt, SnapshotData::subxip, SnapshotData::takenDuringRecovery, TopTransactionContext, TransactionIdIsValid, TransactionIdPrecedes(), PGPROC::vxid, xactGetCommittedChildren(), XactIsoLevel, XactReadOnly, SnapshotData::xcnt, SnapshotData::xip, SnapshotData::xmax, and SnapshotData::xmin.

Referenced by pg_export_snapshot(), and SnapBuildExportSnapshot().

◆ GetActiveSnapshot()

◆ GetCatalogSnapshot()

Snapshot GetCatalogSnapshot ( Oid  relid)
extern

Definition at line 385 of file snapmgr.c.

386{
387 /*
388 * Return historic snapshot while we're doing logical decoding, so we can
389 * see the appropriate state of the catalog.
390 *
391 * This is the primary reason for needing to reset the system caches after
392 * finishing decoding.
393 */
395 return HistoricSnapshot;
396
397 return GetNonHistoricCatalogSnapshot(relid);
398}
static Snapshot HistoricSnapshot
Definition snapmgr.c:152
bool HistoricSnapshotActive(void)
Definition snapmgr.c:1691
Snapshot GetNonHistoricCatalogSnapshot(Oid relid)
Definition snapmgr.c:407

References GetNonHistoricCatalogSnapshot(), HistoricSnapshot, and HistoricSnapshotActive().

Referenced by process_settings(), systable_beginscan(), systable_beginscan_ordered(), systable_recheck_tuple(), and table_beginscan_catalog().

◆ GetLatestSnapshot()

Snapshot GetLatestSnapshot ( void  )
extern

Definition at line 354 of file snapmgr.c.

355{
356 /*
357 * We might be able to relax this, but nothing that could otherwise work
358 * needs it.
359 */
360 if (IsInParallelMode())
361 elog(ERROR,
362 "cannot update SecondarySnapshot during a parallel operation");
363
364 /*
365 * So far there are no cases requiring support for GetLatestSnapshot()
366 * during logical decoding, but it wouldn't be hard to add if required.
367 */
369
370 /* If first call in transaction, go ahead and set the xact snapshot */
371 if (!FirstSnapshotSet)
372 return GetTransactionSnapshot();
373
375
376 return SecondarySnapshot;
377}
Snapshot GetSnapshotData(Snapshot snapshot)
Definition procarray.c:2114
Snapshot GetTransactionSnapshot(void)
Definition snapmgr.c:272
static SnapshotData SecondarySnapshotData
Definition snapmgr.c:142
bool IsInParallelMode(void)
Definition xact.c:1119

References Assert, elog, ERROR, FirstSnapshotSet, GetSnapshotData(), GetTransactionSnapshot(), HistoricSnapshotActive(), IsInParallelMode(), SecondarySnapshot, and SecondarySnapshotData.

Referenced by asyncQueueReadAllNotifications(), ATRewriteTable(), check_default_partition_contents(), currtid_internal(), FindConflictTuple(), IndexCheckExclusion(), MergePartitionsMoveRows(), RelationFindReplTupleByIndex(), RelationFindReplTupleSeq(), RI_Initial_Check(), RI_PartitionRemove_Check(), ri_PerformCheck(), ScanSourceDatabasePgClass(), SplitPartitionMoveRows(), validateDomainCheckConstraint(), validateDomainNotNullConstraint(), and validateForeignKeyConstraint().

◆ GetNonHistoricCatalogSnapshot()

Snapshot GetNonHistoricCatalogSnapshot ( Oid  relid)
extern

Definition at line 407 of file snapmgr.c.

408{
409 /*
410 * If the caller is trying to scan a relation that has no syscache, no
411 * catcache invalidations will be sent when it is updated. For a few key
412 * relations, snapshot invalidations are sent instead. If we're trying to
413 * scan a relation for which neither catcache nor snapshot invalidations
414 * are sent, we must refresh the snapshot every time.
415 */
416 if (CatalogSnapshot &&
418 !RelationHasSysCache(relid))
420
421 if (CatalogSnapshot == NULL)
422 {
423 /* Get new snapshot. */
425
426 /*
427 * Make sure the catalog snapshot will be accounted for in decisions
428 * about advancing PGPROC->xmin. We could apply RegisterSnapshot, but
429 * that would result in making a physical copy, which is overkill; and
430 * it would also create a dependency on some resource owner, which we
431 * do not want for reasons explained at the head of this file. Instead
432 * just shove the CatalogSnapshot into the pairing heap manually. This
433 * has to be reversed in InvalidateCatalogSnapshot, of course.
434 *
435 * NB: it had better be impossible for this to throw error, since the
436 * CatalogSnapshot pointer is already valid.
437 */
439 }
440
441 return CatalogSnapshot;
442}
static SnapshotData CatalogSnapshotData
Definition snapmgr.c:143
static Snapshot CatalogSnapshot
Definition snapmgr.c:151
bool RelationHasSysCache(Oid relid)
Definition syscache.c:738
bool RelationInvalidatesSnapshotsOnly(Oid relid)
Definition syscache.c:715

References CatalogSnapshot, CatalogSnapshotData, fb(), GetSnapshotData(), InvalidateCatalogSnapshot(), pairingheap_add(), SnapshotData::ph_node, RegisteredSnapshots, RelationHasSysCache(), and RelationInvalidatesSnapshotsOnly().

Referenced by GetCatalogSnapshot(), and ScanPgRelation().

◆ GetTransactionSnapshot()

Snapshot GetTransactionSnapshot ( void  )
extern

Definition at line 272 of file snapmgr.c.

273{
274 /*
275 * Return historic snapshot if doing logical decoding.
276 *
277 * Historic snapshots are only usable for catalog access, not for
278 * general-purpose queries. The caller is responsible for ensuring that
279 * the snapshot is used correctly! (PostgreSQL code never calls this
280 * during logical decoding, but extensions can do it.)
281 */
283 {
284 /*
285 * We'll never need a non-historic transaction snapshot in this
286 * (sub-)transaction, so there's no need to be careful to set one up
287 * for later calls to GetTransactionSnapshot().
288 */
290 return HistoricSnapshot;
291 }
292
293 /* First call in transaction? */
294 if (!FirstSnapshotSet)
295 {
296 /*
297 * Don't allow catalog snapshot to be older than xact snapshot. Must
298 * do this first to allow the empty-heap Assert to succeed.
299 */
301
304
305 if (IsInParallelMode())
306 elog(ERROR,
307 "cannot take query snapshot during a parallel operation");
308
309 /*
310 * In transaction-snapshot mode, the first snapshot must live until
311 * end of xact regardless of what the caller does with it, so we must
312 * make a copy of it rather than returning CurrentSnapshotData
313 * directly. Furthermore, if we're running in serializable mode,
314 * predicate.c needs to wrap the snapshot fetch in its own processing.
315 */
317 {
318 /* First, create the snapshot in CurrentSnapshotData */
321 else
323 /* Make a saved copy */
326 /* Mark it as "registered" in FirstXactSnapshot */
329 }
330 else
332
333 FirstSnapshotSet = true;
334 return CurrentSnapshot;
335 }
336
338 return CurrentSnapshot;
339
340 /* Don't allow catalog snapshot to be older than xact snapshot. */
342
344
345 return CurrentSnapshot;
346}
Snapshot GetSerializableTransactionSnapshot(Snapshot snapshot)
Definition predicate.c:1611
static SnapshotData CurrentSnapshotData
Definition snapmgr.c:141
#define IsolationUsesXactSnapshot()
Definition xact.h:52
#define IsolationIsSerializable()
Definition xact.h:53

References Assert, CopySnapshot(), CurrentSnapshot, CurrentSnapshotData, elog, ERROR, fb(), FirstSnapshotSet, FirstXactSnapshot, GetSerializableTransactionSnapshot(), GetSnapshotData(), HistoricSnapshot, HistoricSnapshotActive(), InvalidateCatalogSnapshot(), IsInParallelMode(), IsolationIsSerializable, IsolationUsesXactSnapshot, pairingheap_add(), pairingheap_is_empty, SnapshotData::ph_node, SnapshotData::regd_count, and RegisteredSnapshots.

Referenced by _brin_begin_parallel(), _bt_begin_parallel(), _gin_begin_parallel(), _SPI_execute_plan(), AfterTriggerFireDeferred(), AfterTriggerSetState(), ATExecDetachPartition(), begin_replication_step(), bt_check_every_level(), BuildCachedPlan(), CheckTargetForConflictsIn(), clear_subscription_skip_lsn(), DefineIndex(), detachPartitionTable(), DisableSubscriptionAndExit(), do_autovacuum(), EnsurePortalSnapshotExists(), EventTriggerOnLogin(), exec_bind_message(), exec_eval_simple_expr(), exec_parse_message(), exec_simple_query(), ExecRepack(), execute_sql_string(), ExecuteCallStmt(), fmgr_sql(), GetLatestSnapshot(), HandleFunctionRequest(), heapam_index_build_range_scan(), index_drop(), initialize_worker_spi(), InitializeParallelDSM(), LogicalRepSyncTableStart(), pg_get_constraintdef_worker(), PortalRunMulti(), PortalRunUtility(), PortalStart(), PreCommit_on_commit_actions(), process_single_relation(), ReindexMultipleInternal(), ReindexRelationConcurrently(), RemoveTempRelationsCallback(), RevalidateCachedQuery(), ri_FastPathBatchFlush(), ri_FastPathCheck(), ri_PerformCheck(), run_apply_worker(), SPI_cursor_open_internal(), update_retention_status(), vacuum(), vacuum_rel(), verify_heapam(), worker_spi_main(), and XidIsConcurrent().

◆ GlobalVisCheckRemovableFullXid()

bool GlobalVisCheckRemovableFullXid ( Relation  rel,
FullTransactionId  fxid 
)
extern

Definition at line 4326 of file procarray.c.

4327{
4329
4330 state = GlobalVisTestFor(rel);
4331
4332 return GlobalVisTestIsRemovableFullXid(state, fxid, true);
4333}
GlobalVisState * GlobalVisTestFor(Relation rel)
Definition procarray.c:4114
bool GlobalVisTestIsRemovableFullXid(GlobalVisState *state, FullTransactionId fxid, bool allow_update)
Definition procarray.c:4234

References GlobalVisTestFor(), and GlobalVisTestIsRemovableFullXid().

Referenced by _bt_pendingfsm_finalize(), BTPageIsRecyclable(), and gistPageRecyclable().

◆ GlobalVisCheckRemovableXid()

bool GlobalVisCheckRemovableXid ( Relation  rel,
TransactionId  xid 
)
extern

Definition at line 4340 of file procarray.c.

4341{
4343
4344 state = GlobalVisTestFor(rel);
4345
4346 return GlobalVisTestIsRemovableXid(state, xid, true);
4347}
bool GlobalVisTestIsRemovableXid(GlobalVisState *state, TransactionId xid, bool allow_update)
Definition procarray.c:4277

References GlobalVisTestFor(), and GlobalVisTestIsRemovableXid().

Referenced by GinPageIsRecyclable().

◆ GlobalVisTestFor()

GlobalVisState * GlobalVisTestFor ( Relation  rel)
extern

Definition at line 4114 of file procarray.c.

4115{
4117
4118 /* XXX: we should assert that a snapshot is pushed or registered */
4120
4121 switch (GlobalVisHorizonKindForRel(rel))
4122 {
4123 case VISHORIZON_SHARED:
4125 break;
4126 case VISHORIZON_CATALOG:
4128 break;
4129 case VISHORIZON_DATA:
4131 break;
4132 case VISHORIZON_TEMP:
4134 break;
4135 }
4136
4137 Assert(FullTransactionIdIsValid(state->definitely_needed) &&
4138 FullTransactionIdIsValid(state->maybe_needed));
4139
4140 return state;
4141}
static GlobalVisState GlobalVisDataRels
Definition procarray.c:316
static GlobalVisState GlobalVisSharedRels
Definition procarray.c:314
static GlobalVisState GlobalVisCatalogRels
Definition procarray.c:315
static GlobalVisState GlobalVisTempRels
Definition procarray.c:317
@ VISHORIZON_SHARED
Definition procarray.c:268
@ VISHORIZON_DATA
Definition procarray.c:270
@ VISHORIZON_CATALOG
Definition procarray.c:269
@ VISHORIZON_TEMP
Definition procarray.c:271
static GlobalVisHorizonKind GlobalVisHorizonKindForRel(Relation rel)
Definition procarray.c:1910
TransactionId RecentXmin
Definition snapmgr.c:160
#define FullTransactionIdIsValid(x)
Definition transam.h:55

References Assert, fb(), FullTransactionIdIsValid, GlobalVisCatalogRels, GlobalVisDataRels, GlobalVisHorizonKindForRel(), GlobalVisSharedRels, GlobalVisTempRels, RecentXmin, VISHORIZON_CATALOG, VISHORIZON_DATA, VISHORIZON_SHARED, and VISHORIZON_TEMP.

Referenced by get_actual_variable_endpoint(), GlobalVisCheckRemovableFullXid(), GlobalVisCheckRemovableXid(), heap_hot_search_buffer(), heap_index_delete_tuples(), heap_page_prune_opt(), heap_vacuum_rel(), and vacuumRedirectAndPlaceholder().

◆ GlobalVisTestIsRemovableFullXid()

bool GlobalVisTestIsRemovableFullXid ( GlobalVisState state,
FullTransactionId  fxid,
bool  allow_update 
)
extern

Definition at line 4234 of file procarray.c.

4237{
4238 /*
4239 * If fxid is older than maybe_needed bound, it definitely is visible to
4240 * everyone.
4241 */
4242 if (FullTransactionIdPrecedes(fxid, state->maybe_needed))
4243 return true;
4244
4245 /*
4246 * If fxid is >= definitely_needed bound, it is very likely to still be
4247 * considered running.
4248 */
4249 if (FullTransactionIdFollowsOrEquals(fxid, state->definitely_needed))
4250 return false;
4251
4252 /*
4253 * fxid is between maybe_needed and definitely_needed, i.e. there might or
4254 * might not exist a snapshot considering fxid running. If it makes sense,
4255 * update boundaries and recheck.
4256 */
4258 {
4260
4261 Assert(FullTransactionIdPrecedes(fxid, state->definitely_needed));
4262
4263 return FullTransactionIdPrecedes(fxid, state->maybe_needed);
4264 }
4265 else
4266 return false;
4267}
static bool GlobalVisTestShouldUpdate(GlobalVisState *state)
Definition procarray.c:4154
static void GlobalVisUpdate(void)
Definition procarray.c:4212
#define FullTransactionIdFollowsOrEquals(a, b)
Definition transam.h:54
#define FullTransactionIdPrecedes(a, b)
Definition transam.h:51

References Assert, fb(), FullTransactionIdFollowsOrEquals, FullTransactionIdPrecedes, GlobalVisTestShouldUpdate(), and GlobalVisUpdate().

Referenced by GlobalVisCheckRemovableFullXid(), and GlobalVisTestIsRemovableXid().

◆ GlobalVisTestIsRemovableXid()

bool GlobalVisTestIsRemovableXid ( GlobalVisState state,
TransactionId  xid,
bool  allow_update 
)
extern

Definition at line 4277 of file procarray.c.

4279{
4280 FullTransactionId fxid;
4281
4282 /*
4283 * Convert 32 bit argument to FullTransactionId. We can do so safely
4284 * because we know the xid has to, at the very least, be between
4285 * [oldestXid, nextXid), i.e. within 2 billion of xid. To avoid taking a
4286 * lock to determine either, we can just compare with
4287 * state->definitely_needed, which was based on those value at the time
4288 * the current snapshot was built.
4289 */
4290 fxid = FullXidRelativeTo(state->definitely_needed, xid);
4291
4293}
static FullTransactionId FullXidRelativeTo(FullTransactionId rel, TransactionId xid)
Definition procarray.c:4361

References fb(), FullXidRelativeTo(), and GlobalVisTestIsRemovableFullXid().

Referenced by GlobalVisCheckRemovableXid(), GlobalVisTestXidConsideredRunning(), heap_page_prune_opt(), heap_prune_satisfies_vacuum(), HeapTupleIsSurelyDead(), HeapTupleSatisfiesNonVacuumable(), and vacuumRedirectAndPlaceholder().

◆ GlobalVisTestXidConsideredRunning()

bool GlobalVisTestXidConsideredRunning ( GlobalVisState state,
TransactionId  xid,
bool  allow_update 
)
extern

Definition at line 4315 of file procarray.c.

4317{
4319}

References fb(), and GlobalVisTestIsRemovableXid().

Referenced by heap_page_prune_and_freeze(), and heap_page_would_be_all_visible().

◆ HaveRegisteredOrActiveSnapshot()

bool HaveRegisteredOrActiveSnapshot ( void  )
extern

Definition at line 1643 of file snapmgr.c.

1644{
1645 if (ActiveSnapshot != NULL)
1646 return true;
1647
1648 /*
1649 * The catalog snapshot is in RegisteredSnapshots when valid, but can be
1650 * removed at any time due to invalidation processing. If explicitly
1651 * registered more than one snapshot has to be in RegisteredSnapshots.
1652 */
1653 if (CatalogSnapshot != NULL &&
1655 return false;
1656
1658}
#define pairingheap_is_singular(h)

References ActiveSnapshot, CatalogSnapshot, fb(), pairingheap_is_empty, pairingheap_is_singular, and RegisteredSnapshots.

Referenced by AssertHasSnapshotForToast(), ExecWaitStmt(), get_toast_snapshot(), and SnapBuildInitialSnapshot().

◆ HistoricSnapshotActive()

◆ HistoricSnapshotGetTupleCids()

struct HTAB * HistoricSnapshotGetTupleCids ( void  )
extern

Definition at line 1697 of file snapmgr.c.

1698{
1700 return tuplecid_data;
1701}
static HTAB * tuplecid_data
Definition snapmgr.c:163

References Assert, HistoricSnapshotActive(), and tuplecid_data.

Referenced by HeapTupleSatisfiesHistoricMVCC().

◆ ImportSnapshot()

void ImportSnapshot ( const char idstr)
extern

Definition at line 1386 of file snapmgr.c.

1387{
1388 char path[MAXPGPATH];
1389 FILE *f;
1390 struct stat stat_buf;
1391 char *filebuf;
1392 int xcnt;
1393 int i;
1395 int src_pid;
1396 Oid src_dbid;
1397 int src_isolevel;
1398 bool src_readonly;
1399 SnapshotData snapshot;
1400
1401 /*
1402 * Must be at top level of a fresh transaction. Note in particular that
1403 * we check we haven't acquired an XID --- if we have, it's conceivable
1404 * that the snapshot would show it as not running, making for very screwy
1405 * behavior.
1406 */
1407 if (FirstSnapshotSet ||
1410 ereport(ERROR,
1412 errmsg("SET TRANSACTION SNAPSHOT must be called before any query")));
1413
1414 /*
1415 * If we are in read committed mode then the next query would execute with
1416 * a new snapshot thus making this function call quite useless.
1417 */
1419 ereport(ERROR,
1421 errmsg("a snapshot-importing transaction must have isolation level SERIALIZABLE or REPEATABLE READ")));
1422
1423 /*
1424 * Verify the identifier: only 0-9, A-F and hyphens are allowed. We do
1425 * this mainly to prevent reading arbitrary files.
1426 */
1427 if (strspn(idstr, "0123456789ABCDEF-") != strlen(idstr))
1428 ereport(ERROR,
1430 errmsg("invalid snapshot identifier: \"%s\"", idstr)));
1431
1432 /* OK, read the file */
1434
1435 f = AllocateFile(path, PG_BINARY_R);
1436 if (!f)
1437 {
1438 /*
1439 * If file is missing while identifier has a correct format, avoid
1440 * system errors.
1441 */
1442 if (errno == ENOENT)
1443 ereport(ERROR,
1445 errmsg("snapshot \"%s\" does not exist", idstr)));
1446 else
1447 ereport(ERROR,
1449 errmsg("could not open file \"%s\" for reading: %m",
1450 path)));
1451 }
1452
1453 /* get the size of the file so that we know how much memory we need */
1454 if (fstat(fileno(f), &stat_buf))
1455 elog(ERROR, "could not stat file \"%s\": %m", path);
1456
1457 /* and read the file into a palloc'd string */
1458 filebuf = (char *) palloc(stat_buf.st_size + 1);
1459 if (fread(filebuf, stat_buf.st_size, 1, f) != 1)
1460 elog(ERROR, "could not read file \"%s\": %m", path);
1461
1462 filebuf[stat_buf.st_size] = '\0';
1463
1464 FreeFile(f);
1465
1466 /*
1467 * Construct a snapshot struct by parsing the file content.
1468 */
1469 memset(&snapshot, 0, sizeof(snapshot));
1470
1471 parseVxidFromText("vxid:", &filebuf, path, &src_vxid);
1472 src_pid = parseIntFromText("pid:", &filebuf, path);
1473 /* we abuse parseXidFromText a bit here ... */
1474 src_dbid = parseXidFromText("dbid:", &filebuf, path);
1475 src_isolevel = parseIntFromText("iso:", &filebuf, path);
1476 src_readonly = parseIntFromText("ro:", &filebuf, path);
1477
1478 snapshot.snapshot_type = SNAPSHOT_MVCC;
1479
1480 snapshot.xmin = parseXidFromText("xmin:", &filebuf, path);
1481 snapshot.xmax = parseXidFromText("xmax:", &filebuf, path);
1482
1483 snapshot.xcnt = xcnt = parseIntFromText("xcnt:", &filebuf, path);
1484
1485 /* sanity-check the xid count before palloc */
1487 ereport(ERROR,
1489 errmsg("invalid snapshot data in file \"%s\"", path)));
1490
1491 snapshot.xip = (TransactionId *) palloc(xcnt * sizeof(TransactionId));
1492 for (i = 0; i < xcnt; i++)
1493 snapshot.xip[i] = parseXidFromText("xip:", &filebuf, path);
1494
1495 snapshot.suboverflowed = parseIntFromText("sof:", &filebuf, path);
1496
1497 if (!snapshot.suboverflowed)
1498 {
1499 snapshot.subxcnt = xcnt = parseIntFromText("sxcnt:", &filebuf, path);
1500
1501 /* sanity-check the xid count before palloc */
1503 ereport(ERROR,
1505 errmsg("invalid snapshot data in file \"%s\"", path)));
1506
1507 snapshot.subxip = (TransactionId *) palloc(xcnt * sizeof(TransactionId));
1508 for (i = 0; i < xcnt; i++)
1509 snapshot.subxip[i] = parseXidFromText("sxp:", &filebuf, path);
1510 }
1511 else
1512 {
1513 snapshot.subxcnt = 0;
1514 snapshot.subxip = NULL;
1515 }
1516
1517 snapshot.takenDuringRecovery = parseIntFromText("rec:", &filebuf, path);
1518
1519 /*
1520 * Do some additional sanity checking, just to protect ourselves. We
1521 * don't trouble to check the array elements, just the most critical
1522 * fields.
1523 */
1525 !OidIsValid(src_dbid) ||
1526 !TransactionIdIsNormal(snapshot.xmin) ||
1527 !TransactionIdIsNormal(snapshot.xmax))
1528 ereport(ERROR,
1530 errmsg("invalid snapshot data in file \"%s\"", path)));
1531
1532 /*
1533 * If we're serializable, the source transaction must be too, otherwise
1534 * predicate.c has problems (SxactGlobalXmin could go backwards). Also, a
1535 * non-read-only transaction can't adopt a snapshot from a read-only
1536 * transaction, as predicate.c handles the cases very differently.
1537 */
1539 {
1541 ereport(ERROR,
1543 errmsg("a serializable transaction cannot import a snapshot from a non-serializable transaction")));
1544 if (src_readonly && !XactReadOnly)
1545 ereport(ERROR,
1547 errmsg("a non-read-only serializable transaction cannot import a snapshot from a read-only transaction")));
1548 }
1549
1550 /*
1551 * We cannot import a snapshot that was taken in a different database,
1552 * because vacuum calculates OldestXmin on a per-database basis; so the
1553 * source transaction's xmin doesn't protect us from data loss. This
1554 * restriction could be removed if the source transaction were to mark its
1555 * xmin as being globally applicable. But that would require some
1556 * additional syntax, since that has to be known when the snapshot is
1557 * initially taken. (See pgsql-hackers discussion of 2011-10-21.)
1558 */
1559 if (src_dbid != MyDatabaseId)
1560 ereport(ERROR,
1562 errmsg("cannot import a snapshot from a different database")));
1563
1564 /* OK, install the snapshot */
1566}
#define PG_BINARY_R
Definition c.h:1433
#define OidIsValid(objectId)
Definition c.h:917
#define VirtualTransactionIdIsValid(vxid)
Definition lock.h:70
void * palloc(Size size)
Definition mcxt.c:1390
unsigned int Oid
int GetMaxSnapshotXidCount(void)
Definition procarray.c:2008
static void SetTransactionSnapshot(Snapshot sourcesnap, VirtualTransactionId *sourcevxid, int sourcepid, PGPROC *sourceproc)
Definition snapmgr.c:511
static int parseIntFromText(const char *prefix, char **s, const char *filename)
Definition snapmgr.c:1306
static void parseVxidFromText(const char *prefix, char **s, const char *filename, VirtualTransactionId *vxid)
Definition snapmgr.c:1356
static TransactionId parseXidFromText(const char *prefix, char **s, const char *filename)
Definition snapmgr.c:1331
#define InvalidTransactionId
Definition transam.h:31
#define TransactionIdIsNormal(xid)
Definition transam.h:42
#define fstat
Definition win32_port.h:73
#define XACT_SERIALIZABLE
Definition xact.h:39

References AllocateFile(), elog, ereport, errcode(), errcode_for_file_access(), errmsg, ERROR, fb(), FirstSnapshotSet, FreeFile(), fstat, GetMaxSnapshotSubxidCount(), GetMaxSnapshotXidCount(), GetTopTransactionIdIfAny(), i, InvalidTransactionId, IsolationIsSerializable, IsolationUsesXactSnapshot, IsSubTransaction(), MAXPGPATH, MyDatabaseId, OidIsValid, palloc(), parseIntFromText(), parseVxidFromText(), parseXidFromText(), PG_BINARY_R, SetTransactionSnapshot(), SNAPSHOT_EXPORT_DIR, SNAPSHOT_MVCC, SnapshotData::snapshot_type, snprintf, SnapshotData::suboverflowed, SnapshotData::subxcnt, SnapshotData::subxip, SnapshotData::takenDuringRecovery, TransactionIdIsNormal, VirtualTransactionIdIsValid, XACT_SERIALIZABLE, XactReadOnly, SnapshotData::xcnt, SnapshotData::xip, SnapshotData::xmax, and SnapshotData::xmin.

Referenced by ExecSetVariableStmt().

◆ InvalidateCatalogSnapshot()

◆ InvalidateCatalogSnapshotConditionally()

void InvalidateCatalogSnapshotConditionally ( void  )
extern

◆ PopActiveSnapshot()

void PopActiveSnapshot ( void  )
extern

Definition at line 775 of file snapmgr.c.

References SnapshotData::active_count, ActiveSnapshot, ActiveSnapshotElt::as_next, ActiveSnapshotElt::as_snap, Assert, fb(), FreeSnapshot(), pfree(), SnapshotData::regd_count, and SnapshotResetXmin().

Referenced by _SPI_execute_plan(), AfterTriggerFireDeferred(), AfterTriggerSetState(), ATExecDetachPartition(), BuildCachedPlan(), clear_subscription_skip_lsn(), DefineIndex(), detachPartitionTable(), DisableSubscriptionAndExit(), do_autovacuum(), DoPortalRewind(), end_replication_step(), EndCopyTo(), EventTriggerOnLogin(), exec_bind_message(), exec_eval_simple_expr(), exec_parse_message(), exec_simple_query(), ExecCreateTableAs(), ExecRepack(), execute_sql_string(), ExecuteCallStmt(), ExecWaitStmt(), ExplainOnePlan(), FindConflictTuple(), fmgr_sql(), ForgetPortalSnapshots(), HandleFunctionRequest(), index_drop(), initialize_worker_spi(), LogicalRepSyncTableStart(), movedb(), ParallelWorkerMain(), PersistHoldablePortal(), PortalRunMulti(), PortalRunSelect(), PortalRunUtility(), PortalStart(), PreCommit_on_commit_actions(), process_single_relation(), rebuild_relation(), refresh_matview_datafill(), ReindexMultipleInternal(), ReindexRelationConcurrently(), RelationFindReplTupleByIndex(), RelationFindReplTupleSeq(), RemoveTempRelationsCallback(), RevalidateCachedQuery(), run_apply_worker(), ShutdownSQLFunction(), update_retention_status(), vacuum(), vacuum_rel(), and worker_spi_main().

◆ PushActiveSnapshot()

void PushActiveSnapshot ( Snapshot  snapshot)
extern

◆ PushActiveSnapshotWithLevel()

void PushActiveSnapshotWithLevel ( Snapshot  snapshot,
int  snap_level 
)
extern

Definition at line 696 of file snapmgr.c.

697{
699
700 Assert(snapshot != InvalidSnapshot);
702
704
705 /*
706 * Checking SecondarySnapshot is probably useless here, but it seems
707 * better to be sure.
708 */
709 if (snapshot == CurrentSnapshot || snapshot == SecondarySnapshot ||
710 !snapshot->copied)
711 newactive->as_snap = CopySnapshot(snapshot);
712 else
713 newactive->as_snap = snapshot;
714
715 newactive->as_next = ActiveSnapshot;
717
718 newactive->as_snap->active_count++;
719
721}
void * MemoryContextAlloc(MemoryContext context, Size size)
Definition mcxt.c:1235

References ActiveSnapshot, ActiveSnapshotElt::as_level, Assert, SnapshotData::copied, CopySnapshot(), CurrentSnapshot, fb(), InvalidSnapshot, MemoryContextAlloc(), SecondarySnapshot, and TopTransactionContext.

Referenced by EnsurePortalSnapshotExists(), PortalRunUtility(), and PushActiveSnapshot().

◆ PushCopiedSnapshot()

void PushCopiedSnapshot ( Snapshot  snapshot)
extern

Definition at line 732 of file snapmgr.c.

733{
735}
void PushActiveSnapshot(Snapshot snapshot)
Definition snapmgr.c:682

References CopySnapshot(), and PushActiveSnapshot().

Referenced by _SPI_execute_plan(), BeginCopyTo(), ExecCreateTableAs(), ExplainOnePlan(), PortalRunMulti(), and refresh_matview_datafill().

◆ RegisterSnapshot()

◆ RegisterSnapshotOnOwner()

Snapshot RegisterSnapshotOnOwner ( Snapshot  snapshot,
ResourceOwner  owner 
)
extern

Definition at line 837 of file snapmgr.c.

838{
840
841 if (snapshot == InvalidSnapshot)
842 return InvalidSnapshot;
843
844 /* Static snapshot? Create a persistent copy */
845 snap = snapshot->copied ? snapshot : CopySnapshot(snapshot);
846
847 /* and tell resowner.c about it */
849 snap->regd_count++;
851
852 if (snap->regd_count == 1)
854
855 return snap;
856}
void ResourceOwnerEnlarge(ResourceOwner owner)
Definition resowner.c:459
static void ResourceOwnerRememberSnapshot(ResourceOwner owner, Snapshot snap)
Definition snapmgr.c:235

References SnapshotData::copied, CopySnapshot(), fb(), InvalidSnapshot, pairingheap_add(), RegisteredSnapshots, ResourceOwnerEnlarge(), and ResourceOwnerRememberSnapshot().

Referenced by be_lo_open(), and RegisterSnapshot().

◆ RestoreSnapshot()

Snapshot RestoreSnapshot ( char start_address)
extern

Definition at line 1792 of file snapmgr.c.

1793{
1795 Size size;
1796 Snapshot snapshot;
1798
1800 sizeof(SerializedSnapshotData));
1803
1804 /* We allocate any XID arrays needed in the same palloc block. */
1805 size = sizeof(SnapshotData)
1806 + serialized_snapshot.xcnt * sizeof(TransactionId)
1807 + serialized_snapshot.subxcnt * sizeof(TransactionId);
1808
1809 /* Copy all required fields */
1811 snapshot->snapshot_type = SNAPSHOT_MVCC;
1812 snapshot->xmin = serialized_snapshot.xmin;
1813 snapshot->xmax = serialized_snapshot.xmax;
1814 snapshot->xip = NULL;
1815 snapshot->xcnt = serialized_snapshot.xcnt;
1816 snapshot->subxip = NULL;
1817 snapshot->subxcnt = serialized_snapshot.subxcnt;
1818 snapshot->suboverflowed = serialized_snapshot.suboverflowed;
1819 snapshot->takenDuringRecovery = serialized_snapshot.takenDuringRecovery;
1820 snapshot->curcid = serialized_snapshot.curcid;
1821 snapshot->snapXactCompletionCount = 0;
1822
1823 /* Copy XIDs, if present. */
1824 if (serialized_snapshot.xcnt > 0)
1825 {
1826 snapshot->xip = (TransactionId *) (snapshot + 1);
1827 memcpy(snapshot->xip, serialized_xids,
1828 serialized_snapshot.xcnt * sizeof(TransactionId));
1829 }
1830
1831 /* Copy SubXIDs, if present. */
1832 if (serialized_snapshot.subxcnt > 0)
1833 {
1834 snapshot->subxip = ((TransactionId *) (snapshot + 1)) +
1837 serialized_snapshot.subxcnt * sizeof(TransactionId));
1838 }
1839
1840 /* Set the copied flag so that the caller will set refcounts correctly. */
1841 snapshot->regd_count = 0;
1842 snapshot->active_count = 0;
1843 snapshot->copied = true;
1844
1845 return snapshot;
1846}
memcpy(sums, checksumBaseOffsets, sizeof(checksumBaseOffsets))
struct SnapshotData * Snapshot
Definition execnodes.h:60
CommandId curcid
Definition snapshot.h:183
uint64 snapXactCompletionCount
Definition snapshot.h:209

References SnapshotData::active_count, SnapshotData::copied, SnapshotData::curcid, fb(), memcpy(), MemoryContextAlloc(), SnapshotData::regd_count, SNAPSHOT_MVCC, SnapshotData::snapshot_type, SnapshotData::snapXactCompletionCount, SnapshotData::suboverflowed, SnapshotData::subxcnt, SnapshotData::subxip, SnapshotData::takenDuringRecovery, TopTransactionContext, SnapshotData::xcnt, SnapshotData::xip, SnapshotData::xmax, and SnapshotData::xmin.

Referenced by get_initial_snapshot(), index_beginscan_parallel(), ParallelWorkerMain(), table_beginscan_parallel(), and table_beginscan_parallel_tidrange().

◆ RestoreTransactionSnapshot()

void RestoreTransactionSnapshot ( Snapshot  snapshot,
struct PGPROC source_pgproc 
)
extern

Definition at line 1852 of file snapmgr.c.

1853{
1855}
#define InvalidPid
Definition miscadmin.h:32

References fb(), InvalidPid, and SetTransactionSnapshot().

Referenced by CreateReplicationSlot(), and ParallelWorkerMain().

◆ SerializeSnapshot()

void SerializeSnapshot ( Snapshot  snapshot,
char start_address 
)
extern

Definition at line 1735 of file snapmgr.c.

1736{
1738
1739 Assert(snapshot->subxcnt >= 0);
1740
1741 /* Copy all required fields */
1742 serialized_snapshot.xmin = snapshot->xmin;
1743 serialized_snapshot.xmax = snapshot->xmax;
1744 serialized_snapshot.xcnt = snapshot->xcnt;
1745 serialized_snapshot.subxcnt = snapshot->subxcnt;
1746 serialized_snapshot.suboverflowed = snapshot->suboverflowed;
1747 serialized_snapshot.takenDuringRecovery = snapshot->takenDuringRecovery;
1748 serialized_snapshot.curcid = snapshot->curcid;
1749
1750 /*
1751 * Ignore the SubXID array if it has overflowed, unless the snapshot was
1752 * taken during recovery - in that case, top-level XIDs are in subxip as
1753 * well, and we mustn't lose them.
1754 */
1755 if (serialized_snapshot.suboverflowed && !snapshot->takenDuringRecovery)
1756 serialized_snapshot.subxcnt = 0;
1757
1758 /* Copy struct to possibly-unaligned buffer */
1761
1762 /* Copy XID array */
1763 if (snapshot->xcnt > 0)
1765 sizeof(SerializedSnapshotData)),
1766 snapshot->xip, snapshot->xcnt * sizeof(TransactionId));
1767
1768 /*
1769 * Copy SubXID array. Don't bother to copy it if it had overflowed,
1770 * though, because it's not used anywhere in that case. Except if it's a
1771 * snapshot taken during recovery; all the top-level XIDs are in subxip as
1772 * well in that case, so we mustn't lose them.
1773 */
1774 if (serialized_snapshot.subxcnt > 0)
1775 {
1777 snapshot->xcnt * sizeof(TransactionId);
1778
1780 snapshot->subxip, snapshot->subxcnt * sizeof(TransactionId));
1781 }
1782}

References Assert, SnapshotData::curcid, fb(), memcpy(), SnapshotData::suboverflowed, SnapshotData::subxcnt, SnapshotData::subxip, SnapshotData::takenDuringRecovery, SnapshotData::xcnt, SnapshotData::xip, SnapshotData::xmax, and SnapshotData::xmin.

Referenced by export_initial_snapshot(), index_parallelscan_initialize(), InitializeParallelDSM(), and table_parallelscan_initialize().

◆ SetupHistoricSnapshot()

void SetupHistoricSnapshot ( Snapshot  historic_snapshot,
struct HTAB tuplecids 
)
extern

Definition at line 1668 of file snapmgr.c.

1669{
1671
1672 /* setup the timetravel snapshot */
1674
1675 /* setup (cmin, cmax) lookup hash */
1676 tuplecid_data = tuplecids;
1677}

References Assert, fb(), HistoricSnapshot, and tuplecid_data.

Referenced by ReorderBufferProcessTXN(), and ReorderBufferQueueMessage().

◆ SnapshotSetCommandId()

void SnapshotSetCommandId ( CommandId  curcid)
extern

Definition at line 490 of file snapmgr.c.

491{
492 if (!FirstSnapshotSet)
493 return;
494
495 if (CurrentSnapshot)
496 CurrentSnapshot->curcid = curcid;
498 SecondarySnapshot->curcid = curcid;
499 /* Should we do the same with CatalogSnapshot? */
500}

References SnapshotData::curcid, CurrentSnapshot, FirstSnapshotSet, and SecondarySnapshot.

Referenced by CommandCounterIncrement().

◆ TeardownHistoricSnapshot()

void TeardownHistoricSnapshot ( bool  is_error)
extern

Definition at line 1684 of file snapmgr.c.

1685{
1688}

References fb(), HistoricSnapshot, and tuplecid_data.

Referenced by ReorderBufferProcessTXN(), and ReorderBufferQueueMessage().

◆ ThereAreNoPriorRegisteredSnapshots()

bool ThereAreNoPriorRegisteredSnapshots ( void  )
extern

Definition at line 1625 of file snapmgr.c.

1626{
1629 return true;
1630
1631 return false;
1632}

References pairingheap_is_empty, pairingheap_is_singular, and RegisteredSnapshots.

Referenced by CopyFrom().

◆ UnregisterSnapshot()

◆ UnregisterSnapshotFromOwner()

void UnregisterSnapshotFromOwner ( Snapshot  snapshot,
ResourceOwner  owner 
)
extern

Definition at line 879 of file snapmgr.c.

880{
881 if (snapshot == NULL)
882 return;
883
884 ResourceOwnerForgetSnapshot(owner, snapshot);
886}
static void UnregisterSnapshotNoOwner(Snapshot snapshot)
Definition snapmgr.c:889
static void ResourceOwnerForgetSnapshot(ResourceOwner owner, Snapshot snap)
Definition snapmgr.c:240

References fb(), ResourceOwnerForgetSnapshot(), and UnregisterSnapshotNoOwner().

Referenced by closeLOfd(), PortalDrop(), PreCommit_Portals(), and UnregisterSnapshot().

◆ UpdateActiveSnapshotCommandId()

void UpdateActiveSnapshotCommandId ( void  )
extern

Definition at line 744 of file snapmgr.c.

745{
747 curcid;
748
752
753 /*
754 * Don't allow modification of the active snapshot during parallel
755 * operation. We share the snapshot to worker backends at the beginning
756 * of parallel operation, so any change to the snapshot can lead to
757 * inconsistencies. We have other defenses against
758 * CommandCounterIncrement, but there are a few places that call this
759 * directly, so we put an additional guard here.
760 */
762 curcid = GetCurrentCommandId(false);
763 if (IsInParallelMode() && save_curcid != curcid)
764 elog(ERROR, "cannot modify commandid in active snapshot during a parallel operation");
765 ActiveSnapshot->as_snap->curcid = curcid;
766}
uint32 CommandId
Definition c.h:809
CommandId GetCurrentCommandId(bool used)
Definition xact.c:831

References SnapshotData::active_count, ActiveSnapshot, ActiveSnapshotElt::as_snap, Assert, SnapshotData::curcid, elog, ERROR, fb(), GetCurrentCommandId(), IsInParallelMode(), and SnapshotData::regd_count.

Referenced by _SPI_execute_plan(), apply_concurrent_changes(), BeginCopyTo(), ExecCreateTableAs(), ExplainOnePlan(), fmgr_sql(), PortalRunMulti(), rebuild_relation(), and refresh_matview_datafill().

◆ WaitForOlderSnapshots()

void WaitForOlderSnapshots ( TransactionId  limitXmin,
bool  progress 
)
extern

Definition at line 446 of file indexcmds.c.

447{
448 int n_old_snapshots;
449 int i;
451
456 if (progress)
458
459 for (i = 0; i < n_old_snapshots; i++)
460 {
462 continue; /* found uninteresting in previous cycle */
463
464 if (i > 0)
465 {
466 /* see if anything's changed ... */
469 int j;
470 int k;
471
473 true, false,
477 for (j = i; j < n_old_snapshots; j++)
478 {
480 continue; /* found uninteresting in previous cycle */
481 for (k = 0; k < n_newer_snapshots; k++)
482 {
484 newer_snapshots[k]))
485 break;
486 }
487 if (k >= n_newer_snapshots) /* not there anymore */
489 }
491 }
492
494 {
495 /* If requested, publish who we're going to wait for. */
496 if (progress)
497 {
499
500 if (holder)
502 holder->pid);
503 }
505 }
506
507 if (progress)
509 }
510}
void pgstat_progress_update_param(int index, int64 val)
int j
Definition isn.c:78
bool VirtualXactLock(VirtualTransactionId vxid, bool wait)
Definition lock.c:4723
#define VirtualTransactionIdEquals(vxid1, vxid2)
Definition lock.h:74
#define SetInvalidVirtualTransactionId(vxid)
Definition lock.h:77
static int progress
Definition pgbench.c:262
#define PROC_IN_SAFE_IC
Definition proc.h:63
#define PROC_IN_VACUUM
Definition proc.h:62
#define PROC_IS_AUTOVACUUM
Definition proc.h:61
VirtualTransactionId * GetCurrentVirtualXIDs(TransactionId limitXmin, bool excludeXmin0, bool allDbs, int excludeVacuum, int *nvxids)
Definition procarray.c:3284
PGPROC * ProcNumberGetProc(ProcNumber procNumber)
Definition procarray.c:3098
#define PROGRESS_WAITFOR_DONE
Definition progress.h:146
#define PROGRESS_WAITFOR_TOTAL
Definition progress.h:145
#define PROGRESS_WAITFOR_CURRENT_PID
Definition progress.h:147
Definition proc.h:179

References fb(), GetCurrentVirtualXIDs(), i, j, pfree(), pgstat_progress_update_param(), PROC_IN_SAFE_IC, PROC_IN_VACUUM, PROC_IS_AUTOVACUUM, ProcNumberGetProc(), progress, PROGRESS_WAITFOR_CURRENT_PID, PROGRESS_WAITFOR_DONE, PROGRESS_WAITFOR_TOTAL, SetInvalidVirtualTransactionId, VirtualTransactionIdEquals, VirtualTransactionIdIsValid, and VirtualXactLock().

Referenced by ATExecDetachPartitionFinalize(), DefineIndex(), and ReindexRelationConcurrently().

◆ XactHasExportedSnapshots()

bool XactHasExportedSnapshots ( void  )
extern

Definition at line 1573 of file snapmgr.c.

1574{
1575 return (exportedSnapshots != NIL);
1576}

References exportedSnapshots, and NIL.

Referenced by PrepareTransaction().

◆ XidInMVCCSnapshot()

bool XidInMVCCSnapshot ( TransactionId  xid,
Snapshot  snapshot 
)
extern

Definition at line 1868 of file snapmgr.c.

1869{
1870 /*
1871 * Make a quick range check to eliminate most XIDs without looking at the
1872 * xip arrays. Note that this is OK even if we convert a subxact XID to
1873 * its parent below, because a subxact with XID < xmin has surely also got
1874 * a parent with XID < xmin, while one with XID >= xmax must belong to a
1875 * parent that was not yet committed at the time of this snapshot.
1876 */
1877
1878 /* Any xid < xmin is not in-progress */
1879 if (TransactionIdPrecedes(xid, snapshot->xmin))
1880 return false;
1881 /* Any xid >= xmax is in-progress */
1882 if (TransactionIdFollowsOrEquals(xid, snapshot->xmax))
1883 return true;
1884
1885 /*
1886 * Snapshot information is stored slightly differently in snapshots taken
1887 * during recovery.
1888 */
1889 if (!snapshot->takenDuringRecovery)
1890 {
1891 /*
1892 * If the snapshot contains full subxact data, the fastest way to
1893 * check things is just to compare the given XID against both subxact
1894 * XIDs and top-level XIDs. If the snapshot overflowed, we have to
1895 * use pg_subtrans to convert a subxact XID to its parent XID, but
1896 * then we need only look at top-level XIDs not subxacts.
1897 */
1898 if (!snapshot->suboverflowed)
1899 {
1900 /* we have full data, so search subxip */
1901 if (pg_lfind32(xid, snapshot->subxip, snapshot->subxcnt))
1902 return true;
1903
1904 /* not there, fall through to search xip[] */
1905 }
1906 else
1907 {
1908 /*
1909 * Snapshot overflowed, so convert xid to top-level. This is safe
1910 * because we eliminated too-old XIDs above.
1911 */
1913
1914 /*
1915 * If xid was indeed a subxact, we might now have an xid < xmin,
1916 * so recheck to avoid an array scan. No point in rechecking
1917 * xmax.
1918 */
1919 if (TransactionIdPrecedes(xid, snapshot->xmin))
1920 return false;
1921 }
1922
1923 if (pg_lfind32(xid, snapshot->xip, snapshot->xcnt))
1924 return true;
1925 }
1926 else
1927 {
1928 /*
1929 * In recovery we store all xids in the subxip array because it is by
1930 * far the bigger array, and we mostly don't know which xids are
1931 * top-level and which are subxacts. The xip array is empty.
1932 *
1933 * We start by searching subtrans, if we overflowed.
1934 */
1935 if (snapshot->suboverflowed)
1936 {
1937 /*
1938 * Snapshot overflowed, so convert xid to top-level. This is safe
1939 * because we eliminated too-old XIDs above.
1940 */
1942
1943 /*
1944 * If xid was indeed a subxact, we might now have an xid < xmin,
1945 * so recheck to avoid an array scan. No point in rechecking
1946 * xmax.
1947 */
1948 if (TransactionIdPrecedes(xid, snapshot->xmin))
1949 return false;
1950 }
1951
1952 /*
1953 * We now have either a top-level xid higher than xmin or an
1954 * indeterminate xid. We don't know whether it's top level or subxact
1955 * but it doesn't matter. If it's present, the xid is visible.
1956 */
1957 if (pg_lfind32(xid, snapshot->subxip, snapshot->subxcnt))
1958 return true;
1959 }
1960
1961 return false;
1962}
static bool pg_lfind32(uint32 key, const uint32 *base, uint32 nelem)
Definition pg_lfind.h:153
TransactionId SubTransGetTopmostTransaction(TransactionId xid)
Definition subtrans.c:170
static bool TransactionIdFollowsOrEquals(TransactionId id1, TransactionId id2)
Definition transam.h:312

References pg_lfind32(), SnapshotData::suboverflowed, SubTransGetTopmostTransaction(), SnapshotData::subxcnt, SnapshotData::subxip, SnapshotData::takenDuringRecovery, TransactionIdFollowsOrEquals(), TransactionIdPrecedes(), SnapshotData::xcnt, SnapshotData::xip, SnapshotData::xmax, and SnapshotData::xmin.

Referenced by asyncQueueProcessPageEntries(), find_inheritance_children_extended(), HeapTupleSatisfiesMVCC(), and RelationGetPartitionDesc().

Variable Documentation

◆ FirstSnapshotSet

◆ RecentXmin

◆ SnapshotAnyData

PGDLLIMPORT SnapshotData SnapshotAnyData
extern

Definition at line 145 of file snapmgr.c.

@ SNAPSHOT_ANY
Definition snapshot.h:65

◆ SnapshotSelfData

PGDLLIMPORT SnapshotData SnapshotSelfData
extern

Definition at line 144 of file snapmgr.c.

@ SNAPSHOT_SELF
Definition snapshot.h:60

◆ SnapshotToastData

PGDLLIMPORT SnapshotData SnapshotToastData
extern

Definition at line 146 of file snapmgr.c.

@ SNAPSHOT_TOAST
Definition snapshot.h:70

Referenced by get_toast_snapshot().

◆ TransactionXmin