PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
standby.h File Reference
Include dependency graph for standby.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  RunningTransactionsData
 

Macros

#define MinSizeOfXactRunningXacts   offsetof(xl_running_xacts, xids)
 

Typedefs

typedef struct
RunningTransactionsData 
RunningTransactionsData
 
typedef RunningTransactionsDataRunningTransactions
 

Functions

void InitRecoveryTransactionEnvironment (void)
 
void ShutdownRecoveryTransactionEnvironment (void)
 
void ResolveRecoveryConflictWithSnapshot (TransactionId latestRemovedXid, RelFileNode node)
 
void ResolveRecoveryConflictWithTablespace (Oid tsid)
 
void ResolveRecoveryConflictWithDatabase (Oid dbid)
 
void ResolveRecoveryConflictWithLock (LOCKTAG locktag)
 
void ResolveRecoveryConflictWithBufferPin (void)
 
void CheckRecoveryConflictDeadlock (void)
 
void StandbyDeadLockHandler (void)
 
void StandbyTimeoutHandler (void)
 
void StandbyLockTimeoutHandler (void)
 
void StandbyAcquireAccessExclusiveLock (TransactionId xid, Oid dbOid, Oid relOid)
 
void StandbyReleaseLockTree (TransactionId xid, int nsubxids, TransactionId *subxids)
 
void StandbyReleaseAllLocks (void)
 
void StandbyReleaseOldLocks (int nxids, TransactionId *xids)
 
void LogAccessExclusiveLock (Oid dbOid, Oid relOid)
 
void LogAccessExclusiveLockPrepare (void)
 
XLogRecPtr LogStandbySnapshot (void)
 
void LogStandbyInvalidations (int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInitFileInval)
 

Variables

int vacuum_defer_cleanup_age
 
int max_standby_archive_delay
 
int max_standby_streaming_delay
 

Macro Definition Documentation

#define MinSizeOfXactRunningXacts   offsetof(xl_running_xacts, xids)

Definition at line 55 of file standby.h.

Referenced by LogCurrentRunningXacts().

Typedef Documentation

Function Documentation

void CheckRecoveryConflictDeadlock ( void  )

Definition at line 515 of file standby.c.

References Assert, ereport, errcode(), errdetail(), errmsg(), ERROR, HoldingBufferPinThatDelaysRecovery(), and InRecovery.

Referenced by ProcSleep().

516 {
517  Assert(!InRecovery); /* do not call in Startup process */
518 
520  return;
521 
522  /*
523  * Error message should match ProcessInterrupts() but we avoid calling
524  * that because we aren't handling an interrupt at this point. Note that
525  * we only cancel the current transaction here, so if we are in a
526  * subtransaction and the pin is held by a parent, then the Startup
527  * process will continue to wait even though we have avoided deadlock.
528  */
529  ereport(ERROR,
530  (errcode(ERRCODE_T_R_DEADLOCK_DETECTED),
531  errmsg("canceling statement due to conflict with recovery"),
532  errdetail("User transaction caused buffer deadlock with recovery.")));
533 }
bool InRecovery
Definition: xlog.c:191
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:873
#define ereport(elevel, rest)
Definition: elog.h:122
#define Assert(condition)
Definition: c.h:671
bool HoldingBufferPinThatDelaysRecovery(void)
Definition: bufmgr.c:3675
int errmsg(const char *fmt,...)
Definition: elog.c:797
void InitRecoveryTransactionEnvironment ( void  )

Definition at line 63 of file standby.c.

References VirtualTransactionId::backendId, GetNextLocalTransactionId(), VirtualTransactionId::localTransactionId, MyBackendId, SharedInvalBackendInit(), STANDBY_INITIALIZED, standbyState, and VirtualXactLockTableInsert().

Referenced by StartupXLOG().

