mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
process startup: Split single user code out of PostgresMain().
It was harder than necessary to understand PostgresMain() because the code for a normal backend was interspersed with single-user mode specific code. Split most of the single-user mode code into its own function PostgresSingleUserMain(), that does all the necessary setup for single-user mode, and then hands off after that to PostgresMain(). There still is some single-user mode code in InitPostgres(), and it'd likely be worth moving at least some of it out. But that's for later. Reviewed-By: Kyotaro Horiguchi <horikyota.ntt@gmail.com> Author: Andres Freund <andres@anarazel.de> Discussion: https://postgr.es/m/20210802164124.ufo5buo4apl6yuvs@alap3.anarazel.de
This commit is contained in:
@ -192,8 +192,7 @@ main(int argc, char *argv[])
|
|||||||
else if (argc > 1 && strcmp(argv[1], "--describe-config") == 0)
|
else if (argc > 1 && strcmp(argv[1], "--describe-config") == 0)
|
||||||
GucInfoMain();
|
GucInfoMain();
|
||||||
else if (argc > 1 && strcmp(argv[1], "--single") == 0)
|
else if (argc > 1 && strcmp(argv[1], "--single") == 0)
|
||||||
PostgresMain(argc, argv,
|
PostgresSingleUserMain(argc, argv,
|
||||||
NULL, /* no dbname */
|
|
||||||
strdup(get_user_name_or_exit(progname)));
|
strdup(get_user_name_or_exit(progname)));
|
||||||
else
|
else
|
||||||
PostmasterMain(argc, argv);
|
PostmasterMain(argc, argv);
|
||||||
|
@ -4551,19 +4551,13 @@ BackendInitialize(Port *port)
|
|||||||
static void
|
static void
|
||||||
BackendRun(Port *port)
|
BackendRun(Port *port)
|
||||||
{
|
{
|
||||||
char *av[2];
|
|
||||||
const int ac = 1;
|
|
||||||
|
|
||||||
av[0] = "postgres";
|
|
||||||
av[1] = NULL;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Make sure we aren't in PostmasterContext anymore. (We can't delete it
|
* Make sure we aren't in PostmasterContext anymore. (We can't delete it
|
||||||
* just yet, though, because InitPostgres will need the HBA data.)
|
* just yet, though, because InitPostgres will need the HBA data.)
|
||||||
*/
|
*/
|
||||||
MemoryContextSwitchTo(TopMemoryContext);
|
MemoryContextSwitchTo(TopMemoryContext);
|
||||||
|
|
||||||
PostgresMain(ac, av, port->database_name, port->user_name);
|
PostgresMain(port->database_name, port->user_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3654,7 +3654,7 @@ get_stats_option_name(const char *arg)
|
|||||||
|
|
||||||
/* ----------------------------------------------------------------
|
/* ----------------------------------------------------------------
|
||||||
* process_postgres_switches
|
* process_postgres_switches
|
||||||
* Parse command line arguments for PostgresMain
|
* Parse command line arguments for backends
|
||||||
*
|
*
|
||||||
* This is called twice, once for the "secure" options coming from the
|
* This is called twice, once for the "secure" options coming from the
|
||||||
* postmaster or command line, and once for the "insecure" options coming
|
* postmaster or command line, and once for the "insecure" options coming
|
||||||
@ -3915,39 +3915,29 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ----------------------------------------------------------------
|
/*
|
||||||
* PostgresMain
|
* PostgresSingleUserMain
|
||||||
* postgres main loop -- all backends, interactive or otherwise start here
|
* Entry point for single user mode. argc/argv are the command line
|
||||||
|
* arguments to be used.
|
||||||
*
|
*
|
||||||
* argc/argv are the command line arguments to be used. (When being forked
|
* Performs single user specific setup then calls PostgresMain() to actually
|
||||||
* by the postmaster, these are not the original argv array of the process.)
|
* process queries. Single user mode specific setup should go here, rather
|
||||||
* dbname is the name of the database to connect to, or NULL if the database
|
* than PostgresMain() or InitPostgres() when reasonably possible.
|
||||||
* name should be extracted from the command line arguments or defaulted.
|
|
||||||
* username is the PostgreSQL user name to be used for the session.
|
|
||||||
* ----------------------------------------------------------------
|
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
PostgresMain(int argc, char *argv[],
|
PostgresSingleUserMain(int argc, char *argv[],
|
||||||
const char *dbname,
|
|
||||||
const char *username)
|
const char *username)
|
||||||
{
|
{
|
||||||
int firstchar;
|
const char *dbname = NULL;
|
||||||
StringInfoData input_message;
|
|
||||||
sigjmp_buf local_sigjmp_buf;
|
|
||||||
volatile bool send_ready_for_query = true;
|
|
||||||
bool idle_in_transaction_timeout_enabled = false;
|
|
||||||
bool idle_session_timeout_enabled = false;
|
|
||||||
|
|
||||||
/* Initialize startup process environment if necessary. */
|
Assert(!IsUnderPostmaster);
|
||||||
if (!IsUnderPostmaster)
|
|
||||||
|
/* Initialize startup process environment. */
|
||||||
InitStandaloneProcess(argv[0]);
|
InitStandaloneProcess(argv[0]);
|
||||||
|
|
||||||
SetProcessingMode(InitProcessing);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set default values for command-line options.
|
* Set default values for command-line options.
|
||||||
*/
|
*/
|
||||||
if (!IsUnderPostmaster)
|
|
||||||
InitializeGUCOptions();
|
InitializeGUCOptions();
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3966,13 +3956,76 @@ PostgresMain(int argc, char *argv[],
|
|||||||
progname)));
|
progname)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Acquire configuration parameters, unless inherited from postmaster */
|
/* Acquire configuration parameters */
|
||||||
if (!IsUnderPostmaster)
|
|
||||||
{
|
|
||||||
if (!SelectConfigFiles(userDoption, progname))
|
if (!SelectConfigFiles(userDoption, progname))
|
||||||
proc_exit(1);
|
proc_exit(1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Validate we have been given a reasonable-looking DataDir and change
|
||||||
|
* into it.
|
||||||
|
*/
|
||||||
|
checkDataDir();
|
||||||
|
ChangeToDataDir();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create lockfile for data directory.
|
||||||
|
*/
|
||||||
|
CreateDataDirLockFile(false);
|
||||||
|
|
||||||
|
/* read control file (error checking and contains config ) */
|
||||||
|
LocalProcessControlFile(false);
|
||||||
|
|
||||||
|
/* Initialize MaxBackends */
|
||||||
|
InitializeMaxBackends();
|
||||||
|
|
||||||
|
CreateSharedMemoryAndSemaphores();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Remember stand-alone backend startup time,roughly at the same point
|
||||||
|
* during startup that postmaster does so.
|
||||||
|
*/
|
||||||
|
PgStartTime = GetCurrentTimestamp();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Create a per-backend PGPROC struct in shared memory. We must do this
|
||||||
|
* before we can use LWLocks.
|
||||||
|
*/
|
||||||
|
InitProcess();
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Now that sufficient infrastructure has been initialized, PostgresMain()
|
||||||
|
* can do the rest.
|
||||||
|
*/
|
||||||
|
PostgresMain(dbname, username);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ----------------------------------------------------------------
|
||||||
|
* PostgresMain
|
||||||
|
* postgres main loop -- all backends, interactive or otherwise loop here
|
||||||
|
*
|
||||||
|
* dbname is the name of the database to connect to, username is the
|
||||||
|
* PostgreSQL user name to be used for the session.
|
||||||
|
*
|
||||||
|
* NB: Single user mode specific setup should go to PostgresSingleUserMain()
|
||||||
|
* if reasonably possible.
|
||||||
|
* ----------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
PostgresMain(const char *dbname, const char *username)
|
||||||
|
{
|
||||||
|
int firstchar;
|
||||||
|
StringInfoData input_message;
|
||||||
|
sigjmp_buf local_sigjmp_buf;
|
||||||
|
volatile bool send_ready_for_query = true;
|
||||||
|
bool idle_in_transaction_timeout_enabled = false;
|
||||||
|
bool idle_session_timeout_enabled = false;
|
||||||
|
|
||||||
|
AssertArg(dbname != NULL);
|
||||||
|
AssertArg(username != NULL);
|
||||||
|
|
||||||
|
SetProcessingMode(InitProcessing);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Set up signal handlers. (InitPostmasterChild or InitStandaloneProcess
|
* Set up signal handlers. (InitPostmasterChild or InitStandaloneProcess
|
||||||
* has already set up BlockSig and made that the active signal mask.)
|
* has already set up BlockSig and made that the active signal mask.)
|
||||||
@ -4029,43 +4082,6 @@ PostgresMain(int argc, char *argv[],
|
|||||||
* platforms */
|
* platforms */
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!IsUnderPostmaster)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Validate we have been given a reasonable-looking DataDir (if under
|
|
||||||
* postmaster, assume postmaster did this already).
|
|
||||||
*/
|
|
||||||
checkDataDir();
|
|
||||||
|
|
||||||
/* Change into DataDir (if under postmaster, was done already) */
|
|
||||||
ChangeToDataDir();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create lockfile for data directory.
|
|
||||||
*/
|
|
||||||
CreateDataDirLockFile(false);
|
|
||||||
|
|
||||||
/* read control file (error checking and contains config ) */
|
|
||||||
LocalProcessControlFile(false);
|
|
||||||
|
|
||||||
/* Initialize MaxBackends (if under postmaster, was done already) */
|
|
||||||
InitializeMaxBackends();
|
|
||||||
|
|
||||||
CreateSharedMemoryAndSemaphores();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Remember stand-alone backend startup time, roughly at the same
|
|
||||||
* point during startup that postmaster does so.
|
|
||||||
*/
|
|
||||||
PgStartTime = GetCurrentTimestamp();
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Create a per-backend PGPROC struct in shared memory. We must do
|
|
||||||
* this before we can use LWLocks.
|
|
||||||
*/
|
|
||||||
InitProcess();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Early initialization */
|
/* Early initialization */
|
||||||
BaseInit();
|
BaseInit();
|
||||||
|
|
||||||
|
@ -75,8 +75,9 @@ extern void ProcessClientWriteInterrupt(bool blocked);
|
|||||||
|
|
||||||
extern void process_postgres_switches(int argc, char *argv[],
|
extern void process_postgres_switches(int argc, char *argv[],
|
||||||
GucContext ctx, const char **dbname);
|
GucContext ctx, const char **dbname);
|
||||||
extern void PostgresMain(int argc, char *argv[],
|
extern void PostgresSingleUserMain(int argc, char *argv[],
|
||||||
const char *dbname,
|
const char *username) pg_attribute_noreturn();
|
||||||
|
extern void PostgresMain(const char *dbname,
|
||||||
const char *username) pg_attribute_noreturn();
|
const char *username) pg_attribute_noreturn();
|
||||||
extern long get_stack_depth_rlimit(void);
|
extern long get_stack_depth_rlimit(void);
|
||||||
extern void ResetUsage(void);
|
extern void ResetUsage(void);
|
||||||
|
Reference in New Issue
Block a user