PostgreSQL Source Code  git master
standby.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * standby.c
4  * Misc functions used in Hot Standby mode.
5  *
6  * All functions for handling RM_STANDBY_ID, which relate to
7  * AccessExclusiveLocks and starting snapshots for Hot Standby mode.
8  * Plus conflict recovery processing.
9  *
10  * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group
11  * Portions Copyright (c) 1994, Regents of the University of California
12  *
13  * IDENTIFICATION
14  * src/backend/storage/ipc/standby.c
15  *
16  *-------------------------------------------------------------------------
17  */
18 #include "postgres.h"
19 #include "access/transam.h"
20 #include "access/twophase.h"
21 #include "access/xact.h"
22 #include "access/xlog.h"
23 #include "access/xloginsert.h"
24 #include "miscadmin.h"
25 #include "pgstat.h"
26 #include "storage/bufmgr.h"
27 #include "storage/lmgr.h"
28 #include "storage/proc.h"
29 #include "storage/procarray.h"
30 #include "storage/sinvaladt.h"
31 #include "storage/standby.h"
32 #include "utils/hsearch.h"
33 #include "utils/memutils.h"
34 #include "utils/ps_status.h"
35 #include "utils/timeout.h"
36 #include "utils/timestamp.h"
37 
38 /* User-settable GUC parameters */
40 int max_standby_archive_delay = 30 * 1000;
43 
45 
46 /* Flags set by timeout handlers */
47 static volatile sig_atomic_t got_standby_deadlock_timeout = false;
48 static volatile sig_atomic_t got_standby_lock_timeout = false;
49 
51  ProcSignalReason reason,
52  uint32 wait_event_info,
53  bool report_waiting);
56 static void LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks);
57 static const char *get_recovery_conflict_desc(ProcSignalReason reason);
58 
59 /*
60  * Keep track of all the locks owned by a given transaction.
61  */
62 typedef struct RecoveryLockListsEntry
63 {
67 
68 /*
69  * InitRecoveryTransactionEnvironment
70  * Initialize tracking of our primary's in-progress transactions.
71  *
72  * We need to issue shared invalidations and hold locks. Holding locks
73  * means others may want to wait on us, so we need to make a lock table
74  * vxact entry like a real transaction. We could create and delete
75  * lock table entries for each transaction but its simpler just to create
76  * one permanent entry and leave it there all the time. Locks are then
77  * acquired and released as needed. Yes, this means you can see the
78  * Startup process in pg_locks once we have run this.
79  */
80 void
82 {
84  HASHCTL hash_ctl;
85 
86  /*
87  * Initialize the hash table for tracking the list of locks held by each
88  * transaction.
89  */
90  hash_ctl.keysize = sizeof(TransactionId);
91  hash_ctl.entrysize = sizeof(RecoveryLockListsEntry);
92  RecoveryLockLists = hash_create("RecoveryLockLists",
93  64,
94  &hash_ctl,
96 
97  /*
98  * Initialize shared invalidation management for Startup process, being
99  * careful to register ourselves as a sendOnly process so we don't need to
100  * read messages, nor will we get signaled when the queue starts filling
101  * up.
102  */
104 
105  /*
106  * Lock a virtual transaction id for Startup process.
107  *
108  * We need to do GetNextLocalTransactionId() because
109  * SharedInvalBackendInit() leaves localTransactionId invalid and the lock
110  * manager doesn't like that at all.
111  *
112  * Note that we don't need to run XactLockTableInsert() because nobody
113  * needs to wait on xids. That sounds a little strange, but table locks
114  * are held by vxids and row level locks are held by xids. All queries
115  * hold AccessShareLocks so never block while we write or lock new rows.
116  */
117  vxid.backendId = MyBackendId;
120 
122 }
123 
124 /*
125  * ShutdownRecoveryTransactionEnvironment
126  * Shut down transaction tracking
127  *
128  * Prepare to switch from hot standby mode to normal operation. Shut down
129  * recovery-time transaction tracking.
130  */
131 void
133 {
134  /* Mark all tracked in-progress transactions as finished. */
136 
137  /* Release all locks the tracked transactions were holding */
139 
140  /* Destroy the hash table of locks. */
141  hash_destroy(RecoveryLockLists);
142  RecoveryLockLists = NULL;
143 
144  /* Cleanup our VirtualTransaction */
146 }
147 
148 
149 /*
150  * -----------------------------------------------------
151  * Standby wait timers and backend cancel logic
152  * -----------------------------------------------------
153  */
154 
155 /*
156  * Determine the cutoff time at which we want to start canceling conflicting
157  * transactions. Returns zero (a time safely in the past) if we are willing
158  * to wait forever.
159  */
160 static TimestampTz
162 {
163  TimestampTz rtime;
164  bool fromStream;
165 
166  /*
167  * The cutoff time is the last WAL data receipt time plus the appropriate
168  * delay variable. Delay of -1 means wait forever.
169  */
170  GetXLogReceiptTime(&rtime, &fromStream);
171  if (fromStream)
172  {
174  return 0; /* wait forever */
176  }
177  else
178  {
180  return 0; /* wait forever */
182  }
183 }
184 
185 #define STANDBY_INITIAL_WAIT_US 1000
187 
188 /*
189  * Standby wait logic for ResolveRecoveryConflictWithVirtualXIDs.
190  * We wait here for a while then return. If we decide we can't wait any
191  * more then we return true, if we can wait some more return false.
192  */
193 static bool
195 {
196  TimestampTz ltime;
197 
199 
200  /* Are we past the limit time? */
201  ltime = GetStandbyLimitTime();
202  if (ltime && GetCurrentTimestamp() >= ltime)
203  return true;
204 
205  /*
206  * Sleep a bit (this is essential to avoid busy-waiting).
207  */
208  pgstat_report_wait_start(wait_event_info);
211 
212  /*
213  * Progressively increase the sleep times, but not to more than 1s, since
214  * pg_usleep isn't interruptible on some platforms.
215  */
216  standbyWait_us *= 2;
217  if (standbyWait_us > 1000000)
218  standbyWait_us = 1000000;
219 
220  return false;
221 }
222 
223 /*
224  * Log the recovery conflict.
225  *
226  * wait_start is the timestamp when the caller started to wait.
227  * now is the timestamp when this function has been called.
228  * wait_list is the list of virtual transaction ids assigned to
229  * conflicting processes. still_waiting indicates whether
230  * the startup process is still waiting for the recovery conflict
231  * to be resolved or not.
232  */
233 void
236  bool still_waiting)
237 {
238  long secs;
239  int usecs;
240  long msecs;
242  int nprocs = 0;
243 
244  /*
245  * There must be no conflicting processes when the recovery conflict has
246  * already been resolved.
247  */
248  Assert(still_waiting || wait_list == NULL);
249 
250  TimestampDifference(wait_start, now, &secs, &usecs);
251  msecs = secs * 1000 + usecs / 1000;
252  usecs = usecs % 1000;
253 
254  if (wait_list)
255  {
256  VirtualTransactionId *vxids;
257 
258  /* Construct a string of list of the conflicting processes */
259  vxids = wait_list;
260  while (VirtualTransactionIdIsValid(*vxids))
261  {
262  PGPROC *proc = BackendIdGetProc(vxids->backendId);
263 
264  /* proc can be NULL if the target backend is not active */
265  if (proc)
266  {
267  if (nprocs == 0)
268  {
269  initStringInfo(&buf);
270  appendStringInfo(&buf, "%d", proc->pid);
271  }
272  else
273  appendStringInfo(&buf, ", %d", proc->pid);
274 
275  nprocs++;
276  }
277 
278  vxids++;
279  }
280  }
281 
282  /*
283  * If wait_list is specified, report the list of PIDs of active
284  * conflicting backends in a detail message. Note that if all the backends
285  * in the list are not active, no detail message is logged.
286  */
287  if (still_waiting)
288  {
289  ereport(LOG,
290  errmsg("recovery still waiting after %ld.%03d ms: %s",
291  msecs, usecs, _(get_recovery_conflict_desc(reason))),
292  nprocs > 0 ? errdetail_log_plural("Conflicting process: %s.",
293  "Conflicting processes: %s.",
294  nprocs, buf.data) : 0);
295  }
296  else
297  {
298  ereport(LOG,
299  errmsg("recovery finished waiting after %ld.%03d ms: %s",
300  msecs, usecs, _(get_recovery_conflict_desc(reason))));
301  }
302 
303  if (nprocs > 0)
304  pfree(buf.data);
305 }
306 
307 /*
308  * This is the main executioner for any query backend that conflicts with
309  * recovery processing. Judgement has already been passed on it within
310  * a specific rmgr. Here we just issue the orders to the procs. The procs
311  * then throw the required error as instructed.
312  *
313  * If report_waiting is true, "waiting" is reported in PS display and the
314  * wait for recovery conflict is reported in the log, if necessary. If
315  * the caller is responsible for reporting them, report_waiting should be
316  * false. Otherwise, both the caller and this function report the same
317  * thing unexpectedly.
318  */
319 static void
321  ProcSignalReason reason, uint32 wait_event_info,
322  bool report_waiting)
323 {
324  TimestampTz waitStart = 0;
325  char *new_status = NULL;
326  bool logged_recovery_conflict = false;
327 
328  /* Fast exit, to avoid a kernel call if there's no work to be done. */
329  if (!VirtualTransactionIdIsValid(*waitlist))
330  return;
331 
332  /* Set the wait start timestamp for reporting */
333  if (report_waiting && (log_recovery_conflict_waits || update_process_title))
334  waitStart = GetCurrentTimestamp();
335 
336  while (VirtualTransactionIdIsValid(*waitlist))
337  {
338  /* reset standbyWait_us for each xact we wait for */
340 
341  /* wait until the virtual xid is gone */
342  while (!VirtualXactLock(*waitlist, false))
343  {
344  /* Is it time to kill it? */
345  if (WaitExceedsMaxStandbyDelay(wait_event_info))
346  {
347  pid_t pid;
348 
349  /*
350  * Now find out who to throw out of the balloon.
351  */
353  pid = CancelVirtualTransaction(*waitlist, reason);
354 
355  /*
356  * Wait a little bit for it to die so that we avoid flooding
357  * an unresponsive backend when system is heavily loaded.
358  */
359  if (pid != 0)
360  pg_usleep(5000L);
361  }
362 
363  if (waitStart != 0 && (!logged_recovery_conflict || new_status == NULL))
364  {
365  TimestampTz now = 0;
366  bool maybe_log_conflict;
367  bool maybe_update_title;
368 
369  maybe_log_conflict = (log_recovery_conflict_waits && !logged_recovery_conflict);
370  maybe_update_title = (update_process_title && new_status == NULL);
371 
372  /* Get the current timestamp if not report yet */
373  if (maybe_log_conflict || maybe_update_title)
374  now = GetCurrentTimestamp();
375 
376  /*
377  * Report via ps if we have been waiting for more than 500
378  * msec (should that be configurable?)
379  */
380  if (maybe_update_title &&
381  TimestampDifferenceExceeds(waitStart, now, 500))
382  {
383  const char *old_status;
384  int len;
385 
386  old_status = get_ps_display(&len);
387  new_status = (char *) palloc(len + 8 + 1);
388  memcpy(new_status, old_status, len);
389  strcpy(new_status + len, " waiting");
390  set_ps_display(new_status);
391  new_status[len] = '\0'; /* truncate off " waiting" */
392  }
393 
394  /*
395  * Emit the log message if the startup process is waiting
396  * longer than deadlock_timeout for recovery conflict.
397  */
398  if (maybe_log_conflict &&
400  {
401  LogRecoveryConflict(reason, waitStart, now, waitlist, true);
402  logged_recovery_conflict = true;
403  }
404  }
405  }
406 
407  /* The virtual transaction is gone now, wait for the next one */
408  waitlist++;
409  }
410 
411  /*
412  * Emit the log message if recovery conflict was resolved but the startup
413  * process waited longer than deadlock_timeout for it.
414  */
415  if (logged_recovery_conflict)
416  LogRecoveryConflict(reason, waitStart, GetCurrentTimestamp(),
417  NULL, false);
418 
419  /* Reset ps display if we changed it */
420  if (new_status)
421  {
422  set_ps_display(new_status);
423  pfree(new_status);
424  }
425 }
426 
427 void
429 {
430  VirtualTransactionId *backends;
431 
432  /*
433  * If we get passed InvalidTransactionId then we do nothing (no conflict).
434  *
435  * This can happen when replaying already-applied WAL records after a
436  * standby crash or restart, or when replaying an XLOG_HEAP2_VISIBLE
437  * record that marks as frozen a page which was already all-visible. It's
438  * also quite common with records generated during index deletion
439  * (original execution of the deletion can reason that a recovery conflict
440  * which is sufficient for the deletion operation must take place before
441  * replay of the deletion record itself).
442  */
443  if (!TransactionIdIsValid(latestRemovedXid))
444  return;
445 
446  backends = GetConflictingVirtualXIDs(latestRemovedXid,
447  node.dbNode);
448 
452  true);
453 }
454 
455 void
457 {
458  VirtualTransactionId *temp_file_users;
459 
460  /*
461  * Standby users may be currently using this tablespace for their
462  * temporary files. We only care about current users because
463  * temp_tablespace parameter will just ignore tablespaces that no longer
464  * exist.
465  *
466  * Ask everybody to cancel their queries immediately so we can ensure no
467  * temp files remain and we can remove the tablespace. Nuke the entire
468  * site from orbit, it's the only way to be sure.
469  *
470  * XXX: We could work out the pids of active backends using this
471  * tablespace by examining the temp filenames in the directory. We would
472  * then convert the pids into VirtualXIDs before attempting to cancel
473  * them.
474  *
475  * We don't wait for commit because drop tablespace is non-transactional.
476  */
478  InvalidOid);
482  true);
483 }
484 
485 void
487 {
488  /*
489  * We don't do ResolveRecoveryConflictWithVirtualXIDs() here since that
490  * only waits for transactions and completely idle sessions would block
491  * us. This is rare enough that we do this as simply as possible: no wait,
492  * just force them off immediately.
493  *
494  * No locking is required here because we already acquired
495  * AccessExclusiveLock. Anybody trying to connect while we do this will
496  * block during InitPostgres() and then disconnect when they see the
497  * database has been removed.
498  */
499  while (CountDBBackends(dbid) > 0)
500  {
502 
503  /*
504  * Wait awhile for them to die so that we avoid flooding an
505  * unresponsive backend when system is heavily loaded.
506  */
507  pg_usleep(10000);
508  }
509 }
510 
511 /*
512  * ResolveRecoveryConflictWithLock is called from ProcSleep()
513  * to resolve conflicts with other backends holding relation locks.
514  *
515  * The WaitLatch sleep normally done in ProcSleep()
516  * (when not InHotStandby) is performed here, for code clarity.
517  *
518  * We either resolve conflicts immediately or set a timeout to wake us at
519  * the limit of our patience.
520  *
521  * Resolve conflicts by canceling to all backends holding a conflicting
522  * lock. As we are already queued to be granted the lock, no new lock
523  * requests conflicting with ours will be granted in the meantime.
524  *
525  * We also must check for deadlocks involving the Startup process and
526  * hot-standby backend processes. If deadlock_timeout is reached in
527  * this function, all the backends holding the conflicting locks are
528  * requested to check themselves for deadlocks.
529  *
530  * logging_conflict should be true if the recovery conflict has not been
531  * logged yet even though logging is enabled. After deadlock_timeout is
532  * reached and the request for deadlock check is sent, we wait again to
533  * be signaled by the release of the lock if logging_conflict is false.
534  * Otherwise we return without waiting again so that the caller can report
535  * the recovery conflict. In this case, then, this function is called again
536  * with logging_conflict=false (because the recovery conflict has already
537  * been logged) and we will wait again for the lock to be released.
538  */
539 void
540 ResolveRecoveryConflictWithLock(LOCKTAG locktag, bool logging_conflict)
541 {
542  TimestampTz ltime;
543 
545 
546  ltime = GetStandbyLimitTime();
547 
548  if (GetCurrentTimestamp() >= ltime && ltime != 0)
549  {
550  /*
551  * We're already behind, so clear a path as quickly as possible.
552  */
553  VirtualTransactionId *backends;
554 
555  backends = GetLockConflicts(&locktag, AccessExclusiveLock, NULL);
556 
557  /*
558  * Prevent ResolveRecoveryConflictWithVirtualXIDs() from reporting
559  * "waiting" in PS display by disabling its argument report_waiting
560  * because the caller, WaitOnLock(), has already reported that.
561  */
564  PG_WAIT_LOCK | locktag.locktag_type,
565  false);
566  }
567  else
568  {
569  /*
570  * Wait (or wait again) until ltime, and check for deadlocks as well
571  * if we will be waiting longer than deadlock_timeout
572  */
573  EnableTimeoutParams timeouts[2];
574  int cnt = 0;
575 
576  if (ltime != 0)
577  {
578  got_standby_lock_timeout = false;
579  timeouts[cnt].id = STANDBY_LOCK_TIMEOUT;
580  timeouts[cnt].type = TMPARAM_AT;
581  timeouts[cnt].fin_time = ltime;
582  cnt++;
583  }
584 
586  timeouts[cnt].id = STANDBY_DEADLOCK_TIMEOUT;
587  timeouts[cnt].type = TMPARAM_AFTER;
588  timeouts[cnt].delay_ms = DeadlockTimeout;
589  cnt++;
590 
591  enable_timeouts(timeouts, cnt);
592  }
593 
594  /* Wait to be signaled by the release of the Relation Lock */
596 
597  /*
598  * Exit if ltime is reached. Then all the backends holding conflicting
599  * locks will be canceled in the next ResolveRecoveryConflictWithLock()
600  * call.
601  */
603  goto cleanup;
604 
606  {
607  VirtualTransactionId *backends;
608 
609  backends = GetLockConflicts(&locktag, AccessExclusiveLock, NULL);
610 
611  /* Quick exit if there's no work to be done */
612  if (!VirtualTransactionIdIsValid(*backends))
613  goto cleanup;
614 
615  /*
616  * Send signals to all the backends holding the conflicting locks, to
617  * ask them to check themselves for deadlocks.
618  */
619  while (VirtualTransactionIdIsValid(*backends))
620  {
621  SignalVirtualTransaction(*backends,
623  false);
624  backends++;
625  }
626 
627  /*
628  * Exit if the recovery conflict has not been logged yet even though
629  * logging is enabled, so that the caller can log that. Then
630  * RecoveryConflictWithLock() is called again and we will wait again
631  * for the lock to be released.
632  */
633  if (logging_conflict)
634  goto cleanup;
635 
636  /*
637  * Wait again here to be signaled by the release of the Relation Lock,
638  * to prevent the subsequent RecoveryConflictWithLock() from causing
639  * deadlock_timeout and sending a request for deadlocks check again.
640  * Otherwise the request continues to be sent every deadlock_timeout
641  * until the relation locks are released or ltime is reached.
642  */
645  }
646 
647 cleanup:
648 
649  /*
650  * Clear any timeout requests established above. We assume here that the
651  * Startup process doesn't have any other outstanding timeouts than those
652  * used by this function. If that stops being true, we could cancel the
653  * timeouts individually, but that'd be slower.
654  */
655  disable_all_timeouts(false);
656  got_standby_lock_timeout = false;
658 }
659 
660 /*
661  * ResolveRecoveryConflictWithBufferPin is called from LockBufferForCleanup()
662  * to resolve conflicts with other backends holding buffer pins.
663  *
664  * The ProcWaitForSignal() sleep normally done in LockBufferForCleanup()
665  * (when not InHotStandby) is performed here, for code clarity.
666  *
667  * We either resolve conflicts immediately or set a timeout to wake us at
668  * the limit of our patience.
669  *
670  * Resolve conflicts by sending a PROCSIG signal to all backends to check if
671  * they hold one of the buffer pins that is blocking Startup process. If so,
672  * those backends will take an appropriate error action, ERROR or FATAL.
673  *
674  * We also must check for deadlocks. Deadlocks occur because if queries
675  * wait on a lock, that must be behind an AccessExclusiveLock, which can only
676  * be cleared if the Startup process replays a transaction completion record.
677  * If Startup process is also waiting then that is a deadlock. The deadlock
678  * can occur if the query is waiting and then the Startup sleeps, or if
679  * Startup is sleeping and the query waits on a lock. We protect against
680  * only the former sequence here, the latter sequence is checked prior to
681  * the query sleeping, in CheckRecoveryConflictDeadlock().
682  *
683  * Deadlocks are extremely rare, and relatively expensive to check for,
684  * so we don't do a deadlock check right away ... only if we have had to wait
685  * at least deadlock_timeout.
686  */
687 void
689 {
690  TimestampTz ltime;
691 
693 
694  ltime = GetStandbyLimitTime();
695 
696  if (GetCurrentTimestamp() >= ltime && ltime != 0)
697  {
698  /*
699  * We're already behind, so clear a path as quickly as possible.
700  */
702  }
703  else
704  {
705  /*
706  * Wake up at ltime, and check for deadlocks as well if we will be
707  * waiting longer than deadlock_timeout
708  */
709  EnableTimeoutParams timeouts[2];
710  int cnt = 0;
711 
712  if (ltime != 0)
713  {
714  timeouts[cnt].id = STANDBY_TIMEOUT;
715  timeouts[cnt].type = TMPARAM_AT;
716  timeouts[cnt].fin_time = ltime;
717  cnt++;
718  }
719 
721  timeouts[cnt].id = STANDBY_DEADLOCK_TIMEOUT;
722  timeouts[cnt].type = TMPARAM_AFTER;
723  timeouts[cnt].delay_ms = DeadlockTimeout;
724  cnt++;
725 
726  enable_timeouts(timeouts, cnt);
727  }
728 
729  /*
730  * Wait to be signaled by UnpinBuffer().
731  *
732  * We assume that only UnpinBuffer() and the timeout requests established
733  * above can wake us up here. WakeupRecovery() called by walreceiver or
734  * SIGHUP signal handler, etc cannot do that because it uses the different
735  * latch from that ProcWaitForSignal() waits on.
736  */
738 
740  {
741  /*
742  * Send out a request for hot-standby backends to check themselves for
743  * deadlocks.
744  *
745  * XXX The subsequent ResolveRecoveryConflictWithBufferPin() will wait
746  * to be signaled by UnpinBuffer() again and send a request for
747  * deadlocks check if deadlock_timeout happens. This causes the
748  * request to continue to be sent every deadlock_timeout until the
749  * buffer is unpinned or ltime is reached. This would increase the
750  * workload in the startup process and backends. In practice it may
751  * not be so harmful because the period that the buffer is kept pinned
752  * is basically no so long. But we should fix this?
753  */
756  }
757 
758  /*
759  * Clear any timeout requests established above. We assume here that the
760  * Startup process doesn't have any other timeouts than what this function
761  * uses. If that stops being true, we could cancel the timeouts
762  * individually, but that'd be slower.
763  */
764  disable_all_timeouts(false);
766 }
767 
768 static void
770 {
773 
774  /*
775  * We send signal to all backends to ask them if they are holding the
776  * buffer pin which is delaying the Startup process. We must not set the
777  * conflict flag yet, since most backends will be innocent. Let the
778  * SIGUSR1 handling in each backend decide their own fate.
779  */
780  CancelDBBackends(InvalidOid, reason, false);
781 }
782 
783 /*
784  * In Hot Standby perform early deadlock detection. We abort the lock
785  * wait if we are about to sleep while holding the buffer pin that Startup
786  * process is waiting for.
787  *
788  * Note: this code is pessimistic, because there is no way for it to
789  * determine whether an actual deadlock condition is present: the lock we
790  * need to wait for might be unrelated to any held by the Startup process.
791  * Sooner or later, this mechanism should get ripped out in favor of somehow
792  * accounting for buffer locks in DeadLockCheck(). However, errors here
793  * seem to be very low-probability in practice, so for now it's not worth
794  * the trouble.
795  */
796 void
798 {
799  Assert(!InRecovery); /* do not call in Startup process */
800 
802  return;
803 
804  /*
805  * Error message should match ProcessInterrupts() but we avoid calling
806  * that because we aren't handling an interrupt at this point. Note that
807  * we only cancel the current transaction here, so if we are in a
808  * subtransaction and the pin is held by a parent, then the Startup
809  * process will continue to wait even though we have avoided deadlock.
810  */
811  ereport(ERROR,
812  (errcode(ERRCODE_T_R_DEADLOCK_DETECTED),
813  errmsg("canceling statement due to conflict with recovery"),
814  errdetail("User transaction caused buffer deadlock with recovery.")));
815 }
816 
817 
818 /* --------------------------------
819  * timeout handler routines
820  * --------------------------------
821  */
822 
823 /*
824  * StandbyDeadLockHandler() will be called if STANDBY_DEADLOCK_TIMEOUT
825  * occurs before STANDBY_TIMEOUT.
826  */
827 void
829 {
831 }
832 
833 /*
834  * StandbyTimeoutHandler() will be called if STANDBY_TIMEOUT is exceeded.
835  * Send out a request to release conflicting buffer pins unconditionally,
836  * so we can press ahead with applying changes in recovery.
837  */
838 void
840 {
841  /* forget any pending STANDBY_DEADLOCK_TIMEOUT request */
843 
845 }
846 
847 /*
848  * StandbyLockTimeoutHandler() will be called if STANDBY_LOCK_TIMEOUT is exceeded.
849  */
850 void
852 {
854 }
855 
856 /*
857  * -----------------------------------------------------
858  * Locking in Recovery Mode
859  * -----------------------------------------------------
860  *
861  * All locks are held by the Startup process using a single virtual
862  * transaction. This implementation is both simpler and in some senses,
863  * more correct. The locks held mean "some original transaction held
864  * this lock, so query access is not allowed at this time". So the Startup
865  * process is the proxy by which the original locks are implemented.
866  *
867  * We only keep track of AccessExclusiveLocks, which are only ever held by
868  * one transaction on one relation.
869  *
870  * We keep a hash table of lists of locks in local memory keyed by xid,
871  * RecoveryLockLists, so we can keep track of the various entries made by
872  * the Startup process's virtual xid in the shared lock table.
873  *
874  * List elements use type xl_standby_lock, since the WAL record type exactly
875  * matches the information that we need to keep track of.
876  *
877  * We use session locks rather than normal locks so we don't need
878  * ResourceOwners.
879  */
880 
881 
882 void
884 {
885  RecoveryLockListsEntry *entry;
886  xl_standby_lock *newlock;
887  LOCKTAG locktag;
888  bool found;
889 
890  /* Already processed? */
891  if (!TransactionIdIsValid(xid) ||
892  TransactionIdDidCommit(xid) ||
894  return;
895 
897  "adding recovery lock: db %u rel %u", dbOid, relOid);
898 
899  /* dbOid is InvalidOid when we are locking a shared relation. */
900  Assert(OidIsValid(relOid));
901 
902  /* Create a new list for this xid, if we don't have one already. */
903  entry = hash_search(RecoveryLockLists, &xid, HASH_ENTER, &found);
904  if (!found)
905  {
906  entry->xid = xid;
907  entry->locks = NIL;
908  }
909 
910  newlock = palloc(sizeof(xl_standby_lock));
911  newlock->xid = xid;
912  newlock->dbOid = dbOid;
913  newlock->relOid = relOid;
914  entry->locks = lappend(entry->locks, newlock);
915 
916  SET_LOCKTAG_RELATION(locktag, newlock->dbOid, newlock->relOid);
917 
918  (void) LockAcquire(&locktag, AccessExclusiveLock, true, false);
919 }
920 
921 static void
923 {
924  while (locks)
925  {
926  xl_standby_lock *lock = (xl_standby_lock *) linitial(locks);
927  LOCKTAG locktag;
928 
930  "releasing recovery lock: xid %u db %u rel %u",
931  lock->xid, lock->dbOid, lock->relOid);
932  SET_LOCKTAG_RELATION(locktag, lock->dbOid, lock->relOid);
933  if (!LockRelease(&locktag, AccessExclusiveLock, true))
934  {
935  elog(LOG,
936  "RecoveryLockLists contains entry for lock no longer recorded by lock manager: xid %u database %u relation %u",
937  lock->xid, lock->dbOid, lock->relOid);
938  Assert(false);
939  }
940  pfree(lock);
941  locks = list_delete_first(locks);
942  }
943 }
944 
945 static void
947 {
948  RecoveryLockListsEntry *entry;
949 
950  if (TransactionIdIsValid(xid))
951  {
952  if ((entry = hash_search(RecoveryLockLists, &xid, HASH_FIND, NULL)))
953  {
955  hash_search(RecoveryLockLists, entry, HASH_REMOVE, NULL);
956  }
957  }
958  else
960 }
961 
962 /*
963  * Release locks for a transaction tree, starting at xid down, from
964  * RecoveryLockLists.
965  *
966  * Called during WAL replay of COMMIT/ROLLBACK when in hot standby mode,
967  * to remove any AccessExclusiveLocks requested by a transaction.
968  */
969 void
971 {
972  int i;
973 
974  StandbyReleaseLocks(xid);
975 
976  for (i = 0; i < nsubxids; i++)
977  StandbyReleaseLocks(subxids[i]);
978 }
979 
980 /*
981  * Called at end of recovery and when we see a shutdown checkpoint.
982  */
983 void
985 {
987  RecoveryLockListsEntry *entry;
988 
989  elog(trace_recovery(DEBUG2), "release all standby locks");
990 
991  hash_seq_init(&status, RecoveryLockLists);
992  while ((entry = hash_seq_search(&status)))
993  {
995  hash_search(RecoveryLockLists, entry, HASH_REMOVE, NULL);
996  }
997 }
998 
999 /*
1000  * StandbyReleaseOldLocks
1001  * Release standby locks held by top-level XIDs that aren't running,
1002  * as long as they're not prepared transactions.
1003  */
1004 void
1006 {
1008  RecoveryLockListsEntry *entry;
1009 
1010  hash_seq_init(&status, RecoveryLockLists);
1011  while ((entry = hash_seq_search(&status)))
1012  {
1013  Assert(TransactionIdIsValid(entry->xid));
1014 
1015  /* Skip if prepared transaction. */
1016  if (StandbyTransactionIdIsPrepared(entry->xid))
1017  continue;
1018 
1019  /* Skip if >= oldxid. */
1020  if (!TransactionIdPrecedes(entry->xid, oldxid))
1021  continue;
1022 
1023  /* Remove all locks and hash table entry. */
1024  StandbyReleaseLockList(entry->locks);
1025  hash_search(RecoveryLockLists, entry, HASH_REMOVE, NULL);
1026  }
1027 }
1028 
1029 /*
1030  * --------------------------------------------------------------------
1031  * Recovery handling for Rmgr RM_STANDBY_ID
1032  *
1033  * These record types will only be created if XLogStandbyInfoActive()
1034  * --------------------------------------------------------------------
1035  */
1036 
1037 void
1039 {
1040  uint8 info = XLogRecGetInfo(record) & ~XLR_INFO_MASK;
1041 
1042  /* Backup blocks are not used in standby records */
1043  Assert(!XLogRecHasAnyBlockRefs(record));
1044 
1045  /* Do nothing if we're not in hot standby mode */
1047  return;
1048 
1049  if (info == XLOG_STANDBY_LOCK)
1050  {
1051  xl_standby_locks *xlrec = (xl_standby_locks *) XLogRecGetData(record);
1052  int i;
1053 
1054  for (i = 0; i < xlrec->nlocks; i++)
1056  xlrec->locks[i].dbOid,
1057  xlrec->locks[i].relOid);
1058  }
1059  else if (info == XLOG_RUNNING_XACTS)
1060  {
1061  xl_running_xacts *xlrec = (xl_running_xacts *) XLogRecGetData(record);
1062  RunningTransactionsData running;
1063 
1064  running.xcnt = xlrec->xcnt;
1065  running.subxcnt = xlrec->subxcnt;
1066  running.subxid_overflow = xlrec->subxid_overflow;
1067  running.nextXid = xlrec->nextXid;
1068  running.latestCompletedXid = xlrec->latestCompletedXid;
1069  running.oldestRunningXid = xlrec->oldestRunningXid;
1070  running.xids = xlrec->xids;
1071 
1072  ProcArrayApplyRecoveryInfo(&running);
1073  }
1074  else if (info == XLOG_INVALIDATIONS)
1075  {
1076  xl_invalidations *xlrec = (xl_invalidations *) XLogRecGetData(record);
1077 
1079  xlrec->nmsgs,
1080  xlrec->relcacheInitFileInval,
1081  xlrec->dbId,
1082  xlrec->tsId);
1083  }
1084  else
1085  elog(PANIC, "standby_redo: unknown op code %u", info);
1086 }
1087 
1088 /*
1089  * Log details of the current snapshot to WAL. This allows the snapshot state
1090  * to be reconstructed on the standby and for logical decoding.
1091  *
1092  * This is used for Hot Standby as follows:
1093  *
1094  * We can move directly to STANDBY_SNAPSHOT_READY at startup if we
1095  * start from a shutdown checkpoint because we know nothing was running
1096  * at that time and our recovery snapshot is known empty. In the more
1097  * typical case of an online checkpoint we need to jump through a few
1098  * hoops to get a correct recovery snapshot and this requires a two or
1099  * sometimes a three stage process.
1100  *
1101  * The initial snapshot must contain all running xids and all current
1102  * AccessExclusiveLocks at a point in time on the standby. Assembling
1103  * that information while the server is running requires many and
1104  * various LWLocks, so we choose to derive that information piece by
1105  * piece and then re-assemble that info on the standby. When that
1106  * information is fully assembled we move to STANDBY_SNAPSHOT_READY.
1107  *
1108  * Since locking on the primary when we derive the information is not
1109  * strict, we note that there is a time window between the derivation and
1110  * writing to WAL of the derived information. That allows race conditions
1111  * that we must resolve, since xids and locks may enter or leave the
1112  * snapshot during that window. This creates the issue that an xid or
1113  * lock may start *after* the snapshot has been derived yet *before* the
1114  * snapshot is logged in the running xacts WAL record. We resolve this by
1115  * starting to accumulate changes at a point just prior to when we derive
1116  * the snapshot on the primary, then ignore duplicates when we later apply
1117  * the snapshot from the running xacts record. This is implemented during
1118  * CreateCheckpoint() where we use the logical checkpoint location as
1119  * our starting point and then write the running xacts record immediately
1120  * before writing the main checkpoint WAL record. Since we always start
1121  * up from a checkpoint and are immediately at our starting point, we
1122  * unconditionally move to STANDBY_INITIALIZED. After this point we
1123  * must do 4 things:
1124  * * move shared nextXid forwards as we see new xids
1125  * * extend the clog and subtrans with each new xid
1126  * * keep track of uncommitted known assigned xids
1127  * * keep track of uncommitted AccessExclusiveLocks
1128  *
1129  * When we see a commit/abort we must remove known assigned xids and locks
1130  * from the completing transaction. Attempted removals that cannot locate
1131  * an entry are expected and must not cause an error when we are in state
1132  * STANDBY_INITIALIZED. This is implemented in StandbyReleaseLocks() and
1133  * KnownAssignedXidsRemove().
1134  *
1135  * Later, when we apply the running xact data we must be careful to ignore
1136  * transactions already committed, since those commits raced ahead when
1137  * making WAL entries.
1138  *
1139  * The loose timing also means that locks may be recorded that have a
1140  * zero xid, since xids are removed from procs before locks are removed.
1141  * So we must prune the lock list down to ensure we hold locks only for
1142  * currently running xids, performed by StandbyReleaseOldLocks().
1143  * Zero xids should no longer be possible, but we may be replaying WAL
1144  * from a time when they were possible.
1145  *
1146  * For logical decoding only the running xacts information is needed;
1147  * there's no need to look at the locking information, but it's logged anyway,
1148  * as there's no independent knob to just enable logical decoding. For
1149  * details of how this is used, check snapbuild.c's introductory comment.
1150  *
1151  *
1152  * Returns the RecPtr of the last inserted record.
1153  */
1154 XLogRecPtr
1156 {
1157  XLogRecPtr recptr;
1158  RunningTransactions running;
1160  int nlocks;
1161 
1163 
1164  /*
1165  * Get details of any AccessExclusiveLocks being held at the moment.
1166  */
1167  locks = GetRunningTransactionLocks(&nlocks);
1168  if (nlocks > 0)
1169  LogAccessExclusiveLocks(nlocks, locks);
1170  pfree(locks);
1171 
1172  /*
1173  * Log details of all in-progress transactions. This should be the last
1174  * record we write, because standby will open up when it sees this.
1175  */
1176  running = GetRunningTransactionData();
1177 
1178  /*
1179  * GetRunningTransactionData() acquired ProcArrayLock, we must release it.
1180  * For Hot Standby this can be done before inserting the WAL record
1181  * because ProcArrayApplyRecoveryInfo() rechecks the commit status using
1182  * the clog. For logical decoding, though, the lock can't be released
1183  * early because the clog might be "in the future" from the POV of the
1184  * historic snapshot. This would allow for situations where we're waiting
1185  * for the end of a transaction listed in the xl_running_xacts record
1186  * which, according to the WAL, has committed before the xl_running_xacts
1187  * record. Fortunately this routine isn't executed frequently, and it's
1188  * only a shared lock.
1189  */
1191  LWLockRelease(ProcArrayLock);
1192 
1193  recptr = LogCurrentRunningXacts(running);
1194 
1195  /* Release lock if we kept it longer ... */
1197  LWLockRelease(ProcArrayLock);
1198 
1199  /* GetRunningTransactionData() acquired XidGenLock, we must release it */
1200  LWLockRelease(XidGenLock);
1201 
1202  return recptr;
1203 }
1204 
1205 /*
1206  * Record an enhanced snapshot of running transactions into WAL.
1207  *
1208  * The definitions of RunningTransactionsData and xl_xact_running_xacts are
1209  * similar. We keep them separate because xl_xact_running_xacts is a
1210  * contiguous chunk of memory and never exists fully until it is assembled in
1211  * WAL. The inserted records are marked as not being important for durability,
1212  * to avoid triggering superfluous checkpoint / archiving activity.
1213  */
1214 static XLogRecPtr
1216 {
1217  xl_running_xacts xlrec;
1218  XLogRecPtr recptr;
1219 
1220  xlrec.xcnt = CurrRunningXacts->xcnt;
1221  xlrec.subxcnt = CurrRunningXacts->subxcnt;
1222  xlrec.subxid_overflow = CurrRunningXacts->subxid_overflow;
1223  xlrec.nextXid = CurrRunningXacts->nextXid;
1224  xlrec.oldestRunningXid = CurrRunningXacts->oldestRunningXid;
1225  xlrec.latestCompletedXid = CurrRunningXacts->latestCompletedXid;
1226 
1227  /* Header */
1228  XLogBeginInsert();
1230  XLogRegisterData((char *) (&xlrec), MinSizeOfXactRunningXacts);
1231 
1232  /* array of TransactionIds */
1233  if (xlrec.xcnt > 0)
1234  XLogRegisterData((char *) CurrRunningXacts->xids,
1235  (xlrec.xcnt + xlrec.subxcnt) * sizeof(TransactionId));
1236 
1237  recptr = XLogInsert(RM_STANDBY_ID, XLOG_RUNNING_XACTS);
1238 
1239  if (CurrRunningXacts->subxid_overflow)
1241  "snapshot of %u running transactions overflowed (lsn %X/%X oldest xid %u latest complete %u next xid %u)",
1242  CurrRunningXacts->xcnt,
1243  (uint32) (recptr >> 32), (uint32) recptr,
1244  CurrRunningXacts->oldestRunningXid,
1245  CurrRunningXacts->latestCompletedXid,
1246  CurrRunningXacts->nextXid);
1247  else
1249  "snapshot of %u+%u running transaction ids (lsn %X/%X oldest xid %u latest complete %u next xid %u)",
1250  CurrRunningXacts->xcnt, CurrRunningXacts->subxcnt,
1251  (uint32) (recptr >> 32), (uint32) recptr,
1252  CurrRunningXacts->oldestRunningXid,
1253  CurrRunningXacts->latestCompletedXid,
1254  CurrRunningXacts->nextXid);
1255 
1256  /*
1257  * Ensure running_xacts information is synced to disk not too far in the
1258  * future. We don't want to stall anything though (i.e. use XLogFlush()),
1259  * so we let the wal writer do it during normal operation.
1260  * XLogSetAsyncXactLSN() conveniently will mark the LSN as to-be-synced
1261  * and nudge the WALWriter into action if sleeping. Check
1262  * XLogBackgroundFlush() for details why a record might not be flushed
1263  * without it.
1264  */
1265  XLogSetAsyncXactLSN(recptr);
1266 
1267  return recptr;
1268 }
1269 
1270 /*
1271  * Wholesale logging of AccessExclusiveLocks. Other lock types need not be
1272  * logged, as described in backend/storage/lmgr/README.
1273  */
1274 static void
1276 {
1277  xl_standby_locks xlrec;
1278 
1279  xlrec.nlocks = nlocks;
1280 
1281  XLogBeginInsert();
1282  XLogRegisterData((char *) &xlrec, offsetof(xl_standby_locks, locks));
1283  XLogRegisterData((char *) locks, nlocks * sizeof(xl_standby_lock));
1285 
1286  (void) XLogInsert(RM_STANDBY_ID, XLOG_STANDBY_LOCK);
1287 }
1288 
1289 /*
1290  * Individual logging of AccessExclusiveLocks for use during LockAcquire()
1291  */
1292 void
1294 {
1295  xl_standby_lock xlrec;
1296 
1297  xlrec.xid = GetCurrentTransactionId();
1298 
1299  xlrec.dbOid = dbOid;
1300  xlrec.relOid = relOid;
1301 
1302  LogAccessExclusiveLocks(1, &xlrec);
1304 }
1305 
1306 /*
1307  * Prepare to log an AccessExclusiveLock, for use during LockAcquire()
1308  */
1309 void
1311 {
1312  /*
1313  * Ensure that a TransactionId has been assigned to this transaction, for
1314  * two reasons, both related to lock release on the standby. First, we
1315  * must assign an xid so that RecordTransactionCommit() and
1316  * RecordTransactionAbort() do not optimise away the transaction
1317  * completion record which recovery relies upon to release locks. It's a
1318  * hack, but for a corner case not worth adding code for into the main
1319  * commit path. Second, we must assign an xid before the lock is recorded
1320  * in shared memory, otherwise a concurrently executing
1321  * GetRunningTransactionLocks() might see a lock associated with an
1322  * InvalidTransactionId which we later assert cannot happen.
1323  */
1324  (void) GetCurrentTransactionId();
1325 }
1326 
1327 /*
1328  * Emit WAL for invalidations. This currently is only used for commits without
1329  * an xid but which contain invalidations.
1330  */
1331 void
1333  bool relcacheInitFileInval)
1334 {
1335  xl_invalidations xlrec;
1336 
1337  /* prepare record */
1338  memset(&xlrec, 0, sizeof(xlrec));
1339  xlrec.dbId = MyDatabaseId;
1340  xlrec.tsId = MyDatabaseTableSpace;
1341  xlrec.relcacheInitFileInval = relcacheInitFileInval;
1342  xlrec.nmsgs = nmsgs;
1343 
1344  /* perform insertion */
1345  XLogBeginInsert();
1346  XLogRegisterData((char *) (&xlrec), MinSizeOfInvalidations);
1347  XLogRegisterData((char *) msgs,
1348  nmsgs * sizeof(SharedInvalidationMessage));
1349  XLogInsert(RM_STANDBY_ID, XLOG_INVALIDATIONS);
1350 }
1351 
1352 /* Return the description of recovery conflict */
1353 static const char *
1355 {
1356  const char *reasonDesc = gettext_noop("unknown reason");
1357 
1358  switch (reason)
1359  {
1361  reasonDesc = gettext_noop("recovery conflict on buffer pin");
1362  break;
1364  reasonDesc = gettext_noop("recovery conflict on lock");
1365  break;
1367  reasonDesc = gettext_noop("recovery conflict on tablespace");
1368  break;
1370  reasonDesc = gettext_noop("recovery conflict on snapshot");
1371  break;
1373  reasonDesc = gettext_noop("recovery conflict on buffer deadlock");
1374  break;
1376  reasonDesc = gettext_noop("recovery conflict on database");
1377  break;
1378  default:
1379  break;
1380  }
1381 
1382  return reasonDesc;
1383 }
static volatile sig_atomic_t got_standby_deadlock_timeout
Definition: standby.c:47
static void LogAccessExclusiveLocks(int nlocks, xl_standby_lock *locks)
Definition: standby.c:1275
static bool WaitExceedsMaxStandbyDelay(uint32 wait_event_info)
Definition: standby.c:194
void ProcArrayApplyRecoveryInfo(RunningTransactions running)
Definition: procarray.c:1000
static void StandbyReleaseLockList(List *locks)
Definition: standby.c:922
#define NIL
Definition: pg_list.h:65
TransactionId oldestRunningXid
Definition: standby.h:80
pid_t CancelVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode)
Definition: procarray.c:3326
void hash_destroy(HTAB *hashp)
Definition: dynahash.c:862
#define PG_WAIT_LOCK
Definition: pgstat.h:896
static TimestampTz GetStandbyLimitTime(void)
Definition: standby.c:161
TimeoutId id
Definition: timeout.h:55
int CountDBBackends(Oid databaseid)
Definition: procarray.c:3434
void StandbyTimeoutHandler(void)
Definition: standby.c:839
int max_standby_archive_delay
Definition: standby.c:40
static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist, ProcSignalReason reason, uint32 wait_event_info, bool report_waiting)
Definition: standby.c:320
BackendId MyBackendId
Definition: globals.c:82
LockAcquireResult LockAcquire(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock, bool dontWait)
Definition: lock.c:746
void VirtualXactLockTableCleanup(void)
Definition: lock.c:4413
static HTAB * RecoveryLockLists
Definition: standby.c:44
#define HASH_ELEM
Definition: hsearch.h:95
uint32 TransactionId
Definition: c.h:575
void SharedInvalBackendInit(bool sendOnly)
Definition: sinvaladt.c:257
bool update_process_title
Definition: ps_status.c:36
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1578
static void StandbyReleaseLocks(TransactionId xid)
Definition: standby.c:946
int64 TimestampTz
Definition: timestamp.h:39
TimeoutType type
Definition: timeout.h:56
int wal_level
Definition: xlog.c:108
int vacuum_defer_cleanup_age
Definition: standby.c:39
bool InRecovery
Definition: xlog.c:206
VirtualTransactionId * GetConflictingVirtualXIDs(TransactionId limitXmin, Oid dbOid)
Definition: procarray.c:3252
#define XLOG_INVALIDATIONS
Definition: standbydefs.h:36
static int standbyWait_us
Definition: standby.c:186
unsigned char uint8
Definition: c.h:427
#define XLOG_STANDBY_LOCK
Definition: standbydefs.h:34
Definition: lock.h:164
Size entrysize
Definition: hsearch.h:76
#define gettext_noop(x)
Definition: c.h:1185
void LogRecoveryConflict(ProcSignalReason reason, TimestampTz wait_start, TimestampTz now, VirtualTransactionId *wait_list, bool still_waiting)
Definition: standby.c:234
void LogAccessExclusiveLock(Oid dbOid, Oid relOid)
Definition: standby.c:1293
#define InHotStandby
Definition: xlog.h:74
int errcode(int sqlerrcode)
Definition: elog.c:704
TransactionId * xids
Definition: standby.h:83
void * hash_search(HTAB *hashp, const void *keyPtr, HASHACTION action, bool *foundPtr)
Definition: dynahash.c:954
bool TransactionIdDidCommit(TransactionId transactionId)
Definition: transam.c:125
#define LOG
Definition: elog.h:26
unsigned int Oid
Definition: postgres_ext.h:31
LocalTransactionId localTransactionId
Definition: lock.h:65
#define DEBUG4
Definition: elog.h:22
bool TimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec)
Definition: timestamp.c:1709
#define OidIsValid(objectId)
Definition: c.h:698
#define PANIC
Definition: elog.h:55
xl_standby_lock * GetRunningTransactionLocks(int *nlocks)
Definition: lock.c:3932
void ExpireAllKnownAssignedTransactionIds(void)
Definition: procarray.c:4363
TransactionId xid
Definition: standby.c:64
Oid MyDatabaseTableSpace
Definition: globals.c:88
int trace_recovery(int trace_level)
Definition: elog.c:3602
TransactionId latestCompletedXid
Definition: standby.h:81
#define XACT_FLAGS_ACQUIREDACCESSEXCLUSIVELOCK
Definition: xact.h:108
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1810
bool VirtualXactLock(VirtualTransactionId vxid, bool wait)
Definition: lock.c:4460
void set_ps_display(const char *activity)
Definition: ps_status.c:349
TransactionId xids[FLEXIBLE_ARRAY_MEMBER]
Definition: standbydefs.h:56
void pg_usleep(long microsec)
Definition: signal.c:53
Definition: dynahash.c:219
pid_t SignalVirtualTransaction(VirtualTransactionId vxid, ProcSignalReason sigmode, bool conflictPending)
Definition: procarray.c:3332
void enable_timeouts(const EnableTimeoutParams *timeouts, int count)
Definition: timeout.c:572
void pfree(void *pointer)
Definition: mcxt.c:1057
#define XLogRecGetData(decoder)
Definition: xlogreader.h:310
void disable_all_timeouts(bool keep_indicators)
Definition: timeout.c:687
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
#define linitial(l)
Definition: pg_list.h:174
XLogRecPtr LogStandbySnapshot(void)
Definition: standby.c:1155
static XLogRecPtr LogCurrentRunningXacts(RunningTransactions CurrRunningXacts)
Definition: standby.c:1215
#define ERROR
Definition: elog.h:45
void ResolveRecoveryConflictWithBufferPin(void)
Definition: standby.c:688
#define STANDBY_INITIAL_WAIT_US
Definition: standby.c:185
LocalTransactionId GetNextLocalTransactionId(void)
Definition: sinvaladt.c:766
TransactionId latestCompletedXid
Definition: standbydefs.h:54
void CancelDBBackends(Oid databaseid, ProcSignalReason sigmode, bool conflictPending)
Definition: procarray.c:3495
#define DEBUG2
Definition: elog.h:24
TransactionId GetCurrentTransactionId(void)
Definition: xact.c:438
void ResolveRecoveryConflictWithLock(LOCKTAG locktag, bool logging_conflict)
Definition: standby.c:540
void VirtualXactLockTableInsert(VirtualTransactionId vxid)
Definition: lock.c:4390
#define SET_LOCKTAG_RELATION(locktag, dboid, reloid)
Definition: lock.h:181
const char * get_ps_display(int *displen)
Definition: ps_status.c:430
void standby_redo(XLogReaderState *record)
Definition: standby.c:1038
bool relcacheInitFileInval
Definition: standbydefs.h:67
#define MinSizeOfInvalidations
Definition: standbydefs.h:72
static char * buf
Definition: pg_test_fsync.c:68
void LogAccessExclusiveLockPrepare(void)
Definition: standby.c:1310
int errdetail(const char *fmt,...)
Definition: elog.c:1048
#define InvalidTransactionId
Definition: transam.h:31
bool StandbyTransactionIdIsPrepared(TransactionId xid)
Definition: twophase.c:1369
HTAB * hash_create(const char *tabname, long nelem, const HASHCTL *info, int flags)
Definition: dynahash.c:349
void StandbyLockTimeoutHandler(void)
Definition: standby.c:851
void StandbyDeadLockHandler(void)
Definition: standby.c:828
void StandbyReleaseLockTree(TransactionId xid, int nsubxids, TransactionId *subxids)
Definition: standby.c:970
unsigned int uint32
Definition: c.h:429
void CheckRecoveryConflictDeadlock(void)
Definition: standby.c:797
static void pgstat_report_wait_end(void)
Definition: pgstat.h:1512
static void SendRecoveryConflictWithBufferPin(ProcSignalReason reason)
Definition: standby.c:769
void XLogSetRecordFlags(uint8 flags)
Definition: xloginsert.c:404
bool TransactionIdDidAbort(TransactionId transactionId)
Definition: transam.c:181
bool log_recovery_conflict_waits
Definition: standby.c:42
#define XLogRecGetInfo(decoder)
Definition: xlogreader.h:305
#define MinSizeOfXactRunningXacts
Definition: standby.h:59
bool TransactionIdPrecedes(TransactionId id1, TransactionId id2)
Definition: transam.c:300
List * lappend(List *list, void *datum)
Definition: list.c:321
void StandbyReleaseAllLocks(void)
Definition: standby.c:984
int MyXactFlags
Definition: xact.c:132
void ProcWaitForSignal(uint32 wait_event_info)
Definition: proc.c:1867
TransactionId xid
Definition: lockdefs.h:54
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define VirtualTransactionIdIsValid(vxid)
Definition: lock.h:70
void XLogRegisterData(char *data, int len)
Definition: xloginsert.c:330
XLogRecPtr XLogInsert(RmgrId rmid, uint8 info)
Definition: xloginsert.c:422
#define HASH_BLOBS
Definition: hsearch.h:97
static volatile sig_atomic_t got_standby_lock_timeout
Definition: standby.c:48
static void cleanup(void)
Definition: bootstrap.c:862
Oid MyDatabaseId
Definition: globals.c:86
Size keysize
Definition: hsearch.h:75
#define XLogStandbyInfoActive()
Definition: xlog.h:205
int errdetail_log_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1117
#define InvalidOid
Definition: postgres_ext.h:36
#define TimestampTzPlusMilliseconds(tz, ms)
Definition: timestamp.h:56
VirtualTransactionId * GetLockConflicts(const LOCKTAG *locktag, LOCKMODE lockmode, int *countp)
Definition: lock.c:2911
#define ereport(elevel,...)
Definition: elog.h:155
void LogStandbyInvalidations(int nmsgs, SharedInvalidationMessage *msgs, bool relcacheInitFileInval)
Definition: standby.c:1332
void ProcessCommittedInvalidationMessages(SharedInvalidationMessage *msgs, int nmsgs, bool RelcacheInitFileInval, Oid dbid, Oid tsid)
Definition: inval.c:887
void ResolveRecoveryConflictWithTablespace(Oid tsid)
Definition: standby.c:456
void XLogSetAsyncXactLSN(XLogRecPtr asyncXactLSN)
Definition: xlog.c:2698
void ResolveRecoveryConflictWithDatabase(Oid dbid)
Definition: standby.c:486
#define PG_WAIT_BUFFER_PIN
Definition: pgstat.h:897
uint8 locktag_type
Definition: lock.h:170
uint64 XLogRecPtr
Definition: xlogdefs.h:21
void InitRecoveryTransactionEnvironment(void)
Definition: standby.c:81
#define Assert(condition)
Definition: c.h:792
#define XLR_INFO_MASK
Definition: xlogrecord.h:62
#define XLOG_MARK_UNIMPORTANT
Definition: xlog.h:239
BackendId backendId
Definition: lock.h:64
SharedInvalidationMessage msgs[FLEXIBLE_ARRAY_MEMBER]
Definition: standbydefs.h:69
bool HoldingBufferPinThatDelaysRecovery(void)
Definition: bufmgr.c:4147
TimestampTz fin_time
Definition: timeout.h:58
static void pgstat_report_wait_start(uint32 wait_event_info)
Definition: pgstat.h:1488
TransactionId nextXid
Definition: standbydefs.h:52
void * hash_seq_search(HASH_SEQ_STATUS *status)
Definition: dynahash.c:1436
xl_standby_lock locks[FLEXIBLE_ARRAY_MEMBER]
Definition: standbydefs.h:41
void hash_seq_init(HASH_SEQ_STATUS *status, HTAB *hashp)
Definition: dynahash.c:1426
struct RecoveryLockListsEntry RecoveryLockListsEntry
#define AccessExclusiveLock
Definition: lockdefs.h:45
TransactionId nextXid
Definition: standby.h:79
void * palloc(Size size)
Definition: mcxt.c:950
int errmsg(const char *fmt,...)
Definition: elog.c:915
void StandbyAcquireAccessExclusiveLock(TransactionId xid, Oid dbOid, Oid relOid)
Definition: standby.c:883
#define elog(elevel,...)
Definition: elog.h:228
int i
bool LockRelease(const LOCKTAG *locktag, LOCKMODE lockmode, bool sessionLock)
Definition: lock.c:1974
void ResolveRecoveryConflictWithSnapshot(TransactionId latestRemovedXid, RelFileNode node)
Definition: standby.c:428
ProcSignalReason
Definition: procsignal.h:30
TransactionId oldestRunningXid
Definition: standbydefs.h:53
#define XLOG_RUNNING_XACTS
Definition: standbydefs.h:35
RunningTransactions GetRunningTransactionData(void)
Definition: procarray.c:2610
#define XLogRecHasAnyBlockRefs(decoder)
Definition: xlogreader.h:312
int DeadlockTimeout
Definition: proc.c:60
void ShutdownRecoveryTransactionEnvironment(void)
Definition: standby.c:132
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:100
void GetXLogReceiptTime(TimestampTz *rtime, bool *fromStream)
Definition: xlog.c:6244
static const char * get_recovery_conflict_desc(ProcSignalReason reason)
Definition: standby.c:1354
void disable_timeout(TimeoutId id, bool keep_indicator)
Definition: timeout.c:621
#define TransactionIdIsValid(xid)
Definition: transam.h:41
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:227
void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs)
Definition: timestamp.c:1654
void XLogBeginInsert(void)
Definition: xloginsert.c:123
Definition: proc.h:121
Definition: pg_list.h:50
int pid
Definition: proc.h:146
#define _(x)
Definition: elog.c:89
HotStandbyState standbyState
Definition: xlog.c:209
Datum now(PG_FUNCTION_ARGS)
Definition: timestamp.c:1542
#define offsetof(type, field)
Definition: c.h:715
void StandbyReleaseOldLocks(TransactionId oldxid)
Definition: standby.c:1005
int max_standby_streaming_delay
Definition: standby.c:41
List * list_delete_first(List *list)
Definition: list.c:860
PGPROC * BackendIdGetProc(int backendID)
Definition: sinvaladt.c:376