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 + -
显示快捷键?