总结
pg_ctl这个工具我们经常使用的工具,工具启动的过程中去会读取PGDATA这个环境变量,如果 没有不能成功启动,或者我们加上D 参数手动传入,然后重新设置PGDATA这个环境变量,
第一步读取PGDATA
switch (c)
{
case 'D':
{
char *pgdata_D;
pgdata_D = pg_strdup(optarg);
canonicalize_path(pgdata_D);
setenv("PGDATA", pgdata_D, 1);
/*
* We could pass PGDATA just in an environment
* variable but we do -D too for clearer postmaster
* 'ps' display
*/
pgdata_opt = psprintf("-D \"%s\" ", pgdata_D);
free(pgdata_D);
break;
第二步设置PGDATA
/* Note we put any -D switch into the env var above */
pg_config = getenv("PGDATA");
if (pg_config)
{
pg_config = pg_strdup(pg_config);
canonicalize_path(pg_config);
pg_data = pg_strdup(pg_config);
}
第三步执行启动
/* No -D or -D already added during server start */
if (ctl_command == RESTART_COMMAND || pgdata_opt == NULL)
pgdata_opt = "";
if (exec_path == NULL)
exec_path = find_other_exec_or_die(argv0, "postgres", PG_BACKEND_VERSIONSTR);
第四步真正的打工人-干活的函数
pm_pid = start_postmaster();
if (do_wait)
{
/*
* If the user interrupts the startup (e.g. with CTRL-C), we'd like to
* abort the server launch. Install a signal handler that will
* forward SIGINT to the postmaster process, while we wait.
*
* (We don't bother to reset the signal handler after the launch, as
* we're about to exit, anyway.)
*/
postmasterPID = pm_pid;
pqsignal(SIGINT, trap_sigint_during_startup);
print_msg(_("waiting for server to start..."));
switch (wait_for_postmaster_start(pm_pid, false))
{
case POSTMASTER_READY:
print_msg(_(" done\n"));
print_msg(_("server started\n"));
break;
case POSTMASTER_STILL_STARTING:
print_msg(_(" stopped waiting\n"));
write_stderr(_("%s: server did not start in time\n"),
progname);
exit(1);
break;
case POSTMASTER_FAILED:
print_msg(_(" stopped waiting\n"));
write_stderr(_("%s: could not start server\n"
"Examine the log output.\n"),
progname);
exit(1);
break;
}
}
else
print_msg(_("server starting\n"));
相关的工具链
/usr/local/pgsqldebug/bin/pg_ctl -D usr/local/pgsqldebug/data -l logfile start
/usr/local/pgsqldebug/bin/pg_ctl
/usr/local/pgsqldebug/bin/pg_ctl -D usr/local/pgsqldebug/data -l logfile stop
进入pg_ctl
所在的目录, 执行如下命令:
gdb usr/local/pgsqldebug/bin/pg_ctl
(gdb) layout src
(gdb) set args -D /usr/local/pgsqldebug/data start
(gdb) b main
(gdb) run
调试截图

调试信息

switch (ctl_command)
{
case INIT_COMMAND:
do_init();
break;
case STATUS_COMMAND:
do_status();
break;
case START_COMMAND:
do_start();
break;
case STOP_COMMAND:
do_stop();
break;
case RESTART_COMMAND:
do_restart();
break;
case RELOAD_COMMAND:
do_reload();
break;
case PROMOTE_COMMAND:
do_promote();
break;
case LOGROTATE_COMMAND:
do_logrotate();
break;
case KILL_COMMAND:
do_kill(killproc);
break;
#ifdef WIN32
case REGISTER_COMMAND:
pgwin32_doRegister();
break;
case UNREGISTER_COMMAND:
pgwin32_doUnregister();
break;
case RUN_AS_SERVICE_COMMAND:
pgwin32_doRunAsService();
break;
#endif
default:
break;
}
exit(0);
}
static void do_start(void);
static void
do_start(void)
{
pgpid_t old_pid = 0;
pgpid_t pm_pid;
if (ctl_command != RESTART_COMMAND)
{
old_pid = get_pgpid(false);
if (old_pid != 0)
write_stderr(_("%s: another server might be running; "
"trying to start server anyway\n"),
progname);
}
read_post_opts();
/* No -D or -D already added during server start */
if (ctl_command == RESTART_COMMAND || pgdata_opt == NULL)
pgdata_opt = "";
if (exec_path == NULL)
exec_path = find_other_exec_or_die(argv0, "postgres", PG_BACKEND_VERSIONSTR);
#if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
if (allow_core_files)
unlimit_core_size();
#endif
static char *
find_other_exec_or_die(const char *argv0, const char *target, const char *versionstr)
{
int ret;
char *found_path;
found_path = pg_malloc(MAXPGPATH);
if ((ret = find_other_exec(argv0, target, versionstr, found_path)) < 0)
{
char full_path[MAXPGPATH];
if (find_my_exec(argv0, full_path) < 0)
strlcpy(full_path, progname, sizeof(full_path));
if (ret == -1)
write_stderr(_("The program \"%s\" is needed by %s but was not found in the\n"
"same directory as \"%s\".\n"
"Check your installation.\n"),
target, progname, full_path);
else
write_stderr(_("The program \"%s\" was found by \"%s\"\n"
"but was not the same version as %s.\n"
"Check your installation.\n"),
target, full_path, progname);
exit(1);
}
return found_path;
}
文章转载自SmallDB,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