64 {
66 
67  /*
68  * Initialize shared invalidation management for Startup process, being
69  * careful to register ourselves as a sendOnly process so we don't need to
70  * read messages, nor will we get signalled when the queue starts filling
71  * up.
72  */
74 
75  /*
76  * Lock a virtual transaction id for Startup process.
77  *
78  * We need to do GetNextLocalTransactionId() because
79  * SharedInvalBackendInit() leaves localTransactionid invalid and the lock
80  * manager doesn't like that at all.
81  *
82  * Note that we don't need to run XactLockTableInsert() because nobody
83  * needs to wait on xids. That sounds a little strange, but table locks
84  * are held by vxids and row level locks are held by xids. All queries
85  * hold AccessShareLocks so never block while we write or lock new rows.
86  */
87  vxid.backendId = MyBackendId;
90 
92 }
BackendId MyBackendId
Definition: globals.c:72
void SharedInvalBackendInit(bool sendOnly)
Definition: sinvaladt.c:258
LocalTransactionId localTransactionId
Definition: lock.h:66
LocalTransactionId GetNextLocalTransactionId(void)
Definition: sinvaladt.c:769
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
Definition: lock.c:4221
BackendId backendId
Definition: lock.h:65
HotStandbyState standbyState
Definition: xlog.c:194
void LogAccessExclusiveLock ( Oid  dbOid,
Oid  relOid 
)

Definition at line 1051 of file standby.c.

References xl_standby_lock::dbOid, GetTopTransactionId(), LogAccessExclusiveLocks(), xl_standby_lock::relOid, and xl_standby_lock::xid.

Referenced by LockAcquireExtended().

1052 {
1053  xl_standby_lock xlrec;
1054 
1055  xlrec.xid = GetTopTransactionId();
1056 
1057  /*
1058  * Decode the locktag back to the original values, to avoid sending lots
1059  * of empty bytes with every message. See lock.h to check how a locktag
1060  * is defined for LOCKTAG_RELATION
1061  */
1062  xlrec.dbOid = dbOid;
1063  xlrec.relOid = relOid;
1064 
1065  LogAccessExclusiveLocks(1, &xlrec);
1066 }
static void LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks)
Definition: standby.c:1033
TransactionId GetTopTransactionId(void)
Definition: xact.c:388
TransactionId xid
Definition: lockdefs.h:51
void LogAccessExclusiveLockPrepare ( void  )

Definition at line 1072 of file standby.c.

References GetTopTransactionId().

Referenced by LockAcquireExtended().

1073 {
1074  /*
1075  * Ensure that a TransactionId has been assigned to this transaction, for
1076  * two reasons, both related to lock release on the standby. First, we
1077  * must assign an xid so that RecordTransactionCommit() and
1078  * RecordTransactionAbort() do not optimise away the transaction
1079  * completion record which recovery relies upon to release locks. It's a
1080  * hack, but for a corner case not worth adding code for into the main
1081  * commit path. Second, we must assign an xid before the lock is recorded
1082  * in shared memory, otherwise a concurrently executing
1083  * GetRunningTransactionLocks() might see a lock associated with an
1084  * InvalidTransactionId which we later assert cannot happen.
1085  */
1086  (void) GetTopTransactionId();
1087 }
TransactionId GetTopTransactionId(void)
Definition: xact.c:388
void LogStandbyInvalidations ( int  nmsgs,
SharedInvalidationMessage msgs,
bool  relcacheInitFileInval 
)

Definition at line 1094 of file standby.c.

References xl_invalidations::dbId, MinSizeOfInvalidations, MyDatabaseId, MyDatabaseTableSpace, xl_invalidations::nmsgs, xl_invalidations::relcacheInitFileInval, xl_invalidations::tsId, XLOG_INVALIDATIONS, XLogBeginInsert(), XLogInsert(), and XLogRegisterData().

Referenced by RecordTransactionCommit().

1096 {
1097  xl_invalidations xlrec;
1098 
1099  /* prepare record */
1100  memset(&xlrec, 0, sizeof(xlrec));
1101  xlrec.dbId = MyDatabaseId;
1102  xlrec.tsId = MyDatabaseTableSpace;
1103  xlrec.relcacheInitFileInval = relcacheInitFileInval;
1104  xlrec.nmsgs = nmsgs;
1105 
1106  /* perform insertion */
1107  XLogBeginInsert();
1108  XLogRegisterData((char *) (&xlrec), MinSizeOfInvalidations);
1109  XLogRegisterData((char *) msgs,
1110  nmsgs * sizeof(SharedInvalidationMessage));
1111  XLogInsert(RM_STANDBY_ID, XLOG_INVALIDATIONS);
1112 }
#define XLOG_INVALIDATIONS
Definition: standbydefs.h:36
Oid MyDatabaseTableSpace
Definition: globals.c:78
bool relcacheInitFileInval
Definition: standbydefs.h:67
#define MinSizeOfInvalidations
Definition: standbydefs.h:72
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:323
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:415
Oid MyDatabaseId
Definition: globals.c:76
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr LogStandbySnapshot ( void  )

Definition at line 913 of file standby.c.

References Assert, GetRunningTransactionData(), GetRunningTransactionLocks(), LogAccessExclusiveLocks(), LogCurrentRunningXacts(), LWLockRelease(), pfree(), wal_level, WAL_LEVEL_LOGICAL, and XLogStandbyInfoActive.

Referenced by BackgroundWriterMain(), CreateCheckPoint(), and ReplicationSlotReserveWal().

914 {
915  XLogRecPtr recptr;
916  RunningTransactions running;
917  xl_standby_lock *locks;
918  int nlocks;
919 
921 
922  /*
923  * Get details of any AccessExclusiveLocks being held at the moment.
924  */
925  locks = GetRunningTransactionLocks(&nlocks);
926  if (nlocks > 0)
927  LogAccessExclusiveLocks(nlocks, locks);
928  pfree(locks);
929 
930  /*
931  * Log details of all in-progress transactions. This should be the last
932  * record we write, because standby will open up when it sees this.
933  */
934  running = GetRunningTransactionData();
935 
936  /*
937  * GetRunningTransactionData() acquired ProcArrayLock, we must release it.
938  * For Hot Standby this can be done before inserting the WAL record
939  * because ProcArrayApplyRecoveryInfo() rechecks the commit status using
940  * the clog. For logical decoding, though, the lock can't be released
941  * early because the clog might be "in the future" from the POV of the
942  * historic snapshot. This would allow for situations where we're waiting
943  * for the end of a transaction listed in the xl_running_xacts record
944  * which, according to the WAL, has committed before the xl_running_xacts
945  * record. Fortunately this routine isn't executed frequently, and it's
946  * only a shared lock.
947  */
949  LWLockRelease(ProcArrayLock);
950 
951  recptr = LogCurrentRunningXacts(running);
952 
953  /* Release lock if we kept it longer ... */
955  LWLockRelease(ProcArrayLock);
956 
957  /* GetRunningTransactionData() acquired XidGenLock, we must release it */
958  LWLockRelease(XidGenLock);
959 
960  return recptr;
961 }
static void LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks)
Definition: standby.c:1033
int wal_level
Definition: xlog.c:103
xl_standby_lock * GetRunningTransactionLocks(int *nlocks)
Definition: lock.c:3762
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1714
void pfree(void *pointer)
Definition: mcxt.c:992
static XLogRecPtr LogCurrentRunningXacts(RunningTransactions CurrRunningXacts)
Definition: standby.c:973
#define XLogStandbyInfoActive()
Definition: xlog.h:159
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:671
RunningTransactions GetRunningTransactionData(void)
Definition: procarray.c:1925
void ResolveRecoveryConflictWithBufferPin ( void  )

Definition at line 434 of file standby.c.

References Assert, DeadlockTimeout, EnableTimeoutParams::delay_ms, disable_all_timeouts(), enable_timeout_after(), enable_timeouts(), EnableTimeoutParams::fin_time, GetCurrentTimestamp(), GetStandbyLimitTime(), EnableTimeoutParams::id, InHotStandby, PG_WAIT_BUFFER_PIN, PROCSIG_RECOVERY_CONFLICT_BUFFERPIN, ProcWaitForSignal(), SendRecoveryConflictWithBufferPin(), STANDBY_DEADLOCK_TIMEOUT, STANDBY_TIMEOUT, TMPARAM_AFTER, TMPARAM_AT, and EnableTimeoutParams::type.

Referenced by LockBufferForCleanup().

435 {
436  TimestampTz ltime;
437 
439 
440  ltime = GetStandbyLimitTime();
441 
442  if (ltime == 0)
443  {
444  /*
445  * We're willing to wait forever for conflicts, so set timeout for
446  * deadlock check only
447  */
449  }
450  else if (GetCurrentTimestamp() >= ltime)
451  {
452  /*
453  * We're already behind, so clear a path as quickly as possible.
454  */
456  }
457  else
458  {
459  /*
460  * Wake up at ltime, and check for deadlocks as well if we will be
461  * waiting longer than deadlock_timeout
462  */
463  EnableTimeoutParams timeouts[2];
464 
465  timeouts[0].id = STANDBY_TIMEOUT;
466  timeouts[0].type = TMPARAM_AT;
467  timeouts[0].fin_time = ltime;
468  timeouts[1].id = STANDBY_DEADLOCK_TIMEOUT;
469  timeouts[1].type = TMPARAM_AFTER;
470  timeouts[1].delay_ms = DeadlockTimeout;
471  enable_timeouts(timeouts, 2);
472  }
473 
474  /* Wait to be signaled by UnpinBuffer() */
476 
477  /*
478  * Clear any timeout requests established above. We assume here that the
479  * Startup process doesn't have any other timeouts than what this function
480  * uses. If that stops being true, we could cancel the timeouts
481  * individually, but that'd be slower.
482  */
483  disable_all_timeouts(false);
484 }
static TimestampTz GetStandbyLimitTime(void)
Definition: standby.c:127
TimeoutId id
Definition: timeout.h:54
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1569
int64 TimestampTz
Definition: timestamp.h:39
TimeoutType type
Definition: timeout.h:55
#define InHotStandby
Definition: xlog.h:74
void enable_timeouts(const EnableTimeoutParams *timeouts, int count)
Definition: timeout.c:476
void disable_all_timeouts(bool keep_indicators)
Definition: timeout.c:596
static void SendRecoveryConflictWithBufferPin(ProcSignalReason reason)
Definition: standby.c:487
void ProcWaitForSignal(uint32 wait_event_info)
Definition: proc.c:1739
#define PG_WAIT_BUFFER_PIN
Definition: pgstat.h:720
void enable_timeout_after(TimeoutId id, int delay_ms)
Definition: timeout.c:428
#define Assert(condition)
Definition: c.h:671
TimestampTz fin_time
Definition: timeout.h:57
int DeadlockTimeout
Definition: proc.c:60
void ResolveRecoveryConflictWithDatabase ( Oid  dbid)

Definition at line 319 of file standby.c.

References CancelDBBackends(), CountDBBackends(), pg_usleep(), and PROCSIG_RECOVERY_CONFLICT_DATABASE.

Referenced by dbase_redo().

320 {
321  /*
322  * We don't do ResolveRecoveryConflictWithVirtualXIDs() here since that
323  * only waits for transactions and completely idle sessions would block
324  * us. This is rare enough that we do this as simply as possible: no wait,
325  * just force them off immediately.
326  *
327  * No locking is required here because we already acquired
328  * AccessExclusiveLock. Anybody trying to connect while we do this will
329  * block during InitPostgres() and then disconnect when they see the
330  * database has been removed.
331  */
332  while (CountDBBackends(dbid) > 0)
333  {
335 
336  /*
337  * Wait awhile for them to die so that we avoid flooding an
338  * unresponsive backend when system is heavily loaded.
339  */
340  pg_usleep(10000);
341  }
342 }
int CountDBBackends(Oid databaseid)
Definition: procarray.c:2722
void pg_usleep(long microsec)
Definition: signal.c:53
void CancelDBBackends(Oid databaseid, ProcSignalReason sigmode, bool conflictPending)
Definition: procarray.c:2783
void ResolveRecoveryConflictWithLock ( LOCKTAG  locktag)

Definition at line 362 of file standby.c.

References AccessExclusiveLock, Assert, disable_all_timeouts(), enable_timeouts(), EnableTimeoutParams::fin_time, GetCurrentTimestamp(), GetLockConflicts(), GetStandbyLimitTime(), EnableTimeoutParams::id, InHotStandby, LOCKTAG::locktag_type, PG_WAIT_LOCK, PROCSIG_RECOVERY_CONFLICT_LOCK, ProcWaitForSignal(), ResolveRecoveryConflictWithVirtualXIDs(), STANDBY_LOCK_TIMEOUT, TMPARAM_AT, and EnableTimeoutParams::type.

Referenced by ProcSleep().

363 {
364  TimestampTz ltime;
365 
367 
368  ltime = GetStandbyLimitTime();
369 
370  if (GetCurrentTimestamp() >= ltime)
371  {
372  /*
373  * We're already behind, so clear a path as quickly as possible.
374  */
375  VirtualTransactionId *backends;
376 
377  backends = GetLockConflicts(&locktag, AccessExclusiveLock);
380  }
381  else
382  {
383  /*
384  * Wait (or wait again) until ltime
385  */
386  EnableTimeoutParams timeouts[1];
387 
388  timeouts[0].id = STANDBY_LOCK_TIMEOUT;
389  timeouts[0].type = TMPARAM_AT;
390  timeouts[0].fin_time = ltime;
391  enable_timeouts(timeouts, 1);
392  }
393 
394  /* Wait to be signaled by the release of the Relation Lock */
396 
397  /*
398  * Clear any timeout requests established above. We assume here that the
399  * Startup process doesn't have any other outstanding timeouts than those
400  * used by this function. If that stops being true, we could cancel the
401  * timeouts individually, but that'd be slower.
402  */
403  disable_all_timeouts(false);
404 }
#define PG_WAIT_LOCK
Definition: pgstat.h:719
static TimestampTz GetStandbyLimitTime(void)
Definition: standby.c:127
TimeoutId id
Definition: timeout.h:54
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1569
int64 TimestampTz
Definition: timestamp.h:39
TimeoutType type
Definition: timeout.h:55
#define InHotStandby
Definition: xlog.h:74
void enable_timeouts(const EnableTimeoutParams *timeouts, int count)
Definition: timeout.c:476
void disable_all_timeouts(bool keep_indicators)
Definition: timeout.c:596
static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, ProcSignalReason reason)
Definition: standby.c:194
void ProcWaitForSignal(uint32 wait_event_info)
Definition: proc.c:1739
uint8 locktag_type
Definition: lock.h:185
#define Assert(condition)
Definition: c.h:671
TimestampTz fin_time
Definition: timeout.h:57
#define AccessExclusiveLock
Definition: lockdefs.h:46
VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode)
Definition: lock.c:2745
void ResolveRecoveryConflictWithSnapshot ( TransactionId  latestRemovedXid,
RelFileNode  node 
)

Definition at line 267 of file standby.c.

References RelFileNode::dbNode, GetConflictingVirtualXIDs(), PROCSIG_RECOVERY_CONFLICT_SNAPSHOT, ResolveRecoveryConflictWithVirtualXIDs(), and TransactionIdIsValid.

Referenced by btree_xlog_delete(), btree_xlog_reuse_page(), heap_xlog_clean(), heap_xlog_cleanup_info(), heap_xlog_freeze_page(), heap_xlog_visible(), and spgRedoVacuumRedirect().

268 {
269  VirtualTransactionId *backends;
270 
271  /*
272  * If we get passed InvalidTransactionId then we are a little surprised,
273  * but it is theoretically possible in normal running. It also happens
274  * when replaying already applied WAL records after a standby crash or
275  * restart, or when replaying an XLOG_HEAP2_VISIBLE record that marks as
276  * frozen a page which was already all-visible. If latestRemovedXid is
277  * invalid then there is no conflict. That rule applies across all record
278  * types that suffer from this conflict.
279  */
280  if (!TransactionIdIsValid(latestRemovedXid))
281  return;
282 
283  backends = GetConflictingVirtualXIDs(latestRemovedXid,
284  node.dbNode);
285 
288 }
VirtualTransactionId * GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)
Definition: procarray.c:2545
static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, ProcSignalReason reason)
Definition: standby.c:194
#define TransactionIdIsValid(xid)
Definition: transam.h:41
void ResolveRecoveryConflictWithTablespace ( Oid  tsid)

