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