PostgreSQL Source Code git master
Loading...
Searching...
No Matches
postinit.c File Reference
#include "postgres.h"
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include "access/genam.h"
#include "access/heapam.h"
#include "access/htup_details.h"
#include "access/session.h"
#include "access/tableam.h"
#include "access/xact.h"
#include "access/xlog.h"
#include "access/xloginsert.h"
#include "catalog/namespace.h"
#include "catalog/pg_authid.h"
#include "catalog/pg_collation.h"
#include "catalog/pg_database.h"
#include "catalog/pg_db_role_setting.h"
#include "catalog/pg_tablespace.h"
#include "libpq/auth.h"
#include "libpq/libpq-be.h"
#include "mb/pg_wchar.h"
#include "miscadmin.h"
#include "pgstat.h"
#include "port/pg_bitutils.h"
#include "postmaster/autovacuum.h"
#include "postmaster/postmaster.h"
#include "replication/slot.h"
#include "replication/slotsync.h"
#include "replication/walsender.h"
#include "storage/aio_subsys.h"
#include "storage/bufmgr.h"
#include "storage/fd.h"
#include "storage/ipc.h"
#include "storage/lmgr.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "storage/procnumber.h"
#include "storage/procsignal.h"
#include "storage/sinvaladt.h"
#include "storage/smgr.h"
#include "storage/sync.h"
#include "tcop/backend_startup.h"
#include "tcop/tcopprot.h"
#include "utils/acl.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/guc_hooks.h"
#include "utils/injection_point.h"
#include "utils/memutils.h"
#include "utils/pg_locale.h"
#include "utils/portal.h"
#include "utils/ps_status.h"
#include "utils/snapmgr.h"
#include "utils/syscache.h"
#include "utils/timeout.h"
Include dependency graph for postinit.c:

Go to the source code of this file.

Data Structures

struct  ConnectionWarning
 

Typedefs

typedef struct ConnectionWarning ConnectionWarning
 

Functions

static HeapTuple GetDatabaseTuple (const char *dbname)
 
static HeapTuple GetDatabaseTupleByOid (Oid dboid)
 
static void PerformAuthentication (Port *port)
 
static void CheckMyDatabase (const char *name, bool am_superuser, bool override_allow_connections)
 
static void ShutdownPostgres (int code, Datum arg)
 
static void StatementTimeoutHandler (void)
 
static void LockTimeoutHandler (void)
 
static void IdleInTransactionSessionTimeoutHandler (void)
 
static void TransactionTimeoutHandler (void)
 
static void IdleSessionTimeoutHandler (void)
 
static void IdleStatsUpdateTimeoutHandler (void)
 
static void ClientCheckTimeoutHandler (void)
 
static bool ThereIsAtLeastOneRole (void)
 
static void process_startup_options (Port *port, bool am_superuser)
 
static void process_settings (Oid databaseid, Oid roleid)
 
static void EmitConnectionWarnings (void)
 
void pg_split_opts (char **argv, int *argcp, const char *optstr)
 
void InitializeMaxBackends (void)
 
void InitializeFastPathLocks (void)
 
void BaseInit (void)
 
void InitPostgres (const char *in_dbname, Oid dboid, const char *username, Oid useroid, uint32 flags, char *out_dbname)
 
void StoreConnectionWarning (char *msg, char *detail, ConnectionWarningFilter filter)
 

Variables

static bool ConnectionWarningsEmitted
 
static ListConnectionWarnings
 

Typedef Documentation

◆ ConnectionWarning

Function Documentation

◆ BaseInit()

void BaseInit ( void  )

Definition at line 622 of file postinit.c.

623{
624 Assert(MyProc != NULL);
625
626 /*
627 * Initialize our input/output/debugging file descriptors.
628 */
630
631 /*
632 * Initialize file access. Done early so other subsystems can access
633 * files.
634 */
636
637 /*
638 * Initialize statistics reporting. This needs to happen early to ensure
639 * that pgstat's shutdown callback runs after the shutdown callbacks of
640 * all subsystems that can produce stats (like e.g. transaction commits
641 * can).
642 */
644
645 /*
646 * Initialize AIO before infrastructure that might need to actually
647 * execute AIO.
648 */
650
651 /* Do local initialization of storage and buffer managers */
652 InitSync();
653 smgrinit();
655
656 /*
657 * Initialize temporary file access after pgstat, so that the temporary
658 * file shutdown hook can report temporary file statistics.
659 */
661
662 /*
663 * Initialize local buffers for WAL record construction, in case we ever
664 * try to insert XLOG.
665 */
667
668 /* Initialize lock manager's local structs */
670
671 /*
672 * Initialize replication slots after pgstat. The exit hook might need to
673 * drop ephemeral slots, which in turn triggers stats reporting.
674 */
676}
void pgaio_init_backend(void)
Definition aio_init.c:238
void InitBufferManagerAccess(void)
Definition bufmgr.c:4225
#define Assert(condition)
Definition c.h:943
void DebugFileOpen(void)
Definition elog.c:2307
void InitFileAccess(void)
Definition fd.c:904
void InitTemporaryFileAccess(void)
Definition fd.c:934
void InitLockManagerAccess(void)
Definition lock.c:502
void pgstat_initialize(void)
Definition pgstat.c:669
static int fb(int x)
void ReplicationSlotInitialize(void)
Definition slot.c:240
void smgrinit(void)
Definition smgr.c:188
PGPROC * MyProc
Definition proc.c:71
void InitSync(void)
Definition sync.c:125
void InitXLogInsert(void)

References Assert, DebugFileOpen(), fb(), InitBufferManagerAccess(), InitFileAccess(), InitLockManagerAccess(), InitSync(), InitTemporaryFileAccess(), InitXLogInsert(), MyProc, pgaio_init_backend(), pgstat_initialize(), ReplicationSlotInitialize(), and smgrinit().

Referenced by AutoVacLauncherMain(), AutoVacWorkerMain(), AuxiliaryProcessMainCommon(), BackgroundWorkerMain(), BootstrapModeMain(), PostgresMain(), and ReplSlotSyncWorkerMain().

◆ CheckMyDatabase()

static void CheckMyDatabase ( const char name,
bool  am_superuser,
bool  override_allow_connections 
)
static

Definition at line 338 of file postinit.c.

