postgresql/src/backend/postmaster/auxprocess.c

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

138 lines
3.2 KiB
C
Raw Normal View History

/*-------------------------------------------------------------------------
* auxprocess.c
* functions related to auxiliary processes.
*
*
* Portions Copyright (c) 1996-2024, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
* src/backend/postmaster/auxprocess.c
*-------------------------------------------------------------------------
*/
#include "postgres.h"
#include <unistd.h>
#include <signal.h>
#include "miscadmin.h"
#include "pgstat.h"
#include "postmaster/auxprocess.h"
#include "postmaster/bgwriter.h"
#include "postmaster/startup.h"
#include "postmaster/walsummarizer.h"
#include "postmaster/walwriter.h"
#include "replication/walreceiver.h"
#include "storage/condition_variable.h"
#include "storage/ipc.h"
#include "storage/proc.h"
#include "storage/procsignal.h"
#include "utils/ps_status.h"
static void ShutdownAuxiliaryProcess(int code, Datum arg);
/*
* AuxiliaryProcessMain
*
* The main entry point for auxiliary processes, such as the bgwriter,
* walwriter, walreceiver, bootstrapper and the shared memory checker code.
*
* This code is here just because of historical reasons.
*/
void
AuxiliaryProcessMain(BackendType auxtype)
{
Assert(IsUnderPostmaster);
MyBackendType = auxtype;
init_ps_display(NULL);
SetProcessingMode(BootstrapProcessing);
IgnoreSystemIndexes = true;
/*
* As an auxiliary process, we aren't going to do the full InitPostgres
* pushups, but there are a couple of things that need to get lit up even
* in an auxiliary process.
*/
/*
* Create a PGPROC so we can use LWLocks and access shared memory.
*/
InitAuxiliaryProcess();
BaseInit();
Redefine backend ID to be an index into the proc array Previously, backend ID was an index into the ProcState array, in the shared cache invalidation manager (sinvaladt.c). The entry in the ProcState array was reserved at backend startup by scanning the array for a free entry, and that was also when the backend got its backend ID. Things become slightly simpler if we redefine backend ID to be the index into the PGPROC array, and directly use it also as an index to the ProcState array. This uses a little more memory, as we reserve a few extra slots in the ProcState array for aux processes that don't need them, but the simplicity is worth it. Aux processes now also have a backend ID. This simplifies the reservation of BackendStatusArray and ProcSignal slots. You can now convert a backend ID into an index into the PGPROC array simply by subtracting 1. We still use 0-based "pgprocnos" in various places, for indexes into the PGPROC array, but the only difference now is that backend IDs start at 1 while pgprocnos start at 0. (The next commmit will get rid of the term "backend ID" altogether and make everything 0-based.) There is still a 'backendId' field in PGPROC, now part of 'vxid' which encapsulates the backend ID and local transaction ID together. It's needed for prepared xacts. For regular backends, the backendId is always equal to pgprocno + 1, but for prepared xact PGPROC entries, it's the ID of the original backend that processed the transaction. Reviewed-by: Andres Freund, Reid Thompson Discussion: https://www.postgresql.org/message-id/8171f1aa-496f-46a6-afc3-c46fe7a9b407@iki.fi
2024-03-03 18:37:28 +01:00
ProcSignalInit();
/*
* Auxiliary processes don't run transactions, but they may need a
* resource owner anyway to manage buffer pins acquired outside
* transactions (and, perhaps, other things in future).
*/
CreateAuxProcessResourceOwner();
/* Initialize backend status information */
pgstat_beinit();
pgstat_bestart();
/* register a before-shutdown callback for LWLock cleanup */
before_shmem_exit(ShutdownAuxiliaryProcess, 0);
SetProcessingMode(NormalProcessing);
switch (MyBackendType)
{
case B_STARTUP:
StartupProcessMain();
proc_exit(1);
case B_ARCHIVER:
PgArchiverMain();
proc_exit(1);
case B_BG_WRITER:
BackgroundWriterMain();
proc_exit(1);
case B_CHECKPOINTER:
CheckpointerMain();
proc_exit(1);
case B_WAL_WRITER:
WalWriterMain();
proc_exit(1);
case B_WAL_RECEIVER:
WalReceiverMain();
proc_exit(1);
case B_WAL_SUMMARIZER:
WalSummarizerMain();
proc_exit(1);
default:
elog(PANIC, "unrecognized process type: %d", (int) MyBackendType);
proc_exit(1);
}
}
/*
* Begin shutdown of an auxiliary process. This is approximately the equivalent
* of ShutdownPostgres() in postinit.c. We can't run transactions in an
* auxiliary process, so most of the work of AbortTransaction() is not needed,
* but we do need to make sure we've released any LWLocks we are holding.
* (This is only critical during an error exit.)
*/
static void
ShutdownAuxiliaryProcess(int code, Datum arg)
{
LWLockReleaseAll();
ConditionVariableCancelSleep();
pgstat_report_wait_end();
}