Update comments that became out-of-date with the PGXACT struct.

When the "hot" members of PGPROC were split off to separate PGXACT structs,
many PGPROC fields referred to in comments were moved to PGXACT, but the
comments were neglected in the commit. Mostly this is just a search/replace
of PGPROC with PGXACT, but the way the dummy PGPROC entries are created for
prepared transactions changed more, making some of the comments totally
bogus.

Noah Misch
This commit is contained in:
Heikki Linnakangas 2012-05-14 10:22:44 +03:00
parent 64f09ca386
commit 9e4637bf89
11 changed files with 56 additions and 66 deletions

View File

@ -251,7 +251,7 @@ enforce, and it assists with some other issues as explained below.) The
implementation of this is that GetSnapshotData takes the ProcArrayLock in implementation of this is that GetSnapshotData takes the ProcArrayLock in
shared mode (so that multiple backends can take snapshots in parallel), shared mode (so that multiple backends can take snapshots in parallel),
but ProcArrayEndTransaction must take the ProcArrayLock in exclusive mode but ProcArrayEndTransaction must take the ProcArrayLock in exclusive mode
while clearing MyProc->xid at transaction end (either commit or abort). while clearing MyPgXact->xid at transaction end (either commit or abort).
ProcArrayEndTransaction also holds the lock while advancing the shared ProcArrayEndTransaction also holds the lock while advancing the shared
latestCompletedXid variable. This allows GetSnapshotData to use latestCompletedXid variable. This allows GetSnapshotData to use
@ -275,12 +275,12 @@ present in the ProcArray, or not running anymore. (This guarantee doesn't
apply to subtransaction XIDs, because of the possibility that there's not apply to subtransaction XIDs, because of the possibility that there's not
room for them in the subxid array; instead we guarantee that they are room for them in the subxid array; instead we guarantee that they are
present or the overflow flag is set.) If a backend released XidGenLock present or the overflow flag is set.) If a backend released XidGenLock
before storing its XID into MyProc, then it would be possible for another before storing its XID into MyPgXact, then it would be possible for another
backend to allocate and commit a later XID, causing latestCompletedXid to backend to allocate and commit a later XID, causing latestCompletedXid to
pass the first backend's XID, before that value became visible in the pass the first backend's XID, before that value became visible in the
ProcArray. That would break GetOldestXmin, as discussed below. ProcArray. That would break GetOldestXmin, as discussed below.
We allow GetNewTransactionId to store the XID into MyProc->xid (or the We allow GetNewTransactionId to store the XID into MyPgXact->xid (or the
subxid array) without taking ProcArrayLock. This was once necessary to subxid array) without taking ProcArrayLock. This was once necessary to
avoid deadlock; while that is no longer the case, it's still beneficial for avoid deadlock; while that is no longer the case, it's still beneficial for
performance. We are thereby relying on fetch/store of an XID to be atomic, performance. We are thereby relying on fetch/store of an XID to be atomic,
@ -293,7 +293,7 @@ ensure that the C compiler does exactly what you tell it to.)
Another important activity that uses the shared ProcArray is GetOldestXmin, Another important activity that uses the shared ProcArray is GetOldestXmin,
which must determine a lower bound for the oldest xmin of any active MVCC which must determine a lower bound for the oldest xmin of any active MVCC
snapshot, system-wide. Each individual backend advertises the smallest snapshot, system-wide. Each individual backend advertises the smallest
xmin of its own snapshots in MyProc->xmin, or zero if it currently has no xmin of its own snapshots in MyPgXact->xmin, or zero if it currently has no
live snapshots (eg, if it's between transactions or hasn't yet set a live snapshots (eg, if it's between transactions or hasn't yet set a
snapshot for a new transaction). GetOldestXmin takes the MIN() of the snapshot for a new transaction). GetOldestXmin takes the MIN() of the
valid xmin fields. It does this with only shared lock on ProcArrayLock, valid xmin fields. It does this with only shared lock on ProcArrayLock,
@ -320,7 +320,7 @@ too expensive. Note that while it is certain that two concurrent
executions of GetSnapshotData will compute the same xmin for their own executions of GetSnapshotData will compute the same xmin for their own
snapshots, as argued above, it is not certain that they will arrive at the snapshots, as argued above, it is not certain that they will arrive at the
same estimate of RecentGlobalXmin. This is because we allow XID-less same estimate of RecentGlobalXmin. This is because we allow XID-less
transactions to clear their MyProc->xmin asynchronously (without taking transactions to clear their MyPgXact->xmin asynchronously (without taking
ProcArrayLock), so one execution might see what had been the oldest xmin, ProcArrayLock), so one execution might see what had been the oldest xmin,
and another not. This is OK since RecentGlobalXmin need only be a valid and another not. This is OK since RecentGlobalXmin need only be a valid
lower bound. As noted above, we are already assuming that fetch/store lower bound. As noted above, we are already assuming that fetch/store
@ -371,7 +371,7 @@ Top-level transactions do not have a parent, so they leave their pg_subtrans
entries set to the default value of zero (InvalidTransactionId). entries set to the default value of zero (InvalidTransactionId).
pg_subtrans is used to check whether the transaction in question is still pg_subtrans is used to check whether the transaction in question is still
running --- the main Xid of a transaction is recorded in the PGPROC struct, running --- the main Xid of a transaction is recorded in the PGXACT struct,
but since we allow arbitrary nesting of subtransactions, we can't fit all Xids but since we allow arbitrary nesting of subtransactions, we can't fit all Xids
in shared memory, so we have to store them on disk. Note, however, that for in shared memory, so we have to store them on disk. Note, however, that for
each transaction we keep a "cache" of Xids that are known to be part of the each transaction we keep a "cache" of Xids that are known to be part of the

View File

@ -21,10 +21,9 @@
* GIDs and aborts the transaction if there already is a global * GIDs and aborts the transaction if there already is a global
* transaction in prepared state with the same GID. * transaction in prepared state with the same GID.
* *
* A global transaction (gxact) also has a dummy PGPROC that is entered * A global transaction (gxact) also has dummy PGXACT and PGPROC; this is
* into the ProcArray array; this is what keeps the XID considered * what keeps the XID considered running by TransactionIdIsInProgress.
* running by TransactionIdIsInProgress. It is also convenient as a * It is also convenient as a PGPROC to hook the gxact's locks to.
* PGPROC to hook the gxact's locks to.
* *
* In order to survive crashes and shutdowns, all prepared * In order to survive crashes and shutdowns, all prepared
* transactions must be stored in permanent storage. This includes * transactions must be stored in permanent storage. This includes
@ -79,11 +78,6 @@ int max_prepared_xacts = 0;
* This struct describes one global transaction that is in prepared state * This struct describes one global transaction that is in prepared state
* or attempting to become prepared. * or attempting to become prepared.
* *
* The first component of the struct is a dummy PGPROC that is inserted
* into the global ProcArray so that the transaction appears to still be
* running and holding locks. It must be first because we cast pointers
* to PGPROC and pointers to GlobalTransactionData back and forth.
*
* The lifecycle of a global transaction is: * The lifecycle of a global transaction is:
* *
* 1. After checking that the requested GID is not in use, set up an * 1. After checking that the requested GID is not in use, set up an
@ -91,7 +85,7 @@ int max_prepared_xacts = 0;
* with locking_xid = my own XID and valid = false. * with locking_xid = my own XID and valid = false.
* *
* 2. After successfully completing prepare, set valid = true and enter the * 2. After successfully completing prepare, set valid = true and enter the
* contained PGPROC into the global ProcArray. * referenced PGPROC into the global ProcArray.
* *
* 3. To begin COMMIT PREPARED or ROLLBACK PREPARED, check that the entry * 3. To begin COMMIT PREPARED or ROLLBACK PREPARED, check that the entry
* is valid and its locking_xid is no longer active, then store my current * is valid and its locking_xid is no longer active, then store my current
@ -1069,12 +1063,12 @@ EndPrepare(GlobalTransaction gxact)
errmsg("could not close two-phase state file: %m"))); errmsg("could not close two-phase state file: %m")));
/* /*
* Mark the prepared transaction as valid. As soon as xact.c marks MyProc * Mark the prepared transaction as valid. As soon as xact.c marks MyPgXact
* as not running our XID (which it will do immediately after this * as not running our XID (which it will do immediately after this
* function returns), others can commit/rollback the xact. * function returns), others can commit/rollback the xact.
* *
* NB: a side effect of this is to make a dummy ProcArray entry for the * NB: a side effect of this is to make a dummy ProcArray entry for the
* prepared XID. This must happen before we clear the XID from MyProc, * prepared XID. This must happen before we clear the XID from MyPgXact,
* else there is a window where the XID is not running according to * else there is a window where the XID is not running according to
* TransactionIdIsInProgress, and onlookers would be entitled to assume * TransactionIdIsInProgress, and onlookers would be entitled to assume
* the xact crashed. Instead we have a window where the same XID appears * the xact crashed. Instead we have a window where the same XID appears

View File

@ -35,7 +35,7 @@ VariableCache ShmemVariableCache = NULL;
/* /*
* Allocate the next XID for a new transaction or subtransaction. * Allocate the next XID for a new transaction or subtransaction.
* *
* The new XID is also stored into MyProc before returning. * The new XID is also stored into MyPgXact before returning.
* *
* Note: when this is called, we are actually already inside a valid * Note: when this is called, we are actually already inside a valid
* transaction, since XIDs are now not allocated until the transaction * transaction, since XIDs are now not allocated until the transaction
@ -174,19 +174,19 @@ GetNewTransactionId(bool isSubXact)
* latestCompletedXid is present in the ProcArray, which is essential for * latestCompletedXid is present in the ProcArray, which is essential for
* correct OldestXmin tracking; see src/backend/access/transam/README. * correct OldestXmin tracking; see src/backend/access/transam/README.
* *
* XXX by storing xid into MyProc without acquiring ProcArrayLock, we are * XXX by storing xid into MyPgXact without acquiring ProcArrayLock, we are
* relying on fetch/store of an xid to be atomic, else other backends * relying on fetch/store of an xid to be atomic, else other backends
* might see a partially-set xid here. But holding both locks at once * might see a partially-set xid here. But holding both locks at once
* would be a nasty concurrency hit. So for now, assume atomicity. * would be a nasty concurrency hit. So for now, assume atomicity.
* *
* Note that readers of PGPROC xid fields should be careful to fetch the * Note that readers of PGXACT xid fields should be careful to fetch the
* value only once, rather than assume they can read a value multiple * value only once, rather than assume they can read a value multiple
* times and get the same answer each time. * times and get the same answer each time.
* *
* The same comments apply to the subxact xid count and overflow fields. * The same comments apply to the subxact xid count and overflow fields.
* *
* A solution to the atomic-store problem would be to give each PGPROC its * A solution to the atomic-store problem would be to give each PGXACT its
* own spinlock used only for fetching/storing that PGPROC's xid and * own spinlock used only for fetching/storing that PGXACT's xid and
* related fields. * related fields.
* *
* If there's no room to fit a subtransaction XID into PGPROC, set the * If there's no room to fit a subtransaction XID into PGPROC, set the

View File

@ -279,7 +279,7 @@ analyze_rel(Oid relid, VacuumStmt *vacstmt, BufferAccessStrategy bstrategy)
relation_close(onerel, NoLock); relation_close(onerel, NoLock);
/* /*
* Reset my PGPROC flag. Note: we need this here, and not in vacuum_rel, * Reset my PGXACT flag. Note: we need this here, and not in vacuum_rel,
* because the vacuum flag is cleared by the end-of-xact code. * because the vacuum flag is cleared by the end-of-xact code.
*/ */
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);

