Allocate Backend structs in PostmasterContext.

The child processes don't need them. By allocating them in
PostmasterContext, the memory gets free'd and is made available for
other stuff in the child processes.

Reviewed-by: Thomas Munro
Discussion: https://www.postgresql.org/message-id/4f95c1fc-ad3c-7974-3a8c-6faa3931804c@iki.fi
This commit is contained in:
Heikki Linnakangas 2023-10-09 11:23:50 +03:00
parent 1ca312686e
commit 0bbafb5342
2 changed files with 19 additions and 16 deletions

View File

@ -33,6 +33,7 @@
#include "storage/shmem.h"
#include "tcop/tcopprot.h"
#include "utils/ascii.h"
#include "utils/memutils.h"
#include "utils/ps_status.h"
#include "utils/timeout.h"
@ -347,7 +348,9 @@ BackgroundWorkerStateChange(bool allow_new_workers)
/*
* Copy the registration data into the registered workers list.
*/
rw = malloc(sizeof(RegisteredBgWorker));
rw = MemoryContextAllocExtended(PostmasterContext,
sizeof(RegisteredBgWorker),
MCXT_ALLOC_NO_OOM);
if (rw == NULL)
{
ereport(LOG,
@ -455,7 +458,7 @@ ForgetBackgroundWorker(slist_mutable_iter *cur)
rw->rw_worker.bgw_name)));
slist_delete_current(cur);
free(rw);
pfree(rw);
}
/*
@ -951,7 +954,9 @@ RegisterBackgroundWorker(BackgroundWorker *worker)
/*
* Copy the registration data into the registered workers list.
*/
rw = malloc(sizeof(RegisteredBgWorker));
rw = MemoryContextAllocExtended(PostmasterContext,
sizeof(RegisteredBgWorker),
MCXT_ALLOC_NO_OOM);
if (rw == NULL)
{
ereport(LOG,

View File

@ -3321,7 +3321,7 @@ CleanupBackgroundWorker(int pid,
*/
if (rw->rw_backend->bgworker_notify)
BackgroundWorkerStopNotifications(rw->rw_pid);
free(rw->rw_backend);
pfree(rw->rw_backend);
rw->rw_backend = NULL;
rw->rw_pid = 0;
rw->rw_child_slot = 0;
@ -3414,7 +3414,7 @@ CleanupBackend(int pid,
BackgroundWorkerStopNotifications(bp->pid);
}
dlist_delete(iter.cur);
free(bp);
pfree(bp);
break;
}
}
@ -3470,7 +3470,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
#ifdef EXEC_BACKEND
ShmemBackendArrayRemove(rw->rw_backend);
#endif
free(rw->rw_backend);
pfree(rw->rw_backend);
rw->rw_backend = NULL;
rw->rw_pid = 0;
rw->rw_child_slot = 0;
@ -3507,7 +3507,7 @@ HandleChildCrash(int pid, int exitstatus, const char *procname)
#endif
}
dlist_delete(iter.cur);
free(bp);
pfree(bp);
/* Keep looping so we can signal remaining backends */
}
else
@ -4083,7 +4083,7 @@ BackendStartup(Port *port)
* Create backend data structure. Better before the fork() so we can
* handle failure cleanly.
*/
bn = (Backend *) malloc(sizeof(Backend));
bn = (Backend *) palloc_extended(sizeof(Backend), MCXT_ALLOC_NO_OOM);
if (!bn)
{
ereport(LOG,
@ -4099,7 +4099,7 @@ BackendStartup(Port *port)
*/
if (!RandomCancelKey(&MyCancelKey))
{
free(bn);
pfree(bn);
ereport(LOG,
(errcode(ERRCODE_INTERNAL_ERROR),
errmsg("could not generate random cancel key")));
@ -4129,8 +4129,6 @@ BackendStartup(Port *port)
pid = fork_process();
if (pid == 0) /* child */
{
free(bn);
/* Detangle from postmaster */
InitPostmasterChild();
@ -4161,7 +4159,7 @@ BackendStartup(Port *port)
if (!bn->dead_end)
(void) ReleasePostmasterChildSlot(bn->child_slot);
free(bn);
pfree(bn);
errno = save_errno;
ereport(LOG,
(errmsg("could not fork new process for connection: %m")));
@ -5424,7 +5422,7 @@ StartAutovacuumWorker(void)
return;
}
bn = (Backend *) malloc(sizeof(Backend));
bn = (Backend *) palloc_extended(sizeof(Backend), MCXT_ALLOC_NO_OOM);
if (bn)
{
bn->cancel_key = MyCancelKey;
@ -5451,7 +5449,7 @@ StartAutovacuumWorker(void)
* logged by StartAutoVacWorker
*/
(void) ReleasePostmasterChildSlot(bn->child_slot);
free(bn);
pfree(bn);
}
else
ereport(LOG,
@ -5696,7 +5694,7 @@ do_start_bgworker(RegisteredBgWorker *rw)
/* undo what assign_backendlist_entry did */
ReleasePostmasterChildSlot(rw->rw_child_slot);
rw->rw_child_slot = 0;
free(rw->rw_backend);
pfree(rw->rw_backend);
rw->rw_backend = NULL;
/* mark entry as crashed, so we'll try again later */
rw->rw_crashed_at = GetCurrentTimestamp();
@ -5822,7 +5820,7 @@ assign_backendlist_entry(RegisteredBgWorker *rw)
return false;
}
bn = malloc(sizeof(Backend));
bn = palloc_extended(sizeof(Backend), MCXT_ALLOC_NO_OOM);
if (bn == NULL)
{
ereport(LOG,