339{
342 Datum datum;
343 bool isnull;
344 char *collate;
345 char *ctype;
346
347 /* Fetch our pg_database row normally, via syscache */
349 if (!HeapTupleIsValid(tup))
350 elog(ERROR, "cache lookup failed for database %u", MyDatabaseId);
352
353 /* This recheck is strictly paranoia */
354 if (strcmp(name, NameStr(dbform->datname)) != 0)
357 errmsg("database \"%s\" has disappeared from pg_database",
358 name),
359 errdetail("Database OID %u now seems to belong to \"%s\".",
360 MyDatabaseId, NameStr(dbform->datname))));
361
362 /*
363 * Check permissions to connect to the database.
364 *
365 * These checks are not enforced when in standalone mode, so that there is
366 * a way to recover from disabling all access to all databases, for
367 * example "UPDATE pg_database SET datallowconn = false;".
368 */
370 {
371 /*
372 * Check that the database is currently allowing connections.
373 * (Background processes can override this test and the next one by
374 * setting override_allow_connections.)
375 */
376 if (!dbform->datallowconn && !override_allow_connections)
379 errmsg("database \"%s\" is not currently accepting connections",
380 name)));
381
382 /*
383 * Check privilege to connect to the database. (The am_superuser test
384 * is redundant, but since we have the flag, might as well check it
385 * and save a few cycles.)
386 */
392 errmsg("permission denied for database \"%s\"", name),
393 errdetail("User does not have CONNECT privilege.")));
394
395 /*
396 * Check connection limit for this database. We enforce the limit
397 * only for regular backends, since other process types have their own
398 * PGPROC pools.
399 *
400 * There is a race condition here --- we create our PGPROC before
401 * checking for other PGPROCs. If two backends did this at about the
402 * same time, they might both think they were over the limit, while
403 * ideally one should succeed and one fail. Getting that to work
404 * exactly seems more trouble than it is worth, however; instead we
405 * just document that the connection limit is approximate.
406 */
407 if (dbform->datconnlimit >= 0 &&
409 !am_superuser &&
410 CountDBConnections(MyDatabaseId) > dbform->datconnlimit)
413 errmsg("too many connections for database \"%s\"",
414 name)));
415 }
416
417 /*
418 * OK, we're golden. Next to-do item is to save the encoding info out of
419 * the pg_database tuple.
420 */
421 SetDatabaseEncoding(dbform->encoding);
422 /* Record it as a GUC internal option, too */
423 SetConfigOption("server_encoding", GetDatabaseEncodingName(),
425 /* If we have no other source of client_encoding, use server encoding */
426 SetConfigOption("client_encoding", GetDatabaseEncodingName(),
428
429 /* assign locale variables */
431 collate = TextDatumGetCString(datum);
433 ctype = TextDatumGetCString(datum);
434
435 /*
436 * Historically, we set LC_COLLATE from datcollate, as well. That's no
437 * longer necessary because all collation behavior is handled through
438 * pg_locale_t.
439 */
440
441 if (pg_perm_setlocale(LC_CTYPE, ctype) == NULL)
443 (errmsg("database locale is incompatible with operating system"),
444 errdetail("The database was initialized with LC_CTYPE \"%s\", "
445 " which is not recognized by setlocale().", ctype),
446 errhint("Recreate the database with another locale or install the missing locale.")));
447
449
450 /*
451 * Check collation version. See similar code in
452 * pg_newlocale_from_collation(). Note that here we warn instead of error
453 * in any case, so that we don't prevent connecting.
454 */
456 &isnull);
457 if (!isnull)
458 {
459 char *actual_versionstr;
460 char *collversionstr;
461 char *locale;
462
464
465 if (dbform->datlocprovider == COLLPROVIDER_LIBC)
466 locale = collate;
467 else
468 {
470 locale = TextDatumGetCString(datum);
471 }
472
473 actual_versionstr = get_collation_actual_version(dbform->datlocprovider, locale);
475 /* should not happen */
477 "database \"%s\" has no actual collation version, but a version was recorded",
478 name);
481 (errmsg("database \"%s\" has a collation version mismatch",
482 name),
483 errdetail("The database was created using collation version %s, "
484 "but the operating system provides version %s.",
486 errhint("Rebuild all objects in this database that use the default collation and run "
487 "ALTER DATABASE %s REFRESH COLLATION VERSION, "
488 "or build PostgreSQL with the right library version.",
490 }
491
493}
@ ACLCHECK_OK
Definition acl.h:184
AclResult object_aclcheck(Oid classid, Oid objectid, Oid roleid, AclMode mode)
Definition aclchk.c:3880
#define TextDatumGetCString(d)
Definition builtins.h:99
#define NameStr(name)
Definition c.h:835
int errcode(int sqlerrcode)
Definition elog.c:875
int errhint(const char *fmt,...) pg_attribute_printf(1
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define FATAL
Definition elog.h:42
#define WARNING
Definition elog.h:37
#define ERROR
Definition elog.h:40
#define elog(elevel,...)
Definition elog.h:228
#define ereport(elevel,...)
Definition elog.h:152
bool IsUnderPostmaster
Definition globals.c:122
Oid MyDatabaseId
Definition globals.c:96
void SetConfigOption(const char *name, const char *value, GucContext context, GucSource source)
Definition guc.c:4234
@ PGC_S_DYNAMIC_DEFAULT
Definition guc.h:114
@ PGC_INTERNAL
Definition guc.h:73
@ PGC_BACKEND
Definition guc.h:77
#define HeapTupleIsValid(tuple)
Definition htup.h:78
static void * GETSTRUCT(const HeapTupleData *tuple)
const char * GetDatabaseEncodingName(void)
Definition mbutils.c:1395
void SetDatabaseEncoding(int encoding)
Definition mbutils.c:1290
#define AmRegularBackendProcess()
Definition miscadmin.h:387
Oid GetUserId(void)
Definition miscinit.c:470
static char * errmsg
#define ACL_CONNECT
Definition parsenodes.h:87
END_CATALOG_STRUCT typedef FormData_pg_database * Form_pg_database
char * get_collation_actual_version(char collprovider, const char *collcollate)
Definition pg_locale.c:1253
char * pg_perm_setlocale(int category, const char *locale)
Definition pg_locale.c:172
void init_database_collation(void)
Definition pg_locale.c:1131
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
uint64_t Datum
Definition postgres.h:70
int CountDBConnections(Oid databaseid)
Definition procarray.c:3658
const char * quote_identifier(const char *ident)
void ReleaseSysCache(HeapTuple tuple)
Definition syscache.c:265
Datum SysCacheGetAttrNotNull(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber)
Definition syscache.c:626
HeapTuple SearchSysCache1(SysCacheIdentifier cacheId, Datum key1)
Definition syscache.c:221
Datum SysCacheGetAttr(SysCacheIdentifier cacheId, HeapTuple tup, AttrNumber attributeNumber, bool *isNull)
Definition syscache.c:596
const char * name

References ACL_CONNECT, ACLCHECK_OK, AmRegularBackendProcess, CountDBConnections(), elog, ereport, errcode(), errdetail(), errhint(), errmsg, ERROR, FATAL, fb(), Form_pg_database, get_collation_actual_version(), GetDatabaseEncodingName(), GETSTRUCT(), GetUserId(), HeapTupleIsValid, init_database_collation(), IsUnderPostmaster, MyDatabaseId, name, NameStr, object_aclcheck(), ObjectIdGetDatum(), pg_perm_setlocale(), PGC_BACKEND, PGC_INTERNAL, PGC_S_DYNAMIC_DEFAULT, quote_identifier(), ReleaseSysCache(), SearchSysCache1(), SetConfigOption(), SetDatabaseEncoding(), SysCacheGetAttr(), SysCacheGetAttrNotNull(), TextDatumGetCString, and WARNING.

Referenced by InitPostgres().

◆ ClientCheckTimeoutHandler()

static void ClientCheckTimeoutHandler ( void  )
static

Definition at line 1478 of file postinit.c.

1479{
1481 InterruptPending = true;
1483}
volatile sig_atomic_t InterruptPending
Definition globals.c:32
struct Latch * MyLatch
Definition globals.c:65
volatile sig_atomic_t CheckClientConnectionPending
Definition globals.c:35
void SetLatch(Latch *latch)
Definition latch.c:290

References CheckClientConnectionPending, InterruptPending, MyLatch, and SetLatch().

Referenced by InitPostgres().

◆ EmitConnectionWarnings()

static void EmitConnectionWarnings ( void  )
static

Definition at line 1546 of file postinit.c.

1547{
1549 elog(ERROR, "EmitConnectionWarnings() called more than once");
1550 else
1552
1554 {
1555 if (warning->filter == NULL || warning->filter())
1557 (errmsg("%s", warning->message),
1558 errdetail("%s", warning->detail)));
1559
1560 pfree(warning->message);
1561 pfree(warning->detail);
1562 pfree(warning);
1563 }
1564
1567}
void list_free(List *list)
Definition list.c:1546
void pfree(void *pointer)
Definition mcxt.c:1619
#define NIL
Definition pg_list.h:68
#define foreach_ptr(type, var, lst)
Definition pg_list.h:501
static List * ConnectionWarnings
Definition postinit.c:85
static bool ConnectionWarningsEmitted
Definition postinit.c:75
static void static void static void warning(const char *const string,...) pg_attribute_printf(1
Definition zic.c:533

References ConnectionWarnings, ConnectionWarningsEmitted, elog, ereport, errdetail(), errmsg, ERROR, fb(), foreach_ptr, list_free(), NIL, pfree(), WARNING, and warning().

Referenced by InitPostgres().

◆ GetDatabaseTuple()

static HeapTuple GetDatabaseTuple ( const char dbname)
static

Definition at line 120 of file postinit.c.

121{
122 HeapTuple tuple;
123 Relation relation;
124 SysScanDesc scan;
125 ScanKeyData key[1];
126
127 /*
128 * form a scan key
129 */
130 ScanKeyInit(&key[0],
134
135 /*
136 * Open pg_database and fetch a tuple. Force heap scan if we haven't yet
137 * built the critical shared relcache entries (i.e., we're starting up
138 * without a shared relcache cache file).
139 */
143 NULL,
144 1, key);
145
146 tuple = systable_getnext(scan);
147
148 /* Must copy tuple before releasing buffer */
149 if (HeapTupleIsValid(tuple))
150 tuple = heap_copytuple(tuple);
151
152 /* all done */
153 systable_endscan(scan);
154 table_close(relation, AccessShareLock);
155
156 return tuple;
157}
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:604
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:515
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:388
HeapTuple heap_copytuple(HeapTuple tuple)
Definition heaptuple.c:686
#define AccessShareLock
Definition lockdefs.h:36
static Datum CStringGetDatum(const char *X)
Definition postgres.h:383
bool criticalSharedRelcachesBuilt
Definition relcache.c:150
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition scankey.c:76
#define BTEqualStrategyNumber
Definition stratnum.h:31
char * dbname
Definition streamutil.c:49
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40

References AccessShareLock, BTEqualStrategyNumber, criticalSharedRelcachesBuilt, CStringGetDatum(), dbname, fb(), heap_copytuple(), HeapTupleIsValid, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by InitPostgres().

◆ GetDatabaseTupleByOid()

static HeapTuple GetDatabaseTupleByOid ( Oid  dboid)
static

Definition at line 163 of file postinit.c.

164{
165 HeapTuple tuple;
166 Relation relation;
167 SysScanDesc scan;
168 ScanKeyData key[1];
169
170 /*
171 * form a scan key
172 */
173 ScanKeyInit(&key[0],
176 ObjectIdGetDatum(dboid));
177
178 /*
179 * Open pg_database and fetch a tuple. Force heap scan if we haven't yet
180 * built the critical shared relcache entries (i.e., we're starting up
181 * without a shared relcache cache file).
182 */
184 scan = systable_beginscan(relation, DatabaseOidIndexId,
186 NULL,
187 1, key);
188
189 tuple = systable_getnext(scan);
190
191 /* Must copy tuple before releasing buffer */
192 if (HeapTupleIsValid(tuple))
193 tuple = heap_copytuple(tuple);
194
195 /* all done */
196 systable_endscan(scan);
197 table_close(relation, AccessShareLock);
198
199 return tuple;
200}

References AccessShareLock, BTEqualStrategyNumber, criticalSharedRelcachesBuilt, fb(), heap_copytuple(), HeapTupleIsValid, ObjectIdGetDatum(), ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by InitPostgres().

◆ IdleInTransactionSessionTimeoutHandler()

static void IdleInTransactionSessionTimeoutHandler ( void  )
static

Definition at line 1454 of file postinit.c.

1455{
1457 InterruptPending = true;
1459}
volatile sig_atomic_t IdleInTransactionSessionTimeoutPending
Definition globals.c:37

References IdleInTransactionSessionTimeoutPending, InterruptPending, MyLatch, and SetLatch().

Referenced by InitPostgres().

◆ IdleSessionTimeoutHandler()

static void IdleSessionTimeoutHandler ( void  )
static

Definition at line 1462 of file postinit.c.

1463{
1465 InterruptPending = true;
1467}
volatile sig_atomic_t IdleSessionTimeoutPending
Definition globals.c:39

References IdleSessionTimeoutPending, InterruptPending, MyLatch, and SetLatch().

Referenced by InitPostgres().

◆ IdleStatsUpdateTimeoutHandler()

static void IdleStatsUpdateTimeoutHandler ( void  )
static

Definition at line 1470 of file postinit.c.

1471{
1473 InterruptPending = true;
1475}
volatile sig_atomic_t IdleStatsUpdateTimeoutPending
Definition globals.c:42

References IdleStatsUpdateTimeoutPending, InterruptPending, MyLatch, and SetLatch().

Referenced by InitPostgres().

◆ InitializeFastPathLocks()

void InitializeFastPathLocks ( void  )

Definition at line 590 of file postinit.c.

591{
592 /* Should be initialized only once. */
594
595 /*
596 * Based on the max_locks_per_transaction GUC, as that's a good indicator
597 * of the expected number of locks, figure out the value for
598 * FastPathLockGroupsPerBackend. This must be a power-of-two. We cap the
599 * value at FP_LOCK_GROUPS_PER_BACKEND_MAX and insist the value is at
600 * least 1.
601 *
602 * The default max_locks_per_transaction = 128 means 8 groups by default.
603 */
607
608 /* Validate we did get a power-of-two */
611}
#define Min(x, y)
Definition c.h:1091
#define Max(x, y)
Definition c.h:1085
int max_locks_per_xact
Definition lock.c:56
int FastPathLockGroupsPerBackend
Definition lock.c:205
static uint32 pg_nextpower2_32(uint32 num)
#define FP_LOCK_GROUPS_PER_BACKEND_MAX
Definition proc.h:95
#define FP_LOCK_SLOTS_PER_GROUP
Definition proc.h:96

References Assert, FastPathLockGroupsPerBackend, FP_LOCK_GROUPS_PER_BACKEND_MAX, FP_LOCK_SLOTS_PER_GROUP, Max, max_locks_per_xact, Min, and pg_nextpower2_32().

Referenced by BootstrapModeMain(), PostgresSingleUserMain(), and PostmasterMain().

◆ InitializeMaxBackends()

void InitializeMaxBackends ( void  )

Definition at line 565 of file postinit.c.

566{
567 Assert(MaxBackends == 0);
568
569 /* Note that this does not include "auxiliary" processes */
572
576 errmsg("too many server processes configured"),
577 errdetail("\"max_connections\" (%d) plus \"autovacuum_worker_slots\" (%d) plus \"max_worker_processes\" (%d) plus \"max_wal_senders\" (%d) must be less than %d.",
581}
int autovacuum_worker_slots
Definition autovacuum.c:124
int MaxConnections
Definition globals.c:145
int MaxBackends
Definition globals.c:149
int max_worker_processes
Definition globals.c:146
#define NUM_SPECIAL_WORKER_PROCS
Definition proc.h:514
#define MAX_BACKENDS
Definition procnumber.h:39
int max_wal_senders
Definition walsender.c:141

References Assert, autovacuum_worker_slots, ereport, errcode(), errdetail(), errmsg, ERROR, fb(), MAX_BACKENDS, max_wal_senders, max_worker_processes, MaxBackends, MaxConnections, and NUM_SPECIAL_WORKER_PROCS.

Referenced by BootstrapModeMain(), PostgresSingleUserMain(), and PostmasterMain().

◆ InitPostgres()

void InitPostgres ( const char in_dbname,
Oid  dboid,
const char username,
Oid  useroid,
uint32  flags,
char out_dbname 
)

Definition at line 722 of file postinit.c.

726{
728 bool am_superuser;
729 char *fullpath;
730 char dbname[NAMEDATALEN];
731 int nfree = 0;
732
733 elog(DEBUG3, "InitPostgres");
734
735 /*
736 * Add my PGPROC struct to the ProcArray.
737 *
738 * Once I have done this, I am visible to other backends!
739 */
741
742 /* Initialize status reporting */
744
745 /*
746 * And initialize an entry in the PgBackendStatus array. That way, if
747 * LWLocks or third-party authentication should happen to hang, it is
748 * possible to retrieve some information about what is going on.
749 */
750 if (!bootstrap)
751 {
753 INJECTION_POINT("init-pre-auth", NULL);
754 }
755
756 /*
757 * Initialize my entry in the shared-invalidation manager's array of
758 * per-backend data.
759 */
761
762 /*
763 * Prevent consuming interrupts between setting ProcSignalInit and setting
764 * the initial local data checksum value. If a barrier is emitted, and
765 * absorbed, before local cached state is initialized the state transition
766 * can be invalid.
767 */
769
771
772 /*
773 * Initialize a local cache of the data_checksum_version, to be updated by
774 * the procsignal-based barriers.
775 *
776 * This intentionally happens after initializing the procsignal, otherwise
777 * we might miss a state change. This means we can get a barrier for the
778 * state we've just initialized.
779 *
780 * The postmaster (which is what gets forked into the new child process)
781 * does not handle barriers, therefore it may not have the current value
782 * of LocalDataChecksumState value (it'll have the value read from the
783 * control file, which may be arbitrarily old).
784 *
785 * NB: Even if the postmaster handled barriers, the value might still be
786 * stale, as it might have changed after this process forked.
787 */
789
791
792 /*
793 * Also set up timeout handlers needed for backend operation. We need
794 * these in every case except bootstrap.
795 */
796 if (!bootstrap)
797 {
808 }
809
810 /*
811 * If this is either a bootstrap process or a standalone backend, start up
812 * the XLOG machinery, and register to have it closed down at exit. In
813 * other cases, the startup process is responsible for starting up the
814 * XLOG machinery, and the checkpointer for closing it down.
815 */
817 {
818 /*
819 * We don't yet have an aux-process resource owner, but StartupXLOG
820 * and ShutdownXLOG will need one. Hence, create said resource owner
821 * (and register a callback to clean it up after ShutdownXLOG runs).
822 */
824
825 StartupXLOG();
826 /* Release (and warn about) any buffer pins leaked in StartupXLOG */
828 /* Reset CurrentResourceOwner to nothing for the moment */
830
831 /*
832 * Use before_shmem_exit() so that ShutdownXLOG() can rely on DSM
833 * segments etc to work (which in turn is required for pgstats).
834 */
837 }
838
839 /*
840 * Initialize the process-local logical info WAL logging state.
841 *
842 * This must be called after ProcSignalInit() so that the process can
843 * participate in procsignal-based barriers that update this state.
844 * Furthermore, in !IsUnderPostmaster cases, this must occur after
845 * StartupXLOG() where the shared state is first established.
846 */
848
849 /*
850 * Initialize the relation cache and the system catalog caches. Note that
851 * no catalog access happens here; we only set up the hashtable structure.
852 * We must do this before starting a transaction because transaction abort
853 * would try to touch these hashtables.
854 */
858
859 /* Initialize portal manager */
861
862 /*
863 * Load relcache entries for the shared system catalogs. This must create
864 * at least entries for pg_database and catalogs used for authentication.
865 */
867
868 /*
869 * Set up process-exit callback to do pre-shutdown cleanup. This is one
870 * of the first before_shmem_exit callbacks we register; thus, this will
871 * be one of the last things we do before low-level modules like the
872 * buffer manager begin to close down. We need to have this in place
873 * before we begin our first transaction --- if we fail during the
874 * initialization transaction, as is entirely possible, we need the
875 * AbortTransaction call to clean up.
876 */
878
879 /* The autovacuum launcher is done here */
881 {
882 /* fill in the remainder of this entry in the PgBackendStatus array */
884
885 return;
886 }
887
888 /*
889 * Start a new transaction here before first access to db.
890 */
891 if (!bootstrap)
892 {
893 /* statement_timestamp must be set for timeouts to work correctly */
896
897 /*
898 * transaction_isolation will have been set to the default by the
899 * above. If the default is "serializable", and we are in hot
900 * standby, we will fail if we don't change it to something lower.
901 * Fortunately, "read committed" is plenty good enough.
902 */
904 }
905
906 /*
907 * Perform client authentication if necessary, then figure out our
908 * postgres user ID, and see if we are a superuser.
909 *
910 * In standalone mode, autovacuum worker processes and slot sync worker
911 * process, we use a fixed ID, otherwise we figure it out from the
912 * authenticated user name.
913 */
915 {
917 am_superuser = true;
918 }
919 else if (!IsUnderPostmaster)
920 {
922 am_superuser = true;
926 errmsg("no roles are defined in this database system"),
927 errhint("You should immediately run CREATE USER \"%s\" SUPERUSER;.",
928 username != NULL ? username : "postgres")));
929 }
931 {
932 if (username == NULL && !OidIsValid(useroid))
933 {
935 am_superuser = true;
936 }
937 else
938 {
940 (flags & INIT_PG_OVERRIDE_ROLE_LOGIN) != 0);
942 }
943 }
944 else
945 {
946 /* normal multiuser case */
950 /* ensure that auth_method is actually valid, aka authn_id is not NULL */
955 }
956
957 /* Report any SSL/GSS details for the session. */
958 if (MyProcPort != NULL)
959 {
961
963 }
964
965 /*
966 * Binary upgrades only allowed super-user connections
967 */
969 {
972 errmsg("must be superuser to connect in binary upgrade mode")));
973 }
974
975 /*
976 * The last few regular connection slots are reserved for superusers and
977 * roles with privileges of pg_use_reserved_connections. We do not apply
978 * these limits to background processes, since they all have their own
979 * pools of PGPROC slots.
980 *
981 * Note: At this point, the new backend has already claimed a proc struct,
982 * so we must check whether the number of free slots is strictly less than
983 * the reserved connection limits.
984 */
988 {
992 errmsg("remaining connection slots are reserved for roles with the %s attribute",
993 "SUPERUSER")));
994
998 errmsg("remaining connection slots are reserved for roles with privileges of the \"%s\" role",
999 "pg_use_reserved_connections")));
1000 }
1001
1002 /* Check replication permissions needed for walsender processes. */
1003 if (am_walsender)
1004 {
1005 Assert(!bootstrap);
1006
1008 ereport(FATAL,
1010 errmsg("permission denied to start WAL sender"),
1011 errdetail("Only roles with the %s attribute may start a WAL sender process.",
1012 "REPLICATION")));
1013 }
1014
1015 /*
1016 * If this is a plain walsender only supporting physical replication, we
1017 * don't want to connect to any particular database. Just finish the
1018 * backend startup by processing any options from the startup packet, and
1019 * we're done.
1020 */
1022 {
1023 /* process any options passed in the startup packet */
1024 if (MyProcPort != NULL)
1026
1027 /* Apply PostAuthDelay as soon as we've read all options */
1028 if (PostAuthDelay > 0)
1029 pg_usleep(PostAuthDelay * 1000000L);
1030
1031 /* initialize client encoding */
1033
1034 /* fill in the remainder of this entry in the PgBackendStatus array */
1036
1037 /* close the transaction we started above */
1039
1040 /* send any WARNINGs we've accumulated during initialization */
1042
1043 return;
1044 }
1045
1046 /*
1047 * Set up the global variables holding database id and default tablespace.
1048 * But note we won't actually try to touch the database just yet.
1049 *
1050 * We take a shortcut in the bootstrap case, otherwise we have to look up
1051 * the db's entry in pg_database.
1052 */
1053 if (bootstrap)
1054 {
1055 dboid = Template1DbOid;
1057 }
1058 else if (in_dbname != NULL)
1059 {
1060 HeapTuple tuple;
1062
1063 tuple = GetDatabaseTuple(in_dbname);
1064 if (!HeapTupleIsValid(tuple))
1065 ereport(FATAL,
1067 errmsg("database \"%s\" does not exist", in_dbname)));
1069 dboid = dbform->oid;
1070 }
1071 else if (!OidIsValid(dboid))
1072 {
1073 /*
1074 * If this is a background worker not bound to any particular
1075 * database, we're done now. Everything that follows only makes sense
1076 * if we are bound to a specific database. We do need to close the
1077 * transaction we started before returning.
1078 */
1079 if (!bootstrap)
1080 {
1083 }
1084 return;
1085 }
1086
1087 /*
1088 * Now, take a writer's lock on the database we are trying to connect to.
1089 * If there is a concurrently running DROP DATABASE on that database, this
1090 * will block us until it finishes (and has committed its update of
1091 * pg_database).
1092 *
1093 * Note that the lock is not held long, only until the end of this startup
1094 * transaction. This is OK since we will advertise our use of the
1095 * database in the ProcArray before dropping the lock (in fact, that's the
1096 * next thing to do). Anyone trying a DROP DATABASE after this point will
1097 * see us in the array once they have the lock. Ordering is important for
1098 * this because we don't want to advertise ourselves as being in this
1099 * database until we have the lock; otherwise we create what amounts to a
1100 * deadlock with CountOtherDBBackends().
1101 *
1102 * Note: use of RowExclusiveLock here is reasonable because we envision
1103 * our session as being a concurrent writer of the database. If we had a
1104 * way of declaring a session as being guaranteed-read-only, we could use
1105 * AccessShareLock for such sessions and thereby not conflict against
1106 * CREATE DATABASE.
1107 */
1108 if (!bootstrap)
1110
1111 /*
1112 * Recheck pg_database to make sure the target database hasn't gone away.
1113 * If there was a concurrent DROP DATABASE, this ensures we will die
1114 * cleanly without creating a mess.
1115 */
1116 if (!bootstrap)
1117 {
1118 HeapTuple tuple;
1120
1121 tuple = GetDatabaseTupleByOid(dboid);
1122 if (HeapTupleIsValid(tuple))
1124
1125 if (!HeapTupleIsValid(tuple) ||
1126 (in_dbname && namestrcmp(&datform->datname, in_dbname)))
1127 {
1128 if (in_dbname)
1129 ereport(FATAL,
1131 errmsg("database \"%s\" does not exist", in_dbname),
1132 errdetail("It seems to have just been dropped or renamed.")));
1133 else
1134 ereport(FATAL,
1136 errmsg("database %u does not exist", dboid)));
1137 }
1138
1139 strlcpy(dbname, NameStr(datform->datname), sizeof(dbname));
1140
1142 {
1143 ereport(FATAL,
1145 errmsg("cannot connect to invalid database \"%s\"", dbname),
1146 errhint("Use DROP DATABASE to drop invalid databases."));
1147 }
1148
1149 MyDatabaseTableSpace = datform->dattablespace;
1150 MyDatabaseHasLoginEventTriggers = datform->dathasloginevt;
1151 /* pass the database name back to the caller */
1152 if (out_dbname)
1154 }
1155
1156 /*
1157 * Now that we rechecked, we are certain to be connected to a database and
1158 * thus can set MyDatabaseId.
1159 *
1160 * It is important that MyDatabaseId only be set once we are sure that the
1161 * target database can no longer be concurrently dropped or renamed. For
1162 * example, without this guarantee, pgstat_update_dbstats() could create
1163 * entries for databases that were just dropped in the pgstat shutdown
1164 * callback, which could confuse other code paths like the autovacuum
1165 * scheduler.
1166 */
1167 MyDatabaseId = dboid;
1168
1169 /*
1170 * Now we can mark our PGPROC entry with the database ID.
1171 *
1172 * We assume this is an atomic store so no lock is needed; though actually
1173 * things would work fine even if it weren't atomic. Anyone searching the
1174 * ProcArray for this database's ID should hold the database lock, so they
1175 * would not be executing concurrently with this store. A process looking
1176 * for another database's ID could in theory see a chance match if it read
1177 * a partially-updated databaseId value; but as long as all such searches
1178 * wait and retry, as in CountOtherDBBackends(), they will certainly see
1179 * the correct value on their next try.
1180 */
1182
1183 /*
1184 * We established a catalog snapshot while reading pg_authid and/or
1185 * pg_database; but until we have set up MyDatabaseId, we won't react to
1186 * incoming sinval messages for unshared catalogs, so we won't realize it
1187 * if the snapshot has been invalidated. Assume it's no good anymore.
1188 */
1190
1191 /*
1192 * Now we should be able to access the database directory safely. Verify
1193 * it's there and looks reasonable.
1194 */
1196
1197 if (!bootstrap)
1198 {
1199 if (access(fullpath, F_OK) == -1)
1200 {
1201 if (errno == ENOENT)
1202 ereport(FATAL,
1204 errmsg("database \"%s\" does not exist",
1205 dbname),
1206 errdetail("The database subdirectory \"%s\" is missing.",
1207 fullpath)));
1208 else
1209 ereport(FATAL,
1211 errmsg("could not access directory \"%s\": %m",
1212 fullpath)));
1213 }
1214
1215 ValidatePgVersion(fullpath);
1216 }
1217
1218 SetDatabasePath(fullpath);
1219 pfree(fullpath);
1220
1221 /*
1222 * It's now possible to do real access to the system catalogs.
1223 *
1224 * Load relcache entries for the system catalogs. This must create at
1225 * least the minimum set of "nailed-in" cache entries.
1226 */
1228
1229 /* set up ACL framework (so CheckMyDatabase can check permissions) */
1231
1232 /*
1233 * Re-read the pg_database row for our database, check permissions and set
1234 * up database-specific GUC settings. We can't do this until all the
1235 * database-access infrastructure is up. (Also, it wants to know if the
1236 * user is a superuser, so the above stuff has to happen first.)
1237 */
1238 if (!bootstrap)
1240 (flags & INIT_PG_OVERRIDE_ALLOW_CONNS) != 0);
1241
1242 /*
1243 * Now process any command-line switches and any additional GUC variable
1244 * settings passed in the startup packet. We couldn't do this before
1245 * because we didn't know if client is a superuser.
1246 */
1247 if (MyProcPort != NULL)
1249
1250 /* Process pg_db_role_setting options */
1252
1253 /* Apply PostAuthDelay as soon as we've read all options */
1254 if (PostAuthDelay > 0)
1255 pg_usleep(PostAuthDelay * 1000000L);
1256
1257 /*
1258 * Initialize various default states that can't be set up until we've
1259 * selected the active user and gotten the right GUC settings.
1260 */
1261
1262 /* set default namespace search path */
1264
1265 /* initialize client encoding */
1267
1268 /* Initialize this backend's session state. */
1270
1271 /*
1272 * If this is an interactive session, load any libraries that should be
1273 * preloaded at backend start. Since those are determined by GUCs, this
1274 * can't happen until GUC settings are complete, but we want it to happen
1275 * during the initial transaction in case anything that requires database
1276 * access needs to be done.
1277 */
1278 if ((flags & INIT_PG_LOAD_SESSION_LIBS) != 0)
1280
1281 /* fill in the remainder of this entry in the PgBackendStatus array */
1282 if (!bootstrap)
1284
1285 /* close the transaction we started above */
1286 if (!bootstrap)
1288
1289 /* send any WARNINGs we've accumulated during initialization */
1291}
void initialize_acl(void)
Definition acl.c:5069
bool has_privs_of_role(Oid member, Oid role)
Definition acl.c:5314
void pgstat_bestart_security(void)
void pgstat_bestart_initial(void)
void pgstat_beinit(void)
void pgstat_bestart_final(void)
#define OidIsValid(objectId)
Definition c.h:858
bool database_is_invalid_form(Form_pg_database datform)
int errcode_for_file_access(void)
Definition elog.c:898
#define DEBUG3
Definition elog.h:29
bool MyDatabaseHasLoginEventTriggers
Definition globals.c:100
int MyCancelKeyLength
Definition globals.c:55
bool IsBinaryUpgrade
Definition globals.c:123
Oid MyDatabaseTableSpace
Definition globals.c:98
uint8 MyCancelKey[MAX_CANCEL_KEY_LENGTH]
Definition globals.c:54
struct Port * MyProcPort
Definition globals.c:53
const char * hba_authname(UserAuth auth_method)
Definition hba.c:2948
static char * username
Definition initdb.c:153
#define INJECTION_POINT(name, arg)
void before_shmem_exit(pg_on_exit_callback function, Datum arg)
Definition ipc.c:344
void LockSharedObject(Oid classid, Oid objid, uint16 objsubid, LOCKMODE lockmode)
Definition lmgr.c:1088
#define RowExclusiveLock
Definition lockdefs.h:38
void InitializeProcessXLogLogicalInfo(void)
Definition logicalctl.c:174
void InitializeClientEncoding(void)
Definition mbutils.c:290
#define RESUME_INTERRUPTS()
Definition miscadmin.h:138
#define IsBootstrapProcessingMode()
Definition miscadmin.h:486
#define INIT_PG_LOAD_SESSION_LIBS
Definition miscadmin.h:508
#define AmAutoVacuumWorkerProcess()
Definition miscadmin.h:389
#define AmBackgroundWorkerProcess()
Definition miscadmin.h:390
#define AmLogicalSlotSyncWorkerProcess()
Definition miscadmin.h:392
#define HOLD_INTERRUPTS()
Definition miscadmin.h:136
#define AmAutoVacuumLauncherProcess()
Definition miscadmin.h:388
#define INIT_PG_OVERRIDE_ROLE_LOGIN
Definition miscadmin.h:510
#define AmDataChecksumsWorkerProcess()
Definition miscadmin.h:401
#define INIT_PG_OVERRIDE_ALLOW_CONNS
Definition miscadmin.h:509
void InitializeSessionUserId(const char *rolename, Oid roleid, bool bypass_login_check)
Definition miscinit.c:711
void InitializeSystemUser(const char *authn_id, const char *auth_method)
Definition miscinit.c:876
void InitializeSessionUserIdStandalone(void)
Definition miscinit.c:841
void process_session_preload_libraries(void)
Definition miscinit.c:1867
Oid GetSessionUserId(void)
Definition miscinit.c:509
void SetDatabasePath(const char *path)
Definition miscinit.c:284
ClientConnectionInfo MyClientConnectionInfo
Definition miscinit.c:1020
bool has_rolreplication(Oid roleid)
Definition miscinit.c:689
void ValidatePgVersion(const char *path)
Definition miscinit.c:1720
int namestrcmp(Name name, const char *str)
Definition name.c:247
void InitializeSearchPath(void)
Definition namespace.c:4808
#define NAMEDATALEN
void pgstat_before_server_shutdown(int code, Datum arg)
Definition pgstat.c:590
void InitPlanCache(void)
Definition plancache.c:148
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition strlcpy.c:45
void EnablePortalManager(void)
Definition portalmem.c:106
int PostAuthDelay
Definition postgres.c:105
static void ShutdownPostgres(int code, Datum arg)
Definition postinit.c:1397
static void IdleInTransactionSessionTimeoutHandler(void)
Definition postinit.c:1454
static void LockTimeoutHandler(void)
Definition postinit.c:1436
static void IdleStatsUpdateTimeoutHandler(void)
Definition postinit.c:1470
static void process_settings(Oid databaseid, Oid roleid)
Definition postinit.c:1363
static void IdleSessionTimeoutHandler(void)
Definition postinit.c:1462
static void process_startup_options(Port *port, bool am_superuser)
Definition postinit.c:1298
static void StatementTimeoutHandler(void)
Definition postinit.c:1414
static void EmitConnectionWarnings(void)
Definition postinit.c:1546
static void CheckMyDatabase(const char *name, bool am_superuser, bool override_allow_connections)
Definition postinit.c:338
static bool ThereIsAtLeastOneRole(void)
Definition postinit.c:1489
static void PerformAuthentication(Port *port)
Definition postinit.c:209
static void ClientCheckTimeoutHandler(void)
Definition postinit.c:1478
static HeapTuple GetDatabaseTuple(const char *dbname)
Definition postinit.c:120
static HeapTuple GetDatabaseTupleByOid(Oid dboid)
Definition postinit.c:163
static void TransactionTimeoutHandler(void)
Definition postinit.c:1446
int ReservedConnections
Definition postmaster.c:231
int SuperuserReservedConnections
Definition postmaster.c:230
short access
void ProcSignalInit(const uint8 *cancel_key, int cancel_key_len)
Definition procsignal.c:170
void RelationCacheInitializePhase3(void)
Definition relcache.c:4113
void RelationCacheInitialize(void)
Definition relcache.c:4006
void RelationCacheInitializePhase2(void)
Definition relcache.c:4052
char * GetDatabasePath(Oid dbOid, Oid spcOid)
Definition relpath.c:110
void ReleaseAuxProcessResources(bool isCommit)
Definition resowner.c:1026
ResourceOwner CurrentResourceOwner
Definition resowner.c:173
void CreateAuxProcessResourceOwner(void)
Definition resowner.c:1006
void InitializeSession(void)
Definition session.c:54
void pg_usleep(long microsec)
Definition signal.c:53
void SharedInvalBackendInit(bool sendOnly)
Definition sinvaladt.c:274
void InvalidateCatalogSnapshot(void)
Definition snapmgr.c:455
bool HaveNFreeProcs(int n, int *nfree)
Definition proc.c:787
void CheckDeadLockAlert(void)
Definition proc.c:1948
void InitProcessPhase2(void)
Definition proc.c:583
const char * authn_id
Definition libpq-be.h:99
Oid databaseId
Definition proc.h:201
bool superuser(void)
Definition superuser.c:47
void InitCatalogCache(void)
Definition syscache.c:111
TimeoutId RegisterTimeout(TimeoutId id, timeout_handler_proc handler)
Definition timeout.c:505
@ IDLE_SESSION_TIMEOUT
Definition timeout.h:35
@ IDLE_IN_TRANSACTION_SESSION_TIMEOUT
Definition timeout.h:33
@ LOCK_TIMEOUT
Definition timeout.h:28
@ STATEMENT_TIMEOUT
Definition timeout.h:29
@ DEADLOCK_TIMEOUT
Definition timeout.h:27
@ TRANSACTION_TIMEOUT
Definition timeout.h:34
@ IDLE_STATS_UPDATE_TIMEOUT
Definition timeout.h:36
@ CLIENT_CONNECTION_CHECK_TIMEOUT
Definition timeout.h:37
bool am_walsender
Definition walsender.c:135
bool am_db_walsender
Definition walsender.c:138
void StartTransactionCommand(void)
Definition xact.c:3112
int XactIsoLevel
Definition xact.c:81
void SetCurrentStatementStartTimestamp(void)
Definition xact.c:916
void CommitTransactionCommand(void)
Definition xact.c:3210
#define XACT_READ_COMMITTED
Definition xact.h:37
void StartupXLOG(void)
Definition xlog.c:5846
void ShutdownXLOG(int code, Datum arg)
Definition xlog.c:7104
void InitLocalDataChecksumState(void)
Definition xlog.c:4961

References am_db_walsender, am_walsender, AmAutoVacuumLauncherProcess, AmAutoVacuumWorkerProcess, AmBackgroundWorkerProcess, AmDataChecksumsWorkerProcess, AmLogicalSlotSyncWorkerProcess, AmRegularBackendProcess, Assert, ClientConnectionInfo::auth_method, ClientConnectionInfo::authn_id, before_shmem_exit(), CheckDeadLockAlert(), CheckMyDatabase(), CLIENT_CONNECTION_CHECK_TIMEOUT, ClientCheckTimeoutHandler(), CommitTransactionCommand(), CreateAuxProcessResourceOwner(), CurrentResourceOwner, database_is_invalid_form(), PGPROC::databaseId, dbname, DEADLOCK_TIMEOUT, DEBUG3, elog, EmitConnectionWarnings(), EnablePortalManager(), ereport, errcode(), errcode_for_file_access(), errdetail(), errhint(), errmsg, FATAL, fb(), Form_pg_database, GetDatabasePath(), GetDatabaseTuple(), GetDatabaseTupleByOid(), GetSessionUserId(), GETSTRUCT(), GetUserId(), has_privs_of_role(), has_rolreplication(), HaveNFreeProcs(), hba_authname(), HeapTupleIsValid, HOLD_INTERRUPTS, IDLE_IN_TRANSACTION_SESSION_TIMEOUT, IDLE_SESSION_TIMEOUT, IDLE_STATS_UPDATE_TIMEOUT, IdleInTransactionSessionTimeoutHandler(), IdleSessionTimeoutHandler(), IdleStatsUpdateTimeoutHandler(), INIT_PG_LOAD_SESSION_LIBS, INIT_PG_OVERRIDE_ALLOW_CONNS, INIT_PG_OVERRIDE_ROLE_LOGIN, InitCatalogCache(), initialize_acl(), InitializeClientEncoding(), InitializeProcessXLogLogicalInfo(), InitializeSearchPath(), InitializeSession(), InitializeSessionUserId(), InitializeSessionUserIdStandalone(), InitializeSystemUser(), InitLocalDataChecksumState(), InitPlanCache(), InitProcessPhase2(), INJECTION_POINT, InvalidateCatalogSnapshot(), IsBinaryUpgrade, IsBootstrapProcessingMode, IsUnderPostmaster, LOCK_TIMEOUT, LockSharedObject(), LockTimeoutHandler(), MyCancelKey, MyCancelKeyLength, MyClientConnectionInfo, MyDatabaseHasLoginEventTriggers, MyDatabaseId, MyDatabaseTableSpace, MyProc, MyProcPort, NAMEDATALEN, NameStr, namestrcmp(), OidIsValid, PerformAuthentication(), pfree(), pg_usleep(), pgstat_before_server_shutdown(), pgstat_beinit(), pgstat_bestart_final(), pgstat_bestart_initial(), pgstat_bestart_security(), PostAuthDelay, process_session_preload_libraries(), process_settings(), process_startup_options(), ProcSignalInit(), RegisterTimeout(), RelationCacheInitialize(), RelationCacheInitializePhase2(), RelationCacheInitializePhase3(), ReleaseAuxProcessResources(), ReservedConnections, RESUME_INTERRUPTS, RowExclusiveLock, SetCurrentStatementStartTimestamp(), SetDatabasePath(), SharedInvalBackendInit(), ShutdownPostgres(), ShutdownXLOG(), StartTransactionCommand(), StartupXLOG(), STATEMENT_TIMEOUT, StatementTimeoutHandler(), strlcpy(), superuser(), SuperuserReservedConnections, ThereIsAtLeastOneRole(), TRANSACTION_TIMEOUT, TransactionTimeoutHandler(), username, ValidatePgVersion(), WARNING, XACT_READ_COMMITTED, and XactIsoLevel.

Referenced by AutoVacLauncherMain(), AutoVacWorkerMain(), BackgroundWorkerInitializeConnection(), BackgroundWorkerInitializeConnectionByOid(), BootstrapModeMain(), PostgresMain(), and ReplSlotSyncWorkerMain().

◆ LockTimeoutHandler()

static void LockTimeoutHandler ( void  )
static

Definition at line 1436 of file postinit.c.

1437{
1438#ifdef HAVE_SETSID
1439 /* try to signal whole process group */
1441#endif
1443}
int MyProcPid
Definition globals.c:49
#define kill(pid, sig)
Definition win32_port.h:490

References fb(), kill, and MyProcPid.

Referenced by InitPostgres().

◆ PerformAuthentication()

static void PerformAuthentication ( Port port)
static

Definition at line 209 of file postinit.c.

210{
211 /* This should be set already, but let's make sure */
212 ClientAuthInProgress = true; /* limit visibility of log messages */
213
214 /*
215 * In EXEC_BACKEND case, we didn't inherit the contents of pg_hba.conf
216 * etcetera from the postmaster, and have to load them ourselves.
217 *
218 * FIXME: [fork/exec] Ugh. Is there a way around this overhead?
219 */
220#ifdef EXEC_BACKEND
221
222 /*
223 * load_hba() and load_ident() want to work within the PostmasterContext,
224 * so create that if it doesn't exist (which it won't). We'll delete it
225 * again later, in PostgresMain.
226 */
227 if (PostmasterContext == NULL)
229 "Postmaster",
231
232 if (!load_hba())
233 {
234 /*
235 * It makes no sense to continue if we fail to load the HBA file,
236 * since there is no way to connect to the database in this case.
237 */
239 /* translator: %s is a configuration file */
240 (errmsg("could not load %s", HbaFileName)));
241 }
242
243 if (!load_ident())
244 {
245 /*
246 * It is ok to continue if we fail to load the IDENT file, although it
247 * means that you cannot log in using any of the authentication
248 * methods that need a user name mapping. load_ident() already logged
249 * the details of error to the log.
250 */
251 }
252#endif
253
254 /* Capture authentication start time for logging */
256
257 /*
258 * Set up a timeout in case a buggy or malicious client fails to respond
259 * during authentication. Since we're inside a transaction and might do
260 * database access, we have to use the statement_timeout infrastructure.
261 */
263
264 /*
265 * Now perform authentication exchange.
266 */
267 set_ps_display("authentication");
268 ClientAuthentication(port); /* might not return, if failure */
269
270 /*
271 * Done with authentication. Disable the timeout, and log if needed.
272 */
274
275 /* Capture authentication end time for logging */
277
279 {
281
283 if (am_walsender)
284 appendStringInfo(&logmsg, _("replication connection authorized: user=%s"),
285 port->user_name);
286 else
287 appendStringInfo(&logmsg, _("connection authorized: user=%s"),
288 port->user_name);
289 if (!am_walsender)
290 appendStringInfo(&logmsg, _(" database=%s"), port->database_name);
291
292 if (port->application_name != NULL)
293 appendStringInfo(&logmsg, _(" application_name=%s"),
294 port->application_name);
295
296#ifdef USE_SSL
297 if (port->ssl_in_use)
298 appendStringInfo(&logmsg, _(" SSL enabled (protocol=%s, cipher=%s, bits=%d)"),
302#endif
303#ifdef ENABLE_GSS
304 if (port->gss)
305 {
306 const char *princ = be_gssapi_get_princ(port);
307
308 if (princ)
310 _(" GSS (authenticated=%s, encrypted=%s, delegated_credentials=%s, principal=%s)"),
311 be_gssapi_get_auth(port) ? _("yes") : _("no"),
312 be_gssapi_get_enc(port) ? _("yes") : _("no"),
313 be_gssapi_get_delegation(port) ? _("yes") : _("no"),
314 princ);
315 else
317 _(" GSS (authenticated=%s, encrypted=%s, delegated_credentials=%s)"),
318 be_gssapi_get_auth(port) ? _("yes") : _("no"),
319 be_gssapi_get_enc(port) ? _("yes") : _("no"),
320 be_gssapi_get_delegation(port) ? _("yes") : _("no"));
321 }
322#endif
323
324 ereport(LOG, errmsg_internal("%s", logmsg.data));
325 pfree(logmsg.data);
326 }
327
328 set_ps_display("startup");
329
330 ClientAuthInProgress = false; /* client_min_messages is active now */
331}
void ClientAuthentication(Port *port)
Definition auth.c:374
TimestampTz GetCurrentTimestamp(void)
Definition timestamp.c:1649
uint32 log_connections
ConnectionTiming conn_timing
@ LOG_CONNECTION_AUTHORIZATION
bool be_gssapi_get_auth(Port *port)
bool be_gssapi_get_enc(Port *port)
const char * be_gssapi_get_princ(Port *port)
bool be_gssapi_get_delegation(Port *port)
const char * be_tls_get_version(Port *port)
int be_tls_get_cipher_bits(Port *port)
const char * be_tls_get_cipher(Port *port)
#define _(x)
Definition elog.c:96
#define LOG
Definition elog.h:32
int int errmsg_internal(const char *fmt,...) pg_attribute_printf(1
char * HbaFileName
Definition guc_tables.c:584
bool load_ident(void)
Definition hba.c:2846
bool load_hba(void)
Definition hba.c:2452
MemoryContext TopMemoryContext
Definition mcxt.c:167
MemoryContext PostmasterContext
Definition mcxt.c:169
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160
static int port
Definition pg_regress.c:117
bool ClientAuthInProgress
Definition postmaster.c:374
int AuthenticationTimeout
Definition postmaster.c:242
static void set_ps_display(const char *activity)
Definition ps_status.h:40
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition stringinfo.c:145
void initStringInfo(StringInfo str)
Definition stringinfo.c:97
TimestampTz auth_start
void enable_timeout_after(TimeoutId id, int delay_ms)
Definition timeout.c:560
void disable_timeout(TimeoutId id, bool keep_indicator)
Definition timeout.c:685

References _, ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, am_walsender, appendStringInfo(), ConnectionTiming::auth_end, ConnectionTiming::auth_start, AuthenticationTimeout, be_gssapi_get_auth(), be_gssapi_get_delegation(), be_gssapi_get_enc(), be_gssapi_get_princ(), be_tls_get_cipher(), be_tls_get_cipher_bits(), be_tls_get_version(), ClientAuthentication(), ClientAuthInProgress, conn_timing, disable_timeout(), enable_timeout_after(), ereport, errmsg, errmsg_internal(), FATAL, fb(), GetCurrentTimestamp(), HbaFileName, initStringInfo(), load_hba(), load_ident(), LOG, LOG_CONNECTION_AUTHORIZATION, log_connections, pfree(), port, PostmasterContext, set_ps_display(), STATEMENT_TIMEOUT, and TopMemoryContext.

Referenced by InitPostgres().

◆ pg_split_opts()

void pg_split_opts ( char **  argv,
int argcp,
const char optstr 
)

Definition at line 507 of file postinit.c.

508{
510
511 initStringInfo(&s);
512
513 while (*optstr)
514 {
515 bool last_was_escape = false;
516
517 resetStringInfo(&s);
518
519 /* skip over leading space */
520 while (isspace((unsigned char) *optstr))
521 optstr++;
522
523 if (*optstr == '\0')
524 break;
525
526 /*
527 * Parse a single option, stopping at the first space, unless it's
528 * escaped.
529 */
530 while (*optstr)
531 {
532 if (isspace((unsigned char) *optstr) && !last_was_escape)
533 break;
534
535 if (!last_was_escape && *optstr == '\\')
536 last_was_escape = true;
537 else
538 {
539 last_was_escape = false;
541 }
542
543 optstr++;
544 }
545
546 /* now store the option in the next argv[] position */
547 argv[(*argcp)++] = pstrdup(s.data);
548 }
549
550 pfree(s.data);
551}
char * pstrdup(const char *in)
Definition mcxt.c:1910
void resetStringInfo(StringInfo str)
Definition stringinfo.c:126
void appendStringInfoChar(StringInfo str, char ch)
Definition stringinfo.c:242

References appendStringInfoChar(), StringInfoData::data, fb(), initStringInfo(), pfree(), pstrdup(), and resetStringInfo().

Referenced by process_startup_options().

◆ process_settings()

static void process_settings ( Oid  databaseid,
Oid  roleid 
)
static

Definition at line 1363 of file postinit.c.

1364{
1366 Snapshot snapshot;
1367
1368 if (!IsUnderPostmaster)
1369 return;
1370
1372
1373 /* read all the settings under the same snapshot for efficiency */
1375
1376 /* Later settings are ignored if set earlier. */
1378 ApplySetting(snapshot, InvalidOid, roleid, relsetting, PGC_S_USER);
1381
1382 UnregisterSnapshot(snapshot);
1384}
@ PGC_S_GLOBAL
Definition guc.h:118
@ PGC_S_DATABASE
Definition guc.h:119
@ PGC_S_DATABASE_USER
Definition guc.h:121
@ PGC_S_USER
Definition guc.h:120
void ApplySetting(Snapshot snapshot, Oid databaseid, Oid roleid, Relation relsetting, GucSource source)
#define InvalidOid
Snapshot GetCatalogSnapshot(Oid relid)
Definition snapmgr.c:385
void UnregisterSnapshot(Snapshot snapshot)
Definition snapmgr.c:866
Snapshot RegisterSnapshot(Snapshot snapshot)
Definition snapmgr.c:824

References AccessShareLock, ApplySetting(), fb(), GetCatalogSnapshot(), InvalidOid, IsUnderPostmaster, PGC_S_DATABASE, PGC_S_DATABASE_USER, PGC_S_GLOBAL, PGC_S_USER, RegisterSnapshot(), table_close(), table_open(), and UnregisterSnapshot().

Referenced by InitPostgres().

◆ process_startup_options()

static void process_startup_options ( Port port,
bool  am_superuser 
)
static

Definition at line 1298 of file postinit.c.

1299{
1302
1304
1305 /*
1306 * First process any command-line switches that were included in the
1307 * startup packet, if we are in a regular backend.
1308 */
1309 if (port->cmdline_options != NULL)
1310 {
1311 /*
1312 * The maximum possible number of commandline arguments that could
1313 * come from port->cmdline_options is (strlen + 1) / 2; see
1314 * pg_split_opts().
1315 */
1316 char **av;
1317 int maxac;
1318 int ac;
1319
1320 maxac = 2 + (strlen(port->cmdline_options) + 1) / 2;
1321
1322 av = palloc_array(char *, maxac);
1323 ac = 0;
1324
1325 av[ac++] = "postgres";
1326
1327 pg_split_opts(av, &ac, port->cmdline_options);
1328
1329 av[ac] = NULL;
1330
1331 Assert(ac < maxac);
1332
1334 }
1335
1336 /*
1337 * Process any additional GUC variable settings passed in startup packet.
1338 * These are handled exactly like command-line variables.
1339 */
1340 gucopts = list_head(port->guc_options);
1341 while (gucopts)
1342 {
1343 char *name;
1344 char *value;
1345
1346 name = lfirst(gucopts);
1347 gucopts = lnext(port->guc_options, gucopts);
1348
1349 value = lfirst(gucopts);
1350 gucopts = lnext(port->guc_options, gucopts);
1351
1353 }
1354}
#define palloc_array(type, count)
Definition fe_memutils.h:91
@ PGC_S_CLIENT
Definition guc.h:122
GucContext
Definition guc.h:72
@ PGC_SU_BACKEND
Definition guc.h:76
static struct @173 value
#define lfirst(lc)
Definition pg_list.h:172
static ListCell * list_head(const List *l)
Definition pg_list.h:128
static ListCell * lnext(const List *l, const ListCell *c)
Definition pg_list.h:375
void process_postgres_switches(int argc, char *argv[], GucContext ctx, const char **dbname)
Definition postgres.c:3875
void pg_split_opts(char **argv, int *argcp, const char *optstr)
Definition postinit.c:507
struct @10::@11 av[32]

References Assert, av, fb(), lfirst, list_head(), lnext(), name, palloc_array, pg_split_opts(), PGC_BACKEND, PGC_S_CLIENT, PGC_SU_BACKEND, port, process_postgres_switches(), SetConfigOption(), and value.

Referenced by InitPostgres().

◆ ShutdownPostgres()

static void ShutdownPostgres ( int  code,
Datum  arg 
)
static

Definition at line 1397 of file postinit.c.

1398{
1399 /* Make sure we've killed any active transaction */
1401
1402 /*
1403 * User locks are not released by transaction end, so be sure to release
1404 * them explicitly.
1405 */
1407}
void LockReleaseAll(LOCKMETHODID lockmethodid, bool allLocks)
Definition lock.c:2315
#define USER_LOCKMETHOD
Definition locktag.h:26
void AbortOutOfAnyTransaction(void)
Definition xact.c:4916

References AbortOutOfAnyTransaction(), LockReleaseAll(), and USER_LOCKMETHOD.

Referenced by InitPostgres().

◆ StatementTimeoutHandler()

static void StatementTimeoutHandler ( void  )
static

Definition at line 1414 of file postinit.c.

1415{
1416 int sig = SIGINT;
1417
1418 /*
1419 * During authentication the timeout is used to deal with
1420 * authentication_timeout - we want to quit in response to such timeouts.
1421 */
1423 sig = SIGTERM;
1424
1425#ifdef HAVE_SETSID
1426 /* try to signal whole process group */
1427 kill(-MyProcPid, sig);
1428#endif
1429 kill(MyProcPid, sig);
1430}
static int sig
Definition pg_ctl.c:81

References ClientAuthInProgress, fb(), kill, MyProcPid, and sig.

Referenced by InitPostgres().

◆ StoreConnectionWarning()

void StoreConnectionWarning ( char msg,
char detail,
ConnectionWarningFilter  filter 
)

Definition at line 1517 of file postinit.c.

1518{
1519 MemoryContext oldcontext;
1521
1522 Assert(msg);
1523 Assert(detail);
1524
1526 elog(ERROR, "StoreConnectionWarning() called after EmitConnectionWarnings()");
1527
1529
1531 warning->message = msg;
1532 warning->detail = detail;
1533 warning->filter = filter;
1535
1536 MemoryContextSwitchTo(oldcontext);
1537}
#define palloc_object(type)
Definition fe_memutils.h:89
List * lappend(List *list, void *datum)
Definition list.c:339
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:138

References Assert, ConnectionWarnings, ConnectionWarningsEmitted, elog, ERROR, lappend(), MemoryContextSwitchTo(), palloc_object, TopMemoryContext, and warning().

Referenced by get_role_password(), and md5_crypt_verify().

◆ ThereIsAtLeastOneRole()

static bool ThereIsAtLeastOneRole ( void  )
static

Definition at line 1489 of file postinit.c.

1490{
1492 TableScanDesc scan;
1493 bool result;
1494
1496
1499
1500 table_endscan(scan);
1502
1503 return result;
1504}
uint32 result
HeapTuple heap_getnext(TableScanDesc sscan, ScanDirection direction)
Definition heapam.c:1435
@ ForwardScanDirection
Definition sdir.h:28
TableScanDesc table_beginscan_catalog(Relation relation, int nkeys, ScanKeyData *key)
Definition tableam.c:113
static void table_endscan(TableScanDesc scan)
Definition tableam.h:1061

References AccessShareLock, fb(), ForwardScanDirection, heap_getnext(), result, table_beginscan_catalog(), table_close(), table_endscan(), and table_open().

Referenced by InitPostgres().

◆ TransactionTimeoutHandler()

static void TransactionTimeoutHandler ( void  )
static

Definition at line 1446 of file postinit.c.

1447{
1449 InterruptPending = true;
1451}
volatile sig_atomic_t TransactionTimeoutPending
Definition globals.c:38

References InterruptPending, MyLatch, SetLatch(), and TransactionTimeoutPending.

Referenced by InitPostgres().

Variable Documentation

◆ ConnectionWarnings

List* ConnectionWarnings
static

Definition at line 85 of file postinit.c.

Referenced by EmitConnectionWarnings(), and StoreConnectionWarning().

◆ ConnectionWarningsEmitted

bool ConnectionWarningsEmitted
static

Definition at line 75 of file postinit.c.

Referenced by EmitConnectionWarnings(), and StoreConnectionWarning().