View File

@ -892,7 +892,7 @@ vacuum_rel(Oid relid, VacuumStmt *vacstmt, bool do_toast, bool for_wraparound)
* *
* Note: these flags remain set until CommitTransaction or * Note: these flags remain set until CommitTransaction or
* AbortTransaction. We don't want to clear them until we reset * AbortTransaction. We don't want to clear them until we reset
* MyProc->xid/xmin, else OldestXmin might appear to go backwards, * MyPgXact->xid/xmin, else OldestXmin might appear to go backwards,
* which is probably Not Good. * which is probably Not Good.
*/ */
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);

View File

@ -2327,7 +2327,7 @@ do_autovacuum(void)
tab->at_datname, tab->at_nspname, tab->at_relname); tab->at_datname, tab->at_nspname, tab->at_relname);
EmitErrorReport(); EmitErrorReport();
/* this resets the PGPROC flags too */ /* this resets the PGXACT flags too */
AbortOutOfAnyTransaction(); AbortOutOfAnyTransaction();
FlushErrorState(); FlushErrorState();
MemoryContextResetAndDeleteChildren(PortalContext); MemoryContextResetAndDeleteChildren(PortalContext);
@ -2338,7 +2338,7 @@ do_autovacuum(void)
} }
PG_END_TRY(); PG_END_TRY();
/* the PGPROC flags are reset at the next end of transaction */ /* the PGXACT flags are reset at the next end of transaction */
/* be tidy */ /* be tidy */
deleted: deleted:

