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\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