PostgreSQL数据库集簇初始化——initdb初始化数据库(数据库template1)

  在bootstrap模式下创建数据库template1,存储在数据目录的子目录base/1/中。

1 /* Bootstrap template1 */
2 bootstrap_template1(short_version);
3 /* Make the per-database PG_VERSION for template1 only after init'ing it */
4 set_short_version(short_version, "base/1");

headerline数组中存储的内容为# PostgreSQL short_version\n,用于和*bki_lines中的内容进行对比,确保读取的bki是正确的。下一步对bki进行读取,并根据之前配置的内容对bki_lines中的内容进行替换。cmd的内容为"backend_exec" --boot -x1 boot_options talkargs。

#define PG_CMD_DECL char cmd[MAXPGPATH]; FILE *cmdfd

#define PG_CMD_OPEN \
do { \
cmdfd = popen_check(cmd, "w"); \
  if (cmdfd == NULL) \
    exit_nicely(); /* message already printed by popen_check */ \
} while (0)

#define PG_CMD_PUTS(line) \
do { \
  if (fputs(line, cmdfd) < 0 || fflush(cmdfd) < 0) \
    output_failed = true, output_errno = errno; \
} while (0)

#define PG_CMD_CLOSE \
do { \
  if (pclose_check(cmdfd)) \
    exit_nicely(); /* message already printed by pclose_check */ \
} while (0)

 1 /* run the BKI script in bootstrap mode to create template1 */
 2 static void bootstrap_template1(char *short_version) {
 3     PG_CMD_DECL;
 4     char      **line;
 5     char       *talkargs = "";
 6     char      **bki_lines;
 7     char        headerline[MAXPGPATH];
 8     char        buf[64];
 9     printf(_("creating template1 database in %s/base/1 ... "), pg_data);
10     fflush(stdout);
11     if (debug)
12         talkargs = "-d 5";
13     bki_lines = readfile(bki_file);
14     /* Check that bki file appears to be of the right version */
15     snprintf(headerline, sizeof(headerline), "# PostgreSQL %s\n",short_version);
16     if (strcmp(headerline, *bki_lines) != 0){
17         fprintf(stderr,_("%s: input file \"%s\" does not belong to PostgreSQL %s\n" "Check your installation or specify the correct path " "using the option -L.\n"), progname, bki_file, PG_VERSION);
18         exit_nicely();
19     }
20 
21     /* Substitute for various symbols used in the BKI file */
22     sprintf(buf, "%d", NAMEDATALEN);
23     bki_lines = replace_token(bki_lines, "NAMEDATALEN", buf);
24     sprintf(buf, "%d", (int) sizeof(Pointer));
25     bki_lines = replace_token(bki_lines, "SIZEOF_POINTER", buf);
26     bki_lines = replace_token(bki_lines, "ALIGNOF_POINTER",  (sizeof(Pointer) == 4) ? "i" : "d");
27     bki_lines = replace_token(bki_lines, "FLOAT4PASSBYVAL",FLOAT4PASSBYVAL ? "true" : "false");
28     bki_lines = replace_token(bki_lines, "FLOAT8PASSBYVAL", FLOAT8PASSBYVAL ? "true" : "false");
29     bki_lines = replace_token(bki_lines, "POSTGRES",username);
30     bki_lines = replace_token(bki_lines, "ENCODING",encodingid);
31     bki_lines = replace_token(bki_lines, "LC_COLLATE",lc_collate);
32     bki_lines = replace_token(bki_lines, "LC_CTYPE", lc_ctype);
33 
34     /* Pass correct LC_xxx environment to bootstrap. The shell script arranged to restore the LC settings afterwards, but there doesn't seem to be any compelling reason to do that. */
35     snprintf(cmd, sizeof(cmd), "LC_COLLATE=%s", lc_collate);
36     putenv(xstrdup(cmd));
37     snprintf(cmd, sizeof(cmd), "LC_CTYPE=%s", lc_ctype);
38     putenv(xstrdup(cmd));
39     unsetenv("LC_ALL");
40 
41     /* Also ensure backend isn't confused by this environment var: */
42     unsetenv("PGCLIENTENCODING");
43     snprintf(cmd, sizeof(cmd), "\"%s\" --boot -x1 %s %s", backend_exec, boot_options, talkargs);
44 
45     PG_CMD_OPEN;
46     for (line = bki_lines; *line != NULL; line++){
47         PG_CMD_PUTS(*line);
48         free(*line);
49     }
50     PG_CMD_CLOSE;
51     free(bki_lines);
52     check_ok();
53 }

  popen_check使用了popen,popen()函数通过创建一个管道,调用fork()产生一个子进程,执行一个shell以运行命令来开启一个进程。这个管道必须由pclose()函数关闭,而不是fclose()函数。pclose()函数关闭标准I/O流,等待命令执行结束,然后返回shell的终止状态。如果shell不能被执行,则pclose()返回的终止状态与shell已执行exit一样。故使用popen产生子进程去执行comamnd中的命令。

 1 /* Open a subcommand with suitable error messaging */
 2 static FILE * popen_check(const char *command, const char *mode){
 3     FILE       *cmdfd;
 4     fflush(stdout);
 5     fflush(stderr);
 6     errno = 0;
 7     cmdfd = popen(command, mode);
 8     if (cmdfd == NULL)
 9         fprintf(stderr, _("%s: could not execute command \"%s\": %s\n"), progname, command, strerror(errno));
10     return cmdfd;
11 }

 

posted @ 2020-12-26 13:00  肥叔菌  阅读(457)  评论(0编辑  收藏  举报