View File

@ -4,18 +4,18 @@
* POSTGRES process array code. * POSTGRES process array code.
* *
* *
* This module maintains an unsorted array of the PGPROC structures for all * This module maintains arrays of the PGPROC and PGXACT structures for all
* active backends. Although there are several uses for this, the principal * active backends. Although there are several uses for this, the principal
* one is as a means of determining the set of currently running transactions. * one is as a means of determining the set of currently running transactions.
* *
* Because of various subtle race conditions it is critical that a backend * Because of various subtle race conditions it is critical that a backend
* hold the correct locks while setting or clearing its MyProc->xid field. * hold the correct locks while setting or clearing its MyPgXact->xid field.
* See notes in src/backend/access/transam/README. * See notes in src/backend/access/transam/README.
* *
* The process array now also includes PGPROC structures representing * The process arrays now also include structures representing prepared
* prepared transactions. The xid and subxids fields of these are valid, * transactions. The xid and subxids fields of these are valid, as are the
* as are the myProcLocks lists. They can be distinguished from regular * myProcLocks lists. They can be distinguished from regular backend PGPROCs
* backend PGPROCs at need by checking for pid == 0. * at need by checking for pid == 0.
* *
* During hot standby, we also keep a list of XIDs representing transactions * During hot standby, we also keep a list of XIDs representing transactions
* that are known to be running in the master (or more precisely, were running * that are known to be running in the master (or more precisely, were running
@ -75,7 +75,7 @@ typedef struct ProcArrayStruct
/* /*
* Highest subxid that has been removed from KnownAssignedXids array to * Highest subxid that has been removed from KnownAssignedXids array to
* prevent overflow; or InvalidTransactionId if none. We track this for * prevent overflow; or InvalidTransactionId if none. We track this for
* similar reasons to tracking overflowing cached subxids in PGPROC * similar reasons to tracking overflowing cached subxids in PGXACT
* entries. Must hold exclusive ProcArrayLock to change this, and shared * entries. Must hold exclusive ProcArrayLock to change this, and shared
* lock to read it. * lock to read it.
*/ */
@ -440,7 +440,7 @@ ProcArrayEndTransaction(PGPROC *proc, TransactionId latestXid)
* This is used after successfully preparing a 2-phase transaction. We are * This is used after successfully preparing a 2-phase transaction. We are
* not actually reporting the transaction's XID as no longer running --- it * not actually reporting the transaction's XID as no longer running --- it
* will still appear as running because the 2PC's gxact is in the ProcArray * will still appear as running because the 2PC's gxact is in the ProcArray
* too. We just have to clear out our own PGPROC. * too. We just have to clear out our own PGXACT.
*/ */
void void
ProcArrayClearTransaction(PGPROC *proc) ProcArrayClearTransaction(PGPROC *proc)
@ -752,7 +752,7 @@ ProcArrayApplyXidAssignment(TransactionId topxid,
* there are four possibilities for finding a running transaction: * there are four possibilities for finding a running transaction:
* *
* 1. The given Xid is a main transaction Id. We will find this out cheaply * 1. The given Xid is a main transaction Id. We will find this out cheaply
* by looking at the PGPROC struct for each backend. * by looking at the PGXACT struct for each backend.
* *
* 2. The given Xid is one of the cached subxact Xids in the PGPROC array. * 2. The given Xid is one of the cached subxact Xids in the PGPROC array.
* We can find this out cheaply too. * We can find this out cheaply too.
@ -760,16 +760,16 @@ ProcArrayApplyXidAssignment(TransactionId topxid,
* 3. In Hot Standby mode, we must search the KnownAssignedXids list to see * 3. In Hot Standby mode, we must search the KnownAssignedXids list to see
* if the Xid is running on the master. * if the Xid is running on the master.
* *
* 4. Search the SubTrans tree to find the Xid's topmost parent, and then * 4. Search the SubTrans tree to find the Xid's topmost parent, and then see
* see if that is running according to PGPROC or KnownAssignedXids. This is * if that is running according to PGXACT or KnownAssignedXids. This is the
* the slowest way, but sadly it has to be done always if the others failed, * slowest way, but sadly it has to be done always if the others failed,
* unless we see that the cached subxact sets are complete (none have * unless we see that the cached subxact sets are complete (none have
* overflowed). * overflowed).
* *
* ProcArrayLock has to be held while we do 1, 2, 3. If we save the top Xids * ProcArrayLock has to be held while we do 1, 2, 3. If we save the top Xids
* while doing 1 and 3, we can release the ProcArrayLock while we do 4. * while doing 1 and 3, we can release the ProcArrayLock while we do 4.
* This buys back some concurrency (and we can't retrieve the main Xids from * This buys back some concurrency (and we can't retrieve the main Xids from
* PGPROC again anyway; see GetNewTransactionId). * PGXACT again anyway; see GetNewTransactionId).
*/ */
bool bool
TransactionIdIsInProgress(TransactionId xid) TransactionIdIsInProgress(TransactionId xid)
@ -915,7 +915,7 @@ TransactionIdIsInProgress(TransactionId xid)
*/ */
if (RecoveryInProgress()) if (RecoveryInProgress())
{ {
/* none of the PGPROC entries should have XIDs in hot standby mode */ /* none of the PGXACT entries should have XIDs in hot standby mode */
Assert(nxids == 0); Assert(nxids == 0);
if (KnownAssignedXidExists(xid)) if (KnownAssignedXidExists(xid))
@ -1283,7 +1283,7 @@ GetSnapshotData(Snapshot snapshot)
/* /*
* It is sufficient to get shared lock on ProcArrayLock, even if we are * It is sufficient to get shared lock on ProcArrayLock, even if we are
* going to set MyProc->xmin. * going to set MyPgXact->xmin.
*/ */
LWLockAcquire(ProcArrayLock, LW_SHARED); LWLockAcquire(ProcArrayLock, LW_SHARED);
@ -1462,7 +1462,7 @@ GetSnapshotData(Snapshot snapshot)
} }
/* /*
* ProcArrayInstallImportedXmin -- install imported xmin into MyProc->xmin * ProcArrayInstallImportedXmin -- install imported xmin into MyPgXact->xmin
* *
* This is called when installing a snapshot imported from another * This is called when installing a snapshot imported from another
* transaction. To ensure that OldestXmin doesn't go backwards, we must * transaction. To ensure that OldestXmin doesn't go backwards, we must
@ -1538,7 +1538,7 @@ ProcArrayInstallImportedXmin(TransactionId xmin, TransactionId sourcexid)
* GetRunningTransactionData -- returns information about running transactions. * GetRunningTransactionData -- returns information about running transactions.
* *
* Similar to GetSnapshotData but returns more information. We include * Similar to GetSnapshotData but returns more information. We include
* all PGPROCs with an assigned TransactionId, even VACUUM processes. * all PGXACTs with an assigned TransactionId, even VACUUM processes.
* *
* We acquire XidGenLock, but the caller is responsible for releasing it. * We acquire XidGenLock, but the caller is responsible for releasing it.
* This ensures that no new XIDs enter the proc array until the caller has * This ensures that no new XIDs enter the proc array until the caller has
@ -1679,7 +1679,7 @@ GetRunningTransactionData(void)
* GetOldestActiveTransactionId() * GetOldestActiveTransactionId()
* *
* Similar to GetSnapshotData but returns just oldestActiveXid. We include * Similar to GetSnapshotData but returns just oldestActiveXid. We include
* all PGPROCs with an assigned TransactionId, even VACUUM processes. * all PGXACTs with an assigned TransactionId, even VACUUM processes.
* We look at all databases, though there is no need to include WALSender * We look at all databases, though there is no need to include WALSender
* since this has no effect on hot standby conflicts. * since this has no effect on hot standby conflicts.
* *
@ -1744,7 +1744,7 @@ GetOldestActiveTransactionId(void)
* GetTransactionsInCommit -- Get the XIDs of transactions that are committing * GetTransactionsInCommit -- Get the XIDs of transactions that are committing
* *
* Constructs an array of XIDs of transactions that are currently in commit * Constructs an array of XIDs of transactions that are currently in commit
* critical sections, as shown by having inCommit set in their PGPROC entries. * critical sections, as shown by having inCommit set in their PGXACT entries.
* *
* *xids_p is set to a palloc'd array that should be freed by the caller. * *xids_p is set to a palloc'd array that should be freed by the caller.
* The return value is the number of valid entries. * The return value is the number of valid entries.
@ -2189,7 +2189,7 @@ MinimumActiveBackends(int min)
* *
* If someone just decremented numProcs, 'proc' could also point to a * If someone just decremented numProcs, 'proc' could also point to a
* PGPROC entry that's no longer in the array. It still points to a * PGPROC entry that's no longer in the array. It still points to a
* PGPROC struct, though, because freed PGPPROC entries just go to the * PGPROC struct, though, because freed PGPROC entries just go to the
* free list and are recycled. Its contents are nonsense in that case, * free list and are recycled. Its contents are nonsense in that case,
* but that's acceptable for this function. * but that's acceptable for this function.
*/ */
@ -2514,7 +2514,7 @@ DisplayXidCache(void)
* In Hot Standby mode, we maintain a list of transactions that are (or were) * In Hot Standby mode, we maintain a list of transactions that are (or were)
* running in the master at the current point in WAL. These XIDs must be * running in the master at the current point in WAL. These XIDs must be
* treated as running by standby transactions, even though they are not in * treated as running by standby transactions, even though they are not in
* the standby server's PGPROC array. * the standby server's PGXACT array.
* *
* We record all XIDs that we know have been assigned. That includes all the * We record all XIDs that we know have been assigned. That includes all the
* XIDs seen in WAL records, plus all unobserved XIDs that we can deduce have * XIDs seen in WAL records, plus all unobserved XIDs that we can deduce have

View File

@ -56,7 +56,7 @@ int DeadlockTimeout = 1000;
int StatementTimeout = 0; int StatementTimeout = 0;
bool log_lock_waits = false; bool log_lock_waits = false;
/* Pointer to this process's PGPROC struct, if any */ /* Pointer to this process's PGPROC and PGXACT structs, if any */
PGPROC *MyProc = NULL; PGPROC *MyProc = NULL;
PGXACT *MyPgXact = NULL; PGXACT *MyPgXact = NULL;
@ -190,15 +190,11 @@ InitProcGlobal(void)
ProcGlobal->checkpointerLatch = NULL; ProcGlobal->checkpointerLatch = NULL;
/* /*
* Create and initialize all the PGPROC structures we'll need (except for * Create and initialize all the PGPROC structures we'll need. There are
* those used for 2PC, which are embedded within a GlobalTransactionData * four separate consumers: (1) normal backends, (2) autovacuum workers
* struct). * and the autovacuum launcher, (3) auxiliary processes, and (4) prepared
* * transactions. Each PGPROC structure is dedicated to exactly one of
* There are four separate consumers of PGPROC structures: (1) normal * these purposes, and they do not move between groups.
* backends, (2) autovacuum workers and the autovacuum launcher, (3)
* auxiliary processes, and (4) prepared transactions. Each PGPROC
* structure is dedicated to exactly one of these purposes, and they do
* not move between groups.
*/ */
procs = (PGPROC *) ShmemAlloc(TotalProcs * sizeof(PGPROC)); procs = (PGPROC *) ShmemAlloc(TotalProcs * sizeof(PGPROC));
ProcGlobal->allProcs = procs; ProcGlobal->allProcs = procs;
@ -214,7 +210,7 @@ InitProcGlobal(void)
* from the main PGPROC array so that the most heavily accessed data is * from the main PGPROC array so that the most heavily accessed data is
* stored contiguously in memory in as few cache lines as possible. This * stored contiguously in memory in as few cache lines as possible. This
* provides significant performance benefits, especially on a * provides significant performance benefits, especially on a
* multiprocessor system. Thereis one PGXACT structure for every PGPROC * multiprocessor system. There is one PGXACT structure for every PGPROC
* structure. * structure.
*/ */
pgxacts = (PGXACT *) ShmemAlloc(TotalProcs * sizeof(PGXACT)); pgxacts = (PGXACT *) ShmemAlloc(TotalProcs * sizeof(PGXACT));

View File

@ -19,7 +19,7 @@
* have regd_count = 1 and are counted in RegisteredSnapshots, but are not * have regd_count = 1 and are counted in RegisteredSnapshots, but are not
* tracked by any resource owner. * tracked by any resource owner.
* *
* These arrangements let us reset MyProc->xmin when there are no snapshots * These arrangements let us reset MyPgXact->xmin when there are no snapshots
* referenced by this transaction. (One possible improvement would be to be * referenced by this transaction. (One possible improvement would be to be
* able to advance Xmin when the snapshot with the earliest Xmin is no longer * able to advance Xmin when the snapshot with the earliest Xmin is no longer
* referenced. That's a bit harder though, it requires more locking, and * referenced. That's a bit harder though, it requires more locking, and
@ -104,7 +104,7 @@ static ActiveSnapshotElt *ActiveSnapshot = NULL;
* How many snapshots is resowner.c tracking for us? * How many snapshots is resowner.c tracking for us?
* *
* Note: for now, a simple counter is enough. However, if we ever want to be * Note: for now, a simple counter is enough. However, if we ever want to be
* smarter about advancing our MyProc->xmin we will need to be more * smarter about advancing our MyPgXact->xmin we will need to be more
* sophisticated about this, perhaps keeping our own list of snapshots. * sophisticated about this, perhaps keeping our own list of snapshots.
*/ */
static int RegisteredSnapshots = 0; static int RegisteredSnapshots = 0;
@ -266,7 +266,7 @@ SetTransactionSnapshot(Snapshot sourcesnap, TransactionId sourcexid)
/* NB: curcid should NOT be copied, it's a local matter */ /* NB: curcid should NOT be copied, it's a local matter */
/* /*
* Now we have to fix what GetSnapshotData did with MyProc->xmin and * Now we have to fix what GetSnapshotData did with MyPgXact->xmin and
* TransactionXmin. There is a race condition: to make sure we are not * TransactionXmin. There is a race condition: to make sure we are not
* causing the global xmin to go backwards, we have to test that the * causing the global xmin to go backwards, we have to test that the
* source transaction is still running, and that has to be done atomically. * source transaction is still running, and that has to be done atomically.
@ -569,7 +569,7 @@ UnregisterSnapshotFromOwner(Snapshot snapshot, ResourceOwner owner)
/* /*
* SnapshotResetXmin * SnapshotResetXmin
* *
* If there are no more snapshots, we can reset our PGPROC->xmin to InvalidXid. * If there are no more snapshots, we can reset our PGXACT->xmin to InvalidXid.
* Note we can do this without locking because we assume that storing an Xid * Note we can do this without locking because we assume that storing an Xid
* is atomic. * is atomic.
*/ */

View File

@ -10,12 +10,12 @@
* the passed-in buffer. The caller must hold not only a pin, but at least * the passed-in buffer. The caller must hold not only a pin, but at least
* shared buffer content lock on the buffer containing the tuple. * shared buffer content lock on the buffer containing the tuple.
* *
* NOTE: must check TransactionIdIsInProgress (which looks in PGPROC array) * NOTE: must check TransactionIdIsInProgress (which looks in PGXACT array)
* before TransactionIdDidCommit/TransactionIdDidAbort (which look in * before TransactionIdDidCommit/TransactionIdDidAbort (which look in
* pg_clog). Otherwise we have a race condition: we might decide that a * pg_clog). Otherwise we have a race condition: we might decide that a
* just-committed transaction crashed, because none of the tests succeed. * just-committed transaction crashed, because none of the tests succeed.
* xact.c is careful to record commit/abort in pg_clog before it unsets * xact.c is careful to record commit/abort in pg_clog before it unsets
* MyProc->xid in PGPROC array. That fixes that problem, but it also * MyPgXact->xid in PGXACT array. That fixes that problem, but it also
* means there is a window where TransactionIdIsInProgress and * means there is a window where TransactionIdIsInProgress and
* TransactionIdDidCommit will both return true. If we check only * TransactionIdDidCommit will both return true. If we check only
* TransactionIdDidCommit, we could consider a tuple committed when a * TransactionIdDidCommit, we could consider a tuple committed when a

View File

@ -38,7 +38,7 @@ struct XidCache
TransactionId xids[PGPROC_MAX_CACHED_SUBXIDS]; TransactionId xids[PGPROC_MAX_CACHED_SUBXIDS];
}; };
/* Flags for PGPROC->vacuumFlags */ /* Flags for PGXACT->vacuumFlags */
#define PROC_IS_AUTOVACUUM 0x01 /* is it an autovac worker? */ #define PROC_IS_AUTOVACUUM 0x01 /* is it an autovac worker? */
#define PROC_IN_VACUUM 0x02 /* currently running lazy vacuum */ #define PROC_IN_VACUUM 0x02 /* currently running lazy vacuum */
#define PROC_IN_ANALYZE 0x04 /* currently running analyze */ #define PROC_IN_ANALYZE 0x04 /* currently running analyze */