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 564 of file standby.c.

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

Referenced by ProcSleep().

565 {
566  Assert(!InRecovery); /* do not call in Startup process */
567 
569  return;
570 
571  /*
572  * Error message should match ProcessInterrupts() but we avoid calling
573  * that because we aren't handling an interrupt at this point. Note that
574  * we only cancel the current transaction here, so if we are in a
575  * subtransaction and the pin is held by a parent, then the Startup
576  * process will continue to wait even though we have avoided deadlock.
577  */
578  ereport(ERROR,
579  (errcode(ERRCODE_T_R_DEADLOCK_DETECTED),
580  errmsg("canceling statement due to conflict with recovery"),
581  errdetail("User transaction caused buffer deadlock with recovery.")));
582 }
bool InRecovery
Definition: xlog.c:205
int errcode(int sqlerrcode)
Definition: elog.c:610
#define ERROR
Definition: elog.h:43
int errdetail(const char *fmt,...)
Definition: elog.c:957
#define ereport(elevel,...)
Definition: elog.h:144
#define Assert(condition)
Definition: c.h:745
bool HoldingBufferPinThatDelaysRecovery(void)
Definition: bufmgr.c:3918
int errmsg(const char *fmt,...)
Definition: elog.c:824

◆ InitRecoveryTransactionEnvironment()

void InitRecoveryTransactionEnvironment ( void  )

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

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

◆ LogAccessExclusiveLock()

void LogAccessExclusiveLock ( Oid  dbOid,
Oid  relOid 
)

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

1062 {
1063  xl_standby_lock xlrec;
1064 
1065  xlrec.xid = GetCurrentTransactionId();
1066 
1067  xlrec.dbOid = dbOid;
1068  xlrec.relOid = relOid;
1069 
1070  LogAccessExclusiveLocks(1, &xlrec);
1072 }
static void LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks)
Definition: standby.c:1043
#define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK
Definition: xact.h:107
TransactionId GetCurrentTransactionId(void)
Definition: xact.c:438
int MyXactFlags
Definition: xact.c:132
TransactionId xid
Definition: lockdefs.h:54

◆ LogAccessExclusiveLockPrepare()

void LogAccessExclusiveLockPrepare ( void  )

Definition at line 1078 of file standby.c.

References GetCurrentTransactionId().

Referenced by LockAcquireExtended().

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

◆ LogStandbyInvalidations()

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

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

1102 {
1103  xl_invalidations xlrec;
1104 
1105  /* prepare record */
1106  memset(&xlrec, 0, sizeof(xlrec));
1107  xlrec.dbId = MyDatabaseId;
1108  xlrec.tsId = MyDatabaseTableSpace;
1109  xlrec.relcacheInitFileInval = relcacheInitFileInval;
1110  xlrec.nmsgs = nmsgs;
1111 
1112  /* perform insertion */
1113  XLogBeginInsert();
1114  XLogRegisterData((char *) (&xlrec), MinSizeOfInvalidations);
1115  XLogRegisterData((char *) msgs,
1116  nmsgs * sizeof(SharedInvalidationMessage));
1117  XLogInsert(RM_STANDBY_ID, XLOG_INVALIDATIONS);
1118 }
#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:330
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:422
Oid MyDatabaseId
Definition: globals.c:85
void XLogBeginInsert(void)
Definition: xloginsert.c:123

◆ LogStandbySnapshot()

XLogRecPtr LogStandbySnapshot ( void  )

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

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

◆ ResolveRecoveryConflictWithBufferPin()

void ResolveRecoveryConflictWithBufferPin ( void  )

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

484 {
485  TimestampTz ltime;
486 
488 
489  ltime = GetStandbyLimitTime();
490 
491  if (ltime == 0)
492  {
493  /*
494  * We're willing to wait forever for conflicts, so set timeout for
495  * deadlock check only
496  */
498  }
499  else if (GetCurrentTimestamp() >= ltime)
500  {
501  /*
502  * We're already behind, so clear a path as quickly as possible.
503  */
505  }
506  else
507  {
508  /*
509  * Wake up at ltime, and check for deadlocks as well if we will be
510  * waiting longer than deadlock_timeout
511  */
512  EnableTimeoutParams timeouts[2];
513 
514  timeouts[0].id = STANDBY_TIMEOUT;
515  timeouts[0].type = TMPARAM_AT;
516  timeouts[0].fin_time = ltime;
517  timeouts[1].id = STANDBY_DEADLOCK_TIMEOUT;
518  timeouts[1].type = TMPARAM_AFTER;
519  timeouts[1].delay_ms = DeadlockTimeout;
520  enable_timeouts(timeouts, 2);
521  }
522 
523  /* Wait to be signaled by UnpinBuffer() */
525 
526  /*
527  * Clear any timeout requests established above. We assume here that the
528  * Startup process doesn't have any other timeouts than what this function
529  * uses. If that stops being true, we could cancel the timeouts
530  * individually, but that'd be slower.
531  */
532  disable_all_timeouts(false);
533 }
static TimestampTz GetStandbyLimitTime(void)
Definition: standby.c:156
TimeoutId id
Definition: timeout.h:54
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1574
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:536
void ProcWaitForSignal(uint32 wait_event_info)
Definition: proc.c:1796
#define PG_WAIT_BUFFER_PIN
Definition: pgstat.h:786
void enable_timeout_after(TimeoutId id, int delay_ms)
Definition: timeout.c:435
#define Assert(condition)
Definition: c.h:745
TimestampTz fin_time
Definition: timeout.h:57
int DeadlockTimeout
Definition: proc.c:60

◆ ResolveRecoveryConflictWithDatabase()

void ResolveRecoveryConflictWithDatabase ( Oid  dbid)

Definition at line 360 of file standby.c.

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

Referenced by dbase_redo().

361 {
362  /*
363  * We don't do ResolveRecoveryConflictWithVirtualXIDs() here since that
364  * only waits for transactions and completely idle sessions would block
365  * us. This is rare enough that we do this as simply as possible: no wait,
366  * just force them off immediately.
367  *
368  * No locking is required here because we already acquired
369  * AccessExclusiveLock. Anybody trying to connect while we do this will
370  * block during InitPostgres() and then disconnect when they see the
371  * database has been removed.
372  */
373  while (CountDBBackends(dbid) > 0)
374  {
376 
377  /*
378  * Wait awhile for them to die so that we avoid flooding an
379  * unresponsive backend when system is heavily loaded.
380  */
381  pg_usleep(10000);
382  }
383 }
int CountDBBackends(Oid databaseid)
Definition: procarray.c:3371
void pg_usleep(long microsec)
Definition: signal.c:53
void CancelDBBackends(Oid databaseid, ProcSignalReason sigmode, bool conflictPending)
Definition: procarray.c:3432

◆ ResolveRecoveryConflictWithLock()

void ResolveRecoveryConflictWithLock ( LOCKTAG  locktag)

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

404 {
405  TimestampTz ltime;
406 
408 
409  ltime = GetStandbyLimitTime();
410 
411  if (GetCurrentTimestamp() >= ltime)
412  {
413  /*
414  * We're already behind, so clear a path as quickly as possible.
415  */
416  VirtualTransactionId *backends;
417 
418  backends = GetLockConflicts(&locktag, AccessExclusiveLock, NULL);
419 
420  /*
421  * Prevent ResolveRecoveryConflictWithVirtualXIDs() from reporting
422  * "waiting" in PS display by disabling its argument report_waiting
423  * because the caller, WaitOnLock(), has already reported that.
424  */
427  PG_WAIT_LOCK | locktag.locktag_type,
428  false);
429  }
430  else
431  {
432  /*
433  * Wait (or wait again) until ltime
434  */
435  EnableTimeoutParams timeouts[1];
436 
437  timeouts[0].id = STANDBY_LOCK_TIMEOUT;
438  timeouts[0].type = TMPARAM_AT;
439  timeouts[0].fin_time = ltime;
440  enable_timeouts(timeouts, 1);
441  }
442 
443  /* Wait to be signaled by the release of the Relation Lock */
445 
446  /*
447  * Clear any timeout requests established above. We assume here that the
448  * Startup process doesn't have any other outstanding timeouts than those
449  * used by this function. If that stops being true, we could cancel the
450  * timeouts individually, but that'd be slower.
451  */
452  disable_all_timeouts(false);
453 }
#define PG_WAIT_LOCK
Definition: pgstat.h:785
static TimestampTz GetStandbyLimitTime(void)
Definition: standby.c:156
TimeoutId id
Definition: timeout.h:54
static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, ProcSignalReason reason, uint32 wait_event_info, bool report_waiting)
Definition: standby.c:229
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1574
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
void ProcWaitForSignal(uint32 wait_event_info)
Definition: proc.c:1796
VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
Definition: lock.c:2912
uint8 locktag_type
Definition: lock.h:170
#define Assert(condition)
Definition: c.h:745
TimestampTz fin_time
Definition: timeout.h:57
#define AccessExclusiveLock
Definition: lockdefs.h:45

