mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-03-07 19:47:50 +08: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:
parent
499c9b1266
commit
7c83a3bf51
@ -192,9 +192,8 @@ main(int argc, char *argv[])
|
||||
else if (argc > 1 && strcmp(argv[1], "--describe-config") == 0)
|
||||
GucInfoMain();
|
||||
else if (argc > 1 && strcmp(argv[1], "--single") == 0)
|
||||
PostgresMain(argc, argv,
|
||||
NULL, /* no dbname */
|
||||
strdup(get_user_name_or_exit(progname)));
|
||||
PostgresSingleUserMain(argc, argv,
|
||||
strdup(get_user_name_or_exit(progname)));
|
||||
else
|
||||
PostmasterMain(argc, argv);
|
||||
/* the functions above should not return */
|
||||
|
@ -4551,19 +4551,13 @@ BackendInitialize(Port *port)
|
||||
static void
|
||||
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
|
||||
* just yet, though, because InitPostgres will need the HBA data.)
|
||||
*/
|
||||
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
|
||||
* Parse command line arguments for PostgresMain
|
||||
* Parse command line arguments for backends
|
||||
*
|
||||
* This is called twice, once for the "secure" options coming from the
|
||||
* postmaster or command line, and once for the "insecure" options coming
|
||||
@ -3915,40 +3915,30 @@ process_postgres_switches(int argc, char *argv[], GucContext ctx,
|
||||
}
|
||||
|
||||
|
||||
/* ----------------------------------------------------------------
|
||||
* PostgresMain
|
||||
* postgres main loop -- all backends, interactive or otherwise start here
|
||||
/*
|
||||
* PostgresSingleUserMain
|
||||
* 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
|
||||
* by the postmaster, these are not the original argv array of the process.)
|
||||
* dbname is the name of the database to connect to, or NULL if the database
|
||||
* name should be extracted from the command line arguments or defaulted.
|
||||
* username is the PostgreSQL user name to be used for the session.
|
||||
* ----------------------------------------------------------------
|
||||
* Performs single user specific setup then calls PostgresMain() to actually
|
||||
* process queries. Single user mode specific setup should go here, rather
|
||||
* than PostgresMain() or InitPostgres() when reasonably possible.
|
||||
*/
|
||||
void
|
||||
PostgresMain(int argc, char *argv[],
|
||||
const char *dbname,
|
||||
const char *username)
|
||||
PostgresSingleUserMain(int argc, char *argv[],
|
||||
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;
|
||||
const char *dbname = NULL;
|
||||
|
||||
/* Initialize startup process environment if necessary. */
|
||||
if (!IsUnderPostmaster)
|
||||
InitStandaloneProcess(argv[0]);
|
||||
Assert(!IsUnderPostmaster);
|
||||
|
||||
SetProcessingMode(InitProcessing);
|
||||
/* Initialize startup process environment. */
|
||||
InitStandaloneProcess(argv[0]);
|
||||
|
||||
/*
|
||||
* Set default values for command-line options.
|
||||
*/
|
||||
if (!IsUnderPostmaster)
|
||||
InitializeGUCOptions();
|
||||
InitializeGUCOptions();
|
||||
|
||||
/*
|
||||
* Parse command-line options.
|
||||
@ -3966,12 +3956,75 @@ PostgresMain(int argc, char *argv[],
|
||||
progname)));
|
||||
}
|
||||
|
||||
/* Acquire configuration parameters, unless inherited from postmaster */
|
||||
if (!IsUnderPostmaster)
|
||||
{
|
||||
if (!SelectConfigFiles(userDoption, progname))
|
||||
proc_exit(1);
|
||||
}
|
||||
/* Acquire configuration parameters */
|
||||
if (!SelectConfigFiles(userDoption, progname))
|
||||
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
|
||||
@ -4029,43 +4082,6 @@ PostgresMain(int argc, char *argv[],
|
||||
* 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 */
|
||||
BaseInit();
|
||||
|
||||
|
@ -75,8 +75,9 @@ extern void ProcessClientWriteInterrupt(bool blocked);
|
||||
|
||||
extern void process_postgres_switches(int argc, char *argv[],
|
||||
GucContext ctx, const char **dbname);
|
||||
extern void PostgresMain(int argc, char *argv[],
|
||||
const char *dbname,
|
||||
extern void PostgresSingleUserMain(int argc, char *argv[],
|
||||
const char *username) pg_attribute_noreturn();
|
||||
extern void PostgresMain(const char *dbname,
|
||||
const char *username) pg_attribute_noreturn();
|
||||
extern long get_stack_depth_rlimit(void);
|
||||
extern void ResetUsage(void);
|
||||
|
Loading…
Reference in New Issue
Block a user