PostgreSQL数据库集簇初始化——initdb初始化数据库(数据库初始设置一)

  数据库初始设置包括创建系统视图、系统表TOAST表等,复制template1来创建template0和postgres,这些操作都用普通的SQL命令来完成。如下代码就是用于数据库初始设置。

 1     setup_auth();
 2     if (pwprompt || pwfilename)
 3         get_set_pwd();
 4     setup_depend();
 5     setup_sysviews();
 6     setup_description();
 7     setup_conversion();
 8     setup_dictionary();
 9     setup_privileges();
10     setup_schema();
11     vacuum_db();
12     make_template0();
13     make_postgres();

setup_auth函数建立shadow密码表,pg_authid_setup中的SQL语句用于为在pg_database表中进行插入完或更新或删除操作时创建触发器pg_sync_pg_database,对于每个语句执行过程flatfile_ipdate_trigger();为在pg_authid表中进行插入后或更新或删除操作时创建触发器pg_sync_pg_authid,对于每个语句执行过程flatfile_update_trigger();为在pg_auth_members表中进行插入后或更新或删除操作时创建触发器pg_sync_pg_auth_members,对于每个语句执行过程flatfile_update_trigger()。pg_authid表处理只能使用视图访问,以确保密码不能公开获取(REVOKE ALL on pg_authid FROM public)。

 1 static void setup_auth(void)  {
 2     PG_CMD_DECL;
 3     const char **line;
 4     static const char *pg_authid_setup[] = {
 5         /* Create triggers to ensure manual updates to shared catalogs will be reflected into their "flat file" copies.  */
 6         "CREATE TRIGGER pg_sync_pg_database "
 7         "  AFTER INSERT OR UPDATE OR DELETE ON pg_database "
 8         "  FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n",
 9         "CREATE TRIGGER pg_sync_pg_authid "
10         "  AFTER INSERT OR UPDATE OR DELETE ON pg_authid "
11         "  FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n",
12         "CREATE TRIGGER pg_sync_pg_auth_members "
13         "  AFTER INSERT OR UPDATE OR DELETE ON pg_auth_members "
14         "  FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n",
15         /* The authid table shouldn't be readable except through views, to ensure passwords are not publicly visible. */
16         "REVOKE ALL on pg_authid FROM public;\n",
17         NULL
18     };
19     fputs(_("initializing pg_authid ... "), stdout);
20     fflush(stdout);
21     snprintf(cmd, sizeof(cmd), "\"%s\" %s template1 >%s", backend_exec, backend_options, DEVNULL);
22     PG_CMD_OPEN;
23     for (line = pg_authid_setup; *line != NULL; line++)
24         PG_CMD_PUTS(*line);
25     PG_CMD_CLOSE;
26     check_ok();
27 }

get_set_pwd函数获取超级用户密码,调用postgres设置该密码。先判断是否是通过终端交互输入密码,或者通过文件读取密码。为用户创建密码ALTER USER \"%s\" WITH PASSWORD E'%s

 1 static void get_set_pwd(void) {
 2     PG_CMD_DECL;
 3     char       *pwd1, *pwd2;
 4     char        pwdpath[MAXPGPATH];
 5     struct stat statbuf;
 6     if (pwprompt){
 7         /* Read password from terminal */
 8         pwd1 = simple_prompt("Enter new superuser password: ", 100, false);
 9         pwd2 = simple_prompt("Enter it again: ", 100, false);
10         if (strcmp(pwd1, pwd2) != 0){
11             fprintf(stderr, _("Passwords didn't match.\n"));
12             exit_nicely();
13         }
14         free(pwd2);
15     }else{
16         /* Read password from file Ideally this should insist that the file not be world-readable. However, this option is mainly intended for use on Windows where file permissions may not exist at all, so we'll skip the paranoia for now. */
17         FILE       *pwf = fopen(pwfilename, "r");
18         char        pwdbuf[MAXPGPATH];
19         int            i;
20         if (!pwf){
21             fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"),progname, pwfilename, strerror(errno));
22             exit_nicely();
23         }
24         if (!fgets(pwdbuf, sizeof(pwdbuf), pwf)){
25             fprintf(stderr, _("%s: could not read password from file \"%s\": %s\n"),progname, pwfilename, strerror(errno));
26             exit_nicely();
27         }
28         fclose(pwf);
29         i = strlen(pwdbuf);
30         while (i > 0 && (pwdbuf[i - 1] == '\r' || pwdbuf[i - 1] == '\n'))
31             pwdbuf[--i] = '\0';
32         pwd1 = xstrdup(pwdbuf);
33     }
34     printf(_("setting password ... "));
35     fflush(stdout);
36     snprintf(cmd, sizeof(cmd), "\"%s\" %s template1 >%s", backend_exec, backend_options, DEVNULL);
37     PG_CMD_OPEN;
38     PG_CMD_PRINTF2("ALTER USER \"%s\" WITH PASSWORD E'%s';\n",username, escape_quotes(pwd1));
39     /* MM: pwd1 is no longer needed, freeing it */
40     free(pwd1);
41     PG_CMD_CLOSE;
42     check_ok();
43     snprintf(pwdpath, sizeof(pwdpath), "%s/global/pg_auth", pg_data);
44     if (stat(pwdpath, &statbuf) != 0 ||!S_ISREG(statbuf.st_mode)){
45         fprintf(stderr,_("%s: The password file was not generated. " "Please report this problem.\n"),progname);
46         exit_nicely();
47     }
48 }

setup_depend函数用于设置pg_depend表,先从pg_depend表中删除已有的条目,并进行VACUUM,从pg_shdepend表中删除已有条目,并进行VACUUM,从pg_class中取出tableoid和oid并处理成pg_depend的条目,存入pg_depend表中,对pg_proc、pg_type、pg_cast、pg_constraint、pg_attrdef等表进行处理。

 1 static void setup_depend(void) {
 2     PG_CMD_DECL;
 3     const char **line;
 4     static const char *pg_depend_setup[] = {
 5         /* First delete any already-made entries */
 6         "DELETE FROM pg_depend;\n",
 7         "VACUUM pg_depend;\n",
 8         "DELETE FROM pg_shdepend;\n",
 9         "VACUUM pg_shdepend;\n",
10         "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
11         " FROM pg_class;\n",
12         "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
13         " FROM pg_proc;\n",
14         "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
15         " FROM pg_type;\n",
16         "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
17         " FROM pg_cast;\n",
18         "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
19         " FROM pg_constraint;\n",
20         "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
21         " FROM pg_attrdef;\n",
22         "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
23         " FROM pg_language;\n",
24         "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
25         " FROM pg_operator;\n",
26         "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
27         " FROM pg_opclass;\n",
28         "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
29         " FROM pg_opfamily;\n",
30         "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
31         " FROM pg_amop;\n",
32         "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
33         " FROM pg_amproc;\n",
34         "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
35         " FROM pg_rewrite;\n",
36         "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
37         " FROM pg_trigger;\n",
38         /* restriction here to avoid pinning the public namespace */
39         "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
40         " FROM pg_namespace "
41         "    WHERE nspname LIKE 'pg%';\n",
42         "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
43         " FROM pg_ts_parser;\n",
44         "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
45         " FROM pg_ts_dict;\n",
46         "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
47         " FROM pg_ts_template;\n",
48         "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' "
49         " FROM pg_ts_config;\n",
50         "INSERT INTO pg_shdepend SELECT 0,0,0,0, tableoid,oid, 'p' "
51         " FROM pg_authid;\n",
52         NULL
53     };
54     fputs(_("initializing dependencies ... "), stdout);
55     fflush(stdout);
56     snprintf(cmd, sizeof(cmd), "\"%s\" %s template1 >%s", backend_exec, backend_options, DEVNULL);
57     PG_CMD_OPEN;
58     for (line = pg_depend_setup; *line != NULL; line++)
59         PG_CMD_PUTS(*line);
60     PG_CMD_CLOSE;
61     check_ok();
62 }

 

posted @ 2020-12-29 12:51  肥叔菌  阅读(962)  评论(0编辑  收藏  举报