◆ ResolveRecoveryConflictWithSnapshot()

void ResolveRecoveryConflictWithSnapshot ( TransactionId  latestRemovedXid,
RelFileNode  node 
)

Definition at line 304 of file standby.c.

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

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().

305 {
306  VirtualTransactionId *backends;
307 
308  /*
309  * If we get passed InvalidTransactionId then we are a little surprised,
310  * but it is theoretically possible in normal running. It also happens
311  * when replaying already applied WAL records after a standby crash or
312  * restart, or when replaying an XLOG_HEAP2_VISIBLE record that marks as
313  * frozen a page which was already all-visible. If latestRemovedXid is
314  * invalid then there is no conflict. That rule applies across all record
315  * types that suffer from this conflict.
316  */
317  if (!TransactionIdIsValid(latestRemovedXid))
318  return;
319 
320  backends = GetConflictingVirtualXIDs(latestRemovedXid,
321  node.dbNode);
322 
326  true);
327 }
static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, ProcSignalReason reason, uint32 wait_event_info, bool report_waiting)
Definition: standby.c:229
VirtualTransactionId * GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)
Definition: procarray.c:3196
#define TransactionIdIsValid(xid)
Definition: transam.h:41

◆ ResolveRecoveryConflictWithTablespace()

void ResolveRecoveryConflictWithTablespace ( Oid  tsid)

Definition at line 330 of file standby.c.

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

Referenced by tblspc_redo().

331 {
332  VirtualTransactionId *temp_file_users;
333 
334  /*
335  * Standby users may be currently using this tablespace for their
336  * temporary files. We only care about current users because
337  * temp_tablespace parameter will just ignore tablespaces that no longer
338  * exist.
339  *
340  * Ask everybody to cancel their queries immediately so we can ensure no
341  * temp files remain and we can remove the tablespace. Nuke the entire
342  * site from orbit, it's the only way to be sure.
343  *
344  * XXX: We could work out the pids of active backends using this
345  * tablespace by examining the temp filenames in the directory. We would
346  * then convert the pids into VirtualXIDs before attempting to cancel
347  * them.
348  *
349  * We don't wait for commit because drop tablespace is non-transactional.
350  */
352  InvalidOid);
356  true);
357 }
static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, ProcSignalReason reason, uint32 wait_event_info, bool report_waiting)
Definition: standby.c:229
VirtualTransactionId * GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)
Definition: procarray.c:3196
#define InvalidTransactionId
Definition: transam.h:31
#define InvalidOid
Definition: postgres_ext.h:36

◆ ShutdownRecoveryTransactionEnvironment()

void ShutdownRecoveryTransactionEnvironment ( void  )

Definition at line 127 of file standby.c.

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

Referenced by StartupXLOG().

128 {
129  /* Mark all tracked in-progress transactions as finished. */
131 
132  /* Release all locks the tracked transactions were holding */
134 
135  /* Destroy the hash table of locks. */
137  RecoveryLockLists = NULL;
138 
139  /* Cleanup our VirtualTransaction */
141 }
void hash_destroy(HTAB *hashp)
Definition: dynahash.c:827
void VirtualXactLockTableCleanup(void)
Definition: lock.c:4414
static HTAB * RecoveryLockLists
Definition: standby.c:43
void ExpireAllKnownAssignedTransactionIds(void)
Definition: procarray.c:4291
void StandbyReleaseAllLocks(void)
Definition: standby.c:752

◆ StandbyAcquireAccessExclusiveLock()

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

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

