📄 initdb.c
字号:
static const int conns[] = {100, 50, 40, 30, 20, 10}; static const int len = sizeof(conns) / sizeof(int); int i, status; printf(_("selecting default max_connections ... ")); fflush(stdout); for (i = 0; i < len; i++) { snprintf(cmd, sizeof(cmd), "%s\"%s\" -boot -x0 %s " "-c shared_buffers=%d -c max_connections=%d template1 " "< \"%s\" > \"%s\" 2>&1%s", SYSTEMQUOTE, backend_exec, boot_options, conns[i] * 5, conns[i], DEVNULL, DEVNULL, SYSTEMQUOTE); status = system(cmd); if (status == 0) break; } if (i >= len) i = len - 1; n_connections = conns[i]; printf("%d\n", n_connections);}/* * check how many buffers we can run with */static voidtest_buffers(void){ char cmd[MAXPGPATH]; static const int bufs[] = {1000, 900, 800, 700, 600, 500, 400, 300, 200, 100, 50}; static const int len = sizeof(bufs) / sizeof(int); int i, status; printf(_("selecting default shared_buffers ... ")); fflush(stdout); for (i = 0; i < len; i++) { snprintf(cmd, sizeof(cmd), "%s\"%s\" -boot -x0 %s " "-c shared_buffers=%d -c max_connections=%d template1 " "< \"%s\" > \"%s\" 2>&1%s", SYSTEMQUOTE, backend_exec, boot_options, bufs[i], n_connections, DEVNULL, DEVNULL, SYSTEMQUOTE); status = system(cmd); if (status == 0) break; } if (i >= len) i = len - 1; n_buffers = bufs[i]; printf("%d\n", n_buffers);}/* * set up all the config files */static voidsetup_config(void){ char **conflines; char repltok[100]; char path[MAXPGPATH]; fputs(_("creating configuration files ... "), stdout); fflush(stdout); /* postgresql.conf */ conflines = readfile(conf_file); snprintf(repltok, sizeof(repltok), "max_connections = %d", n_connections); conflines = replace_token(conflines, "#max_connections = 100", repltok); snprintf(repltok, sizeof(repltok), "shared_buffers = %d", n_buffers); conflines = replace_token(conflines, "#shared_buffers = 1000", repltok);#if DEF_PGPORT != 5432 snprintf(repltok, sizeof(repltok), "#port = %d", DEF_PGPORT); conflines = replace_token(conflines, "#port = 5432", repltok);#endif lc_messages = escape_quotes(lc_messages); snprintf(repltok, sizeof(repltok), "lc_messages = '%s'", lc_messages); conflines = replace_token(conflines, "#lc_messages = 'C'", repltok); lc_monetary = escape_quotes(lc_monetary); snprintf(repltok, sizeof(repltok), "lc_monetary = '%s'", lc_monetary); conflines = replace_token(conflines, "#lc_monetary = 'C'", repltok); lc_numeric = escape_quotes(lc_numeric); snprintf(repltok, sizeof(repltok), "lc_numeric = '%s'", lc_numeric); conflines = replace_token(conflines, "#lc_numeric = 'C'", repltok); lc_time = escape_quotes(lc_time); snprintf(repltok, sizeof(repltok), "lc_time = '%s'", lc_time); conflines = replace_token(conflines, "#lc_time = 'C'", repltok); snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data); writefile(path, conflines); chmod(path, 0600); free(conflines); /* pg_hba.conf */ conflines = readfile(hba_file);#ifndef HAVE_UNIX_SOCKETS conflines = filter_lines_with_token(conflines, "@remove-line-for-nolocal@");#else conflines = replace_token(conflines, "@remove-line-for-nolocal@", "");#endif#ifdef HAVE_IPV6 /* * Probe to see if there is really any platform support for IPv6, and * comment out the relevant pg_hba line if not. This avoids runtime * warnings if getaddrinfo doesn't actually cope with IPv6. Particularly * useful on Windows, where executables built on a machine with IPv6 may * have to run on a machine without. */ { struct addrinfo *gai_result; struct addrinfo hints; int err = 0;#ifdef WIN32 /* need to call WSAStartup before calling getaddrinfo */ WSADATA wsaData; err = WSAStartup(MAKEWORD(2, 2), &wsaData);#endif /* for best results, this code should match parse_hba() */ hints.ai_flags = AI_NUMERICHOST; hints.ai_family = PF_UNSPEC; hints.ai_socktype = 0; hints.ai_protocol = 0; hints.ai_addrlen = 0; hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; if (err != 0 || getaddrinfo("::1", NULL, &hints, &gai_result) != 0) conflines = replace_token(conflines, "host all all ::1", "#host all all ::1"); }#else /* !HAVE_IPV6 */ /* If we didn't compile IPV6 support at all, always comment it out */ conflines = replace_token(conflines, "host all all ::1", "#host all all ::1");#endif /* HAVE_IPV6 */ /* Replace default authentication methods */ conflines = replace_token(conflines, "@authmethod@", authmethod); conflines = replace_token(conflines, "@authcomment@", strcmp(authmethod, "trust") ? "" : AUTHTRUST_WARNING); snprintf(path, sizeof(path), "%s/pg_hba.conf", pg_data); writefile(path, conflines); chmod(path, 0600); free(conflines); /* pg_ident.conf */ conflines = readfile(ident_file); snprintf(path, sizeof(path), "%s/pg_ident.conf", pg_data); writefile(path, conflines); chmod(path, 0600); free(conflines); check_ok();}/* * run the BKI script in bootstrap mode to create template1 */static voidbootstrap_template1(char *short_version){ PG_CMD_DECL; char **line; char *talkargs = ""; char **bki_lines; char headerline[MAXPGPATH]; printf(_("creating template1 database in %s/base/1 ... "), pg_data); fflush(stdout); if (debug) talkargs = "-d 5"; bki_lines = readfile(bki_file); /* Check that bki file appears to be of the right version */ snprintf(headerline, sizeof(headerline), "# PostgreSQL %s\n", short_version); if (strcmp(headerline, *bki_lines) != 0) { fprintf(stderr, _("%s: input file \"%s\" does not belong to PostgreSQL %s\n" "Check your installation or specify the correct path " "using the option -L.\n"), progname, bki_file, PG_VERSION); exit_nicely(); } bki_lines = replace_token(bki_lines, "POSTGRES", username); bki_lines = replace_token(bki_lines, "ENCODING", encodingid); /* * Pass correct LC_xxx environment to bootstrap. * * The shell script arranged to restore the LC settings afterwards, but * there doesn't seem to be any compelling reason to do that. */ snprintf(cmd, sizeof(cmd), "LC_COLLATE=%s", lc_collate); putenv(xstrdup(cmd)); snprintf(cmd, sizeof(cmd), "LC_CTYPE=%s", lc_ctype); putenv(xstrdup(cmd)); unsetenv("LC_ALL"); /* Also ensure backend isn't confused by this environment var: */ unsetenv("PGCLIENTENCODING"); snprintf(cmd, sizeof(cmd), "\"%s\" -boot -x1 %s %s template1", backend_exec, boot_options, talkargs); PG_CMD_OPEN; for (line = bki_lines; *line != NULL; line++) { PG_CMD_PUTS(*line); free(*line); } PG_CMD_CLOSE; free(bki_lines); check_ok();}/* * set up the shadow password table */static voidsetup_auth(void){ PG_CMD_DECL; char **line; static char *pg_authid_setup[] = { /* * Create triggers to ensure manual updates to shared catalogs will be * reflected into their "flat file" copies. */ "CREATE TRIGGER pg_sync_pg_database " " AFTER INSERT OR UPDATE OR DELETE ON pg_database " " FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n", "CREATE TRIGGER pg_sync_pg_authid " " AFTER INSERT OR UPDATE OR DELETE ON pg_authid " " FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n", "CREATE TRIGGER pg_sync_pg_auth_members " " AFTER INSERT OR UPDATE OR DELETE ON pg_auth_members " " FOR EACH STATEMENT EXECUTE PROCEDURE flatfile_update_trigger();\n", /* * The authid table shouldn't be readable except through views, to * ensure passwords are not publicly visible. */ "REVOKE ALL on pg_authid FROM public;\n", NULL }; fputs(_("initializing pg_authid ... "), stdout); fflush(stdout); snprintf(cmd, sizeof(cmd), "\"%s\" %s template1 >%s", backend_exec, backend_options, DEVNULL); PG_CMD_OPEN; for (line = pg_authid_setup; *line != NULL; line++) PG_CMD_PUTS(*line); PG_CMD_CLOSE; check_ok();}/* * get the superuser password if required, and call postgres to set it */static voidget_set_pwd(void){ PG_CMD_DECL; char *pwd1, *pwd2; char pwdpath[MAXPGPATH]; struct stat statbuf; if (pwprompt) { /* * Read password from terminal */ pwd1 = simple_prompt("Enter new superuser password: ", 100, false); pwd2 = simple_prompt("Enter it again: ", 100, false); if (strcmp(pwd1, pwd2) != 0) { fprintf(stderr, _("Passwords didn't match.\n")); exit_nicely(); } free(pwd2); } else { /* * 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. */ FILE *pwf = fopen(pwfilename, "r"); char pwdbuf[MAXPGPATH]; int i; if (!pwf) { fprintf(stderr, _("%s: could not open file \"%s\" for reading: %s\n"), progname, pwfilename, strerror(errno)); exit_nicely(); } if (!fgets(pwdbuf, sizeof(pwdbuf), pwf)) { fprintf(stderr, _("%s: could not read password from file \"%s\": %s\n"), progname, pwfilename, strerror(errno)); exit_nicely(); } fclose(pwf); i = strlen(pwdbuf); while (i > 0 && (pwdbuf[i - 1] == '\r' || pwdbuf[i - 1] == '\n')) pwdbuf[--i] = '\0'; pwd1 = xstrdup(pwdbuf); } printf(_("setting password ... ")); fflush(stdout); snprintf(cmd, sizeof(cmd), "\"%s\" %s template1 >%s", backend_exec, backend_options, DEVNULL); PG_CMD_OPEN; PG_CMD_PRINTF2("ALTER USER \"%s\" WITH PASSWORD '%s';\n", username, pwd1); PG_CMD_CLOSE; check_ok(); snprintf(pwdpath, sizeof(pwdpath), "%s/global/pg_auth", pg_data); if (stat(pwdpath, &statbuf) != 0 || !S_ISREG(statbuf.st_mode)) { fprintf(stderr, _("%s: The password file was not generated. " "Please report this problem.\n"), progname); exit_nicely(); }}/* * toast sys tables */static voidunlimit_systables(void){ PG_CMD_DECL; char **line; static char *systables_setup[] = { "ALTER TABLE pg_attrdef CREATE TOAST TABLE;\n", "ALTER TABLE pg_authid CREATE TOAST TABLE;\n", "ALTER TABLE pg_constraint CREATE TOAST TABLE;\n", "ALTER TABLE pg_database CREATE TOAST TABLE;\n", "ALTER TABLE pg_description CREATE TOAST TABLE;\n", "ALTER TABLE pg_proc CREATE TOAST TABLE;\n", "ALTER TABLE pg_rewrite CREATE TOAST TABLE;\n", "ALTER TABLE pg_statistic CREATE TOAST TABLE;\n", NULL }; fputs(_("enabling unlimited row size for system tables ... "), stdout); fflush(stdout); snprintf(cmd, sizeof(cmd), "\"%s\" %s template1 >%s", backend_exec, backend_options, DEVNULL); PG_CMD_OPEN; for (line = systables_setup; *line != NULL; line++) PG_CMD_PUTS(*line); PG_CMD_CLOSE; check_ok();}/* * set up pg_depend */static voidsetup_depend(void){ PG_CMD_DECL; char **line; static char *pg_depend_setup[] = { /* * Make PIN entries in pg_depend for all objects made so far in the * tables that the dependency code handles. This is overkill (the * system doesn't really depend on having every last weird datatype, * for instance) but generating only the minimum required set of * dependencies seems hard. * * Note that we deliberately do not pin the system views, which * haven't been created yet. * * First delete any already-made entries; PINs override all else, and * must be the only entries for their objects. */ "DELETE FROM pg_depend;\n", "VACUUM pg_depend;\n", "DELETE FROM pg_shdepend;\n", "VACUUM pg_shdepend;\n", "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " " FROM pg_class;\n", "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " " FROM pg_proc;\n", "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " " FROM pg_type;\n", "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " " FROM pg_cast;\n", "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " " FROM pg_constraint;\n", "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " " FROM pg_attrdef;\n", "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " " FROM pg_language;\n", "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " " FROM pg_operator;\n", "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " " FROM pg_opclass;\n", "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " " FROM pg_rewrite;\n", "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " " FROM pg_trigger;\n", /* * restriction here to avoid pinning the public namespace */ "INSERT INTO pg_depend SELECT 0,0,0, tableoid,oid,0, 'p' " " FROM pg_namespace " " WHERE nspname LIKE 'pg%';\n", "INSERT INTO pg_shdepend SELECT 0, 0, 0, tableoid, oid, 'p' " " FROM pg_authid;\n", NULL }; fputs(_("initializing dependencies ... "), stdout); fflush(stdout); snprintf(cmd, sizeof(cmd), "\"%s\" %s template1 >%s", backend_exec, backend_options, DEVNULL); PG_CMD_OPEN; for (line = pg_depend_setup; *line != NULL; line++) PG_CMD_PUTS(*line); PG_CMD_CLOSE; check_ok();}/* * set up system views */static voidsetup_sysviews(void){ PG_CMD_DECL; char **line; char **sysviews_setup; fputs(_("creating system views ... "), stdout);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -