PostgreSQL Source Code  git master
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 (TransactionId oldxid)
 
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

◆ MinSizeOfXactRunningXacts

#define MinSizeOfXactRunningXacts   offsetof(xl_running_xacts, xids)

Definition at line 55 of file standby.h.

Referenced by LogCurrentRunningXacts().

Typedef Documentation

◆ RunningTransactions

Definition at line 82 of file standby.h.

◆ RunningTransactionsData

Function Documentation

◆ CheckRecoveryConflictDeadlock()

void CheckRecoveryConflictDeadlock ( void  )

Definition at line 542 of file standby.c.

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

Referenced by ProcSleep().

543 {
544  Assert(!InRecovery); /* do not call in Startup process */
545 
547  return;
548 
549  /*
550  * Error message should match ProcessInterrupts() but we avoid calling
551  * that because we aren't handling an interrupt at this point. Note that
552  * we only cancel the current transaction here, so if we are in a
553  * subtransaction and the pin is held by a parent, then the Startup
554  * process will continue to wait even though we have avoided deadlock.
555  */
556  ereport(ERROR,
557  (errcode(ERRCODE_T_R_DEADLOCK_DETECTED),
558  errmsg("canceling statement due to conflict with recovery"),
559  errdetail("User transaction caused buffer deadlock with recovery.")));
560 }
bool InRecovery
Definition: xlog.c:200
int errcode(int sqlerrcode)
Definition: elog.c:608
#define ERROR
Definition: elog.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:957
#define ereport(elevel, rest)
Definition: elog.h:141
#define Assert(condition)
Definition: c.h:733
bool HoldingBufferPinThatDelaysRecovery(void)
Definition: bufmgr.c:3748
int errmsg(const char *fmt,...)
Definition: elog.c:822

◆ InitRecoveryTransactionEnvironment()

void InitRecoveryTransactionEnvironment ( void  )

Definition at line 73 of file standby.c.

References VirtualTransactionId::backendId, HASHCTL::entrysize, GetNextLocalTransactionId(), HASH_BLOBS, hash_create(), HASH_ELEM, HASHCTL::keysize, VirtualTransactionId::localTransactionId, MyBackendId, SharedInvalBackendInit(), STANDBY_INITIALIZED, standbyState, and VirtualXactLockTableInsert().

Referenced by StartupXLOG().

74 {
76  HASHCTL hash_ctl;
77 
78  /*
79  * Initialize the hash table for tracking the list of locks held by each
80  * transaction.
81  */
82  memset(&hash_ctl, 0, sizeof(hash_ctl));
83  hash_ctl.keysize = sizeof(TransactionId);
84  hash_ctl.entrysize = sizeof(RecoveryLockListsEntry);
85  RecoveryLockLists = hash_create("RecoveryLockLists",
86  64,
87  &hash_ctl,
89 
90  /*
91  * Initialize shared invalidation management for Startup process, being
92  * careful to register ourselves as a sendOnly process so we don't need to
93  * read messages, nor will we get signalled when the queue starts filling
94  * up.
95  */
97 
98  /*
99  * Lock a virtual transaction id for Startup process.
100  *
101  * We need to do GetNextLocalTransactionId() because
102  * SharedInvalBackendInit() leaves localTransactionId invalid and the lock
103  * manager doesn't like that at all.
104  *
105  * Note that we don't need to run XactLockTableInsert() because nobody
106  * needs to wait on xids. That sounds a little strange, but table locks
107  * are held by vxids and row level locks are held by xids. All queries
108  * hold AccessShareLocks so never block while we write or lock new rows.
109  */
110  vxid.backendId = MyBackendId;
113 
115 }
BackendId MyBackendId
Definition: globals.c:81
static HTAB * RecoveryLockLists
Definition: standby.c:43
#define HASH_ELEM
Definition: hsearch.h:87
uint32 TransactionId
Definition: c.h:508
void SharedInvalBackendInit(bool sendOnly)
Definition: sinvaladt.c:257
Size entrysize
Definition: hsearch.h:73
LocalTransactionId localTransactionId
Definition: lock.h:66
LocalTransactionId GetNextLocalTransactionId(void)
Definition: sinvaladt.c:768
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
Definition: lock.c:4301
#define HASH_BLOBS
Definition: hsearch.h:88
HTAB * hash_create(const char *tabname, long nelem, HASHCTL *info, int flags)
Definition: dynahash.c:316
Size keysize
Definition: hsearch.h:72
BackendId backendId
Definition: lock.h:65
struct RecoveryLockListsEntry RecoveryLockListsEntry
HotStandbyState standbyState
Definition: xlog.c:203

◆ LogAccessExclusiveLock()

void LogAccessExclusiveLock ( Oid  dbOid,
Oid  relOid 
)

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

1040 {
1041  xl_standby_lock xlrec;
1042 
1043  xlrec.xid = GetCurrentTransactionId();
1044 
1045  xlrec.dbOid = dbOid;
1046  xlrec.relOid = relOid;
1047 
1048  LogAccessExclusiveLocks(1, &xlrec);
1050 }
static void LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks)
Definition: standby.c:1021
#define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK
Definition: xact.h:103
TransactionId GetCurrentTransactionId(void)
Definition: xact.c:422
int MyXactFlags
Definition: xact.c:118
TransactionId xid
Definition: lockdefs.h:54

◆ LogAccessExclusiveLockPrepare()

void LogAccessExclusiveLockPrepare ( void  )

Definition at line 1056 of file standby.c.

References GetCurrentTransactionId().

Referenced by LockAcquireExtended().

1057 {
1058  /*
1059  * Ensure that a TransactionId has been assigned to this transaction, for
1060  * two reasons, both related to lock release on the standby. First, we
1061  * must assign an xid so that RecordTransactionCommit() and
1062  * RecordTransactionAbort() do not optimise away the transaction
1063  * completion record which recovery relies upon to release locks. It's a
1064  * hack, but for a corner case not worth adding code for into the main
1065  * commit path. Second, we must assign an xid before the lock is recorded
1066  * in shared memory, otherwise a concurrently executing
1067  * GetRunningTransactionLocks() might see a lock associated with an
1068  * InvalidTransactionId which we later assert cannot happen.
1069  */
1070  (void) GetCurrentTransactionId();
1071 }
TransactionId GetCurrentTransactionId(void)
Definition: xact.c:422

◆ LogStandbyInvalidations()

void LogStandbyInvalidations ( int  nmsgs,
SharedInvalidationMessage msgs,
bool  relcacheInitFileInval 
)

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

1080 {
1081  xl_invalidations xlrec;
1082 
1083  /* prepare record */
1084  memset(&xlrec, 0, sizeof(xlrec));
1085  xlrec.dbId = MyDatabaseId;
1086  xlrec.tsId = MyDatabaseTableSpace;
1087  xlrec.relcacheInitFileInval = relcacheInitFileInval;
1088  xlrec.nmsgs = nmsgs;
1089 
1090  /* perform insertion */
1091  XLogBeginInsert();
1092  XLogRegisterData((char *) (&xlrec), MinSizeOfInvalidations);
1093  XLogRegisterData((char *) msgs,
1094  nmsgs * sizeof(SharedInvalidationMessage));
1095  XLogInsert(RM_STANDBY_ID, XLOG_INVALIDATIONS);
1096 }
#define XLOG_INVALIDATIONS
Definition: standbydefs.h:36
Oid MyDatabaseTableSpace
Definition: globals.c:87
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:85
void XLogBeginInsert(void)
Definition: xloginsert.c:120

◆ LogStandbySnapshot()

XLogRecPtr LogStandbySnapshot ( void  )

Definition at line 901 of file standby.c.

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

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

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

◆ ResolveRecoveryConflictWithBufferPin()

void ResolveRecoveryConflictWithBufferPin ( void  )

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

462 {
463  TimestampTz ltime;
464 
466 
467  ltime = GetStandbyLimitTime();
468 
469  if (ltime == 0)
470  {
471  /*
472  * We're willing to wait forever for conflicts, so set timeout for
473  * deadlock check only
474  */
476  }
477  else if (GetCurrentTimestamp() >= ltime)
478  {
479  /*
480  * We're already behind, so clear a path as quickly as possible.
481  */
483  }
484  else
485  {
486  /*
487  * Wake up at ltime, and check for deadlocks as well if we will be
488  * waiting longer than deadlock_timeout
489  */
490  EnableTimeoutParams timeouts[2];
491 
492  timeouts[0].id = STANDBY_TIMEOUT;
493  timeouts[0].type = TMPARAM_AT;
494  timeouts[0].fin_time = ltime;
495  timeouts[1].id = STANDBY_DEADLOCK_TIMEOUT;
496  timeouts[1].type = TMPARAM_AFTER;
497  timeouts[1].delay_ms = DeadlockTimeout;
498  enable_timeouts(timeouts, 2);
499  }
500 
501  /* Wait to be signaled by UnpinBuffer() */
503 
504  /*
505  * Clear any timeout requests established above. We assume here that the
506  * Startup process doesn't have any other timeouts than what this function
507  * uses. If that stops being true, we could cancel the timeouts
508  * individually, but that'd be slower.
509  */
510  disable_all_timeouts(false);
511 }
static TimestampTz GetStandbyLimitTime(void)
Definition: standby.c:154
TimeoutId id
Definition: timeout.h:54
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1583
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:483
void disable_all_timeouts(bool keep_indicators)
Definition: timeout.c:598
static void SendRecoveryConflictWithBufferPin(ProcSignalReason reason)
Definition: standby.c:514
void ProcWaitForSignal(uint32 wait_event_info)
Definition: proc.c:1798
#define PG_WAIT_BUFFER_PIN
Definition: pgstat.h:756
void enable_timeout_after(TimeoutId id, int delay_ms)
Definition: timeout.c:435
#define Assert(condition)
Definition: c.h:733
TimestampTz fin_time
Definition: timeout.h:57
int DeadlockTimeout
Definition: proc.c:60

◆ ResolveRecoveryConflictWithDatabase()

void ResolveRecoveryConflictWithDatabase ( Oid  dbid)

Definition at line 346 of file standby.c.

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

Referenced by dbase_redo().

347 {
348  /*
349  * We don't do ResolveRecoveryConflictWithVirtualXIDs() here since that
350  * only waits for transactions and completely idle sessions would block
351  * us. This is rare enough that we do this as simply as possible: no wait,
352  * just force them off immediately.
353  *
354  * No locking is required here because we already acquired
355  * AccessExclusiveLock. Anybody trying to connect while we do this will
356  * block during InitPostgres() and then disconnect when they see the
357  * database has been removed.
358  */
359  while (CountDBBackends(dbid) > 0)
360  {
362 
363  /*
364  * Wait awhile for them to die so that we avoid flooding an
365  * unresponsive backend when system is heavily loaded.
366  */
367  pg_usleep(10000);
368  }
369 }
int CountDBBackends(Oid databaseid)
Definition: procarray.c:2758
void pg_usleep(long microsec)
Definition: signal.c:53
void CancelDBBackends(Oid databaseid, ProcSignalReason sigmode, bool conflictPending)
Definition: procarray.c:2819

◆ ResolveRecoveryConflictWithLock()

void ResolveRecoveryConflictWithLock ( LOCKTAG  locktag)

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

390 {
391  TimestampTz ltime;
392 
394 
395  ltime = GetStandbyLimitTime();
396 
397  if (GetCurrentTimestamp() >= ltime)
398  {
399  /*
400  * We're already behind, so clear a path as quickly as possible.
401  */
402  VirtualTransactionId *backends;
403 
404  backends = GetLockConflicts(&locktag, AccessExclusiveLock, NULL);
407  }
408  else
409  {
410  /*
411  * Wait (or wait again) until ltime
412  */
413  EnableTimeoutParams timeouts[1];
414 
415  timeouts[0].id = STANDBY_LOCK_TIMEOUT;
416  timeouts[0].type = TMPARAM_AT;
417  timeouts[0].fin_time = ltime;
418  enable_timeouts(timeouts, 1);
419  }
420 
421  /* Wait to be signaled by the release of the Relation Lock */
423 
424  /*
425  * Clear any timeout requests established above. We assume here that the
426  * Startup process doesn't have any other outstanding timeouts than those
427  * used by this function. If that stops being true, we could cancel the
428  * timeouts individually, but that'd be slower.
429  */
430  disable_all_timeouts(false);
431 }
#define PG_WAIT_LOCK
Definition: pgstat.h:755
static TimestampTz GetStandbyLimitTime(void)
Definition: standby.c:154
TimeoutId id
Definition: timeout.h:54
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1583
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:483
void disable_all_timeouts(bool keep_indicators)
Definition: timeout.c:598
static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, ProcSignalReason reason)
Definition: standby.c:221
void ProcWaitForSignal(uint32 wait_event_info)
Definition: proc.c:1798
VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
Definition: lock.c:2821
uint8 locktag_type
Definition: lock.h:170
#define Assert(condition)
Definition: c.h:733
TimestampTz fin_time
Definition: timeout.h:57
#define AccessExclusiveLock
Definition: lockdefs.h:45

◆ ResolveRecoveryConflictWithSnapshot()

void ResolveRecoveryConflictWithSnapshot ( TransactionId  latestRemovedXid,
RelFileNode  node 
)

Definition at line 294 of file standby.c.

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

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

295 {
296  VirtualTransactionId *backends;
297 
298  /*
299  * If we get passed InvalidTransactionId then we are a little surprised,
300  * but it is theoretically possible in normal running. It also happens
301  * when replaying already applied WAL records after a standby crash or
302  * restart, or when replaying an XLOG_HEAP2_VISIBLE record that marks as
303  * frozen a page which was already all-visible. If latestRemovedXid is
304  * invalid then there is no conflict. That rule applies across all record
305  * types that suffer from this conflict.
306  */
307  if (!TransactionIdIsValid(latestRemovedXid))
308  return;
309 
310  backends = GetConflictingVirtualXIDs(latestRemovedXid,
311  node.dbNode);
312 
315 }
VirtualTransactionId * GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)
Definition: procarray.c:2581
static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, ProcSignalReason reason)
Definition: standby.c:221
#define TransactionIdIsValid(xid)
Definition: transam.h:41

◆ ResolveRecoveryConflictWithTablespace()

void ResolveRecoveryConflictWithTablespace ( Oid  tsid)

Definition at line 318 of file standby.c.

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

Referenced by tblspc_redo().

319 {
320  VirtualTransactionId *temp_file_users;
321 
322  /*
323  * Standby users may be currently using this tablespace for their
324  * temporary files. We only care about current users because
325  * temp_tablespace parameter will just ignore tablespaces that no longer
326  * exist.
327  *
328  * Ask everybody to cancel their queries immediately so we can ensure no
329  * temp files remain and we can remove the tablespace. Nuke the entire
330  * site from orbit, it's the only way to be sure.
331  *
332  * XXX: We could work out the pids of active backends using this
333  * tablespace by examining the temp filenames in the directory. We would
334  * then convert the pids into VirtualXIDs before attempting to cancel
335  * them.
336  *
337  * We don't wait for commit because drop tablespace is non-transactional.
338  */
340  InvalidOid);
343 }
VirtualTransactionId * GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)
Definition: procarray.c:2581
static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, ProcSignalReason reason)
Definition: standby.c:221
#define InvalidTransactionId
Definition: transam.h:31
#define InvalidOid
Definition: postgres_ext.h:36

◆ ShutdownRecoveryTransactionEnvironment()

void ShutdownRecoveryTransactionEnvironment ( void  )

Definition at line 125 of file standby.c.

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

Referenced by StartupXLOG().

