PostgreSQL的 initdb 源代码分析之十一

继续分析:

    /* 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
"),
                progname, path, strerror(errno));
        exit_nicely();
    }
    if (fclose(conf_file))
    {
        fprintf(stderr, _("%s: could not write file "%s": %s
"),
                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_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_buffers * (BLCKSZ / 1024)) / 1024);
    else
        printf("%dkB
", 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

原文地址:https://www.cnblogs.com/gaojian/p/3177579.html