652 {
653  RecoveryLockListsEntry *entry;
654  xl_standby_lock *newlock;
655  LOCKTAG locktag;
656  bool found;
657 
658  /* Already processed? */
659  if (!TransactionIdIsValid(xid) ||
660  TransactionIdDidCommit(xid) ||
662  return;
663 
665  "adding recovery lock: db %u rel %u", dbOid, relOid);
666 
667  /* dbOid is InvalidOid when we are locking a shared relation. */
668  Assert(OidIsValid(relOid));
669 
670  /* Create a new list for this xid, if we don't have one already. */
671  entry = hash_search(RecoveryLockLists, &xid, HASH_ENTER, &found);
672  if (!found)
673  {
674  entry->xid = xid;
675  entry->locks = NIL;
676  }
677 
678  newlock = palloc(sizeof(xl_standby_lock));
679  newlock->xid = xid;
680  newlock->dbOid = dbOid;
681  newlock->relOid = relOid;
682  entry->locks = lappend(entry->locks, newlock);
683 
684  SET_LOCKTAG_RELATION(locktag, newlock->dbOid, newlock->relOid);
685 
686  (void) LockAcquire(&locktag, AccessExclusiveLock, true, false);
687 }
#define NIL
Definition: pg_list.h:65
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:747
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:919
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:125
#define DEBUG4
Definition: elog.h:22
#define OidIsValid(objectId)
Definition: c.h:651
TransactionId xid
Definition: standby.c:58
int trace_recovery(int trace_level)
Definition: elog.c:3543
#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:321
TransactionId xid
Definition: lockdefs.h:54
#define Assert(condition)
Definition: c.h:745
#define AccessExclusiveLock
Definition: lockdefs.h:45
void * palloc(Size size)
Definition: mcxt.c:950
#define elog(elevel,...)
Definition: elog.h:214
#define TransactionIdIsValid(xid)
Definition: transam.h:41

◆ StandbyDeadLockHandler()

void StandbyDeadLockHandler ( void  )

◆ StandbyLockTimeoutHandler()

void StandbyLockTimeoutHandler ( void  )

Definition at line 620 of file standby.c.

Referenced by StartupProcessMain().

621 {
622 }

◆ StandbyReleaseAllLocks()

void StandbyReleaseAllLocks ( void  )

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

753 {
755  RecoveryLockListsEntry *entry;
756 
757  elog(trace_recovery(DEBUG2), "release all standby locks");
758 
760  while ((entry = hash_seq_search(&status)))
761  {
764  }
765 }
static void StandbyReleaseLockList(List *locks)
Definition: standby.c:690
static HTAB * RecoveryLockLists
Definition: standby.c:43
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:919
int trace_recovery(int trace_level)
Definition: elog.c:3543
#define DEBUG2
Definition: elog.h:24
void * hash_seq_search(HASH_SEQ_STATUS *status)
Definition: dynahash.c:1401
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
Definition: dynahash.c:1391
#define elog(elevel,...)
Definition: elog.h:214
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:227

◆ StandbyReleaseLockTree()

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

Definition at line 738 of file standby.c.

References i, and StandbyReleaseLocks().

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

739 {
740  int i;
741 
742  StandbyReleaseLocks(xid);
743 
744  for (i = 0; i < nsubxids; i++)
745  StandbyReleaseLocks(subxids[i]);
746 }
static void StandbyReleaseLocks(TransactionId xid)
Definition: standby.c:714
int i

◆ StandbyReleaseOldLocks()

void StandbyReleaseOldLocks ( TransactionId  oldxid)

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

774 {
776  RecoveryLockListsEntry *entry;
777 
779  while ((entry = hash_seq_search(&status)))
780  {
782 
783  /* Skip if prepared transaction. */
785  continue;
786 
787  /* Skip if >= oldxid. */
788  if (!TransactionIdPrecedes(entry->xid, oldxid))
789  continue;
790 
791  /* Remove all locks and hash table entry. */
794  }
795 }
static void StandbyReleaseLockList(List *locks)
Definition: standby.c:690
static HTAB * RecoveryLockLists
Definition: standby.c:43
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:919
TransactionId xid
Definition: standby.c:58
bool StandbyTransactionIdIsPrepared(TransactionId xid)
Definition: twophase.c:1369
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
#define Assert(condition)
Definition: c.h:745
void * hash_seq_search(HASH_SEQ_STATUS *status)
Definition: dynahash.c:1401
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
Definition: dynahash.c:1391
#define TransactionIdIsValid(xid)
Definition: transam.h:41
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:227

◆ StandbyTimeoutHandler()

void StandbyTimeoutHandler ( void  )

Definition at line 607 of file standby.c.

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

Referenced by StartupProcessMain().

608 {
609  /* forget any pending STANDBY_DEADLOCK_TIMEOUT request */
611 
613 }
static void SendRecoveryConflictWithBufferPin(ProcSignalReason reason)
Definition: standby.c:536
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 ComputeXidHorizons(), and GetSnapshotData().