1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-10 17:42:29 +03:00

Split the shared-memory array of PGPROC pointers out of the sinval

communication structure, and make it its own module with its own lock.
This should reduce contention at least a little, and it definitely makes
the code seem cleaner.  Per my recent proposal.
This commit is contained in:
Tom Lane
2005-05-19 21:35:48 +00:00
parent 6910032a56
commit ee3b71f6bc
30 changed files with 923 additions and 860 deletions

View File

@@ -1,4 +1,4 @@
$PostgreSQL: pgsql/src/backend/access/transam/README,v 1.2 2004/09/16 16:58:26 tgl Exp $
$PostgreSQL: pgsql/src/backend/access/transam/README,v 1.3 2005/05/19 21:35:45 tgl Exp $
The Transaction System
----------------------
@@ -246,7 +246,7 @@ 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
transaction tree, so we can skip looking at pg_subtrans unless we know the
cache has been overflowed. See storage/ipc/sinval.c for the gory details.
cache has been overflowed. See storage/ipc/procarray.c for the gory details.
slru.c is the supporting mechanism for both pg_clog and pg_subtrans. It
implements the LRU policy for in-memory buffer pages. The high-level routines

View File

@@ -31,7 +31,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/access/transam/multixact.c,v 1.3 2005/05/07 18:14:25 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/multixact.c,v 1.4 2005/05/19 21:35:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -44,7 +44,7 @@
#include "utils/memutils.h"
#include "storage/backendid.h"
#include "storage/lmgr.h"
#include "storage/sinval.h"
#include "storage/procarray.h"
/*
@@ -383,8 +383,8 @@ MultiXactIdIsRunning(MultiXactId multi)
}
/*
* This could be made better by having a special entry point in sinval.c,
* walking the PGPROC array only once for the whole array. But in most
* This could be made faster by having another entry point in procarray.c,
* walking the PGPROC array only once for all the members. But in most
* cases nmembers should be small enough that it doesn't much matter.
*/
for (i = 0; i < nmembers; i++)

View File

@@ -22,7 +22,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/access/transam/subtrans.c,v 1.7 2004/12/31 21:59:29 pgsql Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/subtrans.c,v 1.8 2005/05/19 21:35:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -30,7 +30,6 @@
#include "access/slru.h"
#include "access/subtrans.h"
#include "storage/sinval.h"
#include "utils/tqual.h"

View File

