数据库初始设置包括创建系统视图、系统表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 }