您的位置:首页 > 数据库

PostgreSQL的 initdb 源代码分析之十一

2013-07-08 13:29 471 查看
继续分析:

/* Top level PG_VERSION is checked by bootstrapper, so make it first */
write_version_file(NULL);


就是建立了一个 PG_VERSION的文件

在我系统里,可以看到:

[pgsql@localhost DemoDir]$ cat PG_VERSION
9.1
[pgsql@localhost DemoDir]$


接下来:

我先看看 set_null_conf 函数

/* Select suitable configuration settings */
set_null_conf();
test_config_settings();


展开 set_null_conf 函数:就是生成了一个 空的 postgresql.conf文件。

/*
* set up an empty config file so we can check config settings by launching
* a test backend
*/
static void
set_null_conf(void)
{
FILE       *conf_file;
char       *path;

path = pg_malloc(strlen(pg_data) + 17);
sprintf(path, "%s/postgresql.conf", pg_data);
conf_file = fopen(path, PG_BINARY_W);
if (conf_file == NULL)
{
fprintf(stderr, _("%s: could not open file \"%s\" for writing: %s\n"),
progname, path, strerror(errno));
exit_nicely();
}
if (fclose(conf_file))
{
fprintf(stderr, _("%s: could not write file \"%s\": %s\n"),
progname, path, strerror(errno));
exit_nicely();
}
free(path);
}


再看 test_config_settings() 完成了什么?

我得到的cmd的值是:

对于确定 max_connections :

"/home/pgsql/project/bin/postgres" --boot -x0 -F -c max_connections=100 -c shared_buffers=1000 < "/dev/null" > "/dev/null" 2>&1

对于确定 shared_buffers :

"/home/pgsql/project/bin/postgres" --boot -x0 -F -c max_connections=100 -c shared_buffers=4096 < "/dev/null" > "/dev/null" 2>&1

/*
* Determine platform-specific config settings
*
* Use reasonable values if kernel will let us, else scale back.  Probe
* for max_connections first since it is subject to more constraints than
* shared_buffers.
*/
static void
test_config_settings(void)
{
/*
* This macro defines the minimum shared_buffers we want for a given
* max_connections value. The arrays show the settings to try.
*/
#define MIN_BUFS_FOR_CONNS(nconns)    ((nconns) * 10)

static const int trial_conns[] = {
100, 50, 40, 30, 20, 10
};
static const int trial_bufs[] = {
4096, 3584, 3072, 2560, 2048, 1536,
1000, 900, 800, 700, 600, 500,
400, 300, 200, 100, 50
};

char        cmd[MAXPGPATH];
const int    connslen = sizeof(trial_conns) / sizeof(int);
const int    bufslen = sizeof(trial_bufs) / sizeof(int);
int            i,
status,
test_conns,
test_buffs,
ok_buffers = 0;

printf(_("selecting default max_connections ... "));
fflush(stdout);

for (i = 0; i < connslen; i++)
{
test_conns = trial_conns[i];
test_buffs = MIN_BUFS_FOR_CONNS(test_conns);

snprintf(cmd, sizeof(cmd),
SYSTEMQUOTE "\"%s\" --boot -x0 %s "
"-c max_connections=%d "
"-c shared_buffers=%d "
"< \"%s\" > \"%s\" 2>&1" SYSTEMQUOTE,
backend_exec, boot_options,
test_conns, test_buffs,
DEVNULL, DEVNULL);
status = system(cmd);
if (status == 0)
{
ok_buffers = test_buffs;
break;
}
}
if (i >= connslen)
i = connslen - 1;
n_connections = trial_conns[i];

printf("%d\n", n_connections);

printf(_("selecting default shared_buffers ... "));
fflush(stdout);

for (i = 0; i < bufslen; i++)
{
/* Use same amount of memory, independent of BLCKSZ */
test_buffs = (trial_bufs[i] * 8192) / BLCKSZ;
if (test_buffs <= ok_buffers)
{
test_buffs = ok_buffers;
break;
}

snprintf(cmd, sizeof(cmd),
SYSTEMQUOTE "\"%s\" --boot -x0 %s "
"-c max_connections=%d "
"-c shared_buffers=%d "
"< \"%s\" > \"%s\" 2>&1" SYSTEMQUOTE,
backend_exec, boot_options,
n_connections, test_buffs,
DEVNULL, DEVNULL);
status = system(cmd);
if (status == 0)
break;
}
n_buffers = test_buffs;

if ((n_buffers * (BLCKSZ / 1024)) % 1024 == 0)
printf("%dMB\n", (n_buffers * (BLCKSZ / 1024)) / 1024);
else
printf("%dkB\n", n_buffers * (BLCKSZ / 1024));
}


关键是看 system函数的内容:

int
system(const char *command)
{
pid_t        pid;
int            pstat;
struct sigaction ign,
intact,
quitact;
sigset_t    newsigblock,
oldsigblock;

if (!command)                /* just checking... */
return (1);

/*
* Ignore SIGINT and SIGQUIT, block SIGCHLD. Remember to save existing
* signal dispositions.
*/
ign.sa_handler = SIG_IGN;
(void) sigemptyset(&ign.sa_mask);
ign.sa_flags = 0;
(void) sigaction(SIGINT, &ign, &intact);
(void) sigaction(SIGQUIT, &ign, &quitact);
(void) sigemptyset(&newsigblock);
(void) sigaddset(&newsigblock, SIGCHLD);
(void) sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock);
switch (pid = fork())
{
case -1:                /* error */
break;
case 0:            /* child */

/*
* Restore original signal dispositions and exec the command.
*/
(void) sigaction(SIGINT, &intact, NULL);
(void) sigaction(SIGQUIT, &quitact, NULL);
(void) sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
execl(_PATH_BSHELL, "sh", "-c", command, (char *) NULL);
_exit(127);
default:                /* parent */
do
{
pid = wait4(pid, &pstat, 0, (struct rusage *) 0);
} while (pid == -1 && errno == EINTR);
break;
}
(void) sigaction(SIGINT, &intact, NULL);
(void) sigaction(SIGQUIT, &quitact, NULL);
(void) sigprocmask(SIG_SETMASK, &oldsigblock, NULL);

return (pid == -1 ? -1 : pstat);
}


结合上述 test_config_settings 函数 和 system函数,

可以知道,是给出 max_connections 参数和 shared_buffers参数,带给postgres,让它执行。

如果可以正常返回,说明可以工作,于是就用这个参数。也就是试探出最大允许的max_connections 和 shared_buffers参数。

我的运行结果是:

selecting default max_connections ... 100
selecting default shared_buffers ... 32MB
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: