postgres.c

来自「PostgreSQL7.4.6 for Linux」· C语言 代码 · 共 2,551 行 · 第 1/5 页

C
2,551
字号
		{			puts("postgres (PostgreSQL) " PG_VERSION);			exit(0);		}	}	/*	 * initialize globals (already done if under postmaster, but not if	 * standalone; cheap enough to do over)	 */	MyProcPid = getpid();	/*	 * Fire up essential subsystems: error and memory management	 *	 * If we are running under the postmaster, this is done already.	 */	if (!IsUnderPostmaster)		MemoryContextInit();	set_ps_display("startup");	SetProcessingMode(InitProcessing);	/*	 * Set default values for command-line options.	 */	Noversion = false;	EchoQuery = false;	if (!IsUnderPostmaster /* when exec || ExecBackend */ )	{		InitializeGUCOptions();		potential_DataDir = getenv("PGDATA");	}	/* ----------------	 *	parse command line arguments	 *	 *	There are now two styles of command line layout for the backend:	 *	 *	For interactive use (not started from postmaster) the format is	 *		postgres [switches] [databasename]	 *	If the databasename is omitted it is taken to be the user name.	 *	 *	When started from the postmaster, the format is	 *		postgres [secure switches] -p databasename [insecure switches]	 *	Switches appearing after -p came from the client (via "options"	 *	field of connection request).  For security reasons we restrict	 *	what these switches can do.	 * ----------------	 */	/* all options are allowed until '-p' */	secure = true;	ctx = debug_context = PGC_POSTMASTER;	gucsource = PGC_S_ARGV;		/* initial switches came from command line */	while ((flag = getopt(argc, argv, "A:B:c:CD:d:Eef:FiNOPo:p:S:st:v:W:x:-:")) != -1)		switch (flag)		{			case 'A':#ifdef USE_ASSERT_CHECKING				SetConfigOption("debug_assertions", optarg, ctx, gucsource);#else				ereport(WARNING,						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),						 errmsg("assert checking is not compiled in")));#endif				break;			case 'B':				/*				 * specify the size of buffer pool				 */				SetConfigOption("shared_buffers", optarg, ctx, gucsource);				break;			case 'C':				/*				 * don't print version string				 */				Noversion = true;				break;			case 'D':			/* PGDATA directory */				if (secure)					potential_DataDir = optarg;				break;			case 'd':			/* debug level */				{					/*					 * Client option can't decrease debug level. We have					 * to do the test here because we group priv and					 * client set GUC calls below, after we know the final					 * debug value.					 */					if (ctx != PGC_BACKEND || atoi(optarg) > debug_flag)					{						debug_flag = atoi(optarg);						debug_context = ctx;	/* save context for use												 * below */						/* Set server debugging level. */						if (debug_flag != 0)						{							char	   *debugstr = palloc(strlen("debug") + strlen(optarg) + 1);							sprintf(debugstr, "debug%s", optarg);							SetConfigOption("log_min_messages", debugstr, ctx, gucsource);							pfree(debugstr);						}						else							/*							 * -d0 allows user to prevent postmaster debug							 * from propagating to backend.  It would be							 * nice to set it to the postgresql.conf value							 * here.							 */							SetConfigOption("log_min_messages", "notice",											ctx, gucsource);					}				}				break;			case 'E':				/*				 * E - echo the query the user entered				 */				EchoQuery = true;				break;			case 'e':				/*				 * Use European date input format (DMY)				 */				SetConfigOption("datestyle", "euro", ctx, gucsource);				break;			case 'F':				/*				 * turn off fsync				 */				SetConfigOption("fsync", "false", ctx, gucsource);				break;			case 'f':				/*				 * f - forbid generation of certain plans				 */				tmp = NULL;				switch (optarg[0])				{					case 's':	/* seqscan */						tmp = "enable_seqscan";						break;					case 'i':	/* indexscan */						tmp = "enable_indexscan";						break;					case 't':	/* tidscan */						tmp = "enable_tidscan";						break;					case 'n':	/* nestloop */						tmp = "enable_nestloop";						break;					case 'm':	/* mergejoin */						tmp = "enable_mergejoin";						break;					case 'h':	/* hashjoin */						tmp = "enable_hashjoin";						break;					default:						errs++;				}				if (tmp)					SetConfigOption(tmp, "false", ctx, gucsource);				break;			case 'N':				/*				 * N - Don't use newline as a query delimiter				 */				UseNewLine = 0;				break;			case 'O':				/*				 * allow system table structure modifications				 */				if (secure)		/* XXX safe to allow from client??? */					allowSystemTableMods = true;				break;			case 'P':				/*				 * ignore system indexes				 *				 * As of PG 7.4 this is safe to allow from the client,				 * since it only disables reading the system indexes,				 * not writing them.  Worst case consequence is slowness.				 */				IgnoreSystemIndexes(true);				break;			case 'o':				/*				 * o - send output (stdout and stderr) to the given file				 */				if (secure)					StrNCpy(OutputFileName, optarg, MAXPGPATH);				break;			case 'p':				/*				 * p - special flag passed if backend was forked by a				 * postmaster.				 */				if (secure)				{#ifdef EXEC_BACKEND					char	   *p;					int			i;					int			PMcanAcceptConnections; /* will eventually be														 * global or static,														 * when fork */					sscanf(optarg, "%d,%d,%d,%p,", &MyProcPort->sock, &PMcanAcceptConnections,						   &UsedShmemSegID, &UsedShmemSegAddr);					/* Grab dbname as last param */					for (i = 0, p = optarg - 1; i < 4 && p; i++)						p = strchr(p + 1, ',');					if (i == 4 && p)						dbname = strdup(p + 1);#else					dbname = strdup(optarg);#endif					secure = false;		/* subsequent switches are NOT										 * secure */					ctx = PGC_BACKEND;					gucsource = PGC_S_CLIENT;				}				break;			case 'S':				/*				 * S - amount of sort memory to use in 1k bytes				 */				SetConfigOption("sort_mem", optarg, ctx, gucsource);				break;			case 's':				/*				 * s - report usage statistics (timings) after each query				 */				SetConfigOption("log_statement_stats", "true", ctx, gucsource);				break;			case 't':				/* ---------------				 *	tell postgres to report usage statistics (timings) for				 *	each query				 *				 *	-tpa[rser] = print stats for parser time of each query				 *	-tpl[anner] = print stats for planner time of each query				 *	-te[xecutor] = print stats for executor time of each query				 *	caution: -s can not be used together with -t.				 * ----------------				 */				tmp = NULL;				switch (optarg[0])				{					case 'p':						if (optarg[1] == 'a')							tmp = "log_parser_stats";						else if (optarg[1] == 'l')							tmp = "log_planner_stats";						else							errs++;						break;					case 'e':						tmp = "log_executor_stats";						break;					default:						errs++;						break;				}				if (tmp)					SetConfigOption(tmp, "true", ctx, gucsource);				break;			case 'v':				if (secure)					FrontendProtocol = (ProtocolVersion) atoi(optarg);				break;			case 'W':				/*				 * wait N seconds to allow attach from a debugger				 */				sleep(atoi(optarg));				break;			case 'x':#ifdef NOT_USED					/* planner/xfunc.h */				/*				 * control joey hellerstein's expensive function				 * optimization				 */				if (XfuncMode != 0)				{					elog(WARNING, "only one -x flag is allowed");					errs++;					break;				}				if (strcmp(optarg, "off") == 0)					XfuncMode = XFUNC_OFF;				else if (strcmp(optarg, "nor") == 0)					XfuncMode = XFUNC_NOR;				else if (strcmp(optarg, "nopull") == 0)					XfuncMode = XFUNC_NOPULL;				else if (strcmp(optarg, "nopm") == 0)					XfuncMode = XFUNC_NOPM;				else if (strcmp(optarg, "pullall") == 0)					XfuncMode = XFUNC_PULLALL;				else if (strcmp(optarg, "wait") == 0)					XfuncMode = XFUNC_WAIT;				else				{					elog(WARNING, "use -x {off,nor,nopull,nopm,pullall,wait}");					errs++;				}#endif				break;			case 'c':			case '-':				{					char	   *name,							   *value;					ParseLongOption(optarg, &name, &value);					if (!value)					{						if (flag == '-')							ereport(ERROR,									(errcode(ERRCODE_SYNTAX_ERROR),									 errmsg("--%s requires a value",											optarg)));						else							ereport(ERROR,									(errcode(ERRCODE_SYNTAX_ERROR),									 errmsg("-c %s requires a value",											optarg)));					}					SetConfigOption(name, value, ctx, gucsource);					free(name);					if (value)						free(value);					break;				}			default:				errs++;				break;		}	/*	 * -d is not the same as setting log_min_messages because it enables	 * other output options.	 */	if (debug_flag >= 1)		SetConfigOption("log_connections", "true", debug_context, gucsource);	if (debug_flag >= 2)		SetConfigOption("log_statement", "true", debug_context, gucsource);	if (debug_flag >= 3)		SetConfigOption("debug_print_parse", "true", debug_context, gucsource);	if (debug_flag >= 4)		SetConfigOption("debug_print_plan", "true", debug_context, gucsource);	if (debug_flag >= 5)		SetConfigOption("debug_print_rewritten", "true", debug_context, gucsource);	/*	 * Process any additional GUC variable settings passed in startup	 * packet.	 */	if (MyProcPort != NULL)	{		List	   *gucopts = MyProcPort->guc_options;		while (gucopts)		{			char	   *name,					   *value;			name = lfirst(gucopts);			gucopts = lnext(gucopts);			value = lfirst(gucopts);			gucopts = lnext(gucopts);			SetConfigOption(name, value, PGC_BACKEND, PGC_S_CLIENT);		}	}	/*	 * Post-processing for command line options.	 */	if (log_statement_stats &&		(log_parser_stats || log_planner_stats || log_executor_stats))	{		ereport(WARNING,				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),				 errmsg("statement-level statistics are disabled because parser, planner, or executor statistics are on")));		SetConfigOption("log_statement_stats", "false", ctx, gucsource);	}	if (!IsUnderPostmaster)	{		if (!potential_DataDir)		{			fprintf(stderr,					gettext("%s does not know where to find the database system data.\n"							"You must specify the directory that contains the database system\n"							"either by specifying the -D invocation option or by setting the\n"							"PGDATA environment variable.\n"),					argv[0]);			proc_exit(1);		}		SetDataDir(potential_DataDir);	}	Assert(DataDir);	/* Acquire configuration parameters */	if (IsUnderPostmaster)	{#ifdef EXEC_BACKEND		read_nondefault_variables();#endif	}	else		ProcessConfigFile(PGC_POSTMASTER);	/*	 * Set up signal handlers and masks.	 *	 * Note that postmaster blocked all signals before forking child process,	 * so there is no race condition whereby we might receive a signal	 * before we have set up the handler.	 *	 * Also note: it's best not to use any signals that are SIG_IGNored in	 * the postmaster.	If such a signal arrives before we are able to	 * change the handler to non-SIG_IGN, it'll get dropped.  Instead,	 * make a dummy handler in the postmaster to reserve the signal. (Of	 * course, this isn't an issue for signals that are locally generated,	 * such as SIGALRM and SIGPIPE.)	 */	pqsignal(SIGHUP, SigHupHandler);	/* set flag to read config file */	pqsignal(SIGINT, StatementCancelHandler);	/* cancel current query */	pqsignal(SIGTERM, die);		/* cancel current query and exit */	pqsignal(SIGQUIT, quickdie);	/* hard crash time */	pqsignal(SIGALRM, handle_sig_alarm);		/* timeout conditions */	/*	 * Ignore failure to write to frontend. Note: if frontend closes	 * connection, we will notice it and exit cleanly when control next	 * returns to outer loop.  This seems safer than forcing exit in the	 * midst of output during who-knows-what operation...	 */	pqsignal(SIGPIPE, SIG_IGN);	pqsignal(SIGUSR1, SIG_IGN); /* this signal available for use */	pqsignal(SIGUSR2, Async_NotifyHandler);		/* flush also sinval cache */	pqsignal(SIGFPE, FloatExceptionHandler);	/*	 * Reset some signals that are accepted by postmaster but not by	 * backend	 */	pqsignal(SIGCHLD, SIG_DFL); /* system() requires this on some								 * platforms */	pqinitmask();	/* We allow SIGQUIT (quickdie) at all times */#ifdef HAVE_SIGPROCMASK	sigdelset(&BlockSig, SIGQUIT);#else	BlockSig &= ~(sigmask

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?