PostgreSQL Source Code: src/include/storage/standby.h File Reference (original) (raw)

Go to the source code of this file.

Functions
void InitRecoveryTransactionEnvironment (void)
void ShutdownRecoveryTransactionEnvironment (void)
void ResolveRecoveryConflictWithSnapshot (TransactionId snapshotConflictHorizon, bool isCatalogRel, RelFileLocator locator)
void ResolveRecoveryConflictWithSnapshotFullXid (FullTransactionId snapshotConflictHorizon, bool isCatalogRel, RelFileLocator locator)
void ResolveRecoveryConflictWithTablespace (Oid tsid)
void ResolveRecoveryConflictWithDatabase (Oid dbid)
void ResolveRecoveryConflictWithLock (LOCKTAG locktag, bool logging_conflict)
void ResolveRecoveryConflictWithBufferPin (void)
void CheckRecoveryConflictDeadlock (void)
void StandbyDeadLockHandler (void)
void StandbyTimeoutHandler (void)
void StandbyLockTimeoutHandler (void)
void LogRecoveryConflict (ProcSignalReason reason, TimestampTz wait_start, TimestampTz now, VirtualTransactionId *wait_list, bool still_waiting)
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
PGDLLIMPORT int max_standby_archive_delay
PGDLLIMPORT int max_standby_streaming_delay
PGDLLIMPORT bool log_recovery_conflict_waits

MinSizeOfXactRunningXacts

RunningTransactions

RunningTransactionsData

subxids_array_status

Enumerator
SUBXIDS_IN_ARRAY
SUBXIDS_MISSING
SUBXIDS_IN_SUBTRANS

Definition at line 78 of file standby.h.

CheckRecoveryConflictDeadlock()

void CheckRecoveryConflictDeadlock ( void )

Definition at line 905 of file standby.c.

906{

908

910 return;

911

912

913

914

915

916

917

918

921 errmsg("canceling statement due to conflict with recovery"),

922 errdetail("User transaction caused buffer deadlock with recovery.")));

923}

bool HoldingBufferPinThatDelaysRecovery(void)

int errdetail(const char *fmt,...)

int errcode(int sqlerrcode)

int errmsg(const char *fmt,...)

#define ereport(elevel,...)

Assert(PointerIsAligned(start, uint64))

#define ERRCODE_T_R_DEADLOCK_DETECTED

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

Referenced by ProcSleep().

InitRecoveryTransactionEnvironment()

void InitRecoveryTransactionEnvironment ( void )

Definition at line 95 of file standby.c.

96{

99

101

102

103

104

105

109 64,

110 &hash_ctl,

115 64,

116 &hash_ctl,

118

119

120

121

122

123

124

126

127

128

129

130

131

132

133

134

135

136

137

138

143

145}

HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)

void VirtualXactLockTableInsert(VirtualTransactionId vxid)

struct xl_standby_lock xl_standby_lock

void SharedInvalBackendInit(bool sendOnly)

LocalTransactionId GetNextLocalTransactionId(void)

static HTAB * RecoveryLockXidHash

struct RecoveryLockEntry RecoveryLockEntry

struct RecoveryLockXidEntry RecoveryLockXidEntry

static HTAB * RecoveryLockHash

LocalTransactionId localTransactionId

HotStandbyState standbyState

References Assert(), HASHCTL::entrysize, GetNextLocalTransactionId(), HASH_BLOBS, hash_create(), HASH_ELEM, HASHCTL::keysize, VirtualTransactionId::localTransactionId, MyProc, MyProcNumber, VirtualTransactionId::procNumber, PGPROC::procNumber, RecoveryLockHash, RecoveryLockXidHash, SharedInvalBackendInit(), STANDBY_INITIALIZED, standbyState, VirtualXactLockTableInsert(), and PGPROC::vxid.

Referenced by StartupXLOG().

LogAccessExclusiveLock()

void LogAccessExclusiveLock ( Oid dbOid,
Oid relOid
)

LogAccessExclusiveLockPrepare()

void LogAccessExclusiveLockPrepare ( void )

LogRecoveryConflict()

Definition at line 274 of file standby.c.