126 {
127  /* Mark all tracked in-progress transactions as finished. */
129 
130  /* Release all locks the tracked transactions were holding */
132 
133  /* Destroy the hash table of locks. */
135  RecoveryLockLists = NULL;
136 
137  /* Cleanup our VirtualTransaction */
139 }
void hash_destroy(HTAB *hashp)
Definition: dynahash.c:814
void VirtualXactLockTableCleanup(void)
Definition: lock.c:4324
static HTAB * RecoveryLockLists
Definition: standby.c:43
void ExpireAllKnownAssignedTransactionIds(void)
Definition: procarray.c:3406
void StandbyReleaseAllLocks(void)
Definition: standby.c:730

◆ StandbyAcquireAccessExclusiveLock()

void StandbyAcquireAccessExclusiveLock ( TransactionId  xid,
Oid  dbOid,
Oid  relOid 
)

Definition at line 629 of file standby.c.

References AccessExclusiveLock, Assert, xl_standby_lock::dbOid, DEBUG4, elog, HASH_ENTER, hash_search(), lappend(), LockAcquire(), RecoveryLockListsEntry::locks, NIL, OidIsValid, palloc(), xl_standby_lock::relOid, SET_LOCKTAG_RELATION, trace_recovery(), TransactionIdDidAbort(), TransactionIdDidCommit(), TransactionIdIsValid, xl_standby_lock::xid, and RecoveryLockListsEntry::xid.

Referenced by lock_twophase_standby_recover(), and standby_redo().

630 {
631  RecoveryLockListsEntry *entry;
632  xl_standby_lock *newlock;
633  LOCKTAG locktag;
634  bool found;
635 
636  /* Already processed? */
637  if (!TransactionIdIsValid(xid) ||
638  TransactionIdDidCommit(xid) ||
640  return;
641 
643  "adding recovery lock: db %u rel %u", dbOid, relOid);
644 
645  /* dbOid is InvalidOid when we are locking a shared relation. */
646  Assert(OidIsValid(relOid));
647 
648  /* Create a new list for this xid, if we don't have one already. */
649  entry = hash_search(RecoveryLockLists, &xid, HASH_ENTER, &found);
650  if (!found)
651  {
652  entry->xid = xid;
653  entry->locks = NIL;
654  }
655 
656  newlock = palloc(sizeof(xl_standby_lock));
657  newlock->xid = xid;
658  newlock->dbOid = dbOid;
659  newlock->relOid = relOid;
660  entry->locks = lappend(entry->locks, newlock);
661 
662  SET_LOCKTAG_RELATION(locktag, newlock->dbOid, newlock->relOid);
663 
664  (void) LockAcquire(&locktag, AccessExclusiveLock, true, false);
665 }
#define NIL
Definition: pg_list.h:65
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:708
static HTAB * RecoveryLockLists
Definition: standby.c:43
Definition: lock.h:164
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:906
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:125
#define DEBUG4
Definition: elog.h:22
#define OidIsValid(objectId)
Definition: c.h:639
TransactionId xid
Definition: standby.c:56
int trace_recovery(int trace_level)
Definition: elog.c:3591
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
Definition: lock.h:181
bool TransactionIdDidAbort(TransactionId transactionId)
Definition: transam.c:181
List * lappend(List *list, void *datum)
Definition: list.c:322
TransactionId xid
Definition: lockdefs.h:54
#define Assert(condition)
Definition: c.h:733
#define AccessExclusiveLock
Definition: lockdefs.h:45
void * palloc(Size size)
Definition: mcxt.c:949
#define elog(elevel,...)
Definition: elog.h:228
#define TransactionIdIsValid(xid)
Definition: transam.h:41

◆ StandbyDeadLockHandler()

void StandbyDeadLockHandler ( void  )

◆ StandbyLockTimeoutHandler()

void StandbyLockTimeoutHandler ( void  )

Definition at line 598 of file standby.c.

Referenced by StartupProcessMain().

599 {
600 }

◆ StandbyReleaseAllLocks()

void StandbyReleaseAllLocks ( void  )

Definition at line 730 of file standby.c.

