Skip to content

Commit 2860fc4

Browse files
author
Commitfest Bot
committed
[CF 5894] v02 - Don't keep closed WAL segment in page cache after replay
This branch was automatically generated by a robot using patches from an email thread registered at: https://commitfest.postgresql.org/patch/5894 The branch will be overwritten each time a new patch version is posted to the thread, and also periodically to check for bitrot caused by changes on the master branch. Patch(es): https://www.postgresql.org/message-id/CAO6_Xqpx1ey8DPRub7fq4_-rtL=gygoSDHv4iLw5S3gG7=k1dw@mail.gmail.com Author(s): Anthonin Bonnefoy
2 parents c5d34f4 + 94e257f commit 2860fc4

File tree

4 files changed

+51
-4
lines changed

4 files changed

+51
-4
lines changed

src/backend/access/transam/xlogrecovery.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,15 @@
5050
#include "pgstat.h"
5151
#include "postmaster/bgwriter.h"
5252
#include "postmaster/startup.h"
53+
#include "postmaster/walsummarizer.h"
5354
#include "replication/slot.h"
5455
#include "replication/slotsync.h"
5556
#include "replication/walreceiver.h"
5657
#include "storage/fd.h"
5758
#include "storage/ipc.h"
5859
#include "storage/latch.h"
5960
#include "storage/pmsignal.h"
61+
#include "storage/proc.h"
6062
#include "storage/procarray.h"
6163
#include "storage/spin.h"
6264
#include "utils/datetime.h"
@@ -3358,6 +3360,24 @@ XLogPageRead(XLogReaderState *xlogreader, XLogRecPtr targetPagePtr, int reqLen,
33583360
}
33593361
}
33603362

3363+
/*
3364+
* Once replayed, WAL segment files may be re-read in several cases:
3365+
* archive_mode is set to always, summarize_wal is enabled or the
3366+
* standby acts as a walsender for either logical or physical
3367+
* replication. Outside of those conditions, the WAL segment files
3368+
* shouldn't be re-read and we can signal the kernel to release any
3369+
* cached pages.
3370+
*/
3371+
#if defined(USE_POSIX_FADVISE) && defined(POSIX_FADV_DONTNEED)
3372+
{
3373+
int nfree;
3374+
3375+
if (XLogArchiveMode != ARCHIVE_MODE_ALWAYS &&
3376+
!summarize_wal &&
3377+
(max_wal_senders == 0 || HaveNFreeProcs(max_wal_senders, &nfree, PROC_FREE_WALSENDER)))
3378+
(void) posix_fadvise(readFile, 0, 0, POSIX_FADV_DONTNEED);
3379+
}
3380+
#endif
33613381
close(readFile);
33623382
readFile = -1;
33633383
readSource = XLOG_FROM_ANY;

src/backend/storage/lmgr/proc.c

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -784,17 +784,36 @@ GetStartupBufferPinWaitBufId(void)
784784
* Note: this is designed on the assumption that N will generally be small.
785785
*/
786786
bool
787-
HaveNFreeProcs(int n, int *nfree)
787+
HaveNFreeProcs(int n, int *nfree, ProcFreeList proc_free_list)
788788
{
789789
dlist_iter iter;
790+
dlist_head *free_list;
790791

791792
Assert(n > 0);
792793
Assert(nfree);
793794

795+
switch (proc_free_list)
796+
{
797+
case PROC_FREE_PROCS:
798+
free_list = &ProcGlobal->freeProcs;
799+
break;
800+
case PROC_FREE_AUTOVAC:
801+
free_list = &ProcGlobal->autovacFreeProcs;
802+
break;
803+
case PROC_FREE_BGWORKER:
804+
free_list = &ProcGlobal->bgworkerFreeProcs;
805+
break;
806+
case PROC_FREE_WALSENDER:
807+
free_list = &ProcGlobal->walsenderFreeProcs;
808+
break;
809+
default:
810+
elog(ERROR, "invalid free list: %d", (int) proc_free_list);
811+
}
812+
794813
SpinLockAcquire(ProcStructLock);
795814

796815
*nfree = 0;
797-
dlist_foreach(iter, &ProcGlobal->freeProcs)
816+
dlist_foreach(iter, free_list)
798817
{
799818
(*nfree)++;
800819
if (*nfree == n)

src/backend/utils/init/postinit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -931,7 +931,7 @@ InitPostgres(const char *in_dbname, Oid dboid,
931931
*/
932932
if (AmRegularBackendProcess() && !am_superuser &&
933933
(SuperuserReservedConnections + ReservedConnections) > 0 &&
934-
!HaveNFreeProcs(SuperuserReservedConnections + ReservedConnections, &nfree))
934+
!HaveNFreeProcs(SuperuserReservedConnections + ReservedConnections, &nfree, PROC_FREE_PROCS))
935935
{
936936
if (nfree < SuperuserReservedConnections)
937937
ereport(FATAL,

src/include/storage/proc.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,14 @@ typedef enum
149149
PROC_WAIT_STATUS_ERROR,
150150
} ProcWaitStatus;
151151

152+
typedef enum
153+
{
154+
PROC_FREE_PROCS,
155+
PROC_FREE_AUTOVAC,
156+
PROC_FREE_BGWORKER,
157+
PROC_FREE_WALSENDER,
158+
} ProcFreeList;
159+
152160
/*
153161
* Each backend has a PGPROC struct in shared memory. There is also a list of
154162
* currently-unused PGPROC structs that will be reallocated to new backends.
@@ -497,7 +505,7 @@ extern void InitAuxiliaryProcess(void);
497505
extern void SetStartupBufferPinWaitBufId(int bufid);
498506
extern int GetStartupBufferPinWaitBufId(void);
499507

500-
extern bool HaveNFreeProcs(int n, int *nfree);
508+
extern bool HaveNFreeProcs(int n, int *nfree, ProcFreeList proc_free_list);
501509
extern void ProcReleaseLocks(bool isCommit);
502510

503511
extern ProcWaitStatus JoinWaitQueue(LOCALLOCK *locallock,

0 commit comments

Comments
 (0)