summaryrefslogtreecommitdiff
path: root/src/backend/storage/ipc
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2011-08-04 12:38:33 -0400
committerRobert Haas <rhaas@postgresql.org>2011-08-04 12:38:33 -0400
commit84e37126770dd6de903dad88ce150a49b63b5ef9 (patch)
tree6f18f1599033b0c29687c0a49f18df6e8bc0a8c8 /src/backend/storage/ipc
parent3b17efdfdd846c9bfad1637686e6f18198ea3df5 (diff)
Create VXID locks "lazily" in the main lock table.
Instead of entering them on transaction startup, we materialize them only when someone wants to wait, which will occur only during CREATE INDEX CONCURRENTLY. In Hot Standby mode, the startup process must also be able to probe for conflicting VXID locks, but the lock need never be fully materialized, because the startup process does not use the normal lock wait mechanism. Since most VXID locks never need to touch the lock manager partition locks, this can significantly reduce blocking contention on read-heavy workloads. Patch by me. Review by Jeff Davis.
Diffstat (limited to 'src/backend/storage/ipc')
-rw-r--r--src/backend/storage/ipc/sinvaladt.c21
-rw-r--r--src/backend/storage/ipc/standby.c2
2 files changed, 14 insertions, 9 deletions
diff --git a/src/backend/storage/ipc/sinvaladt.c b/src/backend/storage/ipc/sinvaladt.c
index 47f1a615609..a1d8e26dd9f 100644
--- a/src/backend/storage/ipc/sinvaladt.c
+++ b/src/backend/storage/ipc/sinvaladt.c
@@ -139,6 +139,7 @@ typedef struct ProcState
{
/* procPid is zero in an inactive ProcState array entry. */
pid_t procPid; /* PID of backend, for signaling */
+ PGPROC *proc; /* PGPROC of backend */
/* nextMsgNum is meaningless if procPid == 0 or resetState is true. */
int nextMsgNum; /* next message number to read */
bool resetState; /* backend needs to reset its state */
@@ -246,6 +247,7 @@ CreateSharedInvalidationState(void)
for (i = 0; i < shmInvalBuffer->maxBackends; i++)
{
shmInvalBuffer->procState[i].procPid = 0; /* inactive */
+ shmInvalBuffer->procState[i].proc = NULL;
shmInvalBuffer->procState[i].nextMsgNum = 0; /* meaningless */
shmInvalBuffer->procState[i].resetState = false;
shmInvalBuffer->procState[i].signaled = false;
@@ -313,6 +315,7 @@ SharedInvalBackendInit(bool sendOnly)
/* mark myself active, with all extant messages already read */
stateP->procPid = MyProcPid;
+ stateP->proc = MyProc;
stateP->nextMsgNum = segP->maxMsgNum;
stateP->resetState = false;
stateP->signaled = false;
@@ -353,6 +356,7 @@ CleanupInvalidationState(int status, Datum arg)
/* Mark myself inactive */
stateP->procPid = 0;
+ stateP->proc = NULL;
stateP->nextMsgNum = 0;
stateP->resetState = false;
stateP->signaled = false;
@@ -369,13 +373,16 @@ CleanupInvalidationState(int status, Datum arg)
}
/*
- * BackendIdIsActive
- * Test if the given backend ID is currently assigned to a process.
+ * BackendIdGetProc
+ * Get the PGPROC structure for a backend, given the backend ID.
+ * The result may be out of date arbitrarily quickly, so the caller
+ * must be careful about how this information is used. NULL is
+ * returned if the backend is not active.
*/
-bool
-BackendIdIsActive(int backendID)
+PGPROC *
+BackendIdGetProc(int backendID)
{
- bool result;
+ PGPROC *result = NULL;
SISeg *segP = shmInvalBuffer;
/* Need to lock out additions/removals of backends */
@@ -385,10 +392,8 @@ BackendIdIsActive(int backendID)
{
ProcState *stateP = &segP->procState[backendID - 1];
- result = (stateP->procPid != 0);
+ result = stateP->proc;
}
- else
- result = false;
LWLockRelease(SInvalWriteLock);
diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index bf92d259950..5673c27cbe0 100644
--- a/src/backend/storage/ipc/standby.c
+++ b/src/backend/storage/ipc/standby.c
@@ -201,7 +201,7 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
standbyWait_us = STANDBY_INITIAL_WAIT_US;
/* wait until the virtual xid is gone */
- while (!ConditionalVirtualXactLockTableWait(*waitlist))
+ while (!VirtualXactLock(*waitlist, false))
{
/*
* Report via ps if we have been waiting for more than 500 msec