PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
walsummarizer.h File Reference
#include "access/xlogdefs.h"
Include dependency graph for walsummarizer.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

Size WalSummarizerShmemSize (void)
 
void WalSummarizerShmemInit (void)
 
pg_noreturn void WalSummarizerMain (const void *startup_data, size_t startup_data_len)
 
void GetWalSummarizerState (TimeLineID *summarized_tli, XLogRecPtr *summarized_lsn, XLogRecPtr *pending_lsn, int *summarizer_pid)
 
XLogRecPtr GetOldestUnsummarizedLSN (TimeLineID *tli, bool *lsn_is_exact)
 
void WakeupWalSummarizer (void)
 
void WaitForWalSummarization (XLogRecPtr lsn)
 

Variables

PGDLLIMPORT bool summarize_wal
 
PGDLLIMPORT int wal_summary_keep_time
 

Function Documentation

◆ GetOldestUnsummarizedLSN()

XLogRecPtr GetOldestUnsummarizedLSN ( TimeLineID tli,
bool *  lsn_is_exact 
)

Definition at line 508 of file walsummarizer.c.

509{
510 TimeLineID latest_tli;
511 int n;
512 List *tles;
513 XLogRecPtr unsummarized_lsn = InvalidXLogRecPtr;
514 TimeLineID unsummarized_tli = 0;
515 bool should_make_exact = false;
516 List *existing_summaries;
517 ListCell *lc;
518 bool am_wal_summarizer = AmWalSummarizerProcess();
519
520 /* If not summarizing WAL, do nothing. */
521 if (!summarize_wal)
522 return InvalidXLogRecPtr;
523
524 /*
525 * If we are not the WAL summarizer process, then we normally just want to
526 * read the values from shared memory. However, as an exception, if shared
527 * memory hasn't been initialized yet, then we need to do that so that we
528 * can read legal values and not remove any WAL too early.
529 */
530 if (!am_wal_summarizer)
531 {
532 LWLockAcquire(WALSummarizerLock, LW_SHARED);
533
535 {
536 unsummarized_lsn = WalSummarizerCtl->summarized_lsn;
537 if (tli != NULL)
539 if (lsn_is_exact != NULL)
540 *lsn_is_exact = WalSummarizerCtl->lsn_is_exact;
541 LWLockRelease(WALSummarizerLock);
542 return unsummarized_lsn;
543 }
544
545 LWLockRelease(WALSummarizerLock);
546 }
547
548 /*
549 * Find the oldest timeline on which WAL still exists, and the earliest
550 * segment for which it exists.
551 *
552 * Note that we do this every time the WAL summarizer process restarts or
553 * recovers from an error, in case the contents of pg_wal have changed
554 * under us e.g. if some files were removed, either manually - which
555 * shouldn't really happen, but might - or by postgres itself, if
556 * summarize_wal was turned off and then back on again.
557 */
558 (void) GetLatestLSN(&latest_tli);
559 tles = readTimeLineHistory(latest_tli);
560 for (n = list_length(tles) - 1; n >= 0; --n)
561 {
562 TimeLineHistoryEntry *tle = list_nth(tles, n);
563 XLogSegNo oldest_segno;
564
565 oldest_segno = XLogGetOldestSegno(tle->tli);
566 if (oldest_segno != 0)
567 {
568 /* Compute oldest LSN that still exists on disk. */
570 unsummarized_lsn);
571
572 unsummarized_tli = tle->tli;
573 break;
574 }
575 }
576
577 /*
578 * Don't try to summarize anything older than the end LSN of the newest
579 * summary file that exists for this timeline.
580 */
581 existing_summaries =
582 GetWalSummaries(unsummarized_tli,
584 foreach(lc, existing_summaries)
585 {
586 WalSummaryFile *ws = lfirst(lc);
587
588 if (ws->end_lsn > unsummarized_lsn)
589 {
590 unsummarized_lsn = ws->end_lsn;
591 should_make_exact = true;
592 }
593 }
594
595 /* It really should not be possible for us to find no WAL. */
596 if (unsummarized_tli == 0)
598 errcode(ERRCODE_INTERNAL_ERROR),
599 errmsg_internal("no WAL found on timeline %u", latest_tli));
600
601 /*
602 * If we're the WAL summarizer, we always want to store the values we just
603 * computed into shared memory, because those are the values we're going
604 * to use to drive our operation, and so they are the authoritative
605 * values. Otherwise, we only store values into shared memory if shared
606 * memory is uninitialized. Our values are not canonical in such a case,
607 * but it's better to have something than nothing, to guide WAL retention.
608 */
609 LWLockAcquire(WALSummarizerLock, LW_EXCLUSIVE);
610 if (am_wal_summarizer || !WalSummarizerCtl->initialized)
611 {
613 WalSummarizerCtl->summarized_lsn = unsummarized_lsn;
614 WalSummarizerCtl->summarized_tli = unsummarized_tli;
615 WalSummarizerCtl->lsn_is_exact = should_make_exact;
616 WalSummarizerCtl->pending_lsn = unsummarized_lsn;
617 }
618 else
619 unsummarized_lsn = WalSummarizerCtl->summarized_lsn;
620
621 /* Also return the to the caller as required. */
622 if (tli != NULL)
624 if (lsn_is_exact != NULL)
625 *lsn_is_exact = WalSummarizerCtl->lsn_is_exact;
626 LWLockRelease(WALSummarizerLock);
627
628 return unsummarized_lsn;
629}
List * readTimeLineHistory(TimeLineID targetTLI)
Definition: timeline.c:76
int errmsg_internal(const char *fmt,...)
Definition: elog.c:1158
int errcode(int sqlerrcode)
Definition: elog.c:854
#define ERROR
Definition: elog.h:39
#define ereport(elevel,...)
Definition: elog.h:149
bool LWLockAcquire(LWLock *lock, LWLockMode mode)
Definition: lwlock.c:1182
void LWLockRelease(LWLock *lock)
Definition: lwlock.c:1902
@ LW_SHARED
Definition: lwlock.h:115
@ LW_EXCLUSIVE
Definition: lwlock.h:114
#define AmWalSummarizerProcess()
Definition: miscadmin.h:392
#define lfirst(lc)
Definition: pg_list.h:172
static int list_length(const List *l)
Definition: pg_list.h:152
static void * list_nth(const List *list, int n)
Definition: pg_list.h:299
Definition: pg_list.h:54
TimeLineID tli
Definition: timeline.h:27
XLogRecPtr summarized_lsn
Definition: walsummarizer.c:86
TimeLineID summarized_tli
Definition: walsummarizer.c:85
XLogRecPtr pending_lsn
Definition: walsummarizer.c:89
XLogRecPtr end_lsn
Definition: walsummary.h:30
static XLogRecPtr GetLatestLSN(TimeLineID *tli)
static WalSummarizerData * WalSummarizerCtl
bool summarize_wal
List * GetWalSummaries(TimeLineID tli, XLogRecPtr start_lsn, XLogRecPtr end_lsn)
Definition: walsummary.c:43
int wal_segment_size
Definition: xlog.c:143
XLogSegNo XLogGetOldestSegno(TimeLineID tli)
Definition: xlog.c:3913
#define XLogSegNoOffsetToRecPtr(segno, offset, wal_segsz_bytes, dest)
uint64 XLogRecPtr
Definition: xlogdefs.h:21
#define InvalidXLogRecPtr
Definition: xlogdefs.h:28
uint32 TimeLineID
Definition: xlogdefs.h:59
uint64 XLogSegNo
Definition: xlogdefs.h:48

