/*------------------------------------------------------------------------- * auxprocess.c * functions related to auxiliary processes. * * * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION * src/backend/postmaster/auxprocess.c *------------------------------------------------------------------------- */ #include "postgres.h" #include #include #include "libpq/pqsignal.h" #include "miscadmin.h" #include "pgstat.h" #include "postmaster/auxprocess.h" #include "postmaster/bgwriter.h" #include "postmaster/startup.h" #include "postmaster/walwriter.h" #include "replication/walreceiver.h" #include "storage/bufmgr.h" #include "storage/bufpage.h" #include "storage/condition_variable.h" #include "storage/ipc.h" #include "storage/proc.h" #include "tcop/tcopprot.h" #include "utils/memutils.h" #include "utils/ps_status.h" #include "utils/rel.h" static void ShutdownAuxiliaryProcess(int code, Datum arg); /* ---------------- * global variables * ---------------- */ AuxProcType MyAuxProcType = NotAnAuxProcess; /* declared in miscadmin.h */ /* * 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(AuxProcType auxtype) { Assert(IsUnderPostmaster); MyAuxProcType = auxtype; switch (MyAuxProcType) { case StartupProcess: MyBackendType = B_STARTUP; break; case ArchiverProcess: MyBackendType = B_ARCHIVER; break; case BgWriterProcess: MyBackendType = B_BG_WRITER; break; case CheckpointerProcess: MyBackendType = B_CHECKPOINTER; break; case WalWriterProcess: MyBackendType = B_WAL_WRITER; break; case WalReceiverProcess: MyBackendType = B_WAL_RECEIVER; break; default: elog(PANIC, "unrecognized process type: %d", (int) MyAuxProcType); MyBackendType = B_INVALID; } 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. In the EXEC_BACKEND case, this * was already done by SubPostmasterMain(). */ #ifndef EXEC_BACKEND InitAuxiliaryProcess(); #endif BaseInit(); /* * Assign the ProcSignalSlot for an auxiliary process. Since it doesn't * have a BackendId, the slot is statically allocated based on the * auxiliary process type (MyAuxProcType). Backends use slots indexed in * the range from 1 to MaxBackends (inclusive), so we use MaxBackends + * AuxProcType + 1 as the index of the slot for an auxiliary process. * * This will need rethinking if we ever want more than one of a particular * auxiliary process type. */ ProcSignalInit(MaxBackends + MyAuxProcType + 1); /* * 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 (MyAuxProcType) { case StartupProcess: StartupProcessMain(); proc_exit(1); case ArchiverProcess: PgArchiverMain(); proc_exit(1); case BgWriterProcess: BackgroundWriterMain(); proc_exit(1); case CheckpointerProcess: CheckpointerMain(); proc_exit(1); case WalWriterProcess: WalWriterMain(); proc_exit(1); case WalReceiverProcess: WalReceiverMain(); proc_exit(1); default: elog(PANIC, "unrecognized process type: %d", (int) MyAuxProcType); 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(); }