/src/postgres/src/backend/utils/init/postinit.c
Line | Count | Source |
1 | | /*------------------------------------------------------------------------- |
2 | | * |
3 | | * postinit.c |
4 | | * postgres initialization utilities |
5 | | * |
6 | | * Portions Copyright (c) 1996-2026, PostgreSQL Global Development Group |
7 | | * Portions Copyright (c) 1994, Regents of the University of California |
8 | | * |
9 | | * |
10 | | * IDENTIFICATION |
11 | | * src/backend/utils/init/postinit.c |
12 | | * |
13 | | * |
14 | | *------------------------------------------------------------------------- |
15 | | */ |
16 | | #include "postgres.h" |
17 | | |
18 | | #include <ctype.h> |
19 | | #include <fcntl.h> |
20 | | #include <unistd.h> |
21 | | |
22 | | #include "access/genam.h" |
23 | | #include "access/heapam.h" |
24 | | #include "access/htup_details.h" |
25 | | #include "access/session.h" |
26 | | #include "access/tableam.h" |
27 | | #include "access/xact.h" |
28 | | #include "access/xlog.h" |
29 | | #include "access/xloginsert.h" |
30 | | #include "catalog/namespace.h" |
31 | | #include "catalog/pg_authid.h" |
32 | | #include "catalog/pg_collation.h" |
33 | | #include "catalog/pg_database.h" |
34 | | #include "catalog/pg_db_role_setting.h" |
35 | | #include "catalog/pg_tablespace.h" |
36 | | #include "libpq/auth.h" |
37 | | #include "libpq/libpq-be.h" |
38 | | #include "mb/pg_wchar.h" |
39 | | #include "miscadmin.h" |
40 | | #include "pgstat.h" |
41 | | #include "port/pg_bitutils.h" |
42 | | #include "postmaster/autovacuum.h" |
43 | | #include "postmaster/postmaster.h" |
44 | | #include "replication/slot.h" |
45 | | #include "replication/slotsync.h" |
46 | | #include "replication/walsender.h" |
47 | | #include "storage/aio_subsys.h" |
48 | | #include "storage/bufmgr.h" |
49 | | #include "storage/fd.h" |
50 | | #include "storage/ipc.h" |
51 | | #include "storage/lmgr.h" |
52 | | #include "storage/proc.h" |
53 | | #include "storage/procarray.h" |
54 | | #include "storage/procnumber.h" |
55 | | #include "storage/procsignal.h" |
56 | | #include "storage/sinvaladt.h" |
57 | | #include "storage/smgr.h" |
58 | | #include "storage/sync.h" |
59 | | #include "tcop/backend_startup.h" |
60 | | #include "tcop/tcopprot.h" |
61 | | #include "utils/acl.h" |
62 | | #include "utils/builtins.h" |
63 | | #include "utils/fmgroids.h" |
64 | | #include "utils/guc_hooks.h" |
65 | | #include "utils/injection_point.h" |
66 | | #include "utils/memutils.h" |
67 | | #include "utils/pg_locale.h" |
68 | | #include "utils/portal.h" |
69 | | #include "utils/ps_status.h" |
70 | | #include "utils/snapmgr.h" |
71 | | #include "utils/syscache.h" |
72 | | #include "utils/timeout.h" |
73 | | |
74 | | /* has this backend called EmitConnectionWarnings()? */ |
75 | | static bool ConnectionWarningsEmitted; |
76 | | |
77 | | typedef struct ConnectionWarning |
78 | | { |
79 | | char *message; |
80 | | char *detail; |
81 | | ConnectionWarningFilter filter; |
82 | | } ConnectionWarning; |
83 | | |
84 | | /* warnings to send via EmitConnectionWarnings() */ |
85 | | static List *ConnectionWarnings; |
86 | | |
87 | | static HeapTuple GetDatabaseTuple(const char *dbname); |
88 | | static HeapTuple GetDatabaseTupleByOid(Oid dboid); |
89 | | static void PerformAuthentication(Port *port); |
90 | | static void CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connections); |
91 | | static void ShutdownPostgres(int code, Datum arg); |
92 | | static void StatementTimeoutHandler(void); |
93 | | static void LockTimeoutHandler(void); |
94 | | static void IdleInTransactionSessionTimeoutHandler(void); |
95 | | static void TransactionTimeoutHandler(void); |
96 | | static void IdleSessionTimeoutHandler(void); |
97 | | static void IdleStatsUpdateTimeoutHandler(void); |
98 | | static void ClientCheckTimeoutHandler(void); |
99 | | static bool ThereIsAtLeastOneRole(void); |
100 | | static void process_startup_options(Port *port, bool am_superuser); |
101 | | static void process_settings(Oid databaseid, Oid roleid); |
102 | | static void EmitConnectionWarnings(void); |
103 | | |
104 | | |
105 | | /*** InitPostgres support ***/ |
106 | | |
107 | | |
108 | | /* |
109 | | * GetDatabaseTuple -- fetch the pg_database row for a database |
110 | | * |
111 | | * This is used during backend startup when we don't yet have any access to |
112 | | * system catalogs in general. In the worst case, we can seqscan pg_database |
113 | | * using nothing but the hard-wired descriptor that relcache.c creates for |
114 | | * pg_database. In more typical cases, relcache.c was able to load |
115 | | * descriptors for both pg_database and its indexes from the shared relcache |
116 | | * cache file, and so we can do an indexscan. criticalSharedRelcachesBuilt |
117 | | * tells whether we got the cached descriptors. |
118 | | */ |
119 | | static HeapTuple |
120 | | GetDatabaseTuple(const char *dbname) |
121 | 0 | { |
122 | 0 | HeapTuple tuple; |
123 | 0 | Relation relation; |
124 | 0 | SysScanDesc scan; |
125 | 0 | ScanKeyData key[1]; |
126 | | |
127 | | /* |
128 | | * form a scan key |
129 | | */ |
130 | 0 | ScanKeyInit(&key[0], |
131 | 0 | Anum_pg_database_datname, |
132 | 0 | BTEqualStrategyNumber, F_NAMEEQ, |
133 | 0 | CStringGetDatum(dbname)); |
134 | | |
135 | | /* |
136 | | * Open pg_database and fetch a tuple. Force heap scan if we haven't yet |
137 | | * built the critical shared relcache entries (i.e., we're starting up |
138 | | * without a shared relcache cache file). |
139 | | */ |
140 | 0 | relation = table_open(DatabaseRelationId, AccessShareLock); |
141 | 0 | scan = systable_beginscan(relation, DatabaseNameIndexId, |
142 | 0 | criticalSharedRelcachesBuilt, |
143 | 0 | NULL, |
144 | 0 | 1, key); |
145 | |
|
146 | 0 | tuple = systable_getnext(scan); |
147 | | |
148 | | /* Must copy tuple before releasing buffer */ |
149 | 0 | if (HeapTupleIsValid(tuple)) |
150 | 0 | tuple = heap_copytuple(tuple); |
151 | | |
152 | | /* all done */ |
153 | 0 | systable_endscan(scan); |
154 | 0 | table_close(relation, AccessShareLock); |
155 | |
|
156 | 0 | return tuple; |
157 | 0 | } |
158 | | |
159 | | /* |
160 | | * GetDatabaseTupleByOid -- as above, but search by database OID |
161 | | */ |
162 | | static HeapTuple |
163 | | GetDatabaseTupleByOid(Oid dboid) |
164 | 0 | { |
165 | 0 | HeapTuple tuple; |
166 | 0 | Relation relation; |
167 | 0 | SysScanDesc scan; |
168 | 0 | ScanKeyData key[1]; |
169 | | |
170 | | /* |
171 | | * form a scan key |
172 | | */ |
173 | 0 | ScanKeyInit(&key[0], |
174 | 0 | Anum_pg_database_oid, |
175 | 0 | BTEqualStrategyNumber, F_OIDEQ, |
176 | 0 | ObjectIdGetDatum(dboid)); |
177 | | |
178 | | /* |
179 | | * Open pg_database and fetch a tuple. Force heap scan if we haven't yet |
180 | | * built the critical shared relcache entries (i.e., we're starting up |
181 | | * without a shared relcache cache file). |
182 | | */ |
183 | 0 | relation = table_open(DatabaseRelationId, AccessShareLock); |
184 | 0 | scan = systable_beginscan(relation, DatabaseOidIndexId, |
185 | 0 | criticalSharedRelcachesBuilt, |
186 | 0 | NULL, |
187 | 0 | 1, key); |
188 | |
|
189 | 0 | tuple = systable_getnext(scan); |
190 | | |
191 | | /* Must copy tuple before releasing buffer */ |
192 | 0 | if (HeapTupleIsValid(tuple)) |
193 | 0 | tuple = heap_copytuple(tuple); |
194 | | |
195 | | /* all done */ |
196 | 0 | systable_endscan(scan); |
197 | 0 | table_close(relation, AccessShareLock); |
198 | |
|
199 | 0 | return tuple; |
200 | 0 | } |
201 | | |
202 | | |
203 | | /* |
204 | | * PerformAuthentication -- authenticate a remote client |
205 | | * |
206 | | * returns: nothing. Will not return at all if there's any failure. |
207 | | */ |
208 | | static void |
209 | | PerformAuthentication(Port *port) |
210 | | { |
211 | | /* This should be set already, but let's make sure */ |
212 | | ClientAuthInProgress = true; /* limit visibility of log messages */ |
213 | | |
214 | | /* |
215 | | * In EXEC_BACKEND case, we didn't inherit the contents of pg_hba.conf |
216 | | * etcetera from the postmaster, and have to load them ourselves. |
217 | | * |
218 | | * FIXME: [fork/exec] Ugh. Is there a way around this overhead? |
219 | | */ |
220 | | #ifdef EXEC_BACKEND |
221 | | |
222 | | /* |
223 | | * load_hba() and load_ident() want to work within the PostmasterContext, |
224 | | * so create that if it doesn't exist (which it won't). We'll delete it |
225 | | * again later, in PostgresMain. |
226 | | */ |
227 | | if (PostmasterContext == NULL) |
228 | | PostmasterContext = AllocSetContextCreate(TopMemoryContext, |
229 | | "Postmaster", |
230 | | ALLOCSET_DEFAULT_SIZES); |
231 | | |
232 | | if (!load_hba()) |
233 | | { |
234 | | /* |
235 | | * It makes no sense to continue if we fail to load the HBA file, |
236 | | * since there is no way to connect to the database in this case. |
237 | | */ |
238 | | ereport(FATAL, |
239 | | /* translator: %s is a configuration file */ |
240 | | (errmsg("could not load %s", HbaFileName))); |
241 | | } |
242 | | |
243 | | if (!load_ident()) |
244 | | { |
245 | | /* |
246 | | * It is ok to continue if we fail to load the IDENT file, although it |
247 | | * means that you cannot log in using any of the authentication |
248 | | * methods that need a user name mapping. load_ident() already logged |
249 | | * the details of error to the log. |
250 | | */ |
251 | | } |
252 | | #endif |
253 | | |
254 | | /* Capture authentication start time for logging */ |
255 | | conn_timing.auth_start = GetCurrentTimestamp(); |
256 | | |
257 | | /* |
258 | | * Set up a timeout in case a buggy or malicious client fails to respond |
259 | | * during authentication. Since we're inside a transaction and might do |
260 | | * database access, we have to use the statement_timeout infrastructure. |
261 | | */ |
262 | | enable_timeout_after(STATEMENT_TIMEOUT, AuthenticationTimeout * 1000); |
263 | | |
264 | | /* |
265 | | * Now perform authentication exchange. |
266 | | */ |
267 | | set_ps_display("authentication"); |
268 | | ClientAuthentication(port); /* might not return, if failure */ |
269 | | |
270 | | /* |
271 | | * Done with authentication. Disable the timeout, and log if needed. |
272 | | */ |
273 | | disable_timeout(STATEMENT_TIMEOUT, false); |
274 | | |
275 | | /* Capture authentication end time for logging */ |
276 | | conn_timing.auth_end = GetCurrentTimestamp(); |
277 | | |
278 | | if (log_connections & LOG_CONNECTION_AUTHORIZATION) |
279 | | { |
280 | | StringInfoData logmsg; |
281 | | |
282 | | initStringInfo(&logmsg); |
283 | | if (am_walsender) |
284 | | appendStringInfo(&logmsg, _("replication connection authorized: user=%s"), |
285 | | port->user_name); |
286 | | else |
287 | | appendStringInfo(&logmsg, _("connection authorized: user=%s"), |
288 | | port->user_name); |
289 | | if (!am_walsender) |
290 | | appendStringInfo(&logmsg, _(" database=%s"), port->database_name); |
291 | | |
292 | | if (port->application_name != NULL) |
293 | | appendStringInfo(&logmsg, _(" application_name=%s"), |
294 | | port->application_name); |
295 | | |
296 | | #ifdef USE_SSL |
297 | | if (port->ssl_in_use) |
298 | | appendStringInfo(&logmsg, _(" SSL enabled (protocol=%s, cipher=%s, bits=%d)"), |
299 | | be_tls_get_version(port), |
300 | | be_tls_get_cipher(port), |
301 | | be_tls_get_cipher_bits(port)); |
302 | | #endif |
303 | | #ifdef ENABLE_GSS |
304 | | if (port->gss) |
305 | | { |
306 | | const char *princ = be_gssapi_get_princ(port); |
307 | | |
308 | | if (princ) |
309 | | appendStringInfo(&logmsg, |
310 | | _(" GSS (authenticated=%s, encrypted=%s, delegated_credentials=%s, principal=%s)"), |
311 | | be_gssapi_get_auth(port) ? _("yes") : _("no"), |
312 | | be_gssapi_get_enc(port) ? _("yes") : _("no"), |
313 | | be_gssapi_get_delegation(port) ? _("yes") : _("no"), |
314 | | princ); |
315 | | else |
316 | | appendStringInfo(&logmsg, |
317 | | _(" GSS (authenticated=%s, encrypted=%s, delegated_credentials=%s)"), |
318 | | be_gssapi_get_auth(port) ? _("yes") : _("no"), |
319 | | be_gssapi_get_enc(port) ? _("yes") : _("no"), |
320 | | be_gssapi_get_delegation(port) ? _("yes") : _("no")); |
321 | | } |
322 | | #endif |
323 | | |
324 | | ereport(LOG, errmsg_internal("%s", logmsg.data)); |
325 | | pfree(logmsg.data); |
326 | | } |
327 | | |
328 | | set_ps_display("startup"); |
329 | | |
330 | | ClientAuthInProgress = false; /* client_min_messages is active now */ |
331 | | } |
332 | | |
333 | | |
334 | | /* |
335 | | * CheckMyDatabase -- fetch information from the pg_database entry for our DB |
336 | | */ |
337 | | static void |
338 | | CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connections) |
339 | | { |
340 | | HeapTuple tup; |
341 | | Form_pg_database dbform; |
342 | | Datum datum; |
343 | | bool isnull; |
344 | | char *collate; |
345 | | char *ctype; |
346 | | |
347 | | /* Fetch our pg_database row normally, via syscache */ |
348 | | tup = SearchSysCache1(DATABASEOID, ObjectIdGetDatum(MyDatabaseId)); |
349 | | if (!HeapTupleIsValid(tup)) |
350 | | elog(ERROR, "cache lookup failed for database %u", MyDatabaseId); |
351 | | dbform = (Form_pg_database) GETSTRUCT(tup); |
352 | | |
353 | | /* This recheck is strictly paranoia */ |
354 | | if (strcmp(name, NameStr(dbform->datname)) != 0) |
355 | | ereport(FATAL, |
356 | | (errcode(ERRCODE_UNDEFINED_DATABASE), |
357 | | errmsg("database \"%s\" has disappeared from pg_database", |
358 | | name), |
359 | | errdetail("Database OID %u now seems to belong to \"%s\".", |
360 | | MyDatabaseId, NameStr(dbform->datname)))); |
361 | | |
362 | | /* |
363 | | * Check permissions to connect to the database. |
364 | | * |
365 | | * These checks are not enforced when in standalone mode, so that there is |
366 | | * a way to recover from disabling all access to all databases, for |
367 | | * example "UPDATE pg_database SET datallowconn = false;". |
368 | | */ |
369 | | if (IsUnderPostmaster) |
370 | | { |
371 | | /* |
372 | | * Check that the database is currently allowing connections. |
373 | | * (Background processes can override this test and the next one by |
374 | | * setting override_allow_connections.) |
375 | | */ |
376 | | if (!dbform->datallowconn && !override_allow_connections) |
377 | | ereport(FATAL, |
378 | | (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), |
379 | | errmsg("database \"%s\" is not currently accepting connections", |
380 | | name))); |
381 | | |
382 | | /* |
383 | | * Check privilege to connect to the database. (The am_superuser test |
384 | | * is redundant, but since we have the flag, might as well check it |
385 | | * and save a few cycles.) |
386 | | */ |
387 | | if (!am_superuser && !override_allow_connections && |
388 | | object_aclcheck(DatabaseRelationId, MyDatabaseId, GetUserId(), |
389 | | ACL_CONNECT) != ACLCHECK_OK) |
390 | | ereport(FATAL, |
391 | | (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), |
392 | | errmsg("permission denied for database \"%s\"", name), |
393 | | errdetail("User does not have CONNECT privilege."))); |
394 | | |
395 | | /* |
396 | | * Check connection limit for this database. We enforce the limit |
397 | | * only for regular backends, since other process types have their own |
398 | | * PGPROC pools. |
399 | | * |
400 | | * There is a race condition here --- we create our PGPROC before |
401 | | * checking for other PGPROCs. If two backends did this at about the |
402 | | * same time, they might both think they were over the limit, while |
403 | | * ideally one should succeed and one fail. Getting that to work |
404 | | * exactly seems more trouble than it is worth, however; instead we |
405 | | * just document that the connection limit is approximate. |
406 | | */ |
407 | | if (dbform->datconnlimit >= 0 && |
408 | | AmRegularBackendProcess() && |
409 | | !am_superuser && |
410 | | CountDBConnections(MyDatabaseId) > dbform->datconnlimit) |
411 | | ereport(FATAL, |
412 | | (errcode(ERRCODE_TOO_MANY_CONNECTIONS), |
413 | | errmsg("too many connections for database \"%s\"", |
414 | | name))); |
415 | | } |
416 | | |
417 | | /* |
418 | | * OK, we're golden. Next to-do item is to save the encoding info out of |
419 | | * the pg_database tuple. |
420 | | */ |
421 | | SetDatabaseEncoding(dbform->encoding); |
422 | | /* Record it as a GUC internal option, too */ |
423 | | SetConfigOption("server_encoding", GetDatabaseEncodingName(), |
424 | | PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT); |
425 | | /* If we have no other source of client_encoding, use server encoding */ |
426 | | SetConfigOption("client_encoding", GetDatabaseEncodingName(), |
427 | | PGC_BACKEND, PGC_S_DYNAMIC_DEFAULT); |
428 | | |
429 | | /* assign locale variables */ |
430 | | datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datcollate); |
431 | | collate = TextDatumGetCString(datum); |
432 | | datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datctype); |
433 | | ctype = TextDatumGetCString(datum); |
434 | | |
435 | | if (pg_perm_setlocale(LC_COLLATE, collate) == NULL) |
436 | | ereport(FATAL, |
437 | | (errmsg("database locale is incompatible with operating system"), |
438 | | errdetail("The database was initialized with LC_COLLATE \"%s\", " |
439 | | " which is not recognized by setlocale().", collate), |
440 | | errhint("Recreate the database with another locale or install the missing locale."))); |
441 | | |
442 | | if (pg_perm_setlocale(LC_CTYPE, ctype) == NULL) |
443 | | ereport(FATAL, |
444 | | (errmsg("database locale is incompatible with operating system"), |
445 | | errdetail("The database was initialized with LC_CTYPE \"%s\", " |
446 | | " which is not recognized by setlocale().", ctype), |
447 | | errhint("Recreate the database with another locale or install the missing locale."))); |
448 | | |
449 | | init_database_collation(); |
450 | | |
451 | | /* |
452 | | * Check collation version. See similar code in |
453 | | * pg_newlocale_from_collation(). Note that here we warn instead of error |
454 | | * in any case, so that we don't prevent connecting. |
455 | | */ |
456 | | datum = SysCacheGetAttr(DATABASEOID, tup, Anum_pg_database_datcollversion, |
457 | | &isnull); |
458 | | if (!isnull) |
459 | | { |
460 | | char *actual_versionstr; |
461 | | char *collversionstr; |
462 | | char *locale; |
463 | | |
464 | | collversionstr = TextDatumGetCString(datum); |
465 | | |
466 | | if (dbform->datlocprovider == COLLPROVIDER_LIBC) |
467 | | locale = collate; |
468 | | else |
469 | | { |
470 | | datum = SysCacheGetAttrNotNull(DATABASEOID, tup, Anum_pg_database_datlocale); |
471 | | locale = TextDatumGetCString(datum); |
472 | | } |
473 | | |
474 | | actual_versionstr = get_collation_actual_version(dbform->datlocprovider, locale); |
475 | | if (!actual_versionstr) |
476 | | /* should not happen */ |
477 | | elog(WARNING, |
478 | | "database \"%s\" has no actual collation version, but a version was recorded", |
479 | | name); |
480 | | else if (strcmp(actual_versionstr, collversionstr) != 0) |
481 | | ereport(WARNING, |
482 | | (errmsg("database \"%s\" has a collation version mismatch", |
483 | | name), |
484 | | errdetail("The database was created using collation version %s, " |
485 | | "but the operating system provides version %s.", |
486 | | collversionstr, actual_versionstr), |
487 | | errhint("Rebuild all objects in this database that use the default collation and run " |
488 | | "ALTER DATABASE %s REFRESH COLLATION VERSION, " |
489 | | "or build PostgreSQL with the right library version.", |
490 | | quote_identifier(name)))); |
491 | | } |
492 | | |
493 | | ReleaseSysCache(tup); |
494 | | } |
495 | | |
496 | | |
497 | | /* |
498 | | * pg_split_opts -- split a string of options and append it to an argv array |
499 | | * |
500 | | * The caller is responsible for ensuring the argv array is large enough. The |
501 | | * maximum possible number of arguments added by this routine is |
502 | | * (strlen(optstr) + 1) / 2. |
503 | | * |
504 | | * Because some option values can contain spaces we allow escaping using |
505 | | * backslashes, with \\ representing a literal backslash. |
506 | | */ |
507 | | void |
508 | | pg_split_opts(char **argv, int *argcp, const char *optstr) |
509 | 0 | { |
510 | 0 | StringInfoData s; |
511 | |
|
512 | 0 | initStringInfo(&s); |
513 | |
|
514 | 0 | while (*optstr) |
515 | 0 | { |
516 | 0 | bool last_was_escape = false; |
517 | |
|
518 | 0 | resetStringInfo(&s); |
519 | | |
520 | | /* skip over leading space */ |
521 | 0 | while (isspace((unsigned char) *optstr)) |
522 | 0 | optstr++; |
523 | |
|
524 | 0 | if (*optstr == '\0') |
525 | 0 | break; |
526 | | |
527 | | /* |
528 | | * Parse a single option, stopping at the first space, unless it's |
529 | | * escaped. |
530 | | */ |
531 | 0 | while (*optstr) |
532 | 0 | { |
533 | 0 | if (isspace((unsigned char) *optstr) && !last_was_escape) |
534 | 0 | break; |
535 | | |
536 | 0 | if (!last_was_escape && *optstr == '\\') |
537 | 0 | last_was_escape = true; |
538 | 0 | else |
539 | 0 | { |
540 | 0 | last_was_escape = false; |
541 | 0 | appendStringInfoChar(&s, *optstr); |
542 | 0 | } |
543 | |
|
544 | 0 | optstr++; |
545 | 0 | } |
546 | | |
547 | | /* now store the option in the next argv[] position */ |
548 | 0 | argv[(*argcp)++] = pstrdup(s.data); |
549 | 0 | } |
550 | |
|
551 | 0 | pfree(s.data); |
552 | 0 | } |
553 | | |
554 | | /* |
555 | | * Initialize MaxBackends value from config options. |
556 | | * |
557 | | * This must be called after modules have had the chance to alter GUCs in |
558 | | * shared_preload_libraries and before shared memory size is determined. |
559 | | * |
560 | | * Note that in EXEC_BACKEND environment, the value is passed down from |
561 | | * postmaster to subprocesses via BackendParameters in SubPostmasterMain; only |
562 | | * postmaster itself and processes not under postmaster control should call |
563 | | * this. |
564 | | */ |
565 | | void |
566 | | InitializeMaxBackends(void) |
567 | 2 | { |
568 | 2 | Assert(MaxBackends == 0); |
569 | | |
570 | | /* Note that this does not include "auxiliary" processes */ |
571 | 2 | MaxBackends = MaxConnections + autovacuum_worker_slots + |
572 | 2 | max_worker_processes + max_wal_senders + NUM_SPECIAL_WORKER_PROCS; |
573 | | |
574 | 2 | if (MaxBackends > MAX_BACKENDS) |
575 | 2 | ereport(ERROR, |
576 | 2 | (errcode(ERRCODE_INVALID_PARAMETER_VALUE), |
577 | 2 | errmsg("too many server processes configured"), |
578 | 2 | errdetail("\"max_connections\" (%d) plus \"autovacuum_worker_slots\" (%d) plus \"max_worker_processes\" (%d) plus \"max_wal_senders\" (%d) must be less than %d.", |
579 | 2 | MaxConnections, autovacuum_worker_slots, |
580 | 2 | max_worker_processes, max_wal_senders, |
581 | 2 | MAX_BACKENDS - (NUM_SPECIAL_WORKER_PROCS - 1)))); |
582 | 2 | } |
583 | | |
584 | | /* |
585 | | * Initialize the number of fast-path lock slots in PGPROC. |
586 | | * |
587 | | * This must be called after modules have had the chance to alter GUCs in |
588 | | * shared_preload_libraries and before shared memory size is determined. |
589 | | */ |
590 | | void |
591 | | InitializeFastPathLocks(void) |
592 | 0 | { |
593 | | /* Should be initialized only once. */ |
594 | 0 | Assert(FastPathLockGroupsPerBackend == 0); |
595 | | |
596 | | /* |
597 | | * Based on the max_locks_per_transaction GUC, as that's a good indicator |
598 | | * of the expected number of locks, figure out the value for |
599 | | * FastPathLockGroupsPerBackend. This must be a power-of-two. We cap the |
600 | | * value at FP_LOCK_GROUPS_PER_BACKEND_MAX and insist the value is at |
601 | | * least 1. |
602 | | * |
603 | | * The default max_locks_per_transaction = 128 means 8 groups by default. |
604 | | */ |
605 | 0 | FastPathLockGroupsPerBackend = |
606 | 0 | Max(Min(pg_nextpower2_32(max_locks_per_xact) / FP_LOCK_SLOTS_PER_GROUP, |
607 | 0 | FP_LOCK_GROUPS_PER_BACKEND_MAX), 1); |
608 | | |
609 | | /* Validate we did get a power-of-two */ |
610 | 0 | Assert(FastPathLockGroupsPerBackend == |
611 | 0 | pg_nextpower2_32(FastPathLockGroupsPerBackend)); |
612 | 0 | } |
613 | | |
614 | | /* |
615 | | * Early initialization of a backend (either standalone or under postmaster). |
616 | | * This happens even before InitPostgres. |
617 | | * |
618 | | * This is separate from InitPostgres because it is also called by auxiliary |
619 | | * processes, such as the background writer process, which may not call |
620 | | * InitPostgres at all. |
621 | | */ |
622 | | void |
623 | | BaseInit(void) |
624 | 0 | { |
625 | 0 | Assert(MyProc != NULL); |
626 | | |
627 | | /* |
628 | | * Initialize our input/output/debugging file descriptors. |
629 | | */ |
630 | 0 | DebugFileOpen(); |
631 | | |
632 | | /* |
633 | | * Initialize file access. Done early so other subsystems can access |
634 | | * files. |
635 | | */ |
636 | 0 | InitFileAccess(); |
637 | | |
638 | | /* |
639 | | * Initialize statistics reporting. This needs to happen early to ensure |
640 | | * that pgstat's shutdown callback runs after the shutdown callbacks of |
641 | | * all subsystems that can produce stats (like e.g. transaction commits |
642 | | * can). |
643 | | */ |
644 | 0 | pgstat_initialize(); |
645 | | |
646 | | /* |
647 | | * Initialize AIO before infrastructure that might need to actually |
648 | | * execute AIO. |
649 | | */ |
650 | 0 | pgaio_init_backend(); |
651 | | |
652 | | /* Do local initialization of storage and buffer managers */ |
653 | 0 | InitSync(); |
654 | 0 | smgrinit(); |
655 | 0 | InitBufferManagerAccess(); |
656 | | |
657 | | /* |
658 | | * Initialize temporary file access after pgstat, so that the temporary |
659 | | * file shutdown hook can report temporary file statistics. |
660 | | */ |
661 | 0 | InitTemporaryFileAccess(); |
662 | | |
663 | | /* |
664 | | * Initialize local buffers for WAL record construction, in case we ever |
665 | | * try to insert XLOG. |
666 | | */ |
667 | 0 | InitXLogInsert(); |
668 | | |
669 | | /* Initialize lock manager's local structs */ |
670 | 0 | InitLockManagerAccess(); |
671 | | |
672 | | /* |
673 | | * Initialize replication slots after pgstat. The exit hook might need to |
674 | | * drop ephemeral slots, which in turn triggers stats reporting. |
675 | | */ |
676 | 0 | ReplicationSlotInitialize(); |
677 | 0 | } |
678 | | |
679 | | |
680 | | /* -------------------------------- |
681 | | * InitPostgres |
682 | | * Initialize POSTGRES. |
683 | | * |
684 | | * Parameters: |
685 | | * in_dbname, dboid: specify database to connect to, as described below |
686 | | * username, useroid: specify role to connect as, as described below |
687 | | * flags: |
688 | | * - INIT_PG_LOAD_SESSION_LIBS to honor [session|local]_preload_libraries. |
689 | | * - INIT_PG_OVERRIDE_ALLOW_CONNS to connect despite !datallowconn. |
690 | | * - INIT_PG_OVERRIDE_ROLE_LOGIN to connect despite !rolcanlogin. |
691 | | * out_dbname: optional output parameter, see below; pass NULL if not used |
692 | | * |
693 | | * The database can be specified by name, using the in_dbname parameter, or by |
694 | | * OID, using the dboid parameter. Specify NULL or InvalidOid respectively |
695 | | * for the unused parameter. If dboid is provided, the actual database |
696 | | * name can be returned to the caller in out_dbname. If out_dbname isn't |
697 | | * NULL, it must point to a buffer of size NAMEDATALEN. |
698 | | * |
699 | | * Similarly, the role can be passed by name, using the username parameter, |
700 | | * or by OID using the useroid parameter. |
701 | | * |
702 | | * In bootstrap mode the database and username parameters are NULL/InvalidOid. |
703 | | * The autovacuum launcher process doesn't specify these parameters either, |
704 | | * because it only goes far enough to be able to read pg_database; it doesn't |
705 | | * connect to any particular database. An autovacuum worker specifies a |
706 | | * database but not a username; conversely, a physical walsender specifies |
707 | | * username but not database. |
708 | | * |
709 | | * By convention, INIT_PG_LOAD_SESSION_LIBS should be passed in "flags" in |
710 | | * "interactive" sessions (including standalone backends), but not in |
711 | | * background processes such as autovacuum. Note in particular that it |
712 | | * shouldn't be true in parallel worker processes; those have another |
713 | | * mechanism for replicating their leader's set of loaded libraries. |
714 | | * |
715 | | * We expect that InitProcess() was already called, so we already have a |
716 | | * PGPROC struct ... but it's not completely filled in yet. |
717 | | * |
718 | | * Note: |
719 | | * Be very careful with the order of calls in the InitPostgres function. |
720 | | * -------------------------------- |
721 | | */ |
722 | | void |
723 | | InitPostgres(const char *in_dbname, Oid dboid, |
724 | | const char *username, Oid useroid, |
725 | | uint32 flags, |
726 | | char *out_dbname) |
727 | 0 | { |
728 | 0 | bool bootstrap = IsBootstrapProcessingMode(); |
729 | 0 | bool am_superuser; |
730 | 0 | char *fullpath; |
731 | 0 | char dbname[NAMEDATALEN]; |
732 | 0 | int nfree = 0; |
733 | |
|
734 | 0 | elog(DEBUG3, "InitPostgres"); |
735 | | |
736 | | /* |
737 | | * Add my PGPROC struct to the ProcArray. |
738 | | * |
739 | | * Once I have done this, I am visible to other backends! |
740 | | */ |
741 | 0 | InitProcessPhase2(); |
742 | | |
743 | | /* Initialize status reporting */ |
744 | 0 | pgstat_beinit(); |
745 | | |
746 | | /* |
747 | | * And initialize an entry in the PgBackendStatus array. That way, if |
748 | | * LWLocks or third-party authentication should happen to hang, it is |
749 | | * possible to retrieve some information about what is going on. |
750 | | */ |
751 | 0 | if (!bootstrap) |
752 | 0 | { |
753 | 0 | pgstat_bestart_initial(); |
754 | 0 | INJECTION_POINT("init-pre-auth", NULL); |
755 | 0 | } |
756 | | |
757 | | /* |
758 | | * Initialize my entry in the shared-invalidation manager's array of |
759 | | * per-backend data. |
760 | | */ |
761 | 0 | SharedInvalBackendInit(false); |
762 | | |
763 | | /* |
764 | | * Prevent consuming interrupts between setting ProcSignalInit and setting |
765 | | * the initial local data checksum value. If a barrier is emitted, and |
766 | | * absorbed, before local cached state is initialized the state transition |
767 | | * can be invalid. |
768 | | */ |
769 | 0 | HOLD_INTERRUPTS(); |
770 | |
|
771 | 0 | ProcSignalInit(MyCancelKey, MyCancelKeyLength); |
772 | | |
773 | | /* |
774 | | * Initialize a local cache of the data_checksum_version, to be updated by |
775 | | * the procsignal-based barriers. |
776 | | * |
777 | | * This intentionally happens after initializing the procsignal, otherwise |
778 | | * we might miss a state change. This means we can get a barrier for the |
779 | | * state we've just initialized. |
780 | | * |
781 | | * The postmaster (which is what gets forked into the new child process) |
782 | | * does not handle barriers, therefore it may not have the current value |
783 | | * of LocalDataChecksumState value (it'll have the value read from the |
784 | | * control file, which may be arbitrarily old). |
785 | | * |
786 | | * NB: Even if the postmaster handled barriers, the value might still be |
787 | | * stale, as it might have changed after this process forked. |
788 | | */ |
789 | 0 | InitLocalDataChecksumState(); |
790 | |
|
791 | 0 | RESUME_INTERRUPTS(); |
792 | | |
793 | | /* |
794 | | * Also set up timeout handlers needed for backend operation. We need |
795 | | * these in every case except bootstrap. |
796 | | */ |
797 | 0 | if (!bootstrap) |
798 | 0 | { |
799 | 0 | RegisterTimeout(DEADLOCK_TIMEOUT, CheckDeadLockAlert); |
800 | 0 | RegisterTimeout(STATEMENT_TIMEOUT, StatementTimeoutHandler); |
801 | 0 | RegisterTimeout(LOCK_TIMEOUT, LockTimeoutHandler); |
802 | 0 | RegisterTimeout(IDLE_IN_TRANSACTION_SESSION_TIMEOUT, |
803 | 0 | IdleInTransactionSessionTimeoutHandler); |
804 | 0 | RegisterTimeout(TRANSACTION_TIMEOUT, TransactionTimeoutHandler); |
805 | 0 | RegisterTimeout(IDLE_SESSION_TIMEOUT, IdleSessionTimeoutHandler); |
806 | 0 | RegisterTimeout(CLIENT_CONNECTION_CHECK_TIMEOUT, ClientCheckTimeoutHandler); |
807 | 0 | RegisterTimeout(IDLE_STATS_UPDATE_TIMEOUT, |
808 | 0 | IdleStatsUpdateTimeoutHandler); |
809 | 0 | } |
810 | | |
811 | | /* |
812 | | * If this is either a bootstrap process or a standalone backend, start up |
813 | | * the XLOG machinery, and register to have it closed down at exit. In |
814 | | * other cases, the startup process is responsible for starting up the |
815 | | * XLOG machinery, and the checkpointer for closing it down. |
816 | | */ |
817 | 0 | if (!IsUnderPostmaster) |
818 | 0 | { |
819 | | /* |
820 | | * We don't yet have an aux-process resource owner, but StartupXLOG |
821 | | * and ShutdownXLOG will need one. Hence, create said resource owner |
822 | | * (and register a callback to clean it up after ShutdownXLOG runs). |
823 | | */ |
824 | 0 | CreateAuxProcessResourceOwner(); |
825 | |
|
826 | 0 | StartupXLOG(); |
827 | | /* Release (and warn about) any buffer pins leaked in StartupXLOG */ |
828 | 0 | ReleaseAuxProcessResources(true); |
829 | | /* Reset CurrentResourceOwner to nothing for the moment */ |
830 | 0 | CurrentResourceOwner = NULL; |
831 | | |
832 | | /* |
833 | | * Use before_shmem_exit() so that ShutdownXLOG() can rely on DSM |
834 | | * segments etc to work (which in turn is required for pgstats). |
835 | | */ |
836 | 0 | before_shmem_exit(pgstat_before_server_shutdown, 0); |
837 | 0 | before_shmem_exit(ShutdownXLOG, 0); |
838 | 0 | } |
839 | | |
840 | | /* |
841 | | * Initialize the process-local logical info WAL logging state. |
842 | | * |
843 | | * This must be called after ProcSignalInit() so that the process can |
844 | | * participate in procsignal-based barriers that update this state. |
845 | | * Furthermore, in !IsUnderPostmaster cases, this must occur after |
846 | | * StartupXLOG() where the shared state is first established. |
847 | | */ |
848 | 0 | InitializeProcessXLogLogicalInfo(); |
849 | | |
850 | | /* |
851 | | * Initialize the relation cache and the system catalog caches. Note that |
852 | | * no catalog access happens here; we only set up the hashtable structure. |
853 | | * We must do this before starting a transaction because transaction abort |
854 | | * would try to touch these hashtables. |
855 | | */ |
856 | 0 | RelationCacheInitialize(); |
857 | 0 | InitCatalogCache(); |
858 | 0 | InitPlanCache(); |
859 | | |
860 | | /* Initialize portal manager */ |
861 | 0 | EnablePortalManager(); |
862 | | |
863 | | /* |
864 | | * Load relcache entries for the shared system catalogs. This must create |
865 | | * at least entries for pg_database and catalogs used for authentication. |
866 | | */ |
867 | 0 | RelationCacheInitializePhase2(); |
868 | | |
869 | | /* |
870 | | * Set up process-exit callback to do pre-shutdown cleanup. This is one |
871 | | * of the first before_shmem_exit callbacks we register; thus, this will |
872 | | * be one of the last things we do before low-level modules like the |
873 | | * buffer manager begin to close down. We need to have this in place |
874 | | * before we begin our first transaction --- if we fail during the |
875 | | * initialization transaction, as is entirely possible, we need the |
876 | | * AbortTransaction call to clean up. |
877 | | */ |
878 | 0 | before_shmem_exit(ShutdownPostgres, 0); |
879 | | |
880 | | /* The autovacuum launcher is done here */ |
881 | 0 | if (AmAutoVacuumLauncherProcess()) |
882 | 0 | { |
883 | | /* fill in the remainder of this entry in the PgBackendStatus array */ |
884 | 0 | pgstat_bestart_final(); |
885 | |
|
886 | 0 | return; |
887 | 0 | } |
888 | | |
889 | | /* |
890 | | * Start a new transaction here before first access to db. |
891 | | */ |
892 | 0 | if (!bootstrap) |
893 | 0 | { |
894 | | /* statement_timestamp must be set for timeouts to work correctly */ |
895 | 0 | SetCurrentStatementStartTimestamp(); |
896 | 0 | StartTransactionCommand(); |
897 | | |
898 | | /* |
899 | | * transaction_isolation will have been set to the default by the |
900 | | * above. If the default is "serializable", and we are in hot |
901 | | * standby, we will fail if we don't change it to something lower. |
902 | | * Fortunately, "read committed" is plenty good enough. |
903 | | */ |
904 | 0 | XactIsoLevel = XACT_READ_COMMITTED; |
905 | 0 | } |
906 | | |
907 | | /* |
908 | | * Perform client authentication if necessary, then figure out our |
909 | | * postgres user ID, and see if we are a superuser. |
910 | | * |
911 | | * In standalone mode, autovacuum worker processes and slot sync worker |
912 | | * process, we use a fixed ID, otherwise we figure it out from the |
913 | | * authenticated user name. |
914 | | */ |
915 | 0 | if (bootstrap || AmAutoVacuumWorkerProcess() || AmLogicalSlotSyncWorkerProcess()) |
916 | 0 | { |
917 | 0 | InitializeSessionUserIdStandalone(); |
918 | 0 | am_superuser = true; |
919 | 0 | } |
920 | 0 | else if (!IsUnderPostmaster) |
921 | 0 | { |
922 | 0 | InitializeSessionUserIdStandalone(); |
923 | 0 | am_superuser = true; |
924 | 0 | if (!ThereIsAtLeastOneRole()) |
925 | 0 | ereport(WARNING, |
926 | 0 | (errcode(ERRCODE_UNDEFINED_OBJECT), |
927 | 0 | errmsg("no roles are defined in this database system"), |
928 | 0 | errhint("You should immediately run CREATE USER \"%s\" SUPERUSER;.", |
929 | 0 | username != NULL ? username : "postgres"))); |
930 | 0 | } |
931 | 0 | else if (AmBackgroundWorkerProcess() || AmDataChecksumsWorkerProcess()) |
932 | 0 | { |
933 | 0 | if (username == NULL && !OidIsValid(useroid)) |
934 | 0 | { |
935 | 0 | InitializeSessionUserIdStandalone(); |
936 | 0 | am_superuser = true; |
937 | 0 | } |
938 | 0 | else |
939 | 0 | { |
940 | 0 | InitializeSessionUserId(username, useroid, |
941 | 0 | (flags & INIT_PG_OVERRIDE_ROLE_LOGIN) != 0); |
942 | 0 | am_superuser = superuser(); |
943 | 0 | } |
944 | 0 | } |
945 | 0 | else |
946 | 0 | { |
947 | | /* normal multiuser case */ |
948 | 0 | Assert(MyProcPort != NULL); |
949 | 0 | PerformAuthentication(MyProcPort); |
950 | 0 | InitializeSessionUserId(username, useroid, false); |
951 | | /* ensure that auth_method is actually valid, aka authn_id is not NULL */ |
952 | 0 | if (MyClientConnectionInfo.authn_id) |
953 | 0 | InitializeSystemUser(MyClientConnectionInfo.authn_id, |
954 | 0 | hba_authname(MyClientConnectionInfo.auth_method)); |
955 | 0 | am_superuser = superuser(); |
956 | 0 | } |
957 | | |
958 | | /* Report any SSL/GSS details for the session. */ |
959 | 0 | if (MyProcPort != NULL) |
960 | 0 | { |
961 | 0 | Assert(!bootstrap); |
962 | |
|
963 | 0 | pgstat_bestart_security(); |
964 | 0 | } |
965 | | |
966 | | /* |
967 | | * Binary upgrades only allowed super-user connections |
968 | | */ |
969 | 0 | if (IsBinaryUpgrade && !am_superuser) |
970 | 0 | { |
971 | 0 | ereport(FATAL, |
972 | 0 | (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), |
973 | 0 | errmsg("must be superuser to connect in binary upgrade mode"))); |
974 | 0 | } |
975 | | |
976 | | /* |
977 | | * The last few regular connection slots are reserved for superusers and |
978 | | * roles with privileges of pg_use_reserved_connections. We do not apply |
979 | | * these limits to background processes, since they all have their own |
980 | | * pools of PGPROC slots. |
981 | | * |
982 | | * Note: At this point, the new backend has already claimed a proc struct, |
983 | | * so we must check whether the number of free slots is strictly less than |
984 | | * the reserved connection limits. |
985 | | */ |
986 | 0 | if (AmRegularBackendProcess() && !am_superuser && |
987 | 0 | (SuperuserReservedConnections + ReservedConnections) > 0 && |
988 | 0 | !HaveNFreeProcs(SuperuserReservedConnections + ReservedConnections, &nfree)) |
989 | 0 | { |
990 | 0 | if (nfree < SuperuserReservedConnections) |
991 | 0 | ereport(FATAL, |
992 | 0 | (errcode(ERRCODE_TOO_MANY_CONNECTIONS), |
993 | 0 | errmsg("remaining connection slots are reserved for roles with the %s attribute", |
994 | 0 | "SUPERUSER"))); |
995 | | |
996 | 0 | if (!has_privs_of_role(GetUserId(), ROLE_PG_USE_RESERVED_CONNECTIONS)) |
997 | 0 | ereport(FATAL, |
998 | 0 | (errcode(ERRCODE_TOO_MANY_CONNECTIONS), |
999 | 0 | errmsg("remaining connection slots are reserved for roles with privileges of the \"%s\" role", |
1000 | 0 | "pg_use_reserved_connections"))); |
1001 | 0 | } |
1002 | | |
1003 | | /* Check replication permissions needed for walsender processes. */ |
1004 | 0 | if (am_walsender) |
1005 | 0 | { |
1006 | 0 | Assert(!bootstrap); |
1007 | |
|
1008 | 0 | if (!has_rolreplication(GetUserId())) |
1009 | 0 | ereport(FATAL, |
1010 | 0 | (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), |
1011 | 0 | errmsg("permission denied to start WAL sender"), |
1012 | 0 | errdetail("Only roles with the %s attribute may start a WAL sender process.", |
1013 | 0 | "REPLICATION"))); |
1014 | 0 | } |
1015 | | |
1016 | | /* |
1017 | | * If this is a plain walsender only supporting physical replication, we |
1018 | | * don't want to connect to any particular database. Just finish the |
1019 | | * backend startup by processing any options from the startup packet, and |
1020 | | * we're done. |
1021 | | */ |
1022 | 0 | if (am_walsender && !am_db_walsender) |
1023 | 0 | { |
1024 | | /* process any options passed in the startup packet */ |
1025 | 0 | if (MyProcPort != NULL) |
1026 | 0 | process_startup_options(MyProcPort, am_superuser); |
1027 | | |
1028 | | /* Apply PostAuthDelay as soon as we've read all options */ |
1029 | 0 | if (PostAuthDelay > 0) |
1030 | 0 | pg_usleep(PostAuthDelay * 1000000L); |
1031 | | |
1032 | | /* initialize client encoding */ |
1033 | 0 | InitializeClientEncoding(); |
1034 | | |
1035 | | /* fill in the remainder of this entry in the PgBackendStatus array */ |
1036 | 0 | pgstat_bestart_final(); |
1037 | | |
1038 | | /* close the transaction we started above */ |
1039 | 0 | CommitTransactionCommand(); |
1040 | | |
1041 | | /* send any WARNINGs we've accumulated during initialization */ |
1042 | 0 | EmitConnectionWarnings(); |
1043 | |
|
1044 | 0 | return; |
1045 | 0 | } |
1046 | | |
1047 | | /* |
1048 | | * Set up the global variables holding database id and default tablespace. |
1049 | | * But note we won't actually try to touch the database just yet. |
1050 | | * |
1051 | | * We take a shortcut in the bootstrap case, otherwise we have to look up |
1052 | | * the db's entry in pg_database. |
1053 | | */ |
1054 | 0 | if (bootstrap) |
1055 | 0 | { |
1056 | 0 | dboid = Template1DbOid; |
1057 | 0 | MyDatabaseTableSpace = DEFAULTTABLESPACE_OID; |
1058 | 0 | } |
1059 | 0 | else if (in_dbname != NULL) |
1060 | 0 | { |
1061 | 0 | HeapTuple tuple; |
1062 | 0 | Form_pg_database dbform; |
1063 | |
|
1064 | 0 | tuple = GetDatabaseTuple(in_dbname); |
1065 | 0 | if (!HeapTupleIsValid(tuple)) |
1066 | 0 | ereport(FATAL, |
1067 | 0 | (errcode(ERRCODE_UNDEFINED_DATABASE), |
1068 | 0 | errmsg("database \"%s\" does not exist", in_dbname))); |
1069 | 0 | dbform = (Form_pg_database) GETSTRUCT(tuple); |
1070 | 0 | dboid = dbform->oid; |
1071 | 0 | } |
1072 | 0 | else if (!OidIsValid(dboid)) |
1073 | 0 | { |
1074 | | /* |
1075 | | * If this is a background worker not bound to any particular |
1076 | | * database, we're done now. Everything that follows only makes sense |
1077 | | * if we are bound to a specific database. We do need to close the |
1078 | | * transaction we started before returning. |
1079 | | */ |
1080 | 0 | if (!bootstrap) |
1081 | 0 | { |
1082 | 0 | pgstat_bestart_final(); |
1083 | 0 | CommitTransactionCommand(); |
1084 | 0 | } |
1085 | 0 | return; |
1086 | 0 | } |
1087 | | |
1088 | | /* |
1089 | | * Now, take a writer's lock on the database we are trying to connect to. |
1090 | | * If there is a concurrently running DROP DATABASE on that database, this |
1091 | | * will block us until it finishes (and has committed its update of |
1092 | | * pg_database). |
1093 | | * |
1094 | | * Note that the lock is not held long, only until the end of this startup |
1095 | | * transaction. This is OK since we will advertise our use of the |
1096 | | * database in the ProcArray before dropping the lock (in fact, that's the |
1097 | | * next thing to do). Anyone trying a DROP DATABASE after this point will |
1098 | | * see us in the array once they have the lock. Ordering is important for |
1099 | | * this because we don't want to advertise ourselves as being in this |
1100 | | * database until we have the lock; otherwise we create what amounts to a |
1101 | | * deadlock with CountOtherDBBackends(). |
1102 | | * |
1103 | | * Note: use of RowExclusiveLock here is reasonable because we envision |
1104 | | * our session as being a concurrent writer of the database. If we had a |
1105 | | * way of declaring a session as being guaranteed-read-only, we could use |
1106 | | * AccessShareLock for such sessions and thereby not conflict against |
1107 | | * CREATE DATABASE. |
1108 | | */ |
1109 | 0 | if (!bootstrap) |
1110 | 0 | LockSharedObject(DatabaseRelationId, dboid, 0, RowExclusiveLock); |
1111 | | |
1112 | | /* |
1113 | | * Recheck pg_database to make sure the target database hasn't gone away. |
1114 | | * If there was a concurrent DROP DATABASE, this ensures we will die |
1115 | | * cleanly without creating a mess. |
1116 | | */ |
1117 | 0 | if (!bootstrap) |
1118 | 0 | { |
1119 | 0 | HeapTuple tuple; |
1120 | 0 | Form_pg_database datform; |
1121 | |
|
1122 | 0 | tuple = GetDatabaseTupleByOid(dboid); |
1123 | 0 | if (HeapTupleIsValid(tuple)) |
1124 | 0 | datform = (Form_pg_database) GETSTRUCT(tuple); |
1125 | |
|
1126 | 0 | if (!HeapTupleIsValid(tuple) || |
1127 | 0 | (in_dbname && namestrcmp(&datform->datname, in_dbname))) |
1128 | 0 | { |
1129 | 0 | if (in_dbname) |
1130 | 0 | ereport(FATAL, |
1131 | 0 | (errcode(ERRCODE_UNDEFINED_DATABASE), |
1132 | 0 | errmsg("database \"%s\" does not exist", in_dbname), |
1133 | 0 | errdetail("It seems to have just been dropped or renamed."))); |
1134 | 0 | else |
1135 | 0 | ereport(FATAL, |
1136 | 0 | (errcode(ERRCODE_UNDEFINED_DATABASE), |
1137 | 0 | errmsg("database %u does not exist", dboid))); |
1138 | 0 | } |
1139 | | |
1140 | 0 | strlcpy(dbname, NameStr(datform->datname), sizeof(dbname)); |
1141 | |
|
1142 | 0 | if (database_is_invalid_form(datform)) |
1143 | 0 | { |
1144 | 0 | ereport(FATAL, |
1145 | 0 | errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), |
1146 | 0 | errmsg("cannot connect to invalid database \"%s\"", dbname), |
1147 | 0 | errhint("Use DROP DATABASE to drop invalid databases.")); |
1148 | 0 | } |
1149 | | |
1150 | 0 | MyDatabaseTableSpace = datform->dattablespace; |
1151 | 0 | MyDatabaseHasLoginEventTriggers = datform->dathasloginevt; |
1152 | | /* pass the database name back to the caller */ |
1153 | 0 | if (out_dbname) |
1154 | 0 | strcpy(out_dbname, dbname); |
1155 | 0 | } |
1156 | | |
1157 | | /* |
1158 | | * Now that we rechecked, we are certain to be connected to a database and |
1159 | | * thus can set MyDatabaseId. |
1160 | | * |
1161 | | * It is important that MyDatabaseId only be set once we are sure that the |
1162 | | * target database can no longer be concurrently dropped or renamed. For |
1163 | | * example, without this guarantee, pgstat_update_dbstats() could create |
1164 | | * entries for databases that were just dropped in the pgstat shutdown |
1165 | | * callback, which could confuse other code paths like the autovacuum |
1166 | | * scheduler. |
1167 | | */ |
1168 | 0 | MyDatabaseId = dboid; |
1169 | | |
1170 | | /* |
1171 | | * Now we can mark our PGPROC entry with the database ID. |
1172 | | * |
1173 | | * We assume this is an atomic store so no lock is needed; though actually |
1174 | | * things would work fine even if it weren't atomic. Anyone searching the |
1175 | | * ProcArray for this database's ID should hold the database lock, so they |
1176 | | * would not be executing concurrently with this store. A process looking |
1177 | | * for another database's ID could in theory see a chance match if it read |
1178 | | * a partially-updated databaseId value; but as long as all such searches |
1179 | | * wait and retry, as in CountOtherDBBackends(), they will certainly see |
1180 | | * the correct value on their next try. |
1181 | | */ |
1182 | 0 | MyProc->databaseId = MyDatabaseId; |
1183 | | |
1184 | | /* |
1185 | | * We established a catalog snapshot while reading pg_authid and/or |
1186 | | * pg_database; but until we have set up MyDatabaseId, we won't react to |
1187 | | * incoming sinval messages for unshared catalogs, so we won't realize it |
1188 | | * if the snapshot has been invalidated. Assume it's no good anymore. |
1189 | | */ |
1190 | 0 | InvalidateCatalogSnapshot(); |
1191 | | |
1192 | | /* |
1193 | | * Now we should be able to access the database directory safely. Verify |
1194 | | * it's there and looks reasonable. |
1195 | | */ |
1196 | 0 | fullpath = GetDatabasePath(MyDatabaseId, MyDatabaseTableSpace); |
1197 | |
|
1198 | 0 | if (!bootstrap) |
1199 | 0 | { |
1200 | 0 | if (access(fullpath, F_OK) == -1) |
1201 | 0 | { |
1202 | 0 | if (errno == ENOENT) |
1203 | 0 | ereport(FATAL, |
1204 | 0 | (errcode(ERRCODE_UNDEFINED_DATABASE), |
1205 | 0 | errmsg("database \"%s\" does not exist", |
1206 | 0 | dbname), |
1207 | 0 | errdetail("The database subdirectory \"%s\" is missing.", |
1208 | 0 | fullpath))); |
1209 | 0 | else |
1210 | 0 | ereport(FATAL, |
1211 | 0 | (errcode_for_file_access(), |
1212 | 0 | errmsg("could not access directory \"%s\": %m", |
1213 | 0 | fullpath))); |
1214 | 0 | } |
1215 | | |
1216 | 0 | ValidatePgVersion(fullpath); |
1217 | 0 | } |
1218 | | |
1219 | 0 | SetDatabasePath(fullpath); |
1220 | 0 | pfree(fullpath); |
1221 | | |
1222 | | /* |
1223 | | * It's now possible to do real access to the system catalogs. |
1224 | | * |
1225 | | * Load relcache entries for the system catalogs. This must create at |
1226 | | * least the minimum set of "nailed-in" cache entries. |
1227 | | */ |
1228 | 0 | RelationCacheInitializePhase3(); |
1229 | | |
1230 | | /* set up ACL framework (so CheckMyDatabase can check permissions) */ |
1231 | 0 | initialize_acl(); |
1232 | | |
1233 | | /* |
1234 | | * Re-read the pg_database row for our database, check permissions and set |
1235 | | * up database-specific GUC settings. We can't do this until all the |
1236 | | * database-access infrastructure is up. (Also, it wants to know if the |
1237 | | * user is a superuser, so the above stuff has to happen first.) |
1238 | | */ |
1239 | 0 | if (!bootstrap) |
1240 | 0 | CheckMyDatabase(dbname, am_superuser, |
1241 | 0 | (flags & INIT_PG_OVERRIDE_ALLOW_CONNS) != 0); |
1242 | | |
1243 | | /* |
1244 | | * Now process any command-line switches and any additional GUC variable |
1245 | | * settings passed in the startup packet. We couldn't do this before |
1246 | | * because we didn't know if client is a superuser. |
1247 | | */ |
1248 | 0 | if (MyProcPort != NULL) |
1249 | 0 | process_startup_options(MyProcPort, am_superuser); |
1250 | | |
1251 | | /* Process pg_db_role_setting options */ |
1252 | 0 | process_settings(MyDatabaseId, GetSessionUserId()); |
1253 | | |
1254 | | /* Apply PostAuthDelay as soon as we've read all options */ |
1255 | 0 | if (PostAuthDelay > 0) |
1256 | 0 | pg_usleep(PostAuthDelay * 1000000L); |
1257 | | |
1258 | | /* |
1259 | | * Initialize various default states that can't be set up until we've |
1260 | | * selected the active user and gotten the right GUC settings. |
1261 | | */ |
1262 | | |
1263 | | /* set default namespace search path */ |
1264 | 0 | InitializeSearchPath(); |
1265 | | |
1266 | | /* initialize client encoding */ |
1267 | 0 | InitializeClientEncoding(); |
1268 | | |
1269 | | /* Initialize this backend's session state. */ |
1270 | 0 | InitializeSession(); |
1271 | | |
1272 | | /* |
1273 | | * If this is an interactive session, load any libraries that should be |
1274 | | * preloaded at backend start. Since those are determined by GUCs, this |
1275 | | * can't happen until GUC settings are complete, but we want it to happen |
1276 | | * during the initial transaction in case anything that requires database |
1277 | | * access needs to be done. |
1278 | | */ |
1279 | 0 | if ((flags & INIT_PG_LOAD_SESSION_LIBS) != 0) |
1280 | 0 | process_session_preload_libraries(); |
1281 | | |
1282 | | /* fill in the remainder of this entry in the PgBackendStatus array */ |
1283 | 0 | if (!bootstrap) |
1284 | 0 | pgstat_bestart_final(); |
1285 | | |
1286 | | /* close the transaction we started above */ |
1287 | 0 | if (!bootstrap) |
1288 | 0 | CommitTransactionCommand(); |
1289 | | |
1290 | | /* send any WARNINGs we've accumulated during initialization */ |
1291 | 0 | EmitConnectionWarnings(); |
1292 | 0 | } |
1293 | | |
1294 | | /* |
1295 | | * Process any command-line switches and any additional GUC variable |
1296 | | * settings passed in the startup packet. |
1297 | | */ |
1298 | | static void |
1299 | | process_startup_options(Port *port, bool am_superuser) |
1300 | 0 | { |
1301 | 0 | GucContext gucctx; |
1302 | 0 | ListCell *gucopts; |
1303 | |
|
1304 | 0 | gucctx = am_superuser ? PGC_SU_BACKEND : PGC_BACKEND; |
1305 | | |
1306 | | /* |
1307 | | * First process any command-line switches that were included in the |
1308 | | * startup packet, if we are in a regular backend. |
1309 | | */ |
1310 | 0 | if (port->cmdline_options != NULL) |
1311 | 0 | { |
1312 | | /* |
1313 | | * The maximum possible number of commandline arguments that could |
1314 | | * come from port->cmdline_options is (strlen + 1) / 2; see |
1315 | | * pg_split_opts(). |
1316 | | */ |
1317 | 0 | char **av; |
1318 | 0 | int maxac; |
1319 | 0 | int ac; |
1320 | |
|
1321 | 0 | maxac = 2 + (strlen(port->cmdline_options) + 1) / 2; |
1322 | |
|
1323 | 0 | av = palloc_array(char *, maxac); |
1324 | 0 | ac = 0; |
1325 | |
|
1326 | 0 | av[ac++] = "postgres"; |
1327 | |
|
1328 | 0 | pg_split_opts(av, &ac, port->cmdline_options); |
1329 | |
|
1330 | 0 | av[ac] = NULL; |
1331 | |
|
1332 | 0 | Assert(ac < maxac); |
1333 | |
|
1334 | 0 | (void) process_postgres_switches(ac, av, gucctx, NULL); |
1335 | 0 | } |
1336 | | |
1337 | | /* |
1338 | | * Process any additional GUC variable settings passed in startup packet. |
1339 | | * These are handled exactly like command-line variables. |
1340 | | */ |
1341 | 0 | gucopts = list_head(port->guc_options); |
1342 | 0 | while (gucopts) |
1343 | 0 | { |
1344 | 0 | char *name; |
1345 | 0 | char *value; |
1346 | |
|
1347 | 0 | name = lfirst(gucopts); |
1348 | 0 | gucopts = lnext(port->guc_options, gucopts); |
1349 | |
|
1350 | 0 | value = lfirst(gucopts); |
1351 | 0 | gucopts = lnext(port->guc_options, gucopts); |
1352 | |
|
1353 | 0 | SetConfigOption(name, value, gucctx, PGC_S_CLIENT); |
1354 | 0 | } |
1355 | 0 | } |
1356 | | |
1357 | | /* |
1358 | | * Load GUC settings from pg_db_role_setting. |
1359 | | * |
1360 | | * We try specific settings for the database/role combination, as well as |
1361 | | * general for this database and for this user. |
1362 | | */ |
1363 | | static void |
1364 | | process_settings(Oid databaseid, Oid roleid) |
1365 | 0 | { |
1366 | 0 | Relation relsetting; |
1367 | 0 | Snapshot snapshot; |
1368 | |
|
1369 | 0 | if (!IsUnderPostmaster) |
1370 | 0 | return; |
1371 | | |
1372 | 0 | relsetting = table_open(DbRoleSettingRelationId, AccessShareLock); |
1373 | | |
1374 | | /* read all the settings under the same snapshot for efficiency */ |
1375 | 0 | snapshot = RegisterSnapshot(GetCatalogSnapshot(DbRoleSettingRelationId)); |
1376 | | |
1377 | | /* Later settings are ignored if set earlier. */ |
1378 | 0 | ApplySetting(snapshot, databaseid, roleid, relsetting, PGC_S_DATABASE_USER); |
1379 | 0 | ApplySetting(snapshot, InvalidOid, roleid, relsetting, PGC_S_USER); |
1380 | 0 | ApplySetting(snapshot, databaseid, InvalidOid, relsetting, PGC_S_DATABASE); |
1381 | 0 | ApplySetting(snapshot, InvalidOid, InvalidOid, relsetting, PGC_S_GLOBAL); |
1382 | |
|
1383 | 0 | UnregisterSnapshot(snapshot); |
1384 | 0 | table_close(relsetting, AccessShareLock); |
1385 | 0 | } |
1386 | | |
1387 | | /* |
1388 | | * Backend-shutdown callback. Do cleanup that we want to be sure happens |
1389 | | * before all the supporting modules begin to nail their doors shut via |
1390 | | * their own callbacks. |
1391 | | * |
1392 | | * User-level cleanup, such as temp-relation removal and UNLISTEN, happens |
1393 | | * via separate callbacks that execute before this one. We don't combine the |
1394 | | * callbacks because we still want this one to happen if the user-level |
1395 | | * cleanup fails. |
1396 | | */ |
1397 | | static void |
1398 | | ShutdownPostgres(int code, Datum arg) |
1399 | 0 | { |
1400 | | /* Make sure we've killed any active transaction */ |
1401 | 0 | AbortOutOfAnyTransaction(); |
1402 | | |
1403 | | /* |
1404 | | * User locks are not released by transaction end, so be sure to release |
1405 | | * them explicitly. |
1406 | | */ |
1407 | 0 | LockReleaseAll(USER_LOCKMETHOD, true); |
1408 | 0 | } |
1409 | | |
1410 | | |
1411 | | /* |
1412 | | * STATEMENT_TIMEOUT handler: trigger a query-cancel interrupt. |
1413 | | */ |
1414 | | static void |
1415 | | StatementTimeoutHandler(void) |
1416 | 0 | { |
1417 | 0 | int sig = SIGINT; |
1418 | | |
1419 | | /* |
1420 | | * During authentication the timeout is used to deal with |
1421 | | * authentication_timeout - we want to quit in response to such timeouts. |
1422 | | */ |
1423 | 0 | if (ClientAuthInProgress) |
1424 | 0 | sig = SIGTERM; |
1425 | |
|
1426 | 0 | #ifdef HAVE_SETSID |
1427 | | /* try to signal whole process group */ |
1428 | 0 | kill(-MyProcPid, sig); |
1429 | 0 | #endif |
1430 | 0 | kill(MyProcPid, sig); |
1431 | 0 | } |
1432 | | |
1433 | | /* |
1434 | | * LOCK_TIMEOUT handler: trigger a query-cancel interrupt. |
1435 | | */ |
1436 | | static void |
1437 | | LockTimeoutHandler(void) |
1438 | 0 | { |
1439 | 0 | #ifdef HAVE_SETSID |
1440 | | /* try to signal whole process group */ |
1441 | 0 | kill(-MyProcPid, SIGINT); |
1442 | 0 | #endif |
1443 | 0 | kill(MyProcPid, SIGINT); |
1444 | 0 | } |
1445 | | |
1446 | | static void |
1447 | | TransactionTimeoutHandler(void) |
1448 | 0 | { |
1449 | 0 | TransactionTimeoutPending = true; |
1450 | 0 | InterruptPending = true; |
1451 | 0 | SetLatch(MyLatch); |
1452 | 0 | } |
1453 | | |
1454 | | static void |
1455 | | IdleInTransactionSessionTimeoutHandler(void) |
1456 | 0 | { |
1457 | 0 | IdleInTransactionSessionTimeoutPending = true; |
1458 | 0 | InterruptPending = true; |
1459 | 0 | SetLatch(MyLatch); |
1460 | 0 | } |
1461 | | |
1462 | | static void |
1463 | | IdleSessionTimeoutHandler(void) |
1464 | 0 | { |
1465 | 0 | IdleSessionTimeoutPending = true; |
1466 | 0 | InterruptPending = true; |
1467 | 0 | SetLatch(MyLatch); |
1468 | 0 | } |
1469 | | |
1470 | | static void |
1471 | | IdleStatsUpdateTimeoutHandler(void) |
1472 | 0 | { |
1473 | 0 | IdleStatsUpdateTimeoutPending = true; |
1474 | 0 | InterruptPending = true; |
1475 | 0 | SetLatch(MyLatch); |
1476 | 0 | } |
1477 | | |
1478 | | static void |
1479 | | ClientCheckTimeoutHandler(void) |
1480 | 0 | { |
1481 | 0 | CheckClientConnectionPending = true; |
1482 | 0 | InterruptPending = true; |
1483 | 0 | SetLatch(MyLatch); |
1484 | 0 | } |
1485 | | |
1486 | | /* |
1487 | | * Returns true if at least one role is defined in this database cluster. |
1488 | | */ |
1489 | | static bool |
1490 | | ThereIsAtLeastOneRole(void) |
1491 | 0 | { |
1492 | 0 | Relation pg_authid_rel; |
1493 | 0 | TableScanDesc scan; |
1494 | 0 | bool result; |
1495 | |
|
1496 | 0 | pg_authid_rel = table_open(AuthIdRelationId, AccessShareLock); |
1497 | |
|
1498 | 0 | scan = table_beginscan_catalog(pg_authid_rel, 0, NULL); |
1499 | 0 | result = (heap_getnext(scan, ForwardScanDirection) != NULL); |
1500 | |
|
1501 | 0 | table_endscan(scan); |
1502 | 0 | table_close(pg_authid_rel, AccessShareLock); |
1503 | |
|
1504 | 0 | return result; |
1505 | 0 | } |
1506 | | |
1507 | | /* |
1508 | | * Stores a warning message to be sent later via EmitConnectionWarnings(). |
1509 | | * Both msg and detail must be non-NULL. If filter is non-NULL, it is called |
1510 | | * just before the warning is emitted, after startup and role/database settings |
1511 | | * have been applied. |
1512 | | * |
1513 | | * NB: Caller should ensure the strings are palloc'd in a long-lived context |
1514 | | * like TopMemoryContext. This function takes ownership of the strings, which |
1515 | | * will be pfree'd in EmitConnectionWarnings(). |
1516 | | */ |
1517 | | void |
1518 | | StoreConnectionWarning(char *msg, char *detail, ConnectionWarningFilter filter) |
1519 | 0 | { |
1520 | 0 | MemoryContext oldcontext; |
1521 | 0 | ConnectionWarning *warning; |
1522 | |
|
1523 | 0 | Assert(msg); |
1524 | 0 | Assert(detail); |
1525 | |
|
1526 | 0 | if (ConnectionWarningsEmitted) |
1527 | 0 | elog(ERROR, "StoreConnectionWarning() called after EmitConnectionWarnings()"); |
1528 | | |
1529 | 0 | oldcontext = MemoryContextSwitchTo(TopMemoryContext); |
1530 | |
|
1531 | 0 | warning = palloc_object(ConnectionWarning); |
1532 | 0 | warning->message = msg; |
1533 | 0 | warning->detail = detail; |
1534 | 0 | warning->filter = filter; |
1535 | 0 | ConnectionWarnings = lappend(ConnectionWarnings, warning); |
1536 | |
|
1537 | 0 | MemoryContextSwitchTo(oldcontext); |
1538 | 0 | } |
1539 | | |
1540 | | /* |
1541 | | * Sends the warning messages saved via StoreConnectionWarning() and frees the |
1542 | | * strings and lists. |
1543 | | * |
1544 | | * NB: This can only be called once per backend. |
1545 | | */ |
1546 | | static void |
1547 | | EmitConnectionWarnings(void) |
1548 | | { |
1549 | | if (ConnectionWarningsEmitted) |
1550 | | elog(ERROR, "EmitConnectionWarnings() called more than once"); |
1551 | | else |
1552 | | ConnectionWarningsEmitted = true; |
1553 | | |
1554 | | foreach_ptr(ConnectionWarning, warning, ConnectionWarnings) |
1555 | | { |
1556 | | if (warning->filter == NULL || warning->filter()) |
1557 | | ereport(WARNING, |
1558 | | (errmsg("%s", warning->message), |
1559 | | errdetail("%s", warning->detail))); |
1560 | | |
1561 | | pfree(warning->message); |
1562 | | pfree(warning->detail); |
1563 | | pfree(warning); |
1564 | | } |
1565 | | |
1566 | | list_free(ConnectionWarnings); |
1567 | | ConnectionWarnings = NIL; |
1568 | | } |