References AmWalSummarizerProcess, WalSummaryFile::end_lsn, ereport, errcode(), errmsg_internal(), ERROR, GetLatestLSN(), GetWalSummaries(), WalSummarizerData::initialized, InvalidXLogRecPtr, lfirst, list_length(), list_nth(), WalSummarizerData::lsn_is_exact, LW_EXCLUSIVE, LW_SHARED, LWLockAcquire(), LWLockRelease(), WalSummarizerData::pending_lsn, readTimeLineHistory(), summarize_wal, WalSummarizerData::summarized_lsn, WalSummarizerData::summarized_tli, TimeLineHistoryEntry::tli, wal_segment_size, WalSummarizerCtl, XLogGetOldestSegno(), and XLogSegNoOffsetToRecPtr.

Referenced by KeepLogSeg(), and WalSummarizerMain().

◆ GetWalSummarizerState()

void GetWalSummarizerState ( TimeLineID summarized_tli,
XLogRecPtr summarized_lsn,
XLogRecPtr pending_lsn,
int *  summarizer_pid 
)

Definition at line 450 of file walsummarizer.c.

452{
453 LWLockAcquire(WALSummarizerLock, LW_SHARED);
455 {
456 /*
457 * If initialized is false, the rest of the structure contents are
458 * undefined.
459 */
460 *summarized_tli = 0;
461 *summarized_lsn = InvalidXLogRecPtr;
462 *pending_lsn = InvalidXLogRecPtr;
463 *summarizer_pid = -1;
464 }
465 else
466 {
467 int summarizer_pgprocno = WalSummarizerCtl->summarizer_pgprocno;
468
469 *summarized_tli = WalSummarizerCtl->summarized_tli;
470 *summarized_lsn = WalSummarizerCtl->summarized_lsn;
471 if (summarizer_pgprocno == INVALID_PROC_NUMBER)
472 {
473 /*
474 * If the summarizer has exited, the fact that it had processed
475 * beyond summarized_lsn is irrelevant now.
476 */
477 *pending_lsn = WalSummarizerCtl->summarized_lsn;
478 *summarizer_pid = -1;
479 }
480 else
481 {
482 *pending_lsn = WalSummarizerCtl->pending_lsn;
483
484 /*
485 * We're not fussed about inexact answers here, since they could
486 * become stale instantly, so we don't bother taking the lock, but
487 * make sure that invalid PID values are normalized to -1.
488 */
489 *summarizer_pid = GetPGProcByNumber(summarizer_pgprocno)->pid;
490 if (*summarizer_pid <= 0)
491 *summarizer_pid = -1;
492 }
493 }
494 LWLockRelease(WALSummarizerLock);
495}
#define GetPGProcByNumber(n)
Definition: proc.h:424
#define INVALID_PROC_NUMBER
Definition: procnumber.h:26
ProcNumber summarizer_pgprocno
Definition: walsummarizer.c:88

References GetPGProcByNumber, WalSummarizerData::initialized, INVALID_PROC_NUMBER, InvalidXLogRecPtr, LW_SHARED, LWLockAcquire(), LWLockRelease(), WalSummarizerData::pending_lsn, WalSummarizerData::summarized_lsn, WalSummarizerData::summarized_tli, WalSummarizerData::summarizer_pgprocno, and WalSummarizerCtl.

Referenced by pg_get_wal_summarizer_state().

◆ WaitForWalSummarization()

void WaitForWalSummarization ( XLogRecPtr  lsn)

Definition at line 663 of file walsummarizer.c.

664{
665 TimestampTz initial_time,
666 cycle_time,
667 current_time;
668 XLogRecPtr prior_pending_lsn = InvalidXLogRecPtr;
669 int deadcycles = 0;
670
671 initial_time = cycle_time = GetCurrentTimestamp();
672
673 while (1)
674 {
675 long timeout_in_ms = 10000;
676 XLogRecPtr summarized_lsn;
677 XLogRecPtr pending_lsn;
678
680
681 /* If WAL summarization is disabled while we're waiting, give up. */
682 if (!summarize_wal)
683 return;
684
685 /*
686 * If the LSN summarized on disk has reached the target value, stop.
687 */
688 LWLockAcquire(WALSummarizerLock, LW_EXCLUSIVE);
689 summarized_lsn = WalSummarizerCtl->summarized_lsn;
690 pending_lsn = WalSummarizerCtl->pending_lsn;
691 LWLockRelease(WALSummarizerLock);
692
693 /* If WAL summarization has progressed sufficiently, stop waiting. */
694 if (summarized_lsn >= lsn)
695 break;
696
697 /* Recheck current time. */
698 current_time = GetCurrentTimestamp();
699
700 /* Have we finished the current cycle of waiting? */
701 if (TimestampDifferenceMilliseconds(cycle_time,
702 current_time) >= timeout_in_ms)
703 {
704 long elapsed_seconds;
705
706 /* Begin new wait cycle. */
707 cycle_time = TimestampTzPlusMilliseconds(cycle_time,
708 timeout_in_ms);
709
710 /*
711 * Keep track of the number of cycles during which there has been
712 * no progression of pending_lsn. If pending_lsn is not advancing,
713 * that means that not only are no new files appearing on disk,
714 * but we're not even incorporating new records into the in-memory
715 * state.
716 */
717 if (pending_lsn > prior_pending_lsn)
718 {
719 prior_pending_lsn = pending_lsn;
720 deadcycles = 0;
721 }
722 else
723 ++deadcycles;
724
725 /*
726 * If we've managed to wait for an entire minute without the WAL
727 * summarizer absorbing a single WAL record, error out; probably
728 * something is wrong.
729 *
730 * We could consider also erroring out if the summarizer is taking
731 * too long to catch up, but it's not clear what rate of progress
732 * would be acceptable and what would be too slow. So instead, we
733 * just try to error out in the case where there's no progress at
734 * all. That seems likely to catch a reasonable number of the
735 * things that can go wrong in practice (e.g. the summarizer
736 * process is completely hung, say because somebody hooked up a
737 * debugger to it or something) without giving up too quickly when
738 * the system is just slow.
739 */
740 if (deadcycles >= 6)
742 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
743 errmsg("WAL summarization is not progressing"),
744 errdetail("Summarization is needed through %X/%X, but is stuck at %X/%X on disk and %X/%X in memory.",
745 LSN_FORMAT_ARGS(lsn),
746 LSN_FORMAT_ARGS(summarized_lsn),
747 LSN_FORMAT_ARGS(pending_lsn))));
748
749
750 /*
751 * Otherwise, just let the user know what's happening.
752 */
753 elapsed_seconds =
755 current_time) / 1000;
757 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
758 errmsg_plural("still waiting for WAL summarization through %X/%X after %ld second",
759 "still waiting for WAL summarization through %X/%X after %ld seconds",
760 elapsed_seconds,
761 LSN_FORMAT_ARGS(lsn),
762 elapsed_seconds),
763 errdetail("Summarization has reached %X/%X on disk and %X/%X in memory.",
764 LSN_FORMAT_ARGS(summarized_lsn),
765 LSN_FORMAT_ARGS(pending_lsn))));
766 }
767
768 /*
769 * Align the wait time to prevent drift. This doesn't really matter,
770 * but we'd like the warnings about how long we've been waiting to say
771 * 10 seconds, 20 seconds, 30 seconds, 40 seconds ... without ever
772 * drifting to something that is not a multiple of ten.
773 */
774 timeout_in_ms -=
775 TimestampDifferenceMilliseconds(cycle_time, current_time);
776
777 /* Wait and see. */
779 timeout_in_ms,
780 WAIT_EVENT_WAL_SUMMARY_READY);
781 }
782
784}
long TimestampDifferenceMilliseconds(TimestampTz start_time, TimestampTz stop_time)
Definition: timestamp.c:1757
TimestampTz GetCurrentTimestamp(void)
Definition: timestamp.c:1645
bool ConditionVariableCancelSleep(void)
bool ConditionVariableTimedSleep(ConditionVariable *cv, long timeout, uint32 wait_event_info)
int64 TimestampTz
Definition: timestamp.h:39
int errmsg_plural(const char *fmt_singular, const char *fmt_plural, unsigned long n,...)
Definition: elog.c:1181
int errdetail(const char *fmt,...)
Definition: elog.c:1204
int errmsg(const char *fmt,...)
Definition: elog.c:1071
#define WARNING
Definition: elog.h:36
#define CHECK_FOR_INTERRUPTS()
Definition: miscadmin.h:123
ConditionVariable summary_file_cv
Definition: walsummarizer.c:94
#define TimestampTzPlusMilliseconds(tz, ms)
Definition: timestamp.h:85
#define LSN_FORMAT_ARGS(lsn)
Definition: xlogdefs.h:43

References CHECK_FOR_INTERRUPTS, ConditionVariableCancelSleep(), ConditionVariableTimedSleep(), ereport, errcode(), errdetail(), errmsg(), errmsg_plural(), ERROR, GetCurrentTimestamp(), InvalidXLogRecPtr, LSN_FORMAT_ARGS, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), WalSummarizerData::pending_lsn, summarize_wal, WalSummarizerData::summarized_lsn, WalSummarizerData::summary_file_cv, TimestampDifferenceMilliseconds(), TimestampTzPlusMilliseconds, WalSummarizerCtl, and WARNING.

Referenced by CleanupAfterArchiveRecovery(), and PrepareForIncrementalBackup().

◆ WakeupWalSummarizer()

void WakeupWalSummarizer ( void  )

Definition at line 640 of file walsummarizer.c.

641{
642 ProcNumber pgprocno;
643
644 if (WalSummarizerCtl == NULL)
645 return;
646
647 LWLockAcquire(WALSummarizerLock, LW_EXCLUSIVE);
649 LWLockRelease(WALSummarizerLock);
650
651 if (pgprocno != INVALID_PROC_NUMBER)
653}
void SetLatch(Latch *latch)
Definition: latch.c:288
int ProcNumber
Definition: procnumber.h:24
PROC_HDR * ProcGlobal
Definition: proc.c:79
Latch procLatch
Definition: proc.h:170
PGPROC * allProcs
Definition: proc.h:372