Definition at line 291 of file standby.c.

References GetConflictingVirtualXIDs(), InvalidOid, InvalidTransactionId, PROCSIG_RECOVERY_CONFLICT_TABLESPACE, and ResolveRecoveryConflictWithVirtualXIDs().

Referenced by tblspc_redo().

292 {
293  VirtualTransactionId *temp_file_users;
294 
295  /*
296  * Standby users may be currently using this tablespace for their
297  * temporary files. We only care about current users because
298  * temp_tablespace parameter will just ignore tablespaces that no longer
299  * exist.
300  *
301  * Ask everybody to cancel their queries immediately so we can ensure no
302  * temp files remain and we can remove the tablespace. Nuke the entire
303  * site from orbit, it's the only way to be sure.
304  *
305  * XXX: We could work out the pids of active backends using this
306  * tablespace by examining the temp filenames in the directory. We would
307  * then convert the pids into VirtualXIDs before attempting to cancel
308  * them.
309  *
310  * We don't wait for commit because drop tablespace is non-transactional.
311  */
313  InvalidOid);
316 }
VirtualTransactionId * GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)
Definition: procarray.c:2545
static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, ProcSignalReason reason)
Definition: standby.c:194
#define InvalidTransactionId
Definition: transam.h:31
#define InvalidOid
Definition: postgres_ext.h:36
void ShutdownRecoveryTransactionEnvironment ( void  )

Definition at line 102 of file standby.c.

References ExpireAllKnownAssignedTransactionIds(), StandbyReleaseAllLocks(), and VirtualXactLockTableCleanup().

Referenced by StartupXLOG().

103 {
104  /* Mark all tracked in-progress transactions as finished. */
106 
107  /* Release all locks the tracked transactions were holding */
109 
110  /* Cleanup our VirtualTransaction */
112 }
void VirtualXactLockTableCleanup(void)
Definition: lock.c:4244
void ExpireAllKnownAssignedTransactionIds(void)
Definition: procarray.c:3254
void StandbyReleaseAllLocks(void)
Definition: standby.c:694
void StandbyAcquireAccessExclusiveLock ( TransactionId  xid,
Oid  dbOid,
Oid  relOid 
)

Definition at line 606 of file standby.c.

References AccessExclusiveLock, Assert, xl_standby_lock::dbOid, DEBUG4, elog, lappend(), LockAcquireExtended(), OidIsValid, palloc(), xl_standby_lock::relOid, SET_LOCKTAG_RELATION, trace_recovery(), TransactionIdDidAbort(), TransactionIdDidCommit(), TransactionIdIsValid, and xl_standby_lock::xid.

Referenced by lock_twophase_standby_recover(), and standby_redo().

