zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    RabbitMQ安装
    基于Linux的校园网破解思路和方法
    网络-0001-常见传输介质
    友情链接
    linux简史
    计算机的发展简史
    ArrayList&LinkedList&Vector区别
    Adobe Flash Player PPAPI 32.0.0.330
    ntoskrnl.exe导致蓝屏解决方法
    Git常用命令
  • 原文地址:https://www.cnblogs.com/gaojian/p/3177579.html
Copyright © 2011-2022 走看看