From f46f83ac016388213fd650b57007b70c3de473e6 Mon Sep 17 00:00:00 2001 From: Nathan Bossart Date: Thu, 26 Mar 2020 17:08:26 +0000 Subject: [PATCH v3 1/1] Avoid marking WAL segments as ready-for-archive too early. This is a proof-of-concept patch for relocating the logic that is responsible for marking a segment as ready-for-archive to a separate process. --- src/backend/access/transam/xlog.c | 3 --- src/backend/postmaster/walwriter.c | 43 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/src/backend/access/transam/xlog.c b/src/backend/access/transam/xlog.c index 7621fc05e2..1c4a4a83de 100644 --- a/src/backend/access/transam/xlog.c +++ b/src/backend/access/transam/xlog.c @@ -2564,9 +2564,6 @@ XLogWrite(XLogwrtRqst WriteRqst, bool flexible) LogwrtResult.Flush = LogwrtResult.Write; /* end of page */ - if (XLogArchivingActive()) - XLogArchiveNotifySeg(openLogSegNo); - XLogCtl->lastSegSwitchTime = (pg_time_t) time(NULL); XLogCtl->lastSegSwitchLSN = LogwrtResult.Flush; diff --git a/src/backend/postmaster/walwriter.c b/src/backend/postmaster/walwriter.c index 45a2757969..42a21d9130 100644 --- a/src/backend/postmaster/walwriter.c +++ b/src/backend/postmaster/walwriter.c @@ -45,6 +45,7 @@ #include #include "access/xlog.h" +#include "access/xlog_internal.h" #include "libpq/pqsignal.h" #include "miscadmin.h" #include "pgstat.h" @@ -91,6 +92,9 @@ WalWriterMain(void) MemoryContext walwriter_context; int left_till_hibernate; bool hibernating; + XLogRecPtr insert = (XLogRecPtr) 0; + bool shouldGetCurrBytePos = true; + XLogSegNo lastSegno = (XLogSegNo) 0; /* * Properly accept or ignore signals the postmaster might send us @@ -210,9 +214,21 @@ WalWriterMain(void) /* * Loop forever */ + shouldGetCurrBytePos = true; for (;;) { long cur_timeout; + XLogRecPtr flush; + + /* + * Retrieve the WAL insert pointer, which is expected to always be on a + * WAL record boundary. + */ + if (shouldGetCurrBytePos) + { + insert = GetXLogInsertRecPtr(); + shouldGetCurrBytePos = false; + } /* * Advertise whether we might hibernate in this cycle. We do this @@ -243,6 +259,33 @@ WalWriterMain(void) else if (left_till_hibernate > 0) left_till_hibernate--; + /* + * If the current flush position is greater than or equal to the insert + * position we recorded earlier, it is safe to mark all WAL segments up + * to but excluding the current one as ready for archival. + */ + flush = GetFlushRecPtr(); + if (flush >= insert) + { + XLogSegNo segno; + + /* for proof-of-concept, assume default segment size */ + XLByteToSeg(insert, segno, DEFAULT_XLOG_SEG_SIZE); + + /* for proof-of-concept, initialize lastSegno to current segment */ + if (lastSegno == 0) + lastSegno = segno; + + if (XLogArchivingActive()) + { + for (XLogSegNo i = lastSegno; i < segno; i++) + XLogArchiveNotifySeg(i); + } + + lastSegno = segno; + shouldGetCurrBytePos = true; + } + /* * Sleep until we are signaled or WalWriterDelay has elapsed. If we * haven't done anything useful for quite some time, lengthen the -- 2.16.6