summaryrefslogtreecommitdiff
path: root/src/backend/storage/ipc/standby.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/storage/ipc/standby.c')
-rw-r--r--src/backend/storage/ipc/standby.c198
1 files changed, 100 insertions, 98 deletions
diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index 4712e3bdd8a..a0357bb5476 100644
--- a/src/backend/storage/ipc/standby.c
+++ b/src/backend/storage/ipc/standby.c
@@ -3,15 +3,15 @@
* standby.c
* Misc functions used in Hot Standby mode.
*
- * All functions for handling RM_STANDBY_ID, which relate to
- * AccessExclusiveLocks and starting snapshots for Hot Standby mode.
- * Plus conflict recovery processing.
+ * All functions for handling RM_STANDBY_ID, which relate to
+ * AccessExclusiveLocks and starting snapshots for Hot Standby mode.
+ * Plus conflict recovery processing.
*
* Portions Copyright (c) 1996-2010, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/storage/ipc/standby.c,v 1.13 2010/02/13 16:29:38 sriggs Exp $
+ * $PostgreSQL: pgsql/src/backend/storage/ipc/standby.c,v 1.14 2010/02/26 02:01:00 momjian Exp $
*
*-------------------------------------------------------------------------
*/
@@ -30,7 +30,7 @@
#include "storage/standby.h"
#include "utils/ps_status.h"
-int vacuum_defer_cleanup_age;
+int vacuum_defer_cleanup_age;
static List *RecoveryLockList;
@@ -58,10 +58,10 @@ InitRecoveryTransactionEnvironment(void)
VirtualTransactionId vxid;
/*
- * Initialise shared invalidation management for Startup process,
- * being careful to register ourselves as a sendOnly process so
- * we don't need to read messages, nor will we get signalled
- * when the queue starts filling up.
+ * Initialise shared invalidation management for Startup process, being
+ * careful to register ourselves as a sendOnly process so we don't need to
+ * read messages, nor will we get signalled when the queue starts filling
+ * up.
*/
SharedInvalBackendInit(true);
@@ -74,8 +74,8 @@ InitRecoveryTransactionEnvironment(void)
* Lock a virtual transaction id for Startup process.
*
* We need to do GetNextLocalTransactionId() because
- * SharedInvalBackendInit() leaves localTransactionid invalid and
- * the lock manager doesn't like that at all.
+ * SharedInvalBackendInit() leaves localTransactionid invalid and the lock
+ * manager doesn't like that at all.
*
* Note that we don't need to run XactLockTableInsert() because nobody
* needs to wait on xids. That sounds a little strange, but table locks
@@ -109,12 +109,12 @@ ShutdownRecoveryTransactionEnvironment(void)
/*
* -----------------------------------------------------
- * Standby wait timers and backend cancel logic
+ * Standby wait timers and backend cancel logic
* -----------------------------------------------------
*/
#define STANDBY_INITIAL_WAIT_US 1000
-static int standbyWait_us = STANDBY_INITIAL_WAIT_US;
+static int standbyWait_us = STANDBY_INITIAL_WAIT_US;
/*
* Standby wait logic for ResolveRecoveryConflictWithVirtualXIDs.
@@ -124,8 +124,8 @@ static int standbyWait_us = STANDBY_INITIAL_WAIT_US;
static bool
WaitExceedsMaxStandbyDelay(void)
{
- long delay_secs;
- int delay_usecs;
+ long delay_secs;
+ int delay_usecs;
if (MaxStandbyDelay == -1)
return false;
@@ -168,8 +168,8 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
while (VirtualTransactionIdIsValid(*waitlist))
{
- long wait_s;
- int wait_us; /* wait in microseconds (us) */
+ long wait_s;
+ int wait_us; /* wait in microseconds (us) */
TimestampTz waitStart;
bool logged;
@@ -178,12 +178,13 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
logged = false;
/* wait until the virtual xid is gone */
- while(!ConditionalVirtualXactLockTableWait(*waitlist))
+ while (!ConditionalVirtualXactLockTableWait(*waitlist))
{
/*
* Report if we have been waiting for a while now...
*/
TimestampTz now = GetCurrentTimestamp();
+
TimestampDifference(waitStart, now, &wait_s, &wait_us);
if (!logged && (wait_s > 0 || wait_us > 500000))
{
@@ -211,7 +212,7 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
/* Is it time to kill it? */
if (WaitExceedsMaxStandbyDelay())
{
- pid_t pid;
+ pid_t pid;
/*
* Now find out who to throw out of the balloon.
@@ -237,7 +238,7 @@ ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
/* The virtual transaction is gone now, wait for the next one */
waitlist++;
- }
+ }
}
void
@@ -249,7 +250,7 @@ ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, RelFileNode
node.dbNode);
ResolveRecoveryConflictWithVirtualXIDs(backends,
- PROCSIG_RECOVERY_CONFLICT_SNAPSHOT);
+ PROCSIG_RECOVERY_CONFLICT_SNAPSHOT);
}
void
@@ -258,43 +259,41 @@ ResolveRecoveryConflictWithTablespace(Oid tsid)
VirtualTransactionId *temp_file_users;
/*
- * Standby users may be currently using this tablespace for
- * for their temporary files. We only care about current
- * users because temp_tablespace parameter will just ignore
- * tablespaces that no longer exist.
+ * Standby users may be currently using this tablespace for for their
+ * temporary files. We only care about current users because
+ * temp_tablespace parameter will just ignore tablespaces that no longer
+ * exist.
*
- * Ask everybody to cancel their queries immediately so
- * we can ensure no temp files remain and we can remove the
- * tablespace. Nuke the entire site from orbit, it's the only
- * way to be sure.
+ * Ask everybody to cancel their queries immediately so we can ensure no
+ * temp files remain and we can remove the tablespace. Nuke the entire
+ * site from orbit, it's the only way to be sure.
*
- * XXX: We could work out the pids of active backends
- * using this tablespace by examining the temp filenames in the
- * directory. We would then convert the pids into VirtualXIDs
- * before attempting to cancel them.
+ * XXX: We could work out the pids of active backends using this
+ * tablespace by examining the temp filenames in the directory. We would
+ * then convert the pids into VirtualXIDs before attempting to cancel
+ * them.
*
- * We don't wait for commit because drop tablespace is
- * non-transactional.
+ * We don't wait for commit because drop tablespace is non-transactional.
*/
temp_file_users = GetConflictingVirtualXIDs(InvalidTransactionId,
InvalidOid);
ResolveRecoveryConflictWithVirtualXIDs(temp_file_users,
- PROCSIG_RECOVERY_CONFLICT_TABLESPACE);
+ PROCSIG_RECOVERY_CONFLICT_TABLESPACE);
}
void
ResolveRecoveryConflictWithDatabase(Oid dbid)
{
/*
- * We don't do ResolveRecoveryConflictWithVirutalXIDs() here since
- * that only waits for transactions and completely idle sessions
- * would block us. This is rare enough that we do this as simply
- * as possible: no wait, just force them off immediately.
+ * We don't do ResolveRecoveryConflictWithVirutalXIDs() here since that
+ * only waits for transactions and completely idle sessions would block
+ * us. This is rare enough that we do this as simply as possible: no wait,
+ * just force them off immediately.
*
* No locking is required here because we already acquired
- * AccessExclusiveLock. Anybody trying to connect while we do this
- * will block during InitPostgres() and then disconnect when they
- * see the database has been removed.
+ * AccessExclusiveLock. Anybody trying to connect while we do this will
+ * block during InitPostgres() and then disconnect when they see the
+ * database has been removed.
*/
while (CountDBBackends(dbid) > 0)
{
@@ -312,20 +311,20 @@ static void
ResolveRecoveryConflictWithLock(Oid dbOid, Oid relOid)
{
VirtualTransactionId *backends;
- bool report_memory_error = false;
- bool lock_acquired = false;
- int num_attempts = 0;
- LOCKTAG locktag;
+ bool report_memory_error = false;
+ bool lock_acquired = false;
+ int num_attempts = 0;
+ LOCKTAG locktag;
SET_LOCKTAG_RELATION(locktag, dbOid, relOid);
/*
- * If blowing away everybody with conflicting locks doesn't work,
- * after the first two attempts then we just start blowing everybody
- * away until it does work. We do this because its likely that we
- * either have too many locks and we just can't get one at all,
- * or that there are many people crowding for the same table.
- * Recovery must win; the end justifies the means.
+ * If blowing away everybody with conflicting locks doesn't work, after
+ * the first two attempts then we just start blowing everybody away until
+ * it does work. We do this because its likely that we either have too
+ * many locks and we just can't get one at all, or that there are many
+ * people crowding for the same table. Recovery must win; the end
+ * justifies the means.
*/
while (!lock_acquired)
{
@@ -339,10 +338,10 @@ ResolveRecoveryConflictWithLock(Oid dbOid, Oid relOid)
}
ResolveRecoveryConflictWithVirtualXIDs(backends,
- PROCSIG_RECOVERY_CONFLICT_LOCK);
+ PROCSIG_RECOVERY_CONFLICT_LOCK);
if (LockAcquireExtended(&locktag, AccessExclusiveLock, true, true, false)
- != LOCKACQUIRE_NOT_AVAIL)
+ != LOCKACQUIRE_NOT_AVAIL)
lock_acquired = true;
}
}
@@ -372,14 +371,14 @@ ResolveRecoveryConflictWithLock(Oid dbOid, Oid relOid)
void
ResolveRecoveryConflictWithBufferPin(void)
{
- bool sig_alarm_enabled = false;
+ bool sig_alarm_enabled = false;
Assert(InHotStandby);
if (MaxStandbyDelay == 0)
{
/*
- * We don't want to wait, so just tell everybody holding the pin to
+ * We don't want to wait, so just tell everybody holding the pin to
* get out of town.
*/
SendRecoveryConflictWithBufferPin(PROCSIG_RECOVERY_CONFLICT_BUFFERPIN);
@@ -387,17 +386,17 @@ ResolveRecoveryConflictWithBufferPin(void)
else if (MaxStandbyDelay == -1)
{
/*
- * Send out a request to check for buffer pin deadlocks before we wait.
- * This is fairly cheap, so no need to wait for deadlock timeout before
- * trying to send it out.
+ * Send out a request to check for buffer pin deadlocks before we
+ * wait. This is fairly cheap, so no need to wait for deadlock timeout
+ * before trying to send it out.
*/
SendRecoveryConflictWithBufferPin(PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK);
}
else
{
TimestampTz now;
- long standby_delay_secs; /* How far Startup process is lagging */
- int standby_delay_usecs;
+ long standby_delay_secs; /* How far Startup process is lagging */
+ int standby_delay_usecs;
now = GetCurrentTimestamp();
@@ -414,14 +413,15 @@ ResolveRecoveryConflictWithBufferPin(void)
}
else
{
- TimestampTz fin_time; /* Expected wake-up time by timer */
- long timer_delay_secs; /* Amount of time we set timer for */
- int timer_delay_usecs = 0;
+ TimestampTz fin_time; /* Expected wake-up time by timer */
+ long timer_delay_secs; /* Amount of time we set timer
+ * for */
+ int timer_delay_usecs = 0;
/*
- * Send out a request to check for buffer pin deadlocks before we wait.
- * This is fairly cheap, so no need to wait for deadlock timeout before
- * trying to send it out.
+ * Send out a request to check for buffer pin deadlocks before we
+ * wait. This is fairly cheap, so no need to wait for deadlock
+ * timeout before trying to send it out.
*/
SendRecoveryConflictWithBufferPin(PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK);
@@ -446,8 +446,8 @@ ResolveRecoveryConflictWithBufferPin(void)
* When is the finish time? We recheck this if we are woken early.
*/
fin_time = TimestampTzPlusMilliseconds(now,
- (timer_delay_secs * 1000) +
- (timer_delay_usecs / 1000));
+ (timer_delay_secs * 1000) +
+ (timer_delay_usecs / 1000));
if (enable_standby_sig_alarm(timer_delay_secs, timer_delay_usecs, fin_time))
sig_alarm_enabled = true;
@@ -473,10 +473,10 @@ SendRecoveryConflictWithBufferPin(ProcSignalReason reason)
reason == PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK);
/*
- * We send signal to all backends to ask them if they are holding
- * the buffer pin which is delaying the Startup process. We must
- * not set the conflict flag yet, since most backends will be innocent.
- * Let the SIGUSR1 handling in each backend decide their own fate.
+ * We send signal to all backends to ask them if they are holding the
+ * buffer pin which is delaying the Startup process. We must not set the
+ * conflict flag yet, since most backends will be innocent. Let the
+ * SIGUSR1 handling in each backend decide their own fate.
*/
CancelDBBackends(InvalidOid, reason, false);
}
@@ -503,15 +503,15 @@ CheckRecoveryConflictDeadlock(LWLockId partitionLock)
/*
* Error message should match ProcessInterrupts() but we avoid calling
- * that because we aren't handling an interrupt at this point. Note
- * that we only cancel the current transaction here, so if we are in a
+ * that because we aren't handling an interrupt at this point. Note that
+ * we only cancel the current transaction here, so if we are in a
* subtransaction and the pin is held by a parent, then the Startup
* process will continue to wait even though we have avoided deadlock.
*/
ereport(ERROR,
(errcode(ERRCODE_QUERY_CANCELED),
errmsg("canceling statement due to conflict with recovery"),
- errdetail("User transaction caused buffer deadlock with recovery.")));
+ errdetail("User transaction caused buffer deadlock with recovery.")));
}
/*
@@ -543,8 +543,8 @@ CheckRecoveryConflictDeadlock(LWLockId partitionLock)
void
StandbyAcquireAccessExclusiveLock(TransactionId xid, Oid dbOid, Oid relOid)
{
- xl_standby_lock *newlock;
- LOCKTAG locktag;
+ xl_standby_lock *newlock;
+ LOCKTAG locktag;
/* Already processed? */
if (TransactionIdDidCommit(xid) || TransactionIdDidAbort(xid))
@@ -568,7 +568,7 @@ StandbyAcquireAccessExclusiveLock(TransactionId xid, Oid dbOid, Oid relOid)
SET_LOCKTAG_RELATION(locktag, newlock->dbOid, newlock->relOid);
if (LockAcquireExtended(&locktag, AccessExclusiveLock, true, true, false)
- == LOCKACQUIRE_NOT_AVAIL)
+ == LOCKACQUIRE_NOT_AVAIL)
ResolveRecoveryConflictWithLock(newlock->dbOid, newlock->relOid);
}
@@ -586,6 +586,7 @@ StandbyReleaseLocks(TransactionId xid)
for (cell = list_head(RecoveryLockList); cell; cell = next)
{
xl_standby_lock *lock = (xl_standby_lock *) lfirst(cell);
+
next = lnext(cell);
if (!TransactionIdIsValid(xid) || lock->xid == xid)
@@ -619,7 +620,7 @@ StandbyReleaseLocks(TransactionId xid)
void
StandbyReleaseLockTree(TransactionId xid, int nsubxids, TransactionId *subxids)
{
- int i;
+ int i;
StandbyReleaseLocks(xid);
@@ -647,6 +648,7 @@ StandbyReleaseLocksMany(TransactionId removeXid, bool keepPreparedXacts)
for (cell = list_head(RecoveryLockList); cell; cell = next)
{
xl_standby_lock *lock = (xl_standby_lock *) lfirst(cell);
+
next = lnext(cell);
if (!TransactionIdIsValid(removeXid) || TransactionIdPrecedes(lock->xid, removeXid))
@@ -692,7 +694,7 @@ StandbyReleaseOldLocks(TransactionId removeXid)
/*
* --------------------------------------------------------------------
- * Recovery handling for Rmgr RM_STANDBY_ID
+ * Recovery handling for Rmgr RM_STANDBY_ID
*
* These record types will only be created if XLogStandbyInfoActive()
* --------------------------------------------------------------------
@@ -710,7 +712,7 @@ standby_redo(XLogRecPtr lsn, XLogRecord *record)
if (info == XLOG_STANDBY_LOCK)
{
xl_standby_locks *xlrec = (xl_standby_locks *) XLogRecGetData(record);
- int i;
+ int i;
for (i = 0; i < xlrec->nlocks; i++)
StandbyAcquireAccessExclusiveLock(xlrec->locks[i].xid,
@@ -761,7 +763,7 @@ standby_desc(StringInfo buf, uint8 xl_info, char *rec)
if (info == XLOG_STANDBY_LOCK)
{
xl_standby_locks *xlrec = (xl_standby_locks *) rec;
- int i;
+ int i;
appendStringInfo(buf, "AccessExclusive locks:");
@@ -790,7 +792,7 @@ LogStandbySnapshot(TransactionId *oldestActiveXid, TransactionId *nextXid)
{
RunningTransactions running;
xl_standby_lock *locks;
- int nlocks;
+ int nlocks;
Assert(XLogStandbyInfoActive());
@@ -823,9 +825,9 @@ LogStandbySnapshot(TransactionId *oldestActiveXid, TransactionId *nextXid)
static void
LogCurrentRunningXacts(RunningTransactions CurrRunningXacts)
{
- xl_running_xacts xlrec;
- XLogRecData rdata[2];
- int lastrdata = 0;
+ xl_running_xacts xlrec;
+ XLogRecData rdata[2];
+ int lastrdata = 0;
XLogRecPtr recptr;
xlrec.xcnt = CurrRunningXacts->xcnt;
@@ -876,8 +878,8 @@ LogCurrentRunningXacts(RunningTransactions CurrRunningXacts)
static void
LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks)
{
- XLogRecData rdata[2];
- xl_standby_locks xlrec;
+ XLogRecData rdata[2];
+ xl_standby_locks xlrec;
xlrec.nlocks = nlocks;
@@ -900,22 +902,22 @@ LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks)
void
LogAccessExclusiveLock(Oid dbOid, Oid relOid)
{
- xl_standby_lock xlrec;
+ xl_standby_lock xlrec;
/*
- * Ensure that a TransactionId has been assigned to this transaction.
- * We don't actually need the xid yet but if we don't do this then
+ * Ensure that a TransactionId has been assigned to this transaction. We
+ * don't actually need the xid yet but if we don't do this then
* RecordTransactionCommit() and RecordTransactionAbort() will optimise
* away the transaction completion record which recovery relies upon to
- * release locks. It's a hack, but for a corner case not worth adding
- * code for into the main commit path.
+ * release locks. It's a hack, but for a corner case not worth adding code
+ * for into the main commit path.
*/
xlrec.xid = GetTopTransactionId();
/*
- * Decode the locktag back to the original values, to avoid
- * sending lots of empty bytes with every message. See
- * lock.h to check how a locktag is defined for LOCKTAG_RELATION
+ * Decode the locktag back to the original values, to avoid sending lots
+ * of empty bytes with every message. See lock.h to check how a locktag
+ * is defined for LOCKTAG_RELATION
*/
xlrec.dbOid = dbOid;
xlrec.relOid = relOid;