@@ -6,7 +6,7 @@
* Copyright (c) 2000-2005, PostgreSQL Global Development Group
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/transam/varsup.c,v 1.63 2005/04/13 18:54:56 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/varsup.c,v 1.64 2005/05/19 21:35:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -107,7 +107,7 @@ GetNewTransactionId(bool isSubXact)
* nextXid are already present in PGPROC. Else we have a race
* condition.
*
* XXX by storing xid into MyProc without acquiring SInvalLock, we are
* XXX by storing xid into MyProc 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 (and in fact could cause a
@@ -120,8 +120,7 @@ GetNewTransactionId(bool isSubXact)
*
* 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 related fields. (SInvalLock would then mean primarily that
* PGPROCs couldn't be added/removed while holding the lock.)
* and related fields.
*
* If there's no room to fit a subtransaction XID into PGPROC, set the
* cache-overflowed flag instead. This forces readers to look in

View File

@@ -10,7 +10,7 @@
*
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.200 2005/04/28 21:47:10 tgl Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/xact.c,v 1.201 2005/05/19 21:35:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -34,7 +34,7 @@
#include "miscadmin.h"
#include "storage/fd.h"
#include "storage/proc.h"
#include "storage/sinval.h"
#include "storage/procarray.h"
#include "storage/smgr.h"
#include "utils/flatfiles.h"
#include "utils/guc.h"
@@ -1503,16 +1503,18 @@ CommitTransaction(void)
* this must be done _before_ releasing locks we hold and _after_
* RecordTransactionCommit.
*
* LWLockAcquire(SInvalLock) is required: UPDATE with xid 0 is blocked by
* xid 1' UPDATE, xid 1 is doing commit while xid 2 gets snapshot - if
* xid 2' GetSnapshotData sees xid 1 as running then it must see xid 0
* as running as well or it will see two tuple versions - one deleted
* by xid 1 and one inserted by xid 0. See notes in GetSnapshotData.
* LWLockAcquire(ProcArrayLock) is required; consider this example:
* UPDATE with xid 0 is blocked by xid 1's UPDATE.
* xid 1 is doing commit while xid 2 gets snapshot.
* If xid 2's GetSnapshotData sees xid 1 as running then it must see
* xid 0 as running as well, or it will be able to see two tuple versions
* - one deleted by xid 1 and one inserted by xid 0. See notes in
* GetSnapshotData.
*/
if (MyProc != NULL)
{
/* Lock SInvalLock because that's what GetSnapshotData uses. */
LWLockAcquire(SInvalLock, LW_EXCLUSIVE);
/* Lock ProcArrayLock because that's what GetSnapshotData uses. */
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
MyProc->xid = InvalidTransactionId;
MyProc->xmin = InvalidTransactionId;
@@ -1520,7 +1522,7 @@ CommitTransaction(void)
MyProc->subxids.nxids = 0;
MyProc->subxids.overflowed = false;
LWLockRelease(SInvalLock);
LWLockRelease(ProcArrayLock);
}
/*
@@ -1688,8 +1690,8 @@ AbortTransaction(void)
*/
if (MyProc != NULL)
{
/* Lock SInvalLock because that's what GetSnapshotData uses. */
LWLockAcquire(SInvalLock, LW_EXCLUSIVE);
/* Lock ProcArrayLock because that's what GetSnapshotData uses. */
LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE);
MyProc->xid = InvalidTransactionId;
MyProc->xmin = InvalidTransactionId;
@@ -1697,7 +1699,7 @@ AbortTransaction(void)
MyProc->subxids.nxids = 0;
MyProc->subxids.overflowed = false;
LWLockRelease(SInvalLock);
LWLockRelease(ProcArrayLock);
}
/*

View File

@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.191 2005/05/10 22:27:29 momjian Exp $
* $PostgreSQL: pgsql/src/backend/access/transam/xlog.c,v 1.192 2005/05/19 21:35:45 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@@ -38,7 +38,7 @@
#include "storage/lwlock.h"
#include "storage/pmsignal.h"
#include "storage/proc.h"
#include "storage/sinval.h"
#include "storage/procarray.h"
#include "storage/spin.h"
#include "utils/builtins.h"
#include "utils/guc.h"
@@ -776,7 +776,7 @@ begin:;
if (MyLastRecPtr.xrecoff == 0 && !no_tran)
{
/*
* We do not acquire SInvalLock here because of possible deadlock.
* We do not acquire ProcArrayLock here because of possible deadlock.
* Anyone who wants to inspect other procs' logRec must acquire
* WALInsertLock, instead. A better solution would be a per-PROC
* spinlock, but no time for that before 7.2 --- tgl 12/19/01.
@@ -4887,11 +4887,11 @@ CreateCheckPoint(bool shutdown, bool force)
* commits after REDO point).
*
* XXX temporarily ifdef'd out to avoid three-way deadlock condition:
* GetUndoRecPtr needs to grab SInvalLock to ensure that it is looking
* at a stable set of proc records, but grabbing SInvalLock while
* GetUndoRecPtr needs to grab ProcArrayLock to ensure that it is looking
* at a stable set of proc records, but grabbing ProcArrayLock while
* holding WALInsertLock is no good. GetNewTransactionId may cause a
* WAL record to be written while holding XidGenLock, and
* GetSnapshotData needs to get XidGenLock while holding SInvalLock,
* GetSnapshotData needs to get XidGenLock while holding ProcArrayLock,
* so there's a risk of deadlock. Need to find a better solution. See
* pgsql-hackers discussion of 17-Dec-01.
*