What is the implementation logic of PostgresMain function in PostgreSQL?
Len. * cursor is initialized to zero by makeStringInfo or initStringInfo, * but is not otherwise touched by the stringinfo.c routines. * Some routines use it to scan through a StringInfo. *-* / typedef struct StringInfoData {char * data; int len; int maxlen; int cursor;} StringInfoData; typedef StringInfoData * StringInfo
2. Macro definition
# ifndef WIN32 # define PG_SETMASK (mask) sigprocmask (SIG_SETMASK, mask, NULL) # else / * Emulate POSIX sigset_t APIs on Windows * / typedef int sigset_t; extern int pqsigsetmask (int mask) # define PG_SETMASK (mask) pqsigsetmask (* (mask)) # define sigemptyset (set) (* (set) = 0) # define sigfillset (set) (* (set) = ~ 0) # define sigaddset (set, signum) (* (set) | = (sigmask (signum) # define sigdelset (set, signum) (* (set) & = ~ (sigmask (signum) # endif / * WIN32 * /
3. Global variables
/ * IsPostmasterEnvironment is true in a postmaster process and any postmaster * child process; it is false in a standalone process (bootstrap or * standalone backend). IsUnderPostmaster is true in postmaster child * processes. Note that "child process" includes all children, not only * regular backends. These should be set correctly as early as possible * in the execution of a process, so that error handling will do the right * things if an error should occur during process initialization. * * These are initialized for the bootstrap/standalone case. * / bool IsPostmasterEnvironment = false; bool IsUnderPostmaster = false; bool IsBinaryUpgrade = false; bool IsBackgroundWorker = false; bool am_walsender = false; / * Am I a walsender process? *
Dependent function
1 、 InitStandaloneProcess
/ * Initialize the basic environment for a standalone process. * * argv0 has to be suitable to find the program's executable. * / void InitStandaloneProcess (const char * argv0) {Assert (! IsPostmasterEnvironment); MyProcPid = getpid (); / * reset MyProcPid * / MyStartTime = time (NULL); / * set our start time in case we call elog * / / * Initialize process-local latch support * / InitializeLatchSupport (); MyLatch = & LocalLatchData; InitLatch (MyLatch) / * Compute paths, no postmaster to inherit from * / if (my_exec_path [0] = ='\ 0') {if (find_my_exec (argv0, my_exec_path)
< 0) elog(FATAL, "%s: could not locate my own executable path", argv0); } if (pkglib_path[0] == '\0') get_pkglib_path(my_exec_path, pkglib_path); } 2、InitializeGUCOptions /* * Initialize GUC options during program startup. * * Note that we cannot read the config file yet, since we have not yet * processed command-line switches. */ void InitializeGUCOptions(void) { int i; /* * Before log_line_prefix could possibly receive a nonempty setting, make * sure that timezone processing is minimally alive (see elog.c). */ pg_timezone_initialize(); /* * Build sorted array of all GUC variables. */ build_guc_variables(); /* * Load all variables with their compiled-in defaults, and initialize * status fields as needed. */ for (i = 0; i < num_guc_variables; i++) { InitializeOneGUCOption(guc_variables[i]); } guc_dirty = false; reporting_enabled = false; /* * Prevent any attempt to override the transaction modes from * non-interactive sources. */ SetConfigOption("transaction_isolation", "default", PGC_POSTMASTER, PGC_S_OVERRIDE); SetConfigOption("transaction_read_only", "no", PGC_POSTMASTER, PGC_S_OVERRIDE); SetConfigOption("transaction_deferrable", "no", PGC_POSTMASTER, PGC_S_OVERRIDE); /* * For historical reasons, some GUC parameters can receive defaults from * environment variables. Process those settings. */ InitializeGUCOptionsFromEnvironment(); } 3、process_postgres_switches /* ---------------------------------------------------------------- * process_postgres_switches * Parse command line arguments for PostgresMain * * This is called twice, once for the "secure" options coming from the * postmaster or command line, and once for the "insecure" options coming * from the client's startup packet. The latter have the same syntax but * may be restricted in what they can do. * * argv[0] is ignored in either case (it's assumed to be the program name). * * ctx is PGC_POSTMASTER for secure options, PGC_BACKEND for insecure options * coming from the client, or PGC_SU_BACKEND for insecure options coming from * a superuser client. * * If a database name is present in the command line arguments, it's * returned into *dbname (this is allowed only if *dbname is initially NULL). * ---------------------------------------------------------------- */ void process_postgres_switches(int argc, char *argv[], GucContext ctx, const char **dbname) { bool secure = (ctx == PGC_POSTMASTER); int errs = 0; GucSource gucsource; int flag; if (secure) { gucsource = PGC_S_ARGV; /* switches came from command line */ /* Ignore the initial --single argument, if present */ if (argc > < NUM_LOCK_PARTITIONS; i++) Assert(SHMQueueEmpty(&(MyProc->