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 }