277{

278 long secs;

279 int usecs;

280 long msecs;

282 int nprocs = 0;

283

284

285

286

287

288 Assert(still_waiting || wait_list == NULL);

289

291 msecs = secs * 1000 + usecs / 1000;

292 usecs = usecs % 1000;

293

294 if (wait_list)

295 {

297

298

299 vxids = wait_list;

301 {

303

304

305 if (proc)

306 {

307 if (nprocs == 0)

308 {

311 }

312 else

314

315 nprocs++;

316 }

317

318 vxids++;

319 }

320 }

321

322

323

324

325

326

327 if (still_waiting)

328 {

330 errmsg("recovery still waiting after %ld.%03d ms: %s",

333 "Conflicting processes: %s.",

334 nprocs, buf.data) : 0);

335 }

336 else

337 {

339 errmsg("recovery finished waiting after %ld.%03d ms: %s",

341 }

342

343 if (nprocs > 0)

345}

void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)

Datum now(PG_FUNCTION_ARGS)

int errdetail_log_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)

#define VirtualTransactionIdIsValid(vxid)

void pfree(void *pointer)

PGPROC * ProcNumberGetProc(ProcNumber procNumber)

static const char * get_recovery_conflict_desc(ProcSignalReason reason)

void appendStringInfo(StringInfo str, const char *fmt,...)

void initStringInfo(StringInfo str)

References appendStringInfo(), Assert(), buf, ereport, errdetail_log_plural(), errmsg(), get_recovery_conflict_desc(), initStringInfo(), LOG, now(), pfree(), PGPROC::pid, VirtualTransactionId::procNumber, ProcNumberGetProc(), TimestampDifference(), and VirtualTransactionIdIsValid.

Referenced by LockBufferForCleanup(), ProcSleep(), and ResolveRecoveryConflictWithVirtualXIDs().

LogStandbyInvalidations()

Definition at line 1470 of file standby.c.

1472{

1474

1475

1476 memset(&xlrec, 0, sizeof(xlrec));

1480 xlrec.nmsgs = nmsgs;

1481

1482

1488}

#define XLOG_INVALIDATIONS

#define MinSizeOfInvalidations

bool relcacheInitFileInval

XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)

void XLogRegisterData(const void *data, uint32 len)

void XLogBeginInsert(void)

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

LogStandbySnapshot()

Definition at line 1282 of file standby.c.

1283{

1287 int nlocks;

1288

1290

1291#ifdef USE_INJECTION_POINTS

1293 {

1294

1295

1296

1297

1299 }

1300#endif

1301

1302

1303

1304

1306 if (nlocks > 0)

1309

1310

1311

1312

1313

1315

1316

1317

1318

1319

1320

1321

1322

1323

1324

1325

1326

1327

1330

1332

1333

1336

1337

1339

1340 return recptr;

1341}

#define IS_INJECTION_POINT_ATTACHED(name)

xl_standby_lock * GetRunningTransactionLocks(int *nlocks)

void LWLockRelease(LWLock *lock)

RunningTransactions GetRunningTransactionData(void)

static XLogRecPtr LogCurrentRunningXacts(RunningTransactions CurrRunningXacts)

XLogRecPtr GetInsertRecPtr(void)

#define XLogStandbyInfoActive()

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

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

ResolveRecoveryConflictWithBufferPin()

void ResolveRecoveryConflictWithBufferPin ( void )

Definition at line 793 of file standby.c.

794{

796

798

800

802 {

803

804

805

807 }

808 else

809 {

810

811

812

813

815 int cnt = 0;

816

817 if (ltime != 0)

818 {

821 timeouts[cnt].fin_time = ltime;

822 cnt++;

823 }

824

829 cnt++;

830

832 }

833

834

835

836

837

838

839

840

841

842

844

848 {

849

850

851

852

853

854

855

856

857

858

859

860

861

863 }

864

865

866

867

868

869

870

874}

TimestampTz GetCurrentTimestamp(void)

@ PROCSIG_RECOVERY_CONFLICT_BUFFERPIN

@ PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK

void ProcWaitForSignal(uint32 wait_event_info)

static volatile sig_atomic_t got_standby_deadlock_timeout

