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 NULL18 };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 NULL53 };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 }