diff options
Diffstat (limited to 'src/backend/utils/time')
-rw-r--r-- | src/backend/utils/time/Makefile | 4 | ||||
-rw-r--r-- | src/backend/utils/time/snapmgmt.c | 172 | ||||
-rw-r--r-- | src/backend/utils/time/tqual.c | 153 |
3 files changed, 175 insertions, 154 deletions
diff --git a/src/backend/utils/time/Makefile b/src/backend/utils/time/Makefile index 5e886d425e..68b13e4c39 100644 --- a/src/backend/utils/time/Makefile +++ b/src/backend/utils/time/Makefile @@ -4,7 +4,7 @@ # Makefile for utils/time # # IDENTIFICATION -# $PostgreSQL: pgsql/src/backend/utils/time/Makefile,v 1.13 2008/02/19 10:30:09 petere Exp $ +# $PostgreSQL: pgsql/src/backend/utils/time/Makefile,v 1.14 2008/03/26 16:20:47 alvherre Exp $ # #------------------------------------------------------------------------- @@ -12,6 +12,6 @@ subdir = src/backend/utils/time top_builddir = ../../../.. include $(top_builddir)/src/Makefile.global -OBJS = combocid.o tqual.o +OBJS = combocid.o tqual.o snapmgmt.o include $(top_srcdir)/src/backend/common.mk diff --git a/src/backend/utils/time/snapmgmt.c b/src/backend/utils/time/snapmgmt.c new file mode 100644 index 0000000000..b406b4bc69 --- /dev/null +++ b/src/backend/utils/time/snapmgmt.c @@ -0,0 +1,172 @@ +/*------------------------------------------------------------------------- + * snapmgmt.c + * PostgreSQL snapshot management code. + * + * Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * IDENTIFICATION + * $PostgreSQL: pgsql/src/backend/utils/time/snapmgmt.c,v 1.1 2008/03/26 16:20:47 alvherre Exp $ + * + *------------------------------------------------------------------------- + */ +#include "postgres.h" + +#include "access/xact.h" +#include "access/transam.h" +#include "storage/procarray.h" +#include "utils/snapmgmt.h" +#include "utils/tqual.h" + + +/* + * These SnapshotData structs are static to simplify memory allocation + * (see the hack in GetSnapshotData to avoid repeated malloc/free). + */ +static SnapshotData SerializableSnapshotData = {HeapTupleSatisfiesMVCC}; +static SnapshotData LatestSnapshotData = {HeapTupleSatisfiesMVCC}; + +/* Externally visible pointers to valid snapshots: */ +Snapshot SerializableSnapshot = NULL; +Snapshot LatestSnapshot = NULL; + +/* + * This pointer is not maintained by this module, but it's convenient + * to declare it here anyway. Callers typically assign a copy of + * GetTransactionSnapshot's result to ActiveSnapshot. + */ +Snapshot ActiveSnapshot = NULL; + +/* + * These are updated by GetSnapshotData. We initialize them this way + * for the convenience of TransactionIdIsInProgress: even in bootstrap + * mode, we don't want it to say that BootstrapTransactionId is in progress. + */ +TransactionId TransactionXmin = FirstNormalTransactionId; +TransactionId RecentXmin = FirstNormalTransactionId; +TransactionId RecentGlobalXmin = FirstNormalTransactionId; + + +/* + * GetTransactionSnapshot + * Get the appropriate snapshot for a new query in a transaction. + * + * The SerializableSnapshot is the first one taken in a transaction. + * In serializable mode we just use that one throughout the transaction. + * In read-committed mode, we take a new snapshot each time we are called. + * + * Note that the return value points at static storage that will be modified + * by future calls and by CommandCounterIncrement(). Callers should copy + * the result with CopySnapshot() if it is to be used very long. + */ +Snapshot +GetTransactionSnapshot(void) +{ + /* First call in transaction? */ + if (SerializableSnapshot == NULL) + { + SerializableSnapshot = GetSnapshotData(&SerializableSnapshotData, true); + return SerializableSnapshot; + } + + if (IsXactIsoLevelSerializable) + return SerializableSnapshot; + + LatestSnapshot = GetSnapshotData(&LatestSnapshotData, false); + + return LatestSnapshot; +} + +/* + * GetLatestSnapshot + * Get a snapshot that is up-to-date as of the current instant, + * even if we are executing in SERIALIZABLE mode. + */ +Snapshot +GetLatestSnapshot(void) +{ + /* Should not be first call in transaction */ + if (SerializableSnapshot == NULL) + elog(ERROR, "no snapshot has been set"); + + LatestSnapshot = GetSnapshotData(&LatestSnapshotData, false); + + return LatestSnapshot; +} + +/* + * CopySnapshot + * Copy the given snapshot. + * + * The copy is palloc'd in the current memory context. + */ +Snapshot +CopySnapshot(Snapshot snapshot) +{ + Snapshot newsnap; + Size subxipoff; + Size size; + + /* We allocate any XID arrays needed in the same palloc block. */ + size = subxipoff = sizeof(SnapshotData) + + snapshot->xcnt * sizeof(TransactionId); + if (snapshot->subxcnt > 0) + size += snapshot->subxcnt * sizeof(TransactionId); + + newsnap = (Snapshot) palloc(size); + memcpy(newsnap, snapshot, sizeof(SnapshotData)); + + /* setup XID array */ + if (snapshot->xcnt > 0) + { + newsnap->xip = (TransactionId *) (newsnap + 1); + memcpy(newsnap->xip, snapshot->xip, + snapshot->xcnt * sizeof(TransactionId)); + } + else + newsnap->xip = NULL; + + /* setup subXID array */ + if (snapshot->subxcnt > 0) + { + newsnap->subxip = (TransactionId *) ((char *) newsnap + subxipoff); + memcpy(newsnap->subxip, snapshot->subxip, + snapshot->subxcnt * sizeof(TransactionId)); + } + else + newsnap->subxip = NULL; + + return newsnap; +} + +/* + * FreeSnapshot + * Free a snapshot previously copied with CopySnapshot. + * + * This is currently identical to pfree, but is provided for cleanliness. + * + * Do *not* apply this to the results of GetTransactionSnapshot or + * GetLatestSnapshot, since those are just static structs. + */ +void +FreeSnapshot(Snapshot snapshot) +{ + pfree(snapshot); +} + +/* + * FreeXactSnapshot + * Free snapshot(s) at end of transaction. + */ +void +FreeXactSnapshot(void) +{ + /* + * We do not free the xip arrays for the static snapshot structs; they + * will be reused soon. So this is now just a state change to prevent + * outside callers from accessing the snapshots. + */ + SerializableSnapshot = NULL; + LatestSnapshot = NULL; + ActiveSnapshot = NULL; /* just for cleanliness */ +} diff --git a/src/backend/utils/time/tqual.c b/src/backend/utils/time/tqual.c index 6fbc935a6b..b6737d4069 100644 --- a/src/backend/utils/time/tqual.c +++ b/src/backend/utils/time/tqual.c @@ -31,7 +31,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.109 2008/01/01 19:45:55 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/utils/time/tqual.c,v 1.110 2008/03/26 16:20:47 alvherre Exp $ * *------------------------------------------------------------------------- */ @@ -53,33 +53,6 @@ SnapshotData SnapshotSelfData = {HeapTupleSatisfiesSelf}; SnapshotData SnapshotAnyData = {HeapTupleSatisfiesAny}; SnapshotData SnapshotToastData = {HeapTupleSatisfiesToast}; -/* - * These SnapshotData structs are static to simplify memory allocation - * (see the hack in GetSnapshotData to avoid repeated malloc/free). - */ -static SnapshotData SerializableSnapshotData = {HeapTupleSatisfiesMVCC}; -static SnapshotData LatestSnapshotData = {HeapTupleSatisfiesMVCC}; - -/* Externally visible pointers to valid snapshots: */ -Snapshot SerializableSnapshot = NULL; -Snapshot LatestSnapshot = NULL; - -/* - * This pointer is not maintained by this module, but it's convenient - * to declare it here anyway. Callers typically assign a copy of - * GetTransactionSnapshot's result to ActiveSnapshot. - */ -Snapshot ActiveSnapshot = NULL; - -/* - * These are updated by GetSnapshotData. We initialize them this way - * for the convenience of TransactionIdIsInProgress: even in bootstrap - * mode, we don't want it to say that BootstrapTransactionId is in progress. - */ -TransactionId TransactionXmin = FirstNormalTransactionId; -TransactionId RecentXmin = FirstNormalTransactionId; -TransactionId RecentGlobalXmin = FirstNormalTransactionId; - /* local functions */ static bool XidInMVCCSnapshot(TransactionId xid, Snapshot snapshot); @@ -1236,130 +1209,6 @@ HeapTupleSatisfiesVacuum(HeapTupleHeader tuple, TransactionId OldestXmin, /* - * GetTransactionSnapshot - * Get the appropriate snapshot for a new query in a transaction. - * - * The SerializableSnapshot is the first one taken in a transaction. - * In serializable mode we just use that one throughout the transaction. - * In read-committed mode, we take a new snapshot each time we are called. - * - * Note that the return value points at static storage that will be modified - * by future calls and by CommandCounterIncrement(). Callers should copy - * the result with CopySnapshot() if it is to be used very long. - */ -Snapshot -GetTransactionSnapshot(void) -{ - /* First call in transaction? */ - if (SerializableSnapshot == NULL) - { - SerializableSnapshot = GetSnapshotData(&SerializableSnapshotData, true); - return SerializableSnapshot; - } - - if (IsXactIsoLevelSerializable) - return SerializableSnapshot; - - LatestSnapshot = GetSnapshotData(&LatestSnapshotData, false); - - return LatestSnapshot; -} - -/* - * GetLatestSnapshot - * Get a snapshot that is up-to-date as of the current instant, - * even if we are executing in SERIALIZABLE mode. - */ -Snapshot -GetLatestSnapshot(void) -{ - /* Should not be first call in transaction */ - if (SerializableSnapshot == NULL) - elog(ERROR, "no snapshot has been set"); - - LatestSnapshot = GetSnapshotData(&LatestSnapshotData, false); - - return LatestSnapshot; -} - -/* - * CopySnapshot - * Copy the given snapshot. - * - * The copy is palloc'd in the current memory context. - */ -Snapshot -CopySnapshot(Snapshot snapshot) -{ - Snapshot newsnap; - Size subxipoff; - Size size; - - /* We allocate any XID arrays needed in the same palloc block. */ - size = subxipoff = sizeof(SnapshotData) + - snapshot->xcnt * sizeof(TransactionId); - if (snapshot->subxcnt > 0) - size += snapshot->subxcnt * sizeof(TransactionId); - - newsnap = (Snapshot) palloc(size); - memcpy(newsnap, snapshot, sizeof(SnapshotData)); - - /* setup XID array */ - if (snapshot->xcnt > 0) - { - newsnap->xip = (TransactionId *) (newsnap + 1); - memcpy(newsnap->xip, snapshot->xip, - snapshot->xcnt * sizeof(TransactionId)); - } - else - newsnap->xip = NULL; - - /* setup subXID array */ - if (snapshot->subxcnt > 0) - { - newsnap->subxip = (TransactionId *) ((char *) newsnap + subxipoff); - memcpy(newsnap->subxip, snapshot->subxip, - snapshot->subxcnt * sizeof(TransactionId)); - } - else - newsnap->subxip = NULL; - - return newsnap; -} - -/* - * FreeSnapshot - * Free a snapshot previously copied with CopySnapshot. - * - * This is currently identical to pfree, but is provided for cleanliness. - * - * Do *not* apply this to the results of GetTransactionSnapshot or - * GetLatestSnapshot, since those are just static structs. - */ -void -FreeSnapshot(Snapshot snapshot) -{ - pfree(snapshot); -} - -/* - * FreeXactSnapshot - * Free snapshot(s) at end of transaction. - */ -void -FreeXactSnapshot(void) -{ - /* - * We do not free the xip arrays for the static snapshot structs; they - * will be reused soon. So this is now just a state change to prevent - * outside callers from accessing the snapshots. - */ - SerializableSnapshot = NULL; - LatestSnapshot = NULL; - ActiveSnapshot = NULL; /* just for cleanliness */ -} - -/* * XidInMVCCSnapshot * Is the given XID still-in-progress according to the snapshot? * |