References PROC_HDR::allProcs, INVALID_PROC_NUMBER, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), ProcGlobal, PGPROC::procLatch, SetLatch(), WalSummarizerData::summarizer_pgprocno, and WalSummarizerCtl.

Referenced by CreateCheckPoint().

◆ WalSummarizerMain()

pg_noreturn void WalSummarizerMain ( const void *  startup_data,
size_t  startup_data_len 
)

Definition at line 213 of file walsummarizer.c.

214{
215 sigjmp_buf local_sigjmp_buf;
216 MemoryContext context;
217
218 /*
219 * Within this function, 'current_lsn' and 'current_tli' refer to the
220 * point from which the next WAL summary file should start. 'exact' is
221 * true if 'current_lsn' is known to be the start of a WAL record or WAL
222 * segment, and false if it might be in the middle of a record someplace.
223 *
224 * 'switch_lsn' and 'switch_tli', if set, are the LSN at which we need to
225 * switch to a new timeline and the timeline to which we need to switch.
226 * If not set, we either haven't figured out the answers yet or we're
227 * already on the latest timeline.
228 */
229 XLogRecPtr current_lsn;
230 TimeLineID current_tli;
231 bool exact;
232 XLogRecPtr switch_lsn = InvalidXLogRecPtr;
233 TimeLineID switch_tli = 0;
234
235 Assert(startup_data_len == 0);
236
239
241 (errmsg_internal("WAL summarizer started")));
242
243 /*
244 * Properly accept or ignore signals the postmaster might send us
245 *
246 * We have no particular use for SIGINT at the moment, but seems
247 * reasonable to treat like SIGTERM.
248 */
252 /* SIGQUIT handler was already set up by InitPostmasterChild */
253 pqsignal(SIGALRM, SIG_IGN);
254 pqsignal(SIGPIPE, SIG_IGN);
256 pqsignal(SIGUSR2, SIG_IGN); /* not used */
257
258 /* Advertise ourselves. */
260 LWLockAcquire(WALSummarizerLock, LW_EXCLUSIVE);
262 LWLockRelease(WALSummarizerLock);
263
264 /* Create and switch to a memory context that we can reset on error. */
266 "Wal Summarizer",
268 MemoryContextSwitchTo(context);
269
270 /*
271 * Reset some signals that are accepted by postmaster but not here
272 */
273 pqsignal(SIGCHLD, SIG_DFL);
274
275 /*
276 * If an exception is encountered, processing resumes here.
277 */
278 if (sigsetjmp(local_sigjmp_buf, 1) != 0)
279 {
280 /* Since not using PG_TRY, must reset error stack by hand */
281 error_context_stack = NULL;
282
283 /* Prevent interrupts while cleaning up */
285
286 /* Report the error to the server log */
288
289 /* Release resources we might have acquired. */
295 AtEOXact_Files(false);
296 AtEOXact_HashTables(false);
297
298 /*
299 * Now return to normal top-level context and clear ErrorContext for
300 * next time.
301 */
302 MemoryContextSwitchTo(context);
304
305 /* Flush any leaked data in the top-level context */
306 MemoryContextReset(context);
307
308 /* Now we can allow interrupts again */
310
311 /*
312 * Sleep for 10 seconds before attempting to resume operations in
313 * order to avoid excessive logging.
314 *
315 * Many of the likely error conditions are things that will repeat
316 * every time. For example, if the WAL can't be read or the summary
317 * can't be written, only administrator action will cure the problem.
318 * So a really fast retry time doesn't seem to be especially
319 * beneficial, and it will clutter the logs.
320 */
321 (void) WaitLatch(NULL,
323 10000,
324 WAIT_EVENT_WAL_SUMMARIZER_ERROR);
325 }
326
327 /* We can now handle ereport(ERROR) */
328 PG_exception_stack = &local_sigjmp_buf;
329
330 /*
331 * Unblock signals (they were blocked when the postmaster forked us)
332 */
333 sigprocmask(SIG_SETMASK, &UnBlockSig, NULL);
334
335 /*
336 * Fetch information about previous progress from shared memory, and ask
337 * GetOldestUnsummarizedLSN to reset pending_lsn to summarized_lsn. We
338 * might be recovering from an error, and if so, pending_lsn might have
339 * advanced past summarized_lsn, but any WAL we read previously has been
340 * lost and will need to be reread.
341 *
342 * If we discover that WAL summarization is not enabled, just exit.
343 */
344 current_lsn = GetOldestUnsummarizedLSN(&current_tli, &exact);
345 if (XLogRecPtrIsInvalid(current_lsn))
346 proc_exit(0);
347
348 /*
349 * Loop forever
350 */
351 for (;;)
352 {
353 XLogRecPtr latest_lsn;
354 TimeLineID latest_tli;
355 XLogRecPtr end_of_summary_lsn;
356
357 /* Flush any leaked data in the top-level context */
358 MemoryContextReset(context);
359
360 /* Process any signals received recently. */
362
363 /* If it's time to remove any old WAL summaries, do that now. */
365
366 /* Find the LSN and TLI up to which we can safely summarize. */
367 latest_lsn = GetLatestLSN(&latest_tli);
368
369 /*
370 * If we're summarizing a historic timeline and we haven't yet
371 * computed the point at which to switch to the next timeline, do that
372 * now.
373 *
374 * Note that if this is a standby, what was previously the current
375 * timeline could become historic at any time.
376 *
377 * We could try to make this more efficient by caching the results of
378 * readTimeLineHistory when latest_tli has not changed, but since we
379 * only have to do this once per timeline switch, we probably wouldn't
380 * save any significant amount of work in practice.
381 */
382 if (current_tli != latest_tli && XLogRecPtrIsInvalid(switch_lsn))
383 {
384 List *tles = readTimeLineHistory(latest_tli);
385
386 switch_lsn = tliSwitchPoint(current_tli, tles, &switch_tli);
388 errmsg_internal("switch point from TLI %u to TLI %u is at %X/%X",
389 current_tli, switch_tli, LSN_FORMAT_ARGS(switch_lsn)));
390 }
391
392 /*
393 * If we've reached the switch LSN, we can't summarize anything else
394 * on this timeline. Switch to the next timeline and go around again,
395 * backing up to the exact switch point if we passed it.
396 */
397 if (!XLogRecPtrIsInvalid(switch_lsn) && current_lsn >= switch_lsn)
398 {
399 /* Restart summarization from switch point. */
400 current_tli = switch_tli;
401 current_lsn = switch_lsn;
402
403 /* Next timeline and switch point, if any, not yet known. */
404 switch_lsn = InvalidXLogRecPtr;
405 switch_tli = 0;
406
407 /* Update (really, rewind, if needed) state in shared memory. */
408 LWLockAcquire(WALSummarizerLock, LW_EXCLUSIVE);
409 WalSummarizerCtl->summarized_lsn = current_lsn;
410 WalSummarizerCtl->summarized_tli = current_tli;
412 WalSummarizerCtl->pending_lsn = current_lsn;
413 LWLockRelease(WALSummarizerLock);
414
415 continue;
416 }
417
418 /* Summarize WAL. */
419 end_of_summary_lsn = SummarizeWAL(current_tli,
420 current_lsn, exact,
421 switch_lsn, latest_lsn);
422 Assert(!XLogRecPtrIsInvalid(end_of_summary_lsn));
423 Assert(end_of_summary_lsn >= current_lsn);
424
425 /*
426 * Update state for next loop iteration.
427 *
428 * Next summary file should start from exactly where this one ended.
429 */
430 current_lsn = end_of_summary_lsn;
431 exact = true;
432
433 /* Update state in shared memory. */
434 LWLockAcquire(WALSummarizerLock, LW_EXCLUSIVE);
435 WalSummarizerCtl->summarized_lsn = end_of_summary_lsn;
436 WalSummarizerCtl->summarized_tli = current_tli;
438 WalSummarizerCtl->pending_lsn = end_of_summary_lsn;
439 LWLockRelease(WALSummarizerLock);
440
441 /* Wake up anyone waiting for more summary files to be written. */
443 }
444}
void pgaio_error_cleanup(void)
Definition: aio.c:1062
void AuxiliaryProcessMainCommon(void)
Definition: auxprocess.c:39
XLogRecPtr tliSwitchPoint(TimeLineID tli, List *history, TimeLineID *nextTLI)
Definition: timeline.c:572
sigset_t UnBlockSig
Definition: pqsignal.c:22
void ConditionVariableBroadcast(ConditionVariable *cv)
void AtEOXact_HashTables(bool isCommit)
Definition: dynahash.c:1912
void EmitErrorReport(void)
Definition: elog.c:1709
ErrorContextCallback * error_context_stack
Definition: elog.c:95
void FlushErrorState(void)
Definition: elog.c:1889
sigjmp_buf * PG_exception_stack
Definition: elog.c:97
#define DEBUG1
Definition: elog.h:30
void AtEOXact_Files(bool isCommit)
Definition: fd.c:3229
ProcNumber MyProcNumber
Definition: globals.c:91
Assert(PointerIsAligned(start, uint64))
void SignalHandlerForShutdownRequest(SIGNAL_ARGS)
Definition: interrupt.c:109
void SignalHandlerForConfigReload(SIGNAL_ARGS)
Definition: interrupt.c:65
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:365
void proc_exit(int code)
Definition: ipc.c:104
int WaitLatch(Latch *latch, int wakeEvents, long timeout, uint32 wait_event_info)
Definition: latch.c:172
void LWLockReleaseAll(void)
Definition: lwlock.c:1953
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:414
MemoryContext TopMemoryContext
Definition: mcxt.c:165
#define AllocSetContextCreate
Definition: memutils.h:149
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:180
#define RESUME_INTERRUPTS()
Definition: miscadmin.h:136
#define HOLD_INTERRUPTS()
Definition: miscadmin.h:134
@ B_WAL_SUMMARIZER
Definition: miscadmin.h:367
BackendType MyBackendType
Definition: miscinit.c:64
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
#define pqsignal
Definition: port.h:531
uintptr_t Datum
Definition: postgres.h:69
void procsignal_sigusr1_handler(SIGNAL_ARGS)
Definition: procsignal.c:673
void ReleaseAuxProcessResources(bool isCommit)
Definition: resowner.c:1019
static void pgstat_report_wait_end(void)
Definition: wait_event.h:101
#define WL_TIMEOUT
Definition: waiteventset.h:37
#define WL_EXIT_ON_PM_DEATH
Definition: waiteventset.h:39
static XLogRecPtr SummarizeWAL(TimeLineID tli, XLogRecPtr start_lsn, bool exact, XLogRecPtr switch_lsn, XLogRecPtr maximum_lsn)
static void ProcessWalSummarizerInterrupts(void)
static void WalSummarizerShutdown(int code, Datum arg)
static void MaybeRemoveOldWalSummaries(void)
XLogRecPtr GetOldestUnsummarizedLSN(TimeLineID *tli, bool *lsn_is_exact)
#define SIGCHLD
Definition: win32_port.h:168
#define SIGHUP
Definition: win32_port.h:158
#define SIGPIPE
Definition: win32_port.h:163
#define SIGUSR1
Definition: win32_port.h:170
#define SIGALRM
Definition: win32_port.h:164
#define SIGUSR2
Definition: win32_port.h:171
#define XLogRecPtrIsInvalid(r)
Definition: xlogdefs.h:29

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert(), AtEOXact_Files(), AtEOXact_HashTables(), AuxiliaryProcessMainCommon(), B_WAL_SUMMARIZER, ConditionVariableBroadcast(), ConditionVariableCancelSleep(), DEBUG1, EmitErrorReport(), ereport, errmsg_internal(), error_context_stack, FlushErrorState(), GetLatestLSN(), GetOldestUnsummarizedLSN(), HOLD_INTERRUPTS, InvalidXLogRecPtr, LSN_FORMAT_ARGS, WalSummarizerData::lsn_is_exact, LW_EXCLUSIVE, LWLockAcquire(), LWLockRelease(), LWLockReleaseAll(), MaybeRemoveOldWalSummaries(), MemoryContextReset(), MemoryContextSwitchTo(), MyBackendType, MyProcNumber, on_shmem_exit(), WalSummarizerData::pending_lsn, PG_exception_stack, pgaio_error_cleanup(), pgstat_report_wait_end(), pqsignal, proc_exit(), ProcessWalSummarizerInterrupts(), procsignal_sigusr1_handler(), readTimeLineHistory(), ReleaseAuxProcessResources(), RESUME_INTERRUPTS, SIGALRM, SIGCHLD, SIGHUP, SignalHandlerForConfigReload(), SignalHandlerForShutdownRequest(), SIGPIPE, SIGUSR1, SIGUSR2, WalSummarizerData::summarized_lsn, WalSummarizerData::summarized_tli, WalSummarizerData::summarizer_pgprocno, SummarizeWAL(), WalSummarizerData::summary_file_cv, tliSwitchPoint(), TopMemoryContext, UnBlockSig, WaitLatch(), WalSummarizerCtl, WalSummarizerShutdown(), WL_EXIT_ON_PM_DEATH, WL_TIMEOUT, and XLogRecPtrIsInvalid.

