Line data Source code
1 : /*------------------------------------------------------------------------- 2 : * auxprocess.c 3 : * functions related to auxiliary processes. 4 : * 5 : * 6 : * Portions Copyright (c) 1996-2023, PostgreSQL Global Development Group 7 : * Portions Copyright (c) 1994, Regents of the University of California 8 : * 9 : * IDENTIFICATION 10 : * src/backend/postmaster/auxprocess.c 11 : *------------------------------------------------------------------------- 12 : */ 13 : #include "postgres.h" 14 : 15 : #include <unistd.h> 16 : #include <signal.h> 17 : 18 : #include "libpq/pqsignal.h" 19 : #include "miscadmin.h" 20 : #include "pgstat.h" 21 : #include "postmaster/auxprocess.h" 22 : #include "postmaster/bgwriter.h" 23 : #include "postmaster/startup.h" 24 : #include "postmaster/walwriter.h" 25 : #include "replication/walreceiver.h" 26 : #include "storage/bufmgr.h" 27 : #include "storage/bufpage.h" 28 : #include "storage/condition_variable.h" 29 : #include "storage/ipc.h" 30 : #include "storage/proc.h" 31 : #include "tcop/tcopprot.h" 32 : #include "utils/memutils.h" 33 : #include "utils/ps_status.h" 34 : #include "utils/rel.h" 35 : 36 : 37 : static void ShutdownAuxiliaryProcess(int code, Datum arg); 38 : 39 : 40 : /* ---------------- 41 : * global variables 42 : * ---------------- 43 : */ 44 : 45 : AuxProcType MyAuxProcType = NotAnAuxProcess; /* declared in miscadmin.h */ 46 : 47 : 48 : /* 49 : * AuxiliaryProcessMain 50 : * 51 : * The main entry point for auxiliary processes, such as the bgwriter, 52 : * walwriter, walreceiver, bootstrapper and the shared memory checker code. 53 : * 54 : * This code is here just because of historical reasons. 55 : */ 56 : void 57 3488 : AuxiliaryProcessMain(AuxProcType auxtype) 58 : { 59 : Assert(IsUnderPostmaster); 60 : 61 3488 : MyAuxProcType = auxtype; 62 : 63 3488 : switch (MyAuxProcType) 64 : { 65 1108 : case StartupProcess: 66 1108 : MyBackendType = B_STARTUP; 67 1108 : break; 68 20 : case ArchiverProcess: 69 20 : MyBackendType = B_ARCHIVER; 70 20 : break; 71 694 : case BgWriterProcess: 72 694 : MyBackendType = B_BG_WRITER; 73 694 : break; 74 694 : case CheckpointerProcess: 75 694 : MyBackendType = B_CHECKPOINTER; 76 694 : break; 77 632 : case WalWriterProcess: 78 632 : MyBackendType = B_WAL_WRITER; 79 632 : break; 80 340 : case WalReceiverProcess: 81 340 : MyBackendType = B_WAL_RECEIVER; 82 340 : break; 83 0 : default: 84 0 : elog(PANIC, "unrecognized process type: %d", (int) MyAuxProcType); 85 : MyBackendType = B_INVALID; 86 : } 87 : 88 3488 : init_ps_display(NULL); 89 : 90 3488 : SetProcessingMode(BootstrapProcessing); 91 3488 : IgnoreSystemIndexes = true; 92 : 93 : /* 94 : * As an auxiliary process, we aren't going to do the full InitPostgres 95 : * pushups, but there are a couple of things that need to get lit up even 96 : * in an auxiliary process. 97 : */ 98 : 99 : /* 100 : * Create a PGPROC so we can use LWLocks. In the EXEC_BACKEND case, this 101 : * was already done by SubPostmasterMain(). 102 : */ 103 : #ifndef EXEC_BACKEND 104 3488 : InitAuxiliaryProcess(); 105 : #endif 106 : 107 3488 : BaseInit(); 108 : 109 : /* 110 : * Assign the ProcSignalSlot for an auxiliary process. Since it doesn't 111 : * have a BackendId, the slot is statically allocated based on the 112 : * auxiliary process type (MyAuxProcType). Backends use slots indexed in 113 : * the range from 1 to MaxBackends (inclusive), so we use MaxBackends + 114 : * AuxProcType + 1 as the index of the slot for an auxiliary process. 115 : * 116 : * This will need rethinking if we ever want more than one of a particular 117 : * auxiliary process type. 118 : */ 119 3488 : ProcSignalInit(MaxBackends + MyAuxProcType + 1); 120 : 121 : /* 122 : * Auxiliary processes don't run transactions, but they may need a 123 : * resource owner anyway to manage buffer pins acquired outside 124 : * transactions (and, perhaps, other things in future). 125 : */ 126 3488 : CreateAuxProcessResourceOwner(); 127 : 128 : 129 : /* Initialize backend status information */ 130 3488 : pgstat_beinit(); 131 3488 : pgstat_bestart(); 132 : 133 : /* register a before-shutdown callback for LWLock cleanup */ 134 3488 : before_shmem_exit(ShutdownAuxiliaryProcess, 0); 135 : 136 3488 : SetProcessingMode(NormalProcessing); 137 : 138 3488 : switch (MyAuxProcType) 139 : { 140 1108 : case StartupProcess: 141 1108 : StartupProcessMain(); 142 : proc_exit(1); 143 : 144 20 : case ArchiverProcess: 145 20 : PgArchiverMain(); 146 : proc_exit(1); 147 : 148 694 : case BgWriterProcess: 149 694 : BackgroundWriterMain(); 150 : proc_exit(1); 151 : 152 694 : case CheckpointerProcess: 153 694 : CheckpointerMain(); 154 : proc_exit(1); 155 : 156 632 : case WalWriterProcess: 157 632 : WalWriterMain(); 158 : proc_exit(1); 159 : 160 340 : case WalReceiverProcess: 161 340 : WalReceiverMain(); 162 : proc_exit(1); 163 : 164 0 : default: 165 0 : elog(PANIC, "unrecognized process type: %d", (int) MyAuxProcType); 166 : proc_exit(1); 167 : } 168 : } 169 : 170 : /* 171 : * Begin shutdown of an auxiliary process. This is approximately the equivalent 172 : * of ShutdownPostgres() in postinit.c. We can't run transactions in an 173 : * auxiliary process, so most of the work of AbortTransaction() is not needed, 174 : * but we do need to make sure we've released any LWLocks we are holding. 175 : * (This is only critical during an error exit.) 176 : */ 177 : static void 178 3488 : ShutdownAuxiliaryProcess(int code, Datum arg) 179 : { 180 3488 : LWLockReleaseAll(); 181 3488 : ConditionVariableCancelSleep(); 182 3488 : pgstat_report_wait_end(); 183 3488 : }