PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
postinit.c
Go to the documentation of this file.
1 /*-------------------------------------------------------------------------
2  *
3  * postinit.c
4  * postgres initialization utilities
5  *
6  * Portions Copyright (c) 1996-2017, 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/heapam.h"
23 #include "access/htup_details.h"
24 #include "access/sysattr.h"
25 #include "access/xact.h"
26 #include "access/xlog.h"
27 #include "catalog/catalog.h"
28 #include "catalog/indexing.h"
29 #include "catalog/namespace.h"
30 #include "catalog/pg_authid.h"
31 #include "catalog/pg_database.h"
33 #include "catalog/pg_tablespace.h"
34 #include "libpq/auth.h"
35 #include "libpq/libpq-be.h"
36 #include "mb/pg_wchar.h"
37 #include "miscadmin.h"
38 #include "pgstat.h"
39 #include "postmaster/autovacuum.h"
40 #include "postmaster/postmaster.h"
41 #include "replication/walsender.h"
42 #include "storage/bufmgr.h"
43 #include "storage/fd.h"
44 #include "storage/ipc.h"
45 #include "storage/lmgr.h"
46 #include "storage/procarray.h"
47 #include "storage/procsignal.h"
48 #include "storage/proc.h"
49 #include "storage/sinvaladt.h"
50 #include "storage/smgr.h"
51 #include "tcop/tcopprot.h"
52 #include "utils/acl.h"
53 #include "utils/fmgroids.h"
54 #include "utils/guc.h"
55 #include "utils/memutils.h"
56 #include "utils/pg_locale.h"
57 #include "utils/portal.h"
58 #include "utils/ps_status.h"
59 #include "utils/snapmgr.h"
60 #include "utils/syscache.h"
61 #include "utils/timeout.h"
62 #include "utils/tqual.h"
63 
64 
65 static HeapTuple GetDatabaseTuple(const char *dbname);
66 static HeapTuple GetDatabaseTupleByOid(Oid dboid);
67 static void PerformAuthentication(Port *port);
68 static void CheckMyDatabase(const char *name, bool am_superuser);
69 static void InitCommunication(void);
70 static void ShutdownPostgres(int code, Datum arg);
71 static void StatementTimeoutHandler(void);
72 static void LockTimeoutHandler(void);
74 static bool ThereIsAtLeastOneRole(void);
75 static void process_startup_options(Port *port, bool am_superuser);
76 static void process_settings(Oid databaseid, Oid roleid);
77 
78 
79 /*** InitPostgres support ***/
80 
81 
82 /*
83  * GetDatabaseTuple -- fetch the pg_database row for a database
84  *
85  * This is used during backend startup when we don't yet have any access to
86  * system catalogs in general. In the worst case, we can seqscan pg_database
87  * using nothing but the hard-wired descriptor that relcache.c creates for
88  * pg_database. In more typical cases, relcache.c was able to load
89  * descriptors for both pg_database and its indexes from the shared relcache
90  * cache file, and so we can do an indexscan. criticalSharedRelcachesBuilt
91  * tells whether we got the cached descriptors.
92  */
93 static HeapTuple
95 {
96  HeapTuple tuple;
97  Relation relation;
98  SysScanDesc scan;
99  ScanKeyData key[1];
100 
101  /*
102  * form a scan key
103  */
104  ScanKeyInit(&key[0],
106  BTEqualStrategyNumber, F_NAMEEQ,
107  CStringGetDatum(dbname));
108 
109  /*
110  * Open pg_database and fetch a tuple. Force heap scan if we haven't yet
111  * built the critical shared relcache entries (i.e., we're starting up
112  * without a shared relcache cache file).
113  */
115  scan = systable_beginscan(relation, DatabaseNameIndexId,
117  NULL,
118  1, key);
119 
120  tuple = systable_getnext(scan);
121 
122  /* Must copy tuple before releasing buffer */
123  if (HeapTupleIsValid(tuple))
124  tuple = heap_copytuple(tuple);
125 
126  /* all done */
127  systable_endscan(scan);
128  heap_close(relation, AccessShareLock);
129 
130  return tuple;
131 }
132 
133 /*
134  * GetDatabaseTupleByOid -- as above, but search by database OID
135  */
136 static HeapTuple
138 {
139  HeapTuple tuple;
140  Relation relation;
141  SysScanDesc scan;
142  ScanKeyData key[1];
143 
144  /*
145  * form a scan key
146  */
147  ScanKeyInit(&key[0],
149  BTEqualStrategyNumber, F_OIDEQ,
150  ObjectIdGetDatum(dboid));
151 
152  /*
153  * Open pg_database and fetch a tuple. Force heap scan if we haven't yet
154  * built the critical shared relcache entries (i.e., we're starting up
155  * without a shared relcache cache file).
156  */
158  scan = systable_beginscan(relation, DatabaseOidIndexId,
160  NULL,
161  1, key);
162 
163  tuple = systable_getnext(scan);
164 
165  /* Must copy tuple before releasing buffer */
166  if (HeapTupleIsValid(tuple))
167  tuple = heap_copytuple(tuple);
168 
169  /* all done */
170  systable_endscan(scan);
171  heap_close(relation, AccessShareLock);
172 
173  return tuple;
174 }
175 
176 
177 /*
178  * PerformAuthentication -- authenticate a remote client
179  *
180  * returns: nothing. Will not return at all if there's any failure.
181  */
182 static void
184 {
185  /* This should be set already, but let's make sure */
186  ClientAuthInProgress = true; /* limit visibility of log messages */
187 
188  /*
189  * In EXEC_BACKEND case, we didn't inherit the contents of pg_hba.conf
190  * etcetera from the postmaster, and have to load them ourselves.
191  *
192  * FIXME: [fork/exec] Ugh. Is there a way around this overhead?
193  */
194 #ifdef EXEC_BACKEND
195 
196  /*
197  * load_hba() and load_ident() want to work within the PostmasterContext,
198  * so create that if it doesn't exist (which it won't). We'll delete it
199  * again later, in PostgresMain.
200  */
201  if (PostmasterContext == NULL)
203  "Postmaster",
205 
206  if (!load_hba())
207  {
208  /*
209  * It makes no sense to continue if we fail to load the HBA file,
210  * since there is no way to connect to the database in this case.
211  */
212  ereport(FATAL,
213  (errmsg("could not load pg_hba.conf")));
214  }
215 
216  if (!load_ident())
217  {
218  /*
219  * It is ok to continue if we fail to load the IDENT file, although it
220  * means that you cannot log in using any of the authentication
221  * methods that need a user name mapping. load_ident() already logged
222  * the details of error to the log.
223  */
224  }
225 #endif
226 
227  /*
228  * Set up a timeout in case a buggy or malicious client fails to respond
229  * during authentication. Since we're inside a transaction and might do
230  * database access, we have to use the statement_timeout infrastructure.
231  */
233 
234  /*
235  * Now perform authentication exchange.
236  */
237  ClientAuthentication(port); /* might not return, if failure */
238 
239  /*
240  * Done with authentication. Disable the timeout, and log if needed.
241  */
243 
244  if (Log_connections)
245  {
246  if (am_walsender)
247  {
248 #ifdef USE_OPENSSL
249  if (port->ssl_in_use)
250  ereport(LOG,
251  (errmsg("replication connection authorized: user=%s SSL enabled (protocol=%s, cipher=%s, compression=%s)",
252  port->user_name, SSL_get_version(port->ssl), SSL_get_cipher(port->ssl),
253  SSL_get_current_compression(port->ssl) ? _("on") : _("off"))));
254  else
255 #endif
256  ereport(LOG,
257  (errmsg("replication connection authorized: user=%s",
258  port->user_name)));
259  }
260  else
261  {
262 #ifdef USE_OPENSSL
263  if (port->ssl_in_use)
264  ereport(LOG,
265  (errmsg("connection authorized: user=%s database=%s SSL enabled (protocol=%s, cipher=%s, compression=%s)",
266  port->user_name, port->database_name, SSL_get_version(port->ssl), SSL_get_cipher(port->ssl),
267  SSL_get_current_compression(port->ssl) ? _("on") : _("off"))));
268  else
269 #endif
270  ereport(LOG,
271  (errmsg("connection authorized: user=%s database=%s",
272  port->user_name, port->database_name)));
273  }
274  }
275 
276  set_ps_display("startup", false);
277 
278  ClientAuthInProgress = false; /* client_min_messages is active now */
279 }
280 
281 
282 /*
283  * CheckMyDatabase -- fetch information from the pg_database entry for our DB
284  */
285 static void
286 CheckMyDatabase(const char *name, bool am_superuser)
287 {
288  HeapTuple tup;
289  Form_pg_database dbform;
290  char *collate;
291  char *ctype;
292 
293  /* Fetch our pg_database row normally, via syscache */
295  if (!HeapTupleIsValid(tup))
296  elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
297  dbform = (Form_pg_database) GETSTRUCT(tup);
298 
299  /* This recheck is strictly paranoia */
300  if (strcmp(name, NameStr(dbform->datname)) != 0)
301  ereport(FATAL,
302  (errcode(ERRCODE_UNDEFINED_DATABASE),
303  errmsg("database \"%s\" has disappeared from pg_database",
304  name),
305  errdetail("Database OID %u now seems to belong to \"%s\".",
306  MyDatabaseId, NameStr(dbform->datname))));
307 
308  /*
309  * Check permissions to connect to the database.
310  *
311  * These checks are not enforced when in standalone mode, so that there is
312  * a way to recover from disabling all access to all databases, for
313  * example "UPDATE pg_database SET datallowconn = false;".
314  *
315  * We do not enforce them for autovacuum worker processes either.
316  */
318  {
319  /*
320  * Check that the database is currently allowing connections.
321  */
322  if (!dbform->datallowconn)
323  ereport(FATAL,
324  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
325  errmsg("database \"%s\" is not currently accepting connections",
326  name)));
327 
328  /*
329  * Check privilege to connect to the database. (The am_superuser test
330  * is redundant, but since we have the flag, might as well check it
331  * and save a few cycles.)
332  */
333  if (!am_superuser &&
336  ereport(FATAL,
337  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
338  errmsg("permission denied for database \"%s\"", name),
339  errdetail("User does not have CONNECT privilege.")));
340 
341  /*
342  * Check connection limit for this database.
343  *
344  * There is a race condition here --- we create our PGPROC before
345  * checking for other PGPROCs. If two backends did this at about the
346  * same time, they might both think they were over the limit, while
347  * ideally one should succeed and one fail. Getting that to work
348  * exactly seems more trouble than it is worth, however; instead we
349  * just document that the connection limit is approximate.
350  */
351  if (dbform->datconnlimit >= 0 &&
352  !am_superuser &&
353  CountDBConnections(MyDatabaseId) > dbform->datconnlimit)
354  ereport(FATAL,
355  (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
356  errmsg("too many connections for database \"%s\"",
357  name)));
358  }
359 
360  /*
361  * OK, we're golden. Next to-do item is to save the encoding info out of
362  * the pg_database tuple.
363  */
364  SetDatabaseEncoding(dbform->encoding);
365  /* Record it as a GUC internal option, too */
366  SetConfigOption("server_encoding", GetDatabaseEncodingName(),
368  /* If we have no other source of client_encoding, use server encoding */
369  SetConfigOption("client_encoding", GetDatabaseEncodingName(),
371 
372  /* assign locale variables */
373  collate = NameStr(dbform->datcollate);
374  ctype = NameStr(dbform->datctype);
375 
376  if (pg_perm_setlocale(LC_COLLATE, collate) == NULL)
377  ereport(FATAL,
378  (errmsg("database locale is incompatible with operating system"),
379  errdetail("The database was initialized with LC_COLLATE \"%s\", "
380  " which is not recognized by setlocale().", collate),
381  errhint("Recreate the database with another locale or install the missing locale.")));
382 
383  if (pg_perm_setlocale(LC_CTYPE, ctype) == NULL)
384  ereport(FATAL,
385  (errmsg("database locale is incompatible with operating system"),
386  errdetail("The database was initialized with LC_CTYPE \"%s\", "
387  " which is not recognized by setlocale().", ctype),
388  errhint("Recreate the database with another locale or install the missing locale.")));
389 
390  /* Make the locale settings visible as GUC variables, too */
391  SetConfigOption("lc_collate", collate, PGC_INTERNAL, PGC_S_OVERRIDE);
392  SetConfigOption("lc_ctype", ctype, PGC_INTERNAL, PGC_S_OVERRIDE);
393 
395 
396  ReleaseSysCache(tup);
397 }
398 
399 
400 
401 /* --------------------------------
402  * InitCommunication
403  *
404  * This routine initializes stuff needed for ipc, locking, etc.
405  * it should be called something more informative.
406  * --------------------------------
407  */
408 static void
410 {
411  /*
412  * initialize shared memory and semaphores appropriately.
413  */
414  if (!IsUnderPostmaster) /* postmaster already did this */
415  {
416  /*
417  * We're running a postgres bootstrap process or a standalone backend.
418  * Create private "shmem" and semaphores.
419  */
421  }
422 }
423 
424 
425 /*
426  * pg_split_opts -- split a string of options and append it to an argv array
427  *
428  * The caller is responsible for ensuring the argv array is large enough. The
429  * maximum possible number of arguments added by this routine is
430  * (strlen(optstr) + 1) / 2.
431  *
432  * Because some option values can contain spaces we allow escaping using
433  * backslashes, with \\ representing a literal backslash.
434  */
435 void
436 pg_split_opts(char **argv, int *argcp, const char *optstr)
437 {
438  StringInfoData s;
439 
440  initStringInfo(&s);
441 
442  while (*optstr)
443  {
444  bool last_was_escape = false;
445 
446  resetStringInfo(&s);
447 
448  /* skip over leading space */
449  while (isspace((unsigned char) *optstr))
450  optstr++;
451 
452  if (*optstr == '\0')
453  break;
454 
455  /*
456  * Parse a single option, stopping at the first space, unless it's
457  * escaped.
458  */
459  while (*optstr)
460  {
461  if (isspace((unsigned char) *optstr) && !last_was_escape)
462  break;
463 
464  if (!last_was_escape && *optstr == '\\')
465  last_was_escape = true;
466  else
467  {
468  last_was_escape = false;
469  appendStringInfoChar(&s, *optstr);
470  }
471 
472  optstr++;
473  }
474 
475  /* now store the option in the next argv[] position */
476  argv[(*argcp)++] = pstrdup(s.data);
477  }
478 
479  pfree(s.data);
480 }
481 
482 /*
483  * Initialize MaxBackends value from config options.
484  *
485  * This must be called after modules have had the chance to register background
486  * workers in shared_preload_libraries, and before shared memory size is
487  * determined.
488  *
489  * Note that in EXEC_BACKEND environment, the value is passed down from
490  * postmaster to subprocesses via BackendParameters in SubPostmasterMain; only
491  * postmaster itself and processes not under postmaster control should call
492  * this.
493  */
494 void
496 {
497  Assert(MaxBackends == 0);
498 
499  /* the extra unit accounts for the autovacuum launcher */
502 
503  /* internal error because the values were all checked previously */
505  elog(ERROR, "too many backends configured");
506 }
507 
508 /*
509  * Early initialization of a backend (either standalone or under postmaster).
510  * This happens even before InitPostgres.
511  *
512  * This is separate from InitPostgres because it is also called by auxiliary
513  * processes, such as the background writer process, which may not call
514  * InitPostgres at all.
515  */
516 void
517 BaseInit(void)
518 {
519  /*
520  * Attach to shared memory and semaphores, and initialize our
521  * input/output/debugging file descriptors.
522  */
524  DebugFileOpen();
525 
526  /* Do local initialization of file, storage and buffer managers */
527  InitFileAccess();
528  smgrinit();
530 }
531 
532 
533 /* --------------------------------
534  * InitPostgres
535  * Initialize POSTGRES.
536  *
537  * The database can be specified by name, using the in_dbname parameter, or by
538  * OID, using the dboid parameter. In the latter case, the actual database
539  * name can be returned to the caller in out_dbname. If out_dbname isn't
540  * NULL, it must point to a buffer of size NAMEDATALEN.
541  *
542  * Similarly, the username can be passed by name, using the username parameter,
543  * or by OID using the useroid parameter.
544  *
545  * In bootstrap mode no parameters are used. The autovacuum launcher process
546  * doesn't use any parameters either, because it only goes far enough to be
547  * able to read pg_database; it doesn't connect to any particular database.
548  * In walsender mode only username is used.
549  *
550  * As of PostgreSQL 8.2, we expect InitProcess() was already called, so we
551  * already have a PGPROC struct ... but it's not completely filled in yet.
552  *
553  * Note:
554  * Be very careful with the order of calls in the InitPostgres function.
555  * --------------------------------
556  */
557 void
558 InitPostgres(const char *in_dbname, Oid dboid, const char *username,
559  Oid useroid, char *out_dbname)
560 {
561  bool bootstrap = IsBootstrapProcessingMode();
562  bool am_superuser;
563  char *fullpath;
564  char dbname[NAMEDATALEN];
565 
566  elog(DEBUG3, "InitPostgres");
567 
568  /*
569  * Add my PGPROC struct to the ProcArray.
570  *
571  * Once I have done this, I am visible to other backends!
572  */
574 
575  /*
576  * Initialize my entry in the shared-invalidation manager's array of
577  * per-backend data.
578  *
579  * Sets up MyBackendId, a unique backend identifier.
580  */
582 
583  SharedInvalBackendInit(false);
584 
585  if (MyBackendId > MaxBackends || MyBackendId <= 0)
586  elog(FATAL, "bad backend ID: %d", MyBackendId);
587 
588  /* Now that we have a BackendId, we can participate in ProcSignal */
590 
591  /*
592  * Also set up timeout handlers needed for backend operation. We need
593  * these in every case except bootstrap.
594  */
595  if (!bootstrap)
596  {
602  }
603 
604  /*
605  * bufmgr needs another initialization call too
606  */
608 
609  /*
610  * Initialize local process's access to XLOG.
611  */
612  if (IsUnderPostmaster)
613  {
614  /*
615  * The postmaster already started the XLOG machinery, but we need to
616  * call InitXLOGAccess(), if the system isn't in hot-standby mode.
617  * This is handled by calling RecoveryInProgress and ignoring the
618  * result.
619  */
620  (void) RecoveryInProgress();
621  }
622  else
623  {
624  /*
625  * We are either a bootstrap process or a standalone backend. Either
626  * way, start up the XLOG machinery, and register to have it closed
627  * down at exit.
628  */
629  StartupXLOG();
631  }
632 
633  /*
634  * Initialize the relation cache and the system catalog caches. Note that
635  * no catalog access happens here; we only set up the hashtable structure.
636  * We must do this before starting a transaction because transaction abort
637  * would try to touch these hashtables.
638  */
641  InitPlanCache();
642 
643  /* Initialize portal manager */
645 
646  /* Initialize stats collection --- must happen before first xact */
647  if (!bootstrap)
649 
650  /*
651  * Load relcache entries for the shared system catalogs. This must create
652  * at least entries for pg_database and catalogs used for authentication.
653  */
655 
656  /*
657  * Set up process-exit callback to do pre-shutdown cleanup. This is the
658  * first before_shmem_exit callback we register; thus, this will be the
659  * last thing we do before low-level modules like the buffer manager begin
660  * to close down. We need to have this in place before we begin our first
661  * transaction --- if we fail during the initialization transaction, as is
662  * entirely possible, we need the AbortTransaction call to clean up.
663  */
665 
666  /* The autovacuum launcher is done here */
668  {
669  /* report this backend in the PgBackendStatus array */
670  pgstat_bestart();
671 
672  return;
673  }
674 
675  /*
676  * Start a new transaction here before first access to db, and get a
677  * snapshot. We don't have a use for the snapshot itself, but we're
678  * interested in the secondary effect that it sets RecentGlobalXmin. (This
679  * is critical for anything that reads heap pages, because HOT may decide
680  * to prune them even if the process doesn't attempt to modify any
681  * tuples.)
682  */
683  if (!bootstrap)
684  {
685  /* statement_timestamp must be set for timeouts to work correctly */
688 
689  /*
690  * transaction_isolation will have been set to the default by the
691  * above. If the default is "serializable", and we are in hot
692  * standby, we will fail if we don't change it to something lower.
693  * Fortunately, "read committed" is plenty good enough.
694  */
696 
697  (void) GetTransactionSnapshot();
698  }
699 
700  /*
701  * Perform client authentication if necessary, then figure out our
702  * postgres user ID, and see if we are a superuser.
703  *
704  * In standalone mode and in autovacuum worker processes, we use a fixed
705  * ID, otherwise we figure it out from the authenticated user name.
706  */
707  if (bootstrap || IsAutoVacuumWorkerProcess())
708  {
710  am_superuser = true;
711  }
712  else if (!IsUnderPostmaster)
713  {
715  am_superuser = true;
716  if (!ThereIsAtLeastOneRole())
718  (errcode(ERRCODE_UNDEFINED_OBJECT),
719  errmsg("no roles are defined in this database system"),
720  errhint("You should immediately run CREATE USER \"%s\" SUPERUSER;.",
721  username != NULL ? username : "postgres")));
722  }
723  else if (IsBackgroundWorker)
724  {
725  if (username == NULL && !OidIsValid(useroid))
726  {
728  am_superuser = true;
729  }
730  else
731  {
732  InitializeSessionUserId(username, useroid);
733  am_superuser = superuser();
734  }
735  }
736  else
737  {
738  /* normal multiuser case */
739  Assert(MyProcPort != NULL);
741  InitializeSessionUserId(username, useroid);
742  am_superuser = superuser();
743  }
744 
745  /*
746  * If we're trying to shut down, only superusers can connect, and new
747  * replication connections are not allowed.
748  */
749  if ((!am_superuser || am_walsender) &&
750  MyProcPort != NULL &&
752  {
753  if (am_walsender)
754  ereport(FATAL,
755  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
756  errmsg("new replication connections are not allowed during database shutdown")));
757  else
758  ereport(FATAL,
759  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
760  errmsg("must be superuser to connect during database shutdown")));
761  }
762 
763  /*
764  * Binary upgrades only allowed super-user connections
765  */
766  if (IsBinaryUpgrade && !am_superuser)
767  {
768  ereport(FATAL,
769  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
770  errmsg("must be superuser to connect in binary upgrade mode")));
771  }
772 
773  /*
774  * The last few connections slots are reserved for superusers. Although
775  * replication connections currently require superuser privileges, we
776  * don't allow them to consume the reserved slots, which are intended for
777  * interactive use.
778  */
779  if ((!am_superuser || am_walsender) &&
780  ReservedBackends > 0 &&
782  ereport(FATAL,
783  (errcode(ERRCODE_TOO_MANY_CONNECTIONS),
784  errmsg("remaining connection slots are reserved for non-replication superuser connections")));
785 
786  /* Check replication permissions needed for walsender processes. */
787  if (am_walsender)
788  {
789  Assert(!bootstrap);
790 
791  if (!superuser() && !has_rolreplication(GetUserId()))
792  ereport(FATAL,
793  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
794  errmsg("must be superuser or replication role to start walsender")));
795  }
796 
797  /*
798  * If this is a plain walsender only supporting physical replication, we
799  * don't want to connect to any particular database. Just finish the
800  * backend startup by processing any options from the startup packet, and
801  * we're done.
802  */
804  {
805  /* process any options passed in the startup packet */
806  if (MyProcPort != NULL)
807  process_startup_options(MyProcPort, am_superuser);
808 
809  /* Apply PostAuthDelay as soon as we've read all options */
810  if (PostAuthDelay > 0)
811  pg_usleep(PostAuthDelay * 1000000L);
812 
813  /* initialize client encoding */
815 
816  /* report this backend in the PgBackendStatus array */
817  pgstat_bestart();
818 
819  /* close the transaction we started above */
821 
822  return;
823  }
824 
825  /*
826  * Set up the global variables holding database id and default tablespace.
827  * But note we won't actually try to touch the database just yet.
828  *
829  * We take a shortcut in the bootstrap case, otherwise we have to look up
830  * the db's entry in pg_database.
831  */
832  if (bootstrap)
833  {
836  }
837  else if (in_dbname != NULL)
838  {
839  HeapTuple tuple;
840  Form_pg_database dbform;
841 
842  tuple = GetDatabaseTuple(in_dbname);
843  if (!HeapTupleIsValid(tuple))
844  ereport(FATAL,
845  (errcode(ERRCODE_UNDEFINED_DATABASE),
846  errmsg("database \"%s\" does not exist", in_dbname)));
847  dbform = (Form_pg_database) GETSTRUCT(tuple);
848  MyDatabaseId = HeapTupleGetOid(tuple);
849  MyDatabaseTableSpace = dbform->dattablespace;
850  /* take database name from the caller, just for paranoia */
851  strlcpy(dbname, in_dbname, sizeof(dbname));
852  }
853  else if (OidIsValid(dboid))
854  {
855  /* caller specified database by OID */
856  HeapTuple tuple;
857  Form_pg_database dbform;
858 
859  tuple = GetDatabaseTupleByOid(dboid);
860  if (!HeapTupleIsValid(tuple))
861  ereport(FATAL,
862  (errcode(ERRCODE_UNDEFINED_DATABASE),
863  errmsg("database %u does not exist", dboid)));
864  dbform = (Form_pg_database) GETSTRUCT(tuple);
865  MyDatabaseId = HeapTupleGetOid(tuple);
866  MyDatabaseTableSpace = dbform->dattablespace;
867  Assert(MyDatabaseId == dboid);
868  strlcpy(dbname, NameStr(dbform->datname), sizeof(dbname));
869  /* pass the database name back to the caller */
870  if (out_dbname)
871  strcpy(out_dbname, dbname);
872  }
873  else
874  {
875  /*
876  * If this is a background worker not bound to any particular
877  * database, we're done now. Everything that follows only makes sense
878  * if we are bound to a specific database. We do need to close the
879  * transaction we started before returning.
880  */
881  if (!bootstrap)
882  {
883  pgstat_bestart();
885  }
886  return;
887  }
888 
889  /*
890  * Now, take a writer's lock on the database we are trying to connect to.
891  * If there is a concurrently running DROP DATABASE on that database, this
892  * will block us until it finishes (and has committed its update of
893  * pg_database).
894  *
895  * Note that the lock is not held long, only until the end of this startup
896  * transaction. This is OK since we will advertise our use of the
897  * database in the ProcArray before dropping the lock (in fact, that's the
898  * next thing to do). Anyone trying a DROP DATABASE after this point will
899  * see us in the array once they have the lock. Ordering is important for
900  * this because we don't want to advertise ourselves as being in this
901  * database until we have the lock; otherwise we create what amounts to a
902  * deadlock with CountOtherDBBackends().
903  *
904  * Note: use of RowExclusiveLock here is reasonable because we envision
905  * our session as being a concurrent writer of the database. If we had a
906  * way of declaring a session as being guaranteed-read-only, we could use
907  * AccessShareLock for such sessions and thereby not conflict against
908  * CREATE DATABASE.
909  */
910  if (!bootstrap)
913 
914  /*
915  * Now we can mark our PGPROC entry with the database ID.
916  *
917  * We assume this is an atomic store so no lock is needed; though actually
918  * things would work fine even if it weren't atomic. Anyone searching the
919  * ProcArray for this database's ID should hold the database lock, so they
920  * would not be executing concurrently with this store. A process looking
921  * for another database's ID could in theory see a chance match if it read
922  * a partially-updated databaseId value; but as long as all such searches
923  * wait and retry, as in CountOtherDBBackends(), they will certainly see
924  * the correct value on their next try.
925  */
927 
928  /*
929  * We established a catalog snapshot while reading pg_authid and/or
930  * pg_database; but until we have set up MyDatabaseId, we won't react to
931  * incoming sinval messages for unshared catalogs, so we won't realize it
932  * if the snapshot has been invalidated. Assume it's no good anymore.
933  */
935 
936  /*
937  * Recheck pg_database to make sure the target database hasn't gone away.
938  * If there was a concurrent DROP DATABASE, this ensures we will die
939  * cleanly without creating a mess.
940  */
941  if (!bootstrap)
942  {
943  HeapTuple tuple;
944 
945  tuple = GetDatabaseTuple(dbname);
946  if (!HeapTupleIsValid(tuple) ||
947  MyDatabaseId != HeapTupleGetOid(tuple) ||
948  MyDatabaseTableSpace != ((Form_pg_database) GETSTRUCT(tuple))->dattablespace)
949  ereport(FATAL,
950  (errcode(ERRCODE_UNDEFINED_DATABASE),
951  errmsg("database \"%s\" does not exist", dbname),
952  errdetail("It seems to have just been dropped or renamed.")));
953  }
954 
955  /*
956  * Now we should be able to access the database directory safely. Verify
957  * it's there and looks reasonable.
958  */
960 
961  if (!bootstrap)
962  {
963  if (access(fullpath, F_OK) == -1)
964  {
965  if (errno == ENOENT)
966  ereport(FATAL,
967  (errcode(ERRCODE_UNDEFINED_DATABASE),
968  errmsg("database \"%s\" does not exist",
969  dbname),
970  errdetail("The database subdirectory \"%s\" is missing.",
971  fullpath)));
972  else
973  ereport(FATAL,
975  errmsg("could not access directory \"%s\": %m",
976  fullpath)));
977  }
978 
979  ValidatePgVersion(fullpath);
980  }
981 
982  SetDatabasePath(fullpath);
983 
984  /*
985  * It's now possible to do real access to the system catalogs.
986  *
987  * Load relcache entries for the system catalogs. This must create at
988  * least the minimum set of "nailed-in" cache entries.
989  */
991 
992  /* set up ACL framework (so CheckMyDatabase can check permissions) */
993  initialize_acl();
994 
995  /*
996  * Re-read the pg_database row for our database, check permissions and set
997  * up database-specific GUC settings. We can't do this until all the
998  * database-access infrastructure is up. (Also, it wants to know if the
999  * user is a superuser, so the above stuff has to happen first.)
1000  */
1001  if (!bootstrap)
1002  CheckMyDatabase(dbname, am_superuser);
1003 
1004  /*
1005  * Now process any command-line switches and any additional GUC variable
1006  * settings passed in the startup packet. We couldn't do this before
1007  * because we didn't know if client is a superuser.
1008  */
1009  if (MyProcPort != NULL)
1010  process_startup_options(MyProcPort, am_superuser);
1011 
1012  /* Process pg_db_role_setting options */
1014 
1015  /* Apply PostAuthDelay as soon as we've read all options */
1016  if (PostAuthDelay > 0)
1017  pg_usleep(PostAuthDelay * 1000000L);
1018 
1019  /*
1020  * Initialize various default states that can't be set up until we've
1021  * selected the active user and gotten the right GUC settings.
1022  */
1023 
1024  /* set default namespace search path */
1026 
1027  /* initialize client encoding */
1029 
1030  /* report this backend in the PgBackendStatus array */
1031  if (!bootstrap)
1032  pgstat_bestart();
1033 
1034  /* close the transaction we started above */
1035  if (!bootstrap)
1037 }
1038 
1039 /*
1040  * Process any command-line switches and any additional GUC variable
1041  * settings passed in the startup packet.
1042  */
1043 static void
1044 process_startup_options(Port *port, bool am_superuser)
1045 {
1046  GucContext gucctx;
1047  ListCell *gucopts;
1048 
1049  gucctx = am_superuser ? PGC_SU_BACKEND : PGC_BACKEND;
1050 
1051  /*
1052  * First process any command-line switches that were included in the
1053  * startup packet, if we are in a regular backend.
1054  */
1055  if (port->cmdline_options != NULL)
1056  {
1057  /*
1058  * The maximum possible number of commandline arguments that could
1059  * come from port->cmdline_options is (strlen + 1) / 2; see
1060  * pg_split_opts().
1061  */
1062  char **av;
1063  int maxac;
1064  int ac;
1065 
1066  maxac = 2 + (strlen(port->cmdline_options) + 1) / 2;
1067 
1068  av = (char **) palloc(maxac * sizeof(char *));
1069  ac = 0;
1070 
1071  av[ac++] = "postgres";
1072 
1073  pg_split_opts(av, &ac, port->cmdline_options);
1074 
1075  av[ac] = NULL;
1076 
1077  Assert(ac < maxac);
1078 
1079  (void) process_postgres_switches(ac, av, gucctx, NULL);
1080  }
1081 
1082  /*
1083  * Process any additional GUC variable settings passed in startup packet.
1084  * These are handled exactly like command-line variables.
1085  */
1086  gucopts = list_head(port->guc_options);
1087  while (gucopts)
1088  {
1089  char *name;
1090  char *value;
1091 
1092  name = lfirst(gucopts);
1093  gucopts = lnext(gucopts);
1094 
1095  value = lfirst(gucopts);
1096  gucopts = lnext(gucopts);
1097 
1098  SetConfigOption(name, value, gucctx, PGC_S_CLIENT);
1099  }
1100 }
1101 
1102 /*
1103  * Load GUC settings from pg_db_role_setting.
1104  *
1105  * We try specific settings for the database/role combination, as well as
1106  * general for this database and for this user.
1107  */
1108 static void
1109 process_settings(Oid databaseid, Oid roleid)
1110 {
1111  Relation relsetting;
1112  Snapshot snapshot;
1113 
1114  if (!IsUnderPostmaster)
1115  return;
1116 
1118 
1119  /* read all the settings under the same snapshot for efficiency */
1121 
1122  /* Later settings are ignored if set earlier. */
1123  ApplySetting(snapshot, databaseid, roleid, relsetting, PGC_S_DATABASE_USER);
1124  ApplySetting(snapshot, InvalidOid, roleid, relsetting, PGC_S_USER);
1125  ApplySetting(snapshot, databaseid, InvalidOid, relsetting, PGC_S_DATABASE);
1126  ApplySetting(snapshot, InvalidOid, InvalidOid, relsetting, PGC_S_GLOBAL);
1127 
1128  UnregisterSnapshot(snapshot);
1129  heap_close(relsetting, AccessShareLock);
1130 }
1131 
1132 /*
1133  * Backend-shutdown callback. Do cleanup that we want to be sure happens
1134  * before all the supporting modules begin to nail their doors shut via
1135  * their own callbacks.
1136  *
1137  * User-level cleanup, such as temp-relation removal and UNLISTEN, happens
1138  * via separate callbacks that execute before this one. We don't combine the
1139  * callbacks because we still want this one to happen if the user-level
1140  * cleanup fails.
1141  */
1142 static void
1144 {
1145  /* Make sure we've killed any active transaction */
1147 
1148  /*
1149  * User locks are not released by transaction end, so be sure to release
1150  * them explicitly.
1151  */
1153 }
1154 
1155 
1156 /*
1157  * STATEMENT_TIMEOUT handler: trigger a query-cancel interrupt.
1158  */
1159 static void
1161 {
1162  int sig = SIGINT;
1163 
1164  /*
1165  * During authentication the timeout is used to deal with
1166  * authentication_timeout - we want to quit in response to such timeouts.
1167  */
1169  sig = SIGTERM;
1170 
1171 #ifdef HAVE_SETSID
1172  /* try to signal whole process group */
1173  kill(-MyProcPid, sig);
1174 #endif
1175  kill(MyProcPid, sig);
1176 }
1177 
1178 /*
1179  * LOCK_TIMEOUT handler: trigger a query-cancel interrupt.
1180  */
1181 static void
1183 {
1184 #ifdef HAVE_SETSID
1185  /* try to signal whole process group */
1186  kill(-MyProcPid, SIGINT);
1187 #endif
1188  kill(MyProcPid, SIGINT);
1189 }
1190 
1191 static void
1193 {
1195  InterruptPending = true;
1196  SetLatch(MyLatch);
1197 }
1198 
1199 /*
1200  * Returns true if at least one role is defined in this database cluster.
1201  */
1202 static bool
1204 {
1205  Relation pg_authid_rel;
1206  HeapScanDesc scan;
1207  bool result;
1208 
1209  pg_authid_rel = heap_open(AuthIdRelationId, AccessShareLock);
1210 
1211  scan = heap_beginscan_catalog(pg_authid_rel, 0, NULL);
1212  result = (heap_getnext(scan, ForwardScanDirection) != NULL);
1213 
1214  heap_endscan(scan);
1215  heap_close(pg_authid_rel, AccessShareLock);
1216 
1217  return result;
1218 }
HeapTuple heap_copytuple(HeapTuple tuple)
Definition: heaptuple.c:608
GucContext
Definition: guc.h:68
int MyProcPid
Definition: globals.c:38
int errhint(const char *fmt,...)
Definition: elog.c:987
BackendId MyBackendId
Definition: globals.c:72
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
struct Port * MyProcPort
Definition: globals.c:40
void heap_endscan(HeapScanDesc scan)
Definition: heapam.c:1578
CAC_state canAcceptConnections
Definition: libpq-be.h:129
volatile bool IdleInTransactionSessionTimeoutPending
Definition: globals.c:33
Snapshot RegisterSnapshot(Snapshot snapshot)
Definition: snapmgr.c:858
void SharedInvalBackendInit(bool sendOnly)
Definition: sinvaladt.c:258
#define DEBUG3
Definition: elog.h:23
Oid GetUserId(void)
Definition: miscinit.c:283
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
FormData_pg_database * Form_pg_database
Definition: pg_database.h:57
PGPROC * MyProc
Definition: proc.c:67
static HeapTuple GetDatabaseTuple(const char *dbname)
Definition: postinit.c:94
void ClientAuthentication(Port *port)
Definition: auth.c:339
char * pstrdup(const char *in)
Definition: mcxt.c:1077
#define DatabaseRelationId
Definition: pg_database.h:29
void CommitTransactionCommand(void)
Definition: xact.c:2747
void ValidatePgVersion(const char *path)
Definition: miscinit.c:1349
void RelationCacheInitializePhase2(void)
Definition: relcache.c:3565
Snapshot GetCatalogSnapshot(Oid relid)
Definition: snapmgr.c:436
#define AccessShareLock
Definition: lockdefs.h:36
void set_ps_display(const char *activity, bool force)
Definition: ps_status.c:326
static void PerformAuthentication(Port *port)
Definition: postinit.c:183
static void LockTimeoutHandler(void)
Definition: postinit.c:1182
int errcode(int sqlerrcode)
Definition: elog.c:575
Definition: libpq-be.h:116
bool superuser(void)
Definition: superuser.c:47
return result
Definition: formatting.c:1618
bool ssl_in_use
Definition: libpq-be.h:181
void BaseInit(void)
Definition: postinit.c:517
static void CheckMyDatabase(const char *name, bool am_superuser)
Definition: postinit.c:286
bool criticalSharedRelcachesBuilt
Definition: relcache.c:135
#define heap_close(r, l)
Definition: heapam.h:97
void initialize_acl(void)
Definition: acl.c:4594
#define LOG
Definition: elog.h:26
unsigned int Oid
Definition: postgres_ext.h:31
bool RecoveryInProgress(void)
Definition: xlog.c:7874
bool Log_connections
Definition: postmaster.c:239
List * guc_options
Definition: libpq-be.h:139
Snapshot GetTransactionSnapshot(void)
Definition: snapmgr.c:300
#define OidIsValid(objectId)
Definition: c.h:538
void AbortOutOfAnyTransaction(void)
Definition: xact.c:4222
Oid GetSessionUserId(void)
Definition: miscinit.c:317
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
bool HaveNFreeProcs(int n)
Definition: proc.c:637
bool IsBinaryUpgrade
Definition: globals.c:101
bool load_ident(void)
Definition: hba.c:2873
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:152
int AuthenticationTimeout
Definition: postmaster.c:236
Oid MyDatabaseTableSpace
Definition: globals.c:78
bool IsBackgroundWorker
Definition: globals.c:102
char * pg_perm_setlocale(int category, const char *locale)
Definition: pg_locale.c:151
#define AuthIdRelationId
Definition: pg_authid.h:42
void RelationCacheInitializePhase3(void)
Definition: relcache.c:3624
static void InitCommunication(void)
Definition: postinit.c:409
#define NAMEDATALEN
bool ClientAuthInProgress
Definition: postmaster.c:348
bool am_walsender
Definition: walsender.c:108
void pg_usleep(long microsec)
Definition: signal.c:53
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
void pfree(void *pointer)
Definition: mcxt.c:950
void InitBufferPoolAccess(void)
Definition: bufmgr.c:2437
int CountDBConnections(Oid databaseid)
Definition: procarray.c:2765
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define MAX_BACKENDS
Definition: postmaster.h:75
int ReservedBackends
Definition: postmaster.c:211
#define Anum_pg_database_datname
Definition: pg_database.h:64
#define FATAL
Definition: elog.h:52
void InitializeSearchPath(void)
Definition: namespace.c:4016
int MaxBackends
Definition: globals.c:126
#define ALLOCSET_DEFAULT_SIZES
Definition: memutils.h:165
#define TemplateDbOid
Definition: pg_database.h:80
void on_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:348
void check_strxfrm_bug(void)
Definition: pg_locale.c:993
void SetConfigOption(const char *name, const char *value, GucContext context, GucSource source)
Definition: guc.c:6676
bool load_hba(void)
Definition: hba.c:2091
void pg_split_opts(char **argv, int *argcp, const char *optstr)
Definition: postinit.c:436
bool IsUnderPostmaster
Definition: globals.c:100
#define RowExclusiveLock
Definition: lockdefs.h:38
#define DEFAULTTABLESPACE_OID
Definition: pg_tablespace.h:63
int errdetail(const char *fmt,...)
Definition: elog.c:873
int errcode_for_file_access(void)
Definition: elog.c:598
#define USER_LOCKMETHOD
Definition: lock.h:130
#define CStringGetDatum(X)
Definition: postgres.h:584
static void IdleInTransactionSessionTimeoutHandler(void)
Definition: postinit.c:1192
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition: ipc.c:320
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
char * user_name
Definition: libpq-be.h:137
#define DatabaseOidIndexId
Definition: indexing.h:142
void resetStringInfo(StringInfo str)
Definition: stringinfo.c:94
Oid databaseId
Definition: proc.h:113
void pgstat_initialize(void)
Definition: pgstat.c:2709
HeapScanDesc heap_beginscan_catalog(Relation relation, int nkeys, ScanKey key)
Definition: heapam.c:1399
static bool ThereIsAtLeastOneRole(void)
Definition: postinit.c:1203
void StartupXLOG(void)
Definition: xlog.c:6190
bool IsAutoVacuumWorkerProcess(void)
Definition: autovacuum.c:3360
#define lnext(lc)
Definition: pg_list.h:105
#define ereport(elevel, rest)
Definition: elog.h:122
void DebugFileOpen(void)
Definition: elog.c:1863
void InvalidateCatalogSnapshot(void)
Definition: snapmgr.c:506
MemoryContext TopMemoryContext
Definition: mcxt.c:43
char * GetDatabasePath(Oid dbNode, Oid spcNode)
Definition: relpath.c:108
#define ACL_CONNECT
Definition: parsenodes.h:84
static int port
Definition: pg_regress.c:89
void UnregisterSnapshot(Snapshot snapshot)
Definition: snapmgr.c:900
void SetDatabasePath(const char *path)
Definition: miscinit.c:82
void appendStringInfoChar(StringInfo str, char ch)
Definition: stringinfo.c:201
void initStringInfo(StringInfo str)
Definition: stringinfo.c:65
#define WARNING
Definition: elog.h:40
void ShutdownXLOG(int code, Datum arg)
Definition: xlog.c:8322
struct @18::@19 av[32]
static HeapTuple GetDatabaseTupleByOid(Oid dboid)
Definition: postinit.c:137
void smgrinit(void)
Definition: smgr.c:102
#define InvalidBackendId
Definition: backendid.h:23
MemoryContext AllocSetContextCreate(MemoryContext parent, const char *name, Size minContextSize, Size initBlockSize, Size maxBlockSize)
Definition: aset.c:322
#define SSL_get_current_compression(x)
Definition: port.h:419
uintptr_t Datum
Definition: postgres.h:372
void SetDatabaseEncoding(int encoding)
Definition: mbutils.c:909
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1116
bool am_db_walsender
Definition: walsender.c:111
Oid MyDatabaseId
Definition: globals.c:76
int PostAuthDelay
Definition: postgres.c:97
int MaxConnections
Definition: globals.c:123
HeapTuple heap_getnext(HeapScanDesc scan, ScanDirection direction)
Definition: heapam.c:1794
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition: lmgr.c:871
static int sig
Definition: pg_ctl.c:76
void EnablePortalManager(void)
Definition: portalmem.c:103
static void ShutdownPostgres(int code, Datum arg)
Definition: postinit.c:1143
static char * username
Definition: initdb.c:131
int autovacuum_max_workers
Definition: autovacuum.c:113
#define InvalidOid
Definition: postgres_ext.h:36
volatile bool InterruptPending
Definition: globals.c:29
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
TimeoutId RegisterTimeout(TimeoutId id, timeout_handler_proc handler)
Definition: timeout.c:373
void enable_timeout_after(TimeoutId id, int delay_ms)
Definition: timeout.c:428
bool IsAutoVacuumLauncherProcess(void)
Definition: autovacuum.c:3354
void SetLatch(volatile Latch *latch)
Definition: latch.c:415
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
AclResult pg_database_aclcheck(Oid db_oid, Oid roleid, AclMode mode)
Definition: aclchk.c:4434
#define NULL
Definition: c.h:229
#define Assert(condition)
Definition: c.h:675
#define lfirst(lc)
Definition: pg_list.h:106
const char * GetDatabaseEncodingName(void)
Definition: mbutils.c:1021
void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
Definition: lock.c:2014
void InitializeSessionUserIdStandalone(void)
Definition: miscinit.c:578
void StartTransactionCommand(void)
Definition: xact.c:2677
#define XACT_READ_COMMITTED
Definition: xact.h:29
void InitializeSessionUserId(const char *rolename, Oid roleid)
Definition: miscinit.c:482
void InitializeMaxBackends(void)
Definition: postinit.c:495
char * dbname
Definition: streamutil.c:38
static void process_startup_options(Port *port, bool am_superuser)
Definition: postinit.c:1044
int XactIsoLevel
Definition: xact.c:74
bool has_rolreplication(Oid roleid)
Definition: miscinit.c:464
#define DatabaseNameIndexId
Definition: indexing.h:140
void InitializeClientEncoding(void)
Definition: mbutils.c:293
const char * name
Definition: encode.c:521
void InitPlanCache(void)
Definition: plancache.c:116
void InitProcessPhase2(void)
Definition: proc.c:447
#define IsBootstrapProcessingMode()
Definition: miscadmin.h:365
void RelationCacheInitialize(void)
Definition: relcache.c:3528
void ProcSignalInit(int pss_idx)
Definition: procsignal.c:104
void InitCatalogCache(void)
Definition: syscache.c:1000
static void StatementTimeoutHandler(void)
Definition: postinit.c:1160
void SetCurrentStatementStartTimestamp(void)
Definition: xact.c:740
void InitPostgres(const char *in_dbname, Oid dboid, const char *username, Oid useroid, char *out_dbname)
Definition: postinit.c:558
void * palloc(Size size)
Definition: mcxt.c:849
int errmsg(const char *fmt,...)
Definition: elog.c:797
void pgstat_bestart(void)
Definition: pgstat.c:2749
void ApplySetting(Snapshot snapshot, Oid databaseid, Oid roleid, Relation relsetting, GucSource source)
#define DbRoleSettingRelationId
#define NameStr(name)
Definition: c.h:499
static void process_settings(Oid databaseid, Oid roleid)
Definition: postinit.c:1109
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
char * cmdline_options
Definition: libpq-be.h:138
void * arg
int max_worker_processes
Definition: globals.c:124
struct Latch * MyLatch
Definition: globals.c:51
void CheckDeadLockAlert(void)
Definition: proc.c:1743
void InitBufferPoolBackend(void)
Definition: bufmgr.c:2461
void process_postgres_switches(int argc, char *argv[], GucContext ctx, const char **dbname)
Definition: postgres.c:3308
#define elog
Definition: elog.h:219
void disable_timeout(TimeoutId id, bool keep_indicator)
Definition: timeout.c:525
static struct @121 value
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:695
char * database_name
Definition: libpq-be.h:136
void CreateSharedMemoryAndSemaphores(bool makePrivate, int port)
Definition: ipci.c:96
#define _(x)
Definition: elog.c:84
MemoryContext PostmasterContext
Definition: mcxt.c:45
#define BTEqualStrategyNumber
Definition: stratnum.h:31
void InitFileAccess(void)
Definition: fd.c:764