References DEBUG2, elog, HASH_REMOVE, hash_search(), hash_seq_init(), hash_seq_search(), RecoveryLockListsEntry::locks, StandbyReleaseLockList(), status(), and trace_recovery().

Referenced by ShutdownRecoveryTransactionEnvironment(), and StandbyReleaseLocks().

731 {
733  RecoveryLockListsEntry *entry;
734 
735  elog(trace_recovery(DEBUG2), "release all standby locks");
736 
738  while ((entry = hash_seq_search(&status)))
739  {
742  }
743 }
static void StandbyReleaseLockList(List *locks)
Definition: standby.c:668
static HTAB * RecoveryLockLists
Definition: standby.c:43
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:906
int trace_recovery(int trace_level)
Definition: elog.c:3591
#define DEBUG2
Definition: elog.h:24
void * hash_seq_search(HASH_SEQ_STATUS *status)
Definition: dynahash.c:1389
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
Definition: dynahash.c:1379
#define elog(elevel,...)
Definition: elog.h:228
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:226

◆ StandbyReleaseLockTree()

void StandbyReleaseLockTree ( TransactionId  xid,
int  nsubxids,
TransactionId subxids 
)

Definition at line 716 of file standby.c.

References i, and StandbyReleaseLocks().

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

717 {
718  int i;
719 
720  StandbyReleaseLocks(xid);
721 
722  for (i = 0; i < nsubxids; i++)
723  StandbyReleaseLocks(subxids[i]);
724 }
static void StandbyReleaseLocks(TransactionId xid)
Definition: standby.c:692
int i

◆ StandbyReleaseOldLocks()

void StandbyReleaseOldLocks ( TransactionId  oldxid)

Definition at line 751 of file standby.c.

References Assert, HASH_REMOVE, hash_search(), hash_seq_init(), hash_seq_search(), RecoveryLockListsEntry::locks, StandbyReleaseLockList(), StandbyTransactionIdIsPrepared(), status(), TransactionIdIsValid, TransactionIdPrecedes(), and RecoveryLockListsEntry::xid.

Referenced by ProcArrayApplyRecoveryInfo().

752 {
754  RecoveryLockListsEntry *entry;
755 
757  while ((entry = hash_seq_search(&status)))
758  {
760 
761  /* Skip if prepared transaction. */
763  continue;
764 
765  /* Skip if >= oldxid. */
766  if (!TransactionIdPrecedes(entry->xid, oldxid))
767  continue;
768 
769  /* Remove all locks and hash table entry. */
772  }
773 }
static void StandbyReleaseLockList(List *locks)
Definition: standby.c:668
static HTAB * RecoveryLockLists
Definition: standby.c:43
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:906
TransactionId xid
Definition: standby.c:56
bool StandbyTransactionIdIsPrepared(TransactionId xid)
Definition: twophase.c:1371
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
#define Assert(condition)
Definition: c.h:733
void * hash_seq_search(HASH_SEQ_STATUS *status)
Definition: dynahash.c:1389
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
Definition: dynahash.c:1379
#define TransactionIdIsValid(xid)
Definition: transam.h:41
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:226

◆ StandbyTimeoutHandler()

void StandbyTimeoutHandler ( void  )

Definition at line 585 of file standby.c.

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

Referenced by StartupProcessMain().

586 {
587  /* forget any pending STANDBY_DEADLOCK_TIMEOUT request */
589 
591 }
static void SendRecoveryConflictWithBufferPin(ProcSignalReason reason)
Definition: standby.c:514
void disable_timeout(TimeoutId id, bool keep_indicator)
Definition: timeout.c:532

Variable Documentation

◆ max_standby_archive_delay

int max_standby_archive_delay

Definition at line 40 of file standby.c.

Referenced by GetStandbyLimitTime().

◆ max_standby_streaming_delay

int max_standby_streaming_delay

Definition at line 41 of file standby.c.

Referenced by GetStandbyLimitTime().

◆ vacuum_defer_cleanup_age

int vacuum_defer_cleanup_age

Definition at line 39 of file standby.c.

Referenced by GetOldestXmin(), and GetSnapshotData().