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:192
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:675
bool HoldingBufferPinThatDelaysRecovery(void)
Definition: bufmgr.c:3692
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:73
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:195
void LogAccessExclusiveLock ( Oid  dbOid,
Oid  relOid 
)

Definition at line 1047 of file standby.c.

References xl_standby_lock::dbOid, GetCurrentTransactionId(), LogAccessExclusiveLocks(), MyXactFlags, xl_standby_lock::relOid, XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK, and xl_standby_lock::xid.

Referenced by LockAcquireExtended().

1048 {
1049  xl_standby_lock xlrec;
1050 
1051  xlrec.xid = GetCurrentTransactionId();
1052 
1053  /*
1054  * Decode the locktag back to the original values, to avoid sending lots
1055  * of empty bytes with every message. See lock.h to check how a locktag
1056  * is defined for LOCKTAG_RELATION
1057  */
1058  xlrec.dbOid = dbOid;
1059  xlrec.relOid = relOid;
1060 
1061  LogAccessExclusiveLocks(1, &xlrec);
1063 }
static void LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks)
Definition: standby.c:1029
#define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK
Definition: xact.h:92
TransactionId GetCurrentTransactionId(void)
Definition: xact.c:417
int MyXactFlags
Definition: xact.c:118
TransactionId xid
Definition: lockdefs.h:50
void LogAccessExclusiveLockPrepare ( void  )

Definition at line 1069 of file standby.c.

References GetCurrentTransactionId().

Referenced by LockAcquireExtended().

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

Definition at line 1091 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().

1093 {
1094  xl_invalidations xlrec;
1095 
1096  /* prepare record */
1097  memset(&xlrec, 0, sizeof(xlrec));
1098  xlrec.dbId = MyDatabaseId;
1099  xlrec.tsId = MyDatabaseTableSpace;
1100  xlrec.relcacheInitFileInval = relcacheInitFileInval;
1101  xlrec.nmsgs = nmsgs;
1102 
1103  /* perform insertion */
1104  XLogBeginInsert();
1105  XLogRegisterData((char *) (&xlrec), MinSizeOfInvalidations);
1106  XLogRegisterData((char *) msgs,
1107  nmsgs * sizeof(SharedInvalidationMessage));
1108  XLogInsert(RM_STANDBY_ID, XLOG_INVALIDATIONS);
1109 }
#define XLOG_INVALIDATIONS
Definition: standbydefs.h:36
Oid MyDatabaseTableSpace
Definition: globals.c:79
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:77
void XLogBeginInsert(void)
Definition: xloginsert.c:120
XLogRecPtr LogStandbySnapshot ( void  )

Definition at line 909 of file standby.c.

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

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

910 {
911  XLogRecPtr recptr;
912  RunningTransactions running;
913  xl_standby_lock *locks;
914  int nlocks;
915 
917 
918  /*
919  * Get details of any AccessExclusiveLocks being held at the moment.
920  */
921  locks = GetRunningTransactionLocks(&nlocks);
922  if (nlocks > 0)
923  LogAccessExclusiveLocks(nlocks, locks);
924  pfree(locks);
925 
926  /*
927  * Log details of all in-progress transactions. This should be the last
928  * record we write, because standby will open up when it sees this.
929  */
930  running = GetRunningTransactionData();
931 
932  /*
933  * GetRunningTransactionData() acquired ProcArrayLock, we must release it.
934  * For Hot Standby this can be done before inserting the WAL record
935  * because ProcArrayApplyRecoveryInfo() rechecks the commit status using
936  * the clog. For logical decoding, though, the lock can't be released
937  * early because the clog might be "in the future" from the POV of the
938  * historic snapshot. This would allow for situations where we're waiting
939  * for the end of a transaction listed in the xl_running_xacts record
940  * which, according to the WAL, has committed before the xl_running_xacts
941  * record. Fortunately this routine isn't executed frequently, and it's
942  * only a shared lock.
943  */
945  LWLockRelease(ProcArrayLock);
946 
947  recptr = LogCurrentRunningXacts(running);
948 
949  /* Release lock if we kept it longer ... */
951  LWLockRelease(ProcArrayLock);
952 
953  /* GetRunningTransactionData() acquired XidGenLock, we must release it */
954  LWLockRelease(XidGenLock);
955 
956  return recptr;
957 }
static void LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks)
Definition: standby.c:1029
int wal_level
Definition: xlog.c:104
xl_standby_lock * GetRunningTransactionLocks(int *nlocks)
Definition: lock.c:3762
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1715
void pfree(void *pointer)
Definition: mcxt.c:950
static XLogRecPtr LogCurrentRunningXacts(RunningTransactions CurrRunningXacts)
Definition: standby.c:969
#define XLogStandbyInfoActive()
Definition: xlog.h:159
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define Assert(condition)
Definition: c.h:675
RunningTransactions GetRunningTransactionData(void)
Definition: procarray.c:1933
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:1570
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:1766
#define PG_WAIT_BUFFER_PIN
Definition: pgstat.h:739
void enable_timeout_after(TimeoutId id, int delay_ms)
Definition: timeout.c:428
#define Assert(condition)
Definition: c.h:675
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:2738
void pg_usleep(long microsec)
Definition: signal.c:53
void CancelDBBackends(Oid databaseid, ProcSignalReason sigmode, bool conflictPending)
Definition: procarray.c:2799
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:738
static TimestampTz GetStandbyLimitTime(void)
Definition: standby.c:127
TimeoutId id
Definition: timeout.h:54
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1570
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:1766
uint8 locktag_type
Definition: lock.h:184
#define Assert(condition)
Definition: c.h:675
TimestampTz fin_time
Definition: timeout.h:57
#define AccessExclusiveLock
Definition: lockdefs.h:45
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(), hash_xlog_vacuum_one_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:2561
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:2561
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:3270
void StandbyReleaseAllLocks(void)
Definition: standby.c:690
void StandbyAcquireAccessExclusiveLock ( TransactionId  xid,
Oid  dbOid,
Oid  relOid 
)

Definition at line 602 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().

603 {
604  xl_standby_lock *newlock;
605  LOCKTAG locktag;
606 
607  /* Already processed? */
608  if (!TransactionIdIsValid(xid) ||
609  TransactionIdDidCommit(xid) ||
611  return;
612 
614  "adding recovery lock: db %u rel %u", dbOid, relOid);
615 
616  /* dbOid is InvalidOid when we are locking a shared relation. */
617  Assert(OidIsValid(relOid));
618 
619  newlock = palloc(sizeof(xl_standby_lock));
620  newlock->xid = xid;
621  newlock->dbOid = dbOid;
622  newlock->relOid = relOid;
624 
625  SET_LOCKTAG_RELATION(locktag, newlock->dbOid, newlock->relOid);
626 
627  LockAcquireExtended(&locktag, AccessExclusiveLock, true, false, false);
628 }
static List * RecoveryLockList
Definition: standby.c:41
Definition: lock.h:178
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:125
#define DEBUG4
Definition: elog.h:22
#define OidIsValid(objectId)
Definition: c.h:538
int trace_recovery(int trace_level)
Definition: elog.c:3753
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
Definition: lock.h:193
bool TransactionIdDidAbort(TransactionId transactionId)
Definition: transam.c:181
List * lappend(List *list, void *datum)
Definition: list.c:128
TransactionId xid
Definition: lockdefs.h:50
#define Assert(condition)
Definition: c.h:675
#define AccessExclusiveLock
Definition: lockdefs.h:45
void * palloc(Size size)
Definition: mcxt.c:849
#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 690 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().

691 {
692  ListCell *cell,
693  *prev,
694  *next;
695  LOCKTAG locktag;
696 
697  elog(trace_recovery(DEBUG2), "release all standby locks");
698 
699  prev = NULL;
700  for (cell = list_head(RecoveryLockList); cell; cell = next)
701  {
702  xl_standby_lock *lock = (xl_standby_lock *) lfirst(cell);
703 
704  next = lnext(cell);
705 
707  "releasing recovery lock: xid %u db %u rel %u",
708  lock->xid, lock->dbOid, lock->relOid);
709  SET_LOCKTAG_RELATION(locktag, lock->dbOid, lock->relOid);
710  if (!LockRelease(&locktag, AccessExclusiveLock, true))
711  elog(LOG,
712  "RecoveryLockList contains entry for lock no longer recorded by lock manager: xid %u database %u relation %u",
713  lock->xid, lock->dbOid, lock->relOid);
715  pfree(lock);
716  }
717 }
static List * RecoveryLockList
Definition: standby.c:41
static int32 next
Definition: blutils.c:210
Definition: lock.h:178
#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:950
#define DEBUG2
Definition: elog.h:24
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
Definition: lock.h:193
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:50
List * list_delete_cell(List *list, ListCell *cell, ListCell *prev)
Definition: list.c:528
#define NULL
Definition: c.h:229
#define lfirst(lc)
Definition: pg_list.h:106
#define AccessExclusiveLock
Definition: lockdefs.h:45
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 676 of file standby.c.

References i, and StandbyReleaseLocks().

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

677 {
678  int i;
679 
680  StandbyReleaseLocks(xid);
681 
682  for (i = 0; i < nsubxids; i++)
683  StandbyReleaseLocks(subxids[i]);
684 }
static void StandbyReleaseLocks(TransactionId xid)
Definition: standby.c:631
int i
void StandbyReleaseOldLocks ( int  nxids,
TransactionId xids 
)

Definition at line 725 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().

726 {
727  ListCell *cell,
728  *prev,
729  *next;
730  LOCKTAG locktag;
731 
732  prev = NULL;
733  for (cell = list_head(RecoveryLockList); cell; cell = next)
734  {
735  xl_standby_lock *lock = (xl_standby_lock *) lfirst(cell);
736  bool remove = false;
737 
738  next = lnext(cell);
739 
741 
743  remove = false;
744  else
745  {
746  int i;
747  bool found = false;
748 
749  for (i = 0; i < nxids; i++)
750  {
751  if (lock->xid == xids[i])
752  {
753  found = true;
754  break;
755  }
756  }
757 
758  /*
759  * If its not a running transaction, remove it.
760  */
761  if (!found)
762  remove = true;
763  }
764 
765  if (remove)
766  {
768  "releasing recovery lock: xid %u db %u rel %u",
769  lock->xid, lock->dbOid, lock->relOid);
770  SET_LOCKTAG_RELATION(locktag, lock->dbOid, lock->relOid);
771  if (!LockRelease(&locktag, AccessExclusiveLock, true))
772  elog(LOG,
773  "RecoveryLockList contains entry for lock no longer recorded by lock manager: xid %u database %u relation %u",
774  lock->xid, lock->dbOid, lock->relOid);
776  pfree(lock);
777  }
778  else
779  prev = cell;
780  }
781 }
static List * RecoveryLockList
Definition: standby.c:41
static int32 next
Definition: blutils.c:210
Definition: lock.h:178
#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:950
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
Definition: lock.h:193
bool StandbyTransactionIdIsPrepared(TransactionId xid)
Definition: twophase.c:1339
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:50
List * list_delete_cell(List *list, ListCell *cell, ListCell *prev)
Definition: list.c:528
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define lfirst(lc)
Definition: pg_list.h:106
#define AccessExclusiveLock
Definition: lockdefs.h:45
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().