◆ WalSummarizerShmemInit()

void WalSummarizerShmemInit ( void  )

Definition at line 182 of file walsummarizer.c.

183{
184 bool found;
185
187 ShmemInitStruct("Wal Summarizer Ctl", WalSummarizerShmemSize(),
188 &found);
189
190 if (!found)
191 {
192 /*
193 * First time through, so initialize.
194 *
195 * We're just filling in dummy values here -- the real initialization
196 * will happen when GetOldestUnsummarizedLSN() is called for the first
197 * time.
198 */
206 }
207}
void ConditionVariableInit(ConditionVariable *cv)
void * ShmemInitStruct(const char *name, Size size, bool *foundPtr)
Definition: shmem.c:387
Size WalSummarizerShmemSize(void)

References ConditionVariableInit(), WalSummarizerData::initialized, INVALID_PROC_NUMBER, InvalidXLogRecPtr, WalSummarizerData::lsn_is_exact, WalSummarizerData::pending_lsn, ShmemInitStruct(), WalSummarizerData::summarized_lsn, WalSummarizerData::summarized_tli, WalSummarizerData::summarizer_pgprocno, WalSummarizerData::summary_file_cv, WalSummarizerCtl, and WalSummarizerShmemSize().

Referenced by CreateOrAttachShmemStructs().

◆ WalSummarizerShmemSize()

Size WalSummarizerShmemSize ( void  )

Definition at line 173 of file walsummarizer.c.

174{
175 return sizeof(WalSummarizerData);
176}

Referenced by CalculateShmemSize(), and WalSummarizerShmemInit().

Variable Documentation

◆ summarize_wal

◆ wal_summary_keep_time

PGDLLIMPORT int wal_summary_keep_time
extern

Definition at line 145 of file walsummarizer.c.

Referenced by MaybeRemoveOldWalSummaries().