607 {
608  xl_standby_lock *newlock;
609  LOCKTAG locktag;
610 
611  /* Already processed? */
612  if (!TransactionIdIsValid(xid) ||
613  TransactionIdDidCommit(xid) ||
615  return;
616 
618  "adding recovery lock: db %u rel %u", dbOid, relOid);
619 
620  /* dbOid is InvalidOid when we are locking a shared relation. */
621  Assert(OidIsValid(relOid));
622 
623  newlock = palloc(sizeof(xl_standby_lock));
624  newlock->xid = xid;
625  newlock->dbOid = dbOid;
626  newlock->relOid = relOid;
628 
629  SET_LOCKTAG_RELATION(locktag, newlock->dbOid, newlock->relOid);
630 
631  LockAcquireExtended(&locktag, AccessExclusiveLock, true, false, false);
632 }
static List * RecoveryLockList
Definition: standby.c:41
Definition: lock.h:179
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:125
#define DEBUG4
Definition: elog.h:22
#define OidIsValid(objectId)
Definition: c.h:534
int trace_recovery(int trace_level)
Definition: elog.c:3753
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
Definition: lock.h:194
bool TransactionIdDidAbort(TransactionId transactionId)
Definition: transam.c:181
List * lappend(List *list, void *datum)
Definition: list.c:128
TransactionId xid
Definition: lockdefs.h:51
#define Assert(condition)
Definition: c.h:671
#define AccessExclusiveLock
Definition: lockdefs.h:46
void * palloc(Size size)
Definition: mcxt.c:891
#define elog
Definition: elog.h:219
#define TransactionIdIsValid(xid)
Definition: transam.h:41
LockAcquireResult LockAcquireExtended(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait, bool reportMemoryError)
Definition: lock.c:701
void StandbyDeadLockHandler ( void  )
void StandbyLockTimeoutHandler ( void  )

Definition at line 571 of file standby.c.

Referenced by StartupProcessMain().

572 {
573 }
void StandbyReleaseAllLocks ( void  )

Definition at line 694 of file standby.c.

References AccessExclusiveLock, xl_standby_lock::dbOid, DEBUG2, DEBUG4, elog, lfirst, list_delete_cell(), list_head(), lnext, LockRelease(), LOG, next, NULL, pfree(), xl_standby_lock::relOid, SET_LOCKTAG_RELATION, trace_recovery(), and xl_standby_lock::xid.

Referenced by ShutdownRecoveryTransactionEnvironment().

695 {
696  ListCell *cell,
697  *prev,
698  *next;
699  LOCKTAG locktag;
700 
701  elog(trace_recovery(DEBUG2), "release all standby locks");
702 
703  prev = NULL;
704  for (cell = list_head(RecoveryLockList); cell; cell = next)
705  {
706  xl_standby_lock *lock = (xl_standby_lock *) lfirst(cell);
707 
708  next = lnext(cell);
709 
711  "releasing recovery lock: xid %u db %u rel %u",
712  lock->xid, lock->dbOid, lock->relOid);
713  SET_LOCKTAG_RELATION(locktag, lock->dbOid, lock->relOid);
714  if (!LockRelease(&locktag, AccessExclusiveLock, true))
715  elog(LOG,
716  "RecoveryLockList contains entry for lock no longer recorded by lock manager: xid %u database %u relation %u",
717  lock->xid, lock->dbOid, lock->relOid);
719  pfree(lock);
720  }
721 }
static List * RecoveryLockList
Definition: standby.c:41
static int32 next
Definition: blutils.c:210
Definition: lock.h:179
#define LOG
Definition: elog.h:26
#define DEBUG4
Definition: elog.h:22
int trace_recovery(int trace_level)
Definition: elog.c:3753
void pfree(void *pointer)
Definition: mcxt.c:992
#define DEBUG2
Definition: elog.h:24
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
Definition: lock.h:194
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
#define lnext(lc)
Definition: pg_list.h:105
TransactionId xid
Definition: lockdefs.h:51
List * list_delete_cell(List *list, ListCell *cell, ListCell *prev)
Definition: list.c:528
#define NULL
Definition: c.h:226
#define lfirst(lc)
Definition: pg_list.h:106
#define AccessExclusiveLock
Definition: lockdefs.h:46
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
Definition: lock.c:1818
#define elog
Definition: elog.h:219
void StandbyReleaseLockTree ( TransactionId  xid,
int  nsubxids,
TransactionId subxids 
)

Definition at line 680 of file standby.c.

References i, and StandbyReleaseLocks().

Referenced by RecoverPreparedTransactions(), xact_redo_abort(), and xact_redo_commit().

681 {
682  int i;
683 
684  StandbyReleaseLocks(xid);
685 
686  for (i = 0; i < nsubxids; i++)
687  StandbyReleaseLocks(subxids[i]);
688 }
static void StandbyReleaseLocks(TransactionId xid)
Definition: standby.c:635
int i
void StandbyReleaseOldLocks ( int  nxids,
TransactionId xids 
)

Definition at line 729 of file standby.c.

References AccessExclusiveLock, Assert, xl_standby_lock::dbOid, DEBUG4, elog, i, lfirst, list_delete_cell(), list_head(), lnext, LockRelease(), LOG, next, NULL, pfree(), xl_standby_lock::relOid, SET_LOCKTAG_RELATION, StandbyTransactionIdIsPrepared(), trace_recovery(), TransactionIdIsValid, and xl_standby_lock::xid.

Referenced by ProcArrayApplyRecoveryInfo().

730 {
731  ListCell *cell,
732  *prev,
733  *next;
734  LOCKTAG locktag;
735 
736  prev = NULL;
737  for (cell = list_head(RecoveryLockList); cell; cell = next)
738  {
739  xl_standby_lock *lock = (xl_standby_lock *) lfirst(cell);
740  bool remove = false;
741 
742  next = lnext(cell);
743 
745 
747  remove = false;
748  else
749  {
750  int i;
751  bool found = false;
752 
753  for (i = 0; i < nxids; i++)
754  {
755  if (lock->xid == xids[i])
756  {
757  found = true;
758  break;
759  }
760  }
761 
762  /*
763  * If its not a running transaction, remove it.
764  */
765  if (!found)
766  remove = true;
767  }
768 
769  if (remove)
770  {
772  "releasing recovery lock: xid %u db %u rel %u",
773  lock->xid, lock->dbOid, lock->relOid);
774  SET_LOCKTAG_RELATION(locktag, lock->dbOid, lock->relOid);
775  if (!LockRelease(&locktag, AccessExclusiveLock, true))
776  elog(LOG,
777  "RecoveryLockList contains entry for lock no longer recorded by lock manager: xid %u database %u relation %u",
778  lock->xid, lock->dbOid, lock->relOid);
780  pfree(lock);
781  }
782  else
783  prev = cell;
784  }
785 }
static List * RecoveryLockList
Definition: standby.c:41
static int32 next
Definition: blutils.c:210
Definition: lock.h:179
#define LOG
Definition: elog.h:26
#define DEBUG4
Definition: elog.h:22
int trace_recovery(int trace_level)
Definition: elog.c:3753
void pfree(void *pointer)
Definition: mcxt.c:992
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
Definition: lock.h:194
bool StandbyTransactionIdIsPrepared(TransactionId xid)
Definition: twophase.c:1294
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
#define lnext(lc)
Definition: pg_list.h:105
TransactionId xid
Definition: lockdefs.h:51
List * list_delete_cell(List *list, ListCell *cell, ListCell *prev)
Definition: list.c:528
#define NULL
Definition: c.h:226
#define Assert(condition)
Definition: c.h:671
#define lfirst(lc)
Definition: pg_list.h:106
#define AccessExclusiveLock
Definition: lockdefs.h:46
int i
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
Definition: lock.c:1818
#define elog
Definition: elog.h:219
#define TransactionIdIsValid(xid)
Definition: transam.h:41
void StandbyTimeoutHandler ( void  )

Definition at line 558 of file standby.c.

References disable_timeout(), PROCSIG_RECOVERY_CONFLICT_BUFFERPIN, SendRecoveryConflictWithBufferPin(), and STANDBY_DEADLOCK_TIMEOUT.

Referenced by StartupProcessMain().

559 {
560  /* forget any pending STANDBY_DEADLOCK_TIMEOUT request */
562 
564 }
static void SendRecoveryConflictWithBufferPin(ProcSignalReason reason)
Definition: standby.c:487
void disable_timeout(TimeoutId id, bool keep_indicator)
Definition: timeout.c:525

Variable Documentation

int max_standby_archive_delay

Definition at line 38 of file standby.c.

Referenced by GetStandbyLimitTime().

int max_standby_streaming_delay

Definition at line 39 of file standby.c.

Referenced by GetStandbyLimitTime().

int vacuum_defer_cleanup_age

Definition at line 37 of file standby.c.

Referenced by GetOldestXmin(), and GetSnapshotData().