static TimestampTz GetStandbyLimitTime(void)

static volatile sig_atomic_t got_standby_delay_timeout

static void SendRecoveryConflictWithBufferPin(ProcSignalReason reason)

void disable_all_timeouts(bool keep_indicators)

void enable_timeouts(const EnableTimeoutParams *timeouts, int count)

@ STANDBY_DEADLOCK_TIMEOUT

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

Referenced by LockBufferForCleanup().

ResolveRecoveryConflictWithDatabase()

void ResolveRecoveryConflictWithDatabase ( Oid dbid )

ResolveRecoveryConflictWithLock()

void ResolveRecoveryConflictWithLock ( LOCKTAG locktag,
bool logging_conflict
)

Definition at line 623 of file standby.c.

624{

627

629

632

633

634

635

636

637

638

639

640

641

642

643

644

645

646

647

648

649

652

653 if (now >= ltime && ltime != 0)

654 {

655

656

657

659

661

662

663

664

665

666

670 false);

671 }

672 else

673 {

674

675

676

677

679 int cnt = 0;

680

681 if (ltime != 0)

682 {

686 timeouts[cnt].fin_time = ltime;

687 cnt++;

688 }

689

694 cnt++;

695

697 }

698

699

701

702

703

704

705

706

709

711 {

713

715

716

719

720

721

722

723

725 {

728 false);

729 backends++;

730 }

731

732

733

734

735

736

737

738 if (logging_conflict)

740

741

742

743

744

745

746

747

750 }

751

753

754

755

756

757

758

759

763}

static void pg_atomic_write_u64(volatile pg_atomic_uint64 *ptr, uint64 val)

static uint64 pg_atomic_read_u64(volatile pg_atomic_uint64 *ptr)

static void cleanup(void)

VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)

#define AccessExclusiveLock

pid_t SignalVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode, bool conflictPending)

@ PROCSIG_RECOVERY_CONFLICT_LOCK

static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, ProcSignalReason reason, uint32 wait_event_info, bool report_waiting)

static volatile sig_atomic_t got_standby_lock_timeout

pg_atomic_uint64 waitStart

References AccessExclusiveLock, Assert(), cleanup(), DeadlockTimeout, EnableTimeoutParams::delay_ms, disable_all_timeouts(), enable_timeouts(), EnableTimeoutParams::fin_time, GetCurrentTimestamp(), GetLockConflicts(), GetStandbyLimitTime(), got_standby_deadlock_timeout, got_standby_lock_timeout, EnableTimeoutParams::id, InHotStandby, LOCKTAG::locktag_type, MyProc, now(), pg_atomic_read_u64(), pg_atomic_write_u64(), PG_WAIT_LOCK, PROCSIG_RECOVERY_CONFLICT_LOCK, PROCSIG_RECOVERY_CONFLICT_STARTUP_DEADLOCK, ProcWaitForSignal(), ResolveRecoveryConflictWithVirtualXIDs(), SignalVirtualTransaction(), STANDBY_DEADLOCK_TIMEOUT, STANDBY_LOCK_TIMEOUT, TMPARAM_AFTER, TMPARAM_AT, EnableTimeoutParams::type, VirtualTransactionIdIsValid, and PGPROC::waitStart.

Referenced by ProcSleep().

ResolveRecoveryConflictWithSnapshot()

Definition at line 468 of file standby.c.

471{

473

474

475

476

477

478

479

480

481

482

483

484

486 return;

487

493 WAIT_EVENT_RECOVERY_CONFLICT_SNAPSHOT,

494 true);

495

496

497

498

499

500

501

504 snapshotConflictHorizon);

505}

VirtualTransactionId * GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)

@ PROCSIG_RECOVERY_CONFLICT_SNAPSHOT

bool InvalidateObsoleteReplicationSlots(uint32 possible_causes, XLogSegNo oldestSegno, Oid dboid, TransactionId snapshotConflictHorizon)

#define TransactionIdIsValid(xid)

#define TransactionIdIsNormal(xid)

