diff options
Diffstat (limited to 'src/backend/storage/ipc')
-rw-r--r-- | src/backend/storage/ipc/procarray.c | 270 | ||||
-rw-r--r-- | src/backend/storage/ipc/procsignal.c | 16 | ||||
-rw-r--r-- | src/backend/storage/ipc/sinvaladt.c | 11 | ||||
-rw-r--r-- | src/backend/storage/ipc/standby.c | 198 |
4 files changed, 252 insertions, 243 deletions
diff --git a/src/backend/storage/ipc/procarray.c b/src/backend/storage/ipc/procarray.c index 7cd57f31405..baa2e43f50d 100644 --- a/src/backend/storage/ipc/procarray.c +++ b/src/backend/storage/ipc/procarray.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.59 2010/01/23 16:37:12 sriggs Exp $ + * $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.60 2010/02/26 02:01:00 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -56,7 +56,7 @@ #include "utils/builtins.h" #include "utils/snapmgr.h" -static RunningTransactionsData CurrentRunningXactsData; +static RunningTransactionsData CurrentRunningXactsData; /* Our shared memory area */ typedef struct ProcArrayStruct @@ -64,13 +64,16 @@ typedef struct ProcArrayStruct int numProcs; /* number of valid procs entries */ int maxProcs; /* allocated size of procs array */ - int numKnownAssignedXids; /* current number of known assigned xids */ - int maxKnownAssignedXids; /* allocated size of known assigned xids */ + int numKnownAssignedXids; /* current number of known assigned + * xids */ + int maxKnownAssignedXids; /* allocated size of known assigned + * xids */ + /* * Highest subxid that overflowed KnownAssignedXids array. Similar to * overflowing cached subxids in PGPROC entries. */ - TransactionId lastOverflowedXid; + TransactionId lastOverflowedXid; /* * We declare procs[] as 1 entry because C wants a fixed-size array, but @@ -85,7 +88,7 @@ static ProcArrayStruct *procArray; * Bookkeeping for tracking emulated transactions in recovery */ static HTAB *KnownAssignedXidsHash; -static TransactionId latestObservedXid = InvalidTransactionId; +static TransactionId latestObservedXid = InvalidTransactionId; /* * If we're in STANDBY_SNAPSHOT_PENDING state, standbySnapshotPendingXmin is @@ -135,9 +138,9 @@ static void DisplayXidCache(void); #endif /* XIDCACHE_DEBUG */ /* Primitives for KnownAssignedXids array handling for standby */ -static int KnownAssignedXidsGet(TransactionId *xarray, TransactionId xmax); -static int KnownAssignedXidsGetAndSetXmin(TransactionId *xarray, TransactionId *xmin, - TransactionId xmax); +static int KnownAssignedXidsGet(TransactionId *xarray, TransactionId xmax); +static int KnownAssignedXidsGetAndSetXmin(TransactionId *xarray, TransactionId *xmin, + TransactionId xmax); static bool KnownAssignedXidsExist(TransactionId xid); static void KnownAssignedXidsAdd(TransactionId *xids, int nxids); static void KnownAssignedXidsRemove(TransactionId xid); @@ -436,9 +439,9 @@ ProcArrayInitRecoveryInfo(TransactionId oldestActiveXid) void ProcArrayApplyRecoveryInfo(RunningTransactions running) { - int xid_index; /* main loop */ - TransactionId *xids; - int nxids; + int xid_index; /* main loop */ + TransactionId *xids; + int nxids; Assert(standbyState >= STANDBY_INITIALIZED); @@ -455,14 +458,14 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) return; /* - * If our initial RunningXactData had an overflowed snapshot then we - * knew we were missing some subxids from our snapshot. We can use - * this data as an initial snapshot, but we cannot yet mark it valid. - * We know that the missing subxids are equal to or earlier than - * nextXid. After we initialise we continue to apply changes during - * recovery, so once the oldestRunningXid is later than the nextXid - * from the initial snapshot we know that we no longer have missing - * information and can mark the snapshot as valid. + * If our initial RunningXactData had an overflowed snapshot then we knew + * we were missing some subxids from our snapshot. We can use this data as + * an initial snapshot, but we cannot yet mark it valid. We know that the + * missing subxids are equal to or earlier than nextXid. After we + * initialise we continue to apply changes during recovery, so once the + * oldestRunningXid is later than the nextXid from the initial snapshot we + * know that we no longer have missing information and can mark the + * snapshot as valid. */ if (standbyState == STANDBY_SNAPSHOT_PENDING) { @@ -471,9 +474,9 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) { standbyState = STANDBY_SNAPSHOT_READY; elog(trace_recovery(DEBUG2), - "running xact data now proven complete"); + "running xact data now proven complete"); elog(trace_recovery(DEBUG2), - "recovery snapshots are now enabled"); + "recovery snapshots are now enabled"); } return; } @@ -485,9 +488,9 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) TransactionIdRetreat(latestObservedXid); /* - * If the snapshot overflowed, then we still initialise with what we - * know, but the recovery snapshot isn't fully valid yet because we - * know there are some subxids missing (ergo we don't know which ones) + * If the snapshot overflowed, then we still initialise with what we know, + * but the recovery snapshot isn't fully valid yet because we know there + * are some subxids missing (ergo we don't know which ones) */ if (!running->subxid_overflow) { @@ -508,12 +511,12 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) KnownAssignedXidsDisplay(trace_recovery(DEBUG3)); /* - * Scan through the incoming array of RunningXacts and collect xids. - * We don't use SubtransSetParent because it doesn't matter yet. If - * we aren't overflowed then all xids will fit in snapshot and so we - * don't need subtrans. If we later overflow, an xid assignment record - * will add xids to subtrans. If RunningXacts is overflowed then we - * don't have enough information to correctly update subtrans anyway. + * Scan through the incoming array of RunningXacts and collect xids. We + * don't use SubtransSetParent because it doesn't matter yet. If we aren't + * overflowed then all xids will fit in snapshot and so we don't need + * subtrans. If we later overflow, an xid assignment record will add xids + * to subtrans. If RunningXacts is overflowed then we don't have enough + * information to correctly update subtrans anyway. */ /* @@ -563,10 +566,10 @@ ProcArrayApplyRecoveryInfo(RunningTransactions running) ShmemVariableCache->nextXid = running->nextXid; elog(trace_recovery(DEBUG2), - "running transaction data initialized"); + "running transaction data initialized"); if (standbyState == STANDBY_SNAPSHOT_READY) elog(trace_recovery(DEBUG2), - "recovery snapshots are now enabled"); + "recovery snapshots are now enabled"); } void @@ -574,7 +577,7 @@ ProcArrayApplyXidAssignment(TransactionId topxid, int nsubxids, TransactionId *subxids) { TransactionId max_xid; - int i; + int i; if (standbyState < STANDBY_SNAPSHOT_PENDING) return; @@ -592,15 +595,15 @@ ProcArrayApplyXidAssignment(TransactionId topxid, RecordKnownAssignedTransactionIds(max_xid); /* - * Notice that we update pg_subtrans with the top-level xid, rather - * than the parent xid. This is a difference between normal - * processing and recovery, yet is still correct in all cases. The - * reason is that subtransaction commit is not marked in clog until - * commit processing, so all aborted subtransactions have already been - * clearly marked in clog. As a result we are able to refer directly - * to the top-level transaction's state rather than skipping through - * all the intermediate states in the subtransaction tree. This - * should be the first time we have attempted to SubTransSetParent(). + * Notice that we update pg_subtrans with the top-level xid, rather than + * the parent xid. This is a difference between normal processing and + * recovery, yet is still correct in all cases. The reason is that + * subtransaction commit is not marked in clog until commit processing, so + * all aborted subtransactions have already been clearly marked in clog. + * As a result we are able to refer directly to the top-level + * transaction's state rather than skipping through all the intermediate + * states in the subtransaction tree. This should be the first time we + * have attempted to SubTransSetParent(). */ for (i = 0; i < nsubxids; i++) SubTransSetParent(subxids[i], topxid, false); @@ -697,12 +700,12 @@ TransactionIdIsInProgress(TransactionId xid) if (xids == NULL) { /* - * In hot standby mode, reserve enough space to hold all xids in - * the known-assigned list. If we later finish recovery, we no longer - * need the bigger array, but we don't bother to shrink it. + * In hot standby mode, reserve enough space to hold all xids in the + * known-assigned list. If we later finish recovery, we no longer need + * the bigger array, but we don't bother to shrink it. */ - int maxxids = RecoveryInProgress() ? - arrayP->maxProcs : TOTAL_MAX_CACHED_SUBXIDS; + int maxxids = RecoveryInProgress() ? + arrayP->maxProcs : TOTAL_MAX_CACHED_SUBXIDS; xids = (TransactionId *) malloc(maxxids * sizeof(TransactionId)); if (xids == NULL) @@ -799,10 +802,10 @@ TransactionIdIsInProgress(TransactionId xid) } /* - * If the KnownAssignedXids overflowed, we have to check - * pg_subtrans too. Copy all xids from KnownAssignedXids that are - * lower than xid, since if xid is a subtransaction its parent will - * always have a lower value. + * If the KnownAssignedXids overflowed, we have to check pg_subtrans + * too. Copy all xids from KnownAssignedXids that are lower than xid, + * since if xid is a subtransaction its parent will always have a + * lower value. */ if (TransactionIdPrecedesOrEquals(xid, procArray->lastOverflowedXid)) nxids = KnownAssignedXidsGet(xids, xid); @@ -1052,8 +1055,8 @@ GetSnapshotData(Snapshot snapshot) if (snapshot->xip == NULL) { /* - * First call for this snapshot. Snapshot is same size whether - * or not we are in recovery, see later comments. + * First call for this snapshot. Snapshot is same size whether or not + * we are in recovery, see later comments. */ snapshot->xip = (TransactionId *) malloc(arrayP->maxProcs * sizeof(TransactionId)); @@ -1176,16 +1179,16 @@ GetSnapshotData(Snapshot snapshot) * In recovery we don't know which xids are top-level and which are * subxacts, a design choice that greatly simplifies xid processing. * - * It seems like we would want to try to put xids into xip[] only, - * but that is fairly small. We would either need to make that bigger - * or to increase the rate at which we WAL-log xid assignment; - * neither is an appealing choice. + * It seems like we would want to try to put xids into xip[] only, but + * that is fairly small. We would either need to make that bigger or + * to increase the rate at which we WAL-log xid assignment; neither is + * an appealing choice. * * We could try to store xids into xip[] first and then into subxip[] * if there are too many xids. That only works if the snapshot doesn't * overflow because we do not search subxip[] in that case. A simpler - * way is to just store all xids in the subxact array because this - * is by far the bigger array. We just leave the xip array empty. + * way is to just store all xids in the subxact array because this is + * by far the bigger array. We just leave the xip array empty. * * Either way we need to change the way XidInMVCCSnapshot() works * depending upon when the snapshot was taken, or change normal @@ -1269,8 +1272,8 @@ GetRunningTransactionData(void) * the lock, so we can't look at numProcs. Likewise, we allocate much * more subxip storage than is probably needed. * - * Should only be allocated for bgwriter, since only ever executed - * during checkpoints. + * Should only be allocated for bgwriter, since only ever executed during + * checkpoints. */ if (CurrentRunningXacts->xids == NULL) { @@ -1300,6 +1303,7 @@ GetRunningTransactionData(void) latestCompletedXid = ShmemVariableCache->latestCompletedXid; oldestRunningXid = ShmemVariableCache->nextXid; + /* * Spin over procArray collecting all xids and subxids. */ @@ -1325,8 +1329,8 @@ GetRunningTransactionData(void) oldestRunningXid = xid; /* - * Save subtransaction XIDs. Other backends can't add or remove entries - * while we're holding XidGenLock. + * Save subtransaction XIDs. Other backends can't add or remove + * entries while we're holding XidGenLock. */ nxids = proc->subxids.nxids; if (nxids > 0) @@ -1642,13 +1646,13 @@ GetCurrentVirtualXIDs(TransactionId limitXmin, bool excludeXmin0, * * By using exclusive lock we prevent new snapshots from being taken while * we work out which snapshots to conflict with. This protects those new - * snapshots from also being included in our conflict list. + * snapshots from also being included in our conflict list. * * After the lock is released, we allow snapshots again. It is possible * that we arrive at a snapshot that is identical to one that we just * decided we should conflict with. This a case of false positives, not an * actual problem. - * + * * There are two cases: (1) if we were correct in using latestCompletedXid * then that means that all xids in the snapshot lower than that are FATAL * errors, so not xids that ever commit. We can make no visibility errors @@ -1657,11 +1661,11 @@ GetCurrentVirtualXIDs(TransactionId limitXmin, bool excludeXmin0, * latestCompletedXid then we conflicted with a snapshot needlessly. Taking * another identical snapshot is OK, because the earlier conflicted * snapshot was a false positive. - * + * * In either case, a snapshot taken after conflict assessment will still be * valid and non-conflicting even if an identical snapshot that existed * before conflict assessment was assessed as conflicting. - * + * * If we allowed concurrent snapshots while we were deciding who to * conflict with we would need to include all concurrent snapshotters in * the conflict list as well. We'd have difficulty in working out exactly @@ -1669,7 +1673,7 @@ GetCurrentVirtualXIDs(TransactionId limitXmin, bool excludeXmin0, * lock. Notice that we only hold that lock for as long as it takes to * make the conflict list, not for the whole duration of the conflict * resolution. - * + * * It also means that users waiting for a snapshot is a good thing, since * it is more likely that they will live longer after having waited. So it * is a benefit, not an oversight that we use exclusive lock here. @@ -1695,8 +1699,8 @@ GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid) /* * If not first time through, get workspace to remember main XIDs in. We - * malloc it permanently to avoid repeated palloc/pfree overhead. - * Allow result space, remembering room for a terminator. + * malloc it permanently to avoid repeated palloc/pfree overhead. Allow + * result space, remembering room for a terminator. */ if (vxids == NULL) { @@ -1711,8 +1715,8 @@ GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid) LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); /* - * If we don't know the TransactionId that created the conflict, set - * it to latestCompletedXid which is the latest possible value. + * If we don't know the TransactionId that created the conflict, set it to + * latestCompletedXid which is the latest possible value. */ if (!TransactionIdIsValid(limitXmin)) limitXmin = ShmemVariableCache->latestCompletedXid; @@ -1732,8 +1736,9 @@ GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid) TransactionId pxmin = proc->xmin; /* - * We ignore an invalid pxmin because this means that backend - * has no snapshot and cannot get another one while we hold exclusive lock. + * We ignore an invalid pxmin because this means that backend has + * no snapshot and cannot get another one while we hold exclusive + * lock. */ if (TransactionIdIsValid(pxmin) && !TransactionIdFollows(pxmin, limitXmin)) { @@ -1784,8 +1789,8 @@ CancelVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode) if (pid != 0) { /* - * Kill the pid if it's still here. If not, that's what we wanted - * so ignore any errors. + * Kill the pid if it's still here. If not, that's what we + * wanted so ignore any errors. */ (void) SendProcSignal(pid, sigmode, vxid.backendId); } @@ -1905,8 +1910,8 @@ CancelDBBackends(Oid databaseid, ProcSignalReason sigmode, bool conflictPending) if (pid != 0) { /* - * Kill the pid if it's still here. If not, that's what we wanted - * so ignore any errors. + * Kill the pid if it's still here. If not, that's what we + * wanted so ignore any errors. */ (void) SendProcSignal(pid, sigmode, procvxid.backendId); } @@ -2133,11 +2138,10 @@ DisplayXidCache(void) xc_no_overflow, xc_slow_answer); } - #endif /* XIDCACHE_DEBUG */ /* ---------------------------------------------- - * KnownAssignedTransactions sub-module + * KnownAssignedTransactions sub-module * ---------------------------------------------- */ @@ -2199,48 +2203,49 @@ RecordKnownAssignedTransactionIds(TransactionId xid) return; /* - * We can see WAL records before the running-xacts snapshot that - * contain XIDs that are not in the running-xacts snapshot, but that we - * know to have finished before the running-xacts snapshot was taken. - * Don't waste precious shared memory by keeping them in the hash table. + * We can see WAL records before the running-xacts snapshot that contain + * XIDs that are not in the running-xacts snapshot, but that we know to + * have finished before the running-xacts snapshot was taken. Don't waste + * precious shared memory by keeping them in the hash table. * * We can also see WAL records before the running-xacts snapshot that * contain XIDs that are not in the running-xacts snapshot for a different - * reason: the transaction started *after* the running-xacts snapshot - * was taken, but before it was written to WAL. We must be careful to - * not ignore such XIDs. Because such a transaction started after the - * running-xacts snapshot was taken, it must have an XID larger than - * the oldest XID according to the running-xacts snapshot. + * reason: the transaction started *after* the running-xacts snapshot was + * taken, but before it was written to WAL. We must be careful to not + * ignore such XIDs. Because such a transaction started after the + * running-xacts snapshot was taken, it must have an XID larger than the + * oldest XID according to the running-xacts snapshot. */ if (TransactionIdPrecedes(xid, snapshotOldestActiveXid)) return; ereport(trace_recovery(DEBUG4), - (errmsg("record known xact %u latestObservedXid %u", - xid, latestObservedXid))); + (errmsg("record known xact %u latestObservedXid %u", + xid, latestObservedXid))); /* - * When a newly observed xid arrives, it is frequently the case - * that it is *not* the next xid in sequence. When this occurs, we - * must treat the intervening xids as running also. + * When a newly observed xid arrives, it is frequently the case that it is + * *not* the next xid in sequence. When this occurs, we must treat the + * intervening xids as running also. */ if (TransactionIdFollows(xid, latestObservedXid)) { - TransactionId next_expected_xid = latestObservedXid; + TransactionId next_expected_xid = latestObservedXid; + TransactionIdAdvance(next_expected_xid); /* - * Locking requirement is currently higher than for xid assignment - * in normal running. However, we only get called here for new - * high xids - so on a multi-processor where it is common that xids - * arrive out of order the average number of locks per assignment - * will actually reduce. So not too worried about this locking. + * Locking requirement is currently higher than for xid assignment in + * normal running. However, we only get called here for new high xids + * - so on a multi-processor where it is common that xids arrive out + * of order the average number of locks per assignment will actually + * reduce. So not too worried about this locking. * - * XXX It does seem possible that we could add a whole range - * of numbers atomically to KnownAssignedXids, if we use a sorted - * list for KnownAssignedXids. But that design also increases the - * length of time we hold lock when we process commits/aborts, so - * on balance don't worry about this. + * XXX It does seem possible that we could add a whole range of + * numbers atomically to KnownAssignedXids, if we use a sorted list + * for KnownAssignedXids. But that design also increases the length of + * time we hold lock when we process commits/aborts, so on balance + * don't worry about this. */ LWLockAcquire(ProcArrayLock, LW_EXCLUSIVE); @@ -2248,8 +2253,8 @@ RecordKnownAssignedTransactionIds(TransactionId xid) { if (TransactionIdPrecedes(next_expected_xid, xid)) ereport(trace_recovery(DEBUG4), - (errmsg("recording unobserved xid %u (latestObservedXid %u)", - next_expected_xid, latestObservedXid))); + (errmsg("recording unobserved xid %u (latestObservedXid %u)", + next_expected_xid, latestObservedXid))); KnownAssignedXidsAdd(&next_expected_xid, 1); /* @@ -2327,9 +2332,9 @@ ExpireOldKnownAssignedTransactionIds(TransactionId xid) * * There are 3 main users of the KnownAssignedXids data structure: * - * * backends taking snapshots - * * startup process adding new knownassigned xids - * * startup process removing xids as transactions end + * * backends taking snapshots + * * startup process adding new knownassigned xids + * * startup process removing xids as transactions end * * If we make KnownAssignedXids a simple sorted array then the first two * operations are fast, but the last one is at least O(N). If we make @@ -2354,8 +2359,8 @@ static void KnownAssignedXidsAdd(TransactionId *xids, int nxids) { TransactionId *result; - bool found; - int i; + bool found; + int i; for (i = 0; i < nxids; i++) { @@ -2369,19 +2374,19 @@ KnownAssignedXidsAdd(TransactionId *xids, int nxids) KnownAssignedXidsDisplay(LOG); LWLockRelease(ProcArrayLock); ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("too many KnownAssignedXids"))); + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("too many KnownAssignedXids"))); } result = (TransactionId *) hash_search(KnownAssignedXidsHash, &xids[i], HASH_ENTER, - &found); + &found); if (!result) { LWLockRelease(ProcArrayLock); ereport(ERROR, - (errcode(ERRCODE_OUT_OF_MEMORY), - errmsg("out of shared memory"))); + (errcode(ERRCODE_OUT_OF_MEMORY), + errmsg("out of shared memory"))); } if (found) @@ -2401,7 +2406,8 @@ KnownAssignedXidsAdd(TransactionId *xids, int nxids) static bool KnownAssignedXidsExist(TransactionId xid) { - bool found; + bool found; + (void) hash_search(KnownAssignedXidsHash, &xid, HASH_FIND, &found); return found; } @@ -2414,7 +2420,7 @@ KnownAssignedXidsExist(TransactionId xid) static void KnownAssignedXidsRemove(TransactionId xid) { - bool found; + bool found; Assert(TransactionIdIsValid(xid)); @@ -2427,14 +2433,14 @@ KnownAssignedXidsRemove(TransactionId xid) Assert(procArray->numKnownAssignedXids >= 0); /* - * We can fail to find an xid if the xid came from a subtransaction - * that aborts, though the xid hadn't yet been reported and no WAL records - * have been written using the subxid. In that case the abort record will + * We can fail to find an xid if the xid came from a subtransaction that + * aborts, though the xid hadn't yet been reported and no WAL records have + * been written using the subxid. In that case the abort record will * contain that subxid and we haven't seen it before. * - * If we fail to find it for other reasons it might be a problem, but - * it isn't much use to log that it happened, since we can't divine much - * from just an isolated xid value. + * If we fail to find it for other reasons it might be a problem, but it + * isn't much use to log that it happened, since we can't divine much from + * just an isolated xid value. */ } @@ -2460,7 +2466,7 @@ KnownAssignedXidsGet(TransactionId *xarray, TransactionId xmax) */ static int KnownAssignedXidsGetAndSetXmin(TransactionId *xarray, TransactionId *xmin, - TransactionId xmax) + TransactionId xmax) { HASH_SEQ_STATUS status; TransactionId *knownXid; @@ -2496,7 +2502,7 @@ KnownAssignedXidsGetAndSetXmin(TransactionId *xarray, TransactionId *xmin, static void KnownAssignedXidsRemoveMany(TransactionId xid, bool keepPreparedXacts) { - TransactionId *knownXid; + TransactionId *knownXid; HASH_SEQ_STATUS status; if (TransactionIdIsValid(xid)) @@ -2508,7 +2514,7 @@ KnownAssignedXidsRemoveMany(TransactionId xid, bool keepPreparedXacts) while ((knownXid = (TransactionId *) hash_seq_search(&status)) != NULL) { TransactionId removeXid = *knownXid; - bool found; + bool found; if (!TransactionIdIsValid(xid) || TransactionIdPrecedes(removeXid, xid)) { @@ -2537,9 +2543,9 @@ KnownAssignedXidsDisplay(int trace_level) HASH_SEQ_STATUS status; TransactionId *knownXid; StringInfoData buf; - TransactionId *xids; - int nxids; - int i; + TransactionId *xids; + int nxids; + int i; xids = palloc(sizeof(TransactionId) * TOTAL_MAX_CACHED_SUBXIDS); nxids = 0; diff --git a/src/backend/storage/ipc/procsignal.c b/src/backend/storage/ipc/procsignal.c index 03f61b20eee..a60f466c860 100644 --- a/src/backend/storage/ipc/procsignal.c +++ b/src/backend/storage/ipc/procsignal.c @@ -8,7 +8,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/ipc/procsignal.c,v 1.5 2010/02/13 01:32:19 sriggs Exp $ + * $PostgreSQL: pgsql/src/backend/storage/ipc/procsignal.c,v 1.6 2010/02/26 02:01:00 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -36,12 +36,12 @@ * reason is signaled more than once nearly simultaneously, the process may * observe it only once.) * - * Each process that wants to receive signals registers its process ID + * Each process that wants to receive signals registers its process ID * in the ProcSignalSlots array. The array is indexed by backend ID to make * slot allocation simple, and to avoid having to search the array when you * know the backend ID of the process you're signalling. (We do support * signalling without backend ID, but it's a bit less efficient.) - * + * * The flags are actually declared as "volatile sig_atomic_t" for maximum * portability. This should ensure that loads and stores of the flag * values are atomic, allowing us to dispense with any explicit locking. @@ -57,7 +57,7 @@ typedef struct * possible auxiliary process type. (This scheme assumes there is not * more than one of any auxiliary process type at a time.) */ -#define NumProcSignalSlots (MaxBackends + NUM_AUXPROCTYPES) +#define NumProcSignalSlots (MaxBackends + NUM_AUXPROCTYPES) static ProcSignalSlot *ProcSignalSlots = NULL; static volatile ProcSignalSlot *MyProcSignalSlot = NULL; @@ -146,8 +146,8 @@ CleanupProcSignalState(int status, Datum arg) if (slot->pss_pid != MyProcPid) { /* - * don't ERROR here. We're exiting anyway, and don't want to - * get into infinite loop trying to exit + * don't ERROR here. We're exiting anyway, and don't want to get into + * infinite loop trying to exit */ elog(LOG, "process %d releasing ProcSignal slot %d, but it contains %d", MyProcPid, pss_idx, (int) slot->pss_pid); @@ -201,7 +201,7 @@ SendProcSignal(pid_t pid, ProcSignalReason reason, BackendId backendId) * InvalidBackendId means that the target is most likely an auxiliary * process, which will have a slot near the end of the array. */ - int i; + int i; for (i = NumProcSignalSlots - 1; i >= 0; i--) { @@ -252,7 +252,7 @@ CheckProcSignal(ProcSignalReason reason) void procsignal_sigusr1_handler(SIGNAL_ARGS) { - int save_errno = errno; + int save_errno = errno; if (CheckProcSignal(PROCSIG_CATCHUP_INTERRUPT)) HandleCatchupInterrupt(); diff --git a/src/backend/storage/ipc/sinvaladt.c b/src/backend/storage/ipc/sinvaladt.c index ec3c5599270..0667652ed72 100644 --- a/src/backend/storage/ipc/sinvaladt.c +++ b/src/backend/storage/ipc/sinvaladt.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.81 2010/01/02 16:57:51 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/storage/ipc/sinvaladt.c,v 1.82 2010/02/26 02:01:00 momjian Exp $ * *------------------------------------------------------------------------- */ @@ -145,9 +145,10 @@ typedef struct ProcState bool signaled; /* backend has been sent catchup signal */ /* - * Backend only sends invalidations, never receives them. This only makes sense - * for Startup process during recovery because it doesn't maintain a relcache, - * yet it fires inval messages to allow query backends to see schema changes. + * Backend only sends invalidations, never receives them. This only makes + * sense for Startup process during recovery because it doesn't maintain a + * relcache, yet it fires inval messages to allow query backends to see + * schema changes. */ bool sendOnly; /* backend only sends, never receives */ @@ -587,7 +588,7 @@ SICleanupQueue(bool callerHasWriteLock, int minFree) /* * Recompute minMsgNum = minimum of all backends' nextMsgNum, identify the * furthest-back backend that needs signaling (if any), and reset any - * backends that are too far back. Note that because we ignore sendOnly + * backends that are too far back. Note that because we ignore sendOnly * backends here it is possible for them to keep sending messages without * a problem even when they are the only active backend. */ 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; |