1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-15 03:41:20 +03:00

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
shared mode (so that multiple backends can take snapshots in parallel),
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
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
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
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
pass the first backend's XID, before that value became visible in the
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
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,
@@ -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,
which must determine a lower bound for the oldest xmin of any active MVCC
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
snapshot for a new transaction). GetOldestXmin takes the MIN() of the
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
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
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,
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
@@ -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).
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
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

View File

@@ -21,10 +21,9 @@
* GIDs and aborts the transaction if there already is a global
* transaction in prepared state with the same GID.
*
* A global transaction (gxact) also has a dummy PGPROC that is entered
* into the ProcArray array; this is what keeps the XID considered
* running by TransactionIdIsInProgress. It is also convenient as a
* PGPROC to hook the gxact's locks to.
* A global transaction (gxact) also has dummy PGXACT and PGPROC; this is
* what keeps the XID considered running by TransactionIdIsInProgress.
* It is also convenient as a PGPROC to hook the gxact's locks to.
*
* In order to survive crashes and shutdowns, all prepared
* 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
* 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:
*
* 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.
*
* 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
* 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")));
/*
* 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
* function returns), others can commit/rollback the xact.
*
* 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
* TransactionIdIsInProgress, and onlookers would be entitled to assume
* 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.
*
* 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
* 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
* 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
* might see a partially-set xid here. But holding both locks at once
* 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
* times and get the same answer each time.
*
* 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
* own spinlock used only for fetching/storing that PGPROC's xid and
* A solution to the atomic-store problem would be to give each PGXACT its
* own spinlock used only for fetching/storing that PGXACT's xid and
* related fields.
*
* If there's no room to fit a subtransaction XID into PGPROC, set the