References Assert(), RelFileLocator::dbOid, GetConflictingVirtualXIDs(), InvalidateObsoleteReplicationSlots(), PROCSIG_RECOVERY_CONFLICT_SNAPSHOT, ResolveRecoveryConflictWithVirtualXIDs(), RS_INVAL_HORIZON, TransactionIdIsNormal, TransactionIdIsValid, wal_level, and WAL_LEVEL_LOGICAL.

Referenced by btree_xlog_delete(), gistRedoDeleteRecord(), hash_xlog_vacuum_one_page(), heap_xlog_prune_freeze(), heap_xlog_visible(), ResolveRecoveryConflictWithSnapshotFullXid(), and spgRedoVacuumRedirect().

ResolveRecoveryConflictWithSnapshotFullXid()

ResolveRecoveryConflictWithTablespace()

void ResolveRecoveryConflictWithTablespace ( Oid tsid )

ShutdownRecoveryTransactionEnvironment()

void ShutdownRecoveryTransactionEnvironment ( void )

StandbyAcquireAccessExclusiveLock()

Definition at line 986 of file standby.c.

987{

992 bool found;

993

994

998 return;

999

1000 elog(DEBUG4, "adding recovery lock: db %u rel %u", dbOid, relOid);

1001

1002

1004

1005

1007 if (!found)

1008 {

1009 Assert(xidentry->xid == xid);

1010 xidentry->head = NULL;

1011 }

1012

1013

1014 key.xid = xid;

1015 key.dbOid = dbOid;

1016 key.relOid = relOid;

1018 if (!found)

1019 {

1020

1021 lockentry->next = xidentry->head;

1022 xidentry->head = lockentry;

1023

1024

1026

1028 }

1029}

#define OidIsValid(objectId)

void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)

LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)

#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)

struct RecoveryLockEntry * next

struct RecoveryLockEntry * head

bool TransactionIdDidCommit(TransactionId transactionId)

bool TransactionIdDidAbort(TransactionId transactionId)

References AccessExclusiveLock, Assert(), DEBUG4, elog, HASH_ENTER, hash_search(), RecoveryLockXidEntry::head, sort-test::key, LockAcquire(), RecoveryLockEntry::next, OidIsValid, RecoveryLockHash, RecoveryLockXidHash, SET_LOCKTAG_RELATION, TransactionIdDidAbort(), TransactionIdDidCommit(), TransactionIdIsValid, and RecoveryLockXidEntry::xid.

Referenced by lock_twophase_standby_recover(), and standby_redo().

StandbyDeadLockHandler()

void StandbyDeadLockHandler ( void )

StandbyLockTimeoutHandler()

void StandbyLockTimeoutHandler ( void )

StandbyReleaseAllLocks()

void StandbyReleaseAllLocks ( void )

Definition at line 1106 of file standby.c.

1107{

1110

1111 elog(DEBUG2, "release all standby locks");

1112

1115 {

1118 }

1119}

void * hash_seq_search(HASH_SEQ_STATUS *status)

void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)

static void StandbyReleaseXidEntryLocks(RecoveryLockXidEntry *xidentry)

References DEBUG2, elog, HASH_REMOVE, hash_search(), hash_seq_init(), hash_seq_search(), RecoveryLockXidHash, and StandbyReleaseXidEntryLocks().

Referenced by ShutdownRecoveryTransactionEnvironment(), and StandbyReleaseLocks().

StandbyReleaseLockTree()

StandbyReleaseOldLocks()

Definition at line 1130 of file standby.c.

1131{

1134

1137 {

1139

1140

1142 continue;

1143

1144

1146 continue;

1147

1148

1151 }

1152}

bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)

bool StandbyTransactionIdIsPrepared(TransactionId xid)

References Assert(), HASH_REMOVE, hash_search(), hash_seq_init(), hash_seq_search(), RecoveryLockXidHash, StandbyReleaseXidEntryLocks(), StandbyTransactionIdIsPrepared(), TransactionIdIsValid, TransactionIdPrecedes(), and RecoveryLockXidEntry::xid.

Referenced by ProcArrayApplyRecoveryInfo().

StandbyTimeoutHandler()

void StandbyTimeoutHandler ( void )

log_recovery_conflict_waits

max_standby_archive_delay

max_standby_streaming_delay