Age Owner TLA 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
612 andres 57 CBC 1781 : AuxiliaryProcessMain(AuxProcType auxtype)
58 : {
59 1781 : Assert(IsUnderPostmaster);
60 :
61 1781 : MyAuxProcType = auxtype;
62 :
63 1781 : switch (MyAuxProcType)
64 : {
65 557 : case StartupProcess:
66 557 : MyBackendType = B_STARTUP;
67 557 : break;
68 10 : case ArchiverProcess:
69 10 : MyBackendType = B_ARCHIVER;
70 10 : break;
71 355 : case BgWriterProcess:
72 355 : MyBackendType = B_BG_WRITER;
73 355 : break;
74 355 : case CheckpointerProcess:
75 355 : MyBackendType = B_CHECKPOINTER;
76 355 : break;
77 322 : case WalWriterProcess:
78 322 : MyBackendType = B_WAL_WRITER;
79 322 : break;
80 182 : case WalReceiverProcess:
81 182 : MyBackendType = B_WAL_RECEIVER;
82 182 : break;
612 andres 83 UBC 0 : default:
241 rhaas 84 UNC 0 : elog(PANIC, "unrecognized process type: %d", (int) MyAuxProcType);
85 : MyBackendType = B_INVALID;
86 : }
87 :
612 andres 88 CBC 1781 : init_ps_display(NULL);
89 :
90 1781 : SetProcessingMode(BootstrapProcessing);
91 1781 : 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 1781 : InitAuxiliaryProcess();
105 : #endif
106 :
107 1781 : 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 : */
362 rhaas 119 1781 : 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 : */
612 andres 126 1781 : CreateAuxProcessResourceOwner();
127 :
128 :
129 : /* Initialize backend status information */
130 1781 : pgstat_beinit();
131 1781 : pgstat_bestart();
132 :
133 : /* register a before-shutdown callback for LWLock cleanup */
134 1781 : before_shmem_exit(ShutdownAuxiliaryProcess, 0);
135 :
136 1781 : SetProcessingMode(NormalProcessing);
137 :
138 1781 : switch (MyAuxProcType)
139 : {
140 557 : case StartupProcess:
141 557 : StartupProcessMain();
142 : proc_exit(1);
143 :
144 10 : case ArchiverProcess:
145 10 : PgArchiverMain();
146 : proc_exit(1);
147 :
148 355 : case BgWriterProcess:
149 355 : BackgroundWriterMain();
150 : proc_exit(1);
151 :
152 355 : case CheckpointerProcess:
153 355 : CheckpointerMain();
154 : proc_exit(1);
155 :
156 322 : case WalWriterProcess:
157 322 : WalWriterMain();
158 : proc_exit(1);
159 :
160 182 : case WalReceiverProcess:
161 182 : WalReceiverMain();
162 : proc_exit(1);
163 :
612 andres 164 UBC 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
612 andres 178 CBC 1781 : ShutdownAuxiliaryProcess(int code, Datum arg)
179 : {
180 1781 : LWLockReleaseAll();
181 1781 : ConditionVariableCancelSleep();
182 1781 : pgstat_report_wait_end();
183 1781 : }
|