1. 程式人生 > 資料庫 >PostgreSQL資料庫集簇初始化——initdb初始化資料庫(資料庫初始設定一)

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 }