PostgreSQL数据库集簇初始化——initdb初始化数据库(创建配置文件)
测试当前服务器系统性能,由测试结果创建配置文件postgresql.conf、pg_hba.conf、pg_ident.conf,并对其中定义的参数做一些设置。主要执行流程如下代码所示。
1 /* Top level PG_VERSION is checked by bootstrapper, so make it first */ 2 set_short_version(short_version, NULL); 3 /* Select suitable configuration settings */ 4 set_null_conf(); 5 test_config_settings(); 6 /* Now create all the text config files */ 7 setup_config();
向数据目录中输出PG_VERSION文件,如果extrapath不为NULL,则将其写入数据目录的子目录。通过fprintf(version_file, "%s\n", short_version)向PG_VERSION文件中输出short_versioin。
1 static void set_short_version(char *short_version, char *extrapath) { 2 FILE *version_file; 3 char *path; 4 if (extrapath == NULL) { 5 path = pg_malloc(strlen(pg_data) + 12); 6 sprintf(path, "%s/PG_VERSION", pg_data); 7 } else { 8 path = pg_malloc(strlen(pg_data) + strlen(extrapath) + 13); 9 sprintf(path, "%s/%s/PG_VERSION", pg_data, extrapath); 10 } 11 version_file = fopen(path, PG_BINARY_W); 12 if (version_file == NULL) { 13 fprintf(stderr, _("%s: could not open file \"%s\" for writing: %s\n"), progname, path, strerror(errno)); 14 exit_nicely(); 15 } 16 if (fprintf(version_file, "%s\n", short_version) < 0 || fclose(version_file)) { 17 fprintf(stderr, _("%s: could not write file \"%s\": %s\n"), progname, path, strerror(errno)); 18 exit_nicely(); 19 } 20 free(path); 21 }
测试当前服务器系统性能,由测试结果创建配置文件postgresql.conf、pg_hba.conf、pg_ident.conf,并对其中定义的参数做一些设置,这些功能主要通过函数set_null_conf()和test_config_settings()来实现。
set_null_conf函数建立空配置文件,这样我们可以通过启动test后端来检查配置设置。
1 static void set_null_conf(void) { 2 FILE *conf_file; 3 char *path; 4 path = pg_malloc(strlen(pg_data) + 17); 5 sprintf(path, "%s/postgresql.conf", pg_data); 6 conf_file = fopen(path, PG_BINARY_W); 7 if (conf_file == NULL) { 8 fprintf(stderr, _("%s: could not open file \"%s\" for writing: %s\n"), progname, path, strerror(errno)); 9 exit_nicely(); 10 } 11 if (fclose(conf_file)) { 12 fprintf(stderr, _("%s: could not write file \"%s\": %s\n"), progname, path, strerror(errno)); 13 exit_nicely(); 14 } 15 free(path); 16 }
test_config_setting函数测试服务器所能提供的指定配置设置。先探测max_connections最大连接数,在探测共享缓冲大小。测试服务器连接使用的命令:"backend_exec" --boot -x0 boot_options -c max_connenctions=test_conns -c shared_buffers=test_buffers < "DEVNULL" > "DEVNULL" 2>&1。测试服务器共享缓冲区大小命令:backend_exec" --boot -x0 boot_options -c max_connenctions=n_connections -c shared_buffers=test_buffers < "DEVNULL" > "DEVNULL" 2>&1。
1 static void test_config_settings(void) { 2 /* This macro defines the minimum shared_buffers we want for a given max_connections value. The arrays show the settings to try. */ 3 #define MIN_BUFS_FOR_CONNS(nconns) ((nconns) * 10) 4 static const int trial_conns[] = {100, 50, 40, 30, 20, 10}; 5 static const int trial_bufs[] = { 6 4096, 3584, 3072, 2560, 2048, 1536, 7 1000, 900, 800, 700, 600, 500, 8 400, 300, 200, 100, 50 9 }; 10 11 char cmd[MAXPGPATH]; 12 const int connslen = sizeof(trial_conns) / sizeof(int); 13 const int bufslen = sizeof(trial_bufs) / sizeof(int); 14 int i,status,test_conns,test_buffs,ok_buffers = 0; 15 16 printf(_("selecting default max_connections ... ")); 17 fflush(stdout); 18 19 for (i = 0; i < connslen; i++){ 20 test_conns = trial_conns[i]; 21 test_buffs = MIN_BUFS_FOR_CONNS(test_conns); 22 snprintf(cmd, sizeof(cmd), SYSTEMQUOTE "\"%s\" --boot -x0 %s " "-c max_connections=%d " "-c shared_buffers=%d " "< \"%s\" > \"%s\" 2>&1" SYSTEMQUOTE, backend_exec, boot_options, test_conns, test_buffs, DEVNULL, DEVNULL); 23 status = system(cmd); 24 if (status == 0){ 25 ok_buffers = test_buffs; 26 break; 27 } 28 } 29 if (i >= connslen) 30 i = connslen - 1; 31 n_connections = trial_conns[i]; 32 printf("%d\n", n_connections); 33 printf(_("selecting default shared_buffers ... ")); 34 fflush(stdout); 35 for (i = 0; i < bufslen; i++){ 36 /* Use same amount of memory, independent of BLCKSZ */ 37 test_buffs = (trial_bufs[i] * 8192) / BLCKSZ; 38 if (test_buffs <= ok_buffers){ 39 test_buffs = ok_buffers; 40 break; 41 } 42 snprintf(cmd, sizeof(cmd), SYSTEMQUOTE "\"%s\" --boot -x0 %s " "-c max_connections=%d " "-c shared_buffers=%d " "< \"%s\" > \"%s\" 2>&1" SYSTEMQUOTE, backend_exec, boot_options, n_connections, test_buffs, DEVNULL, DEVNULL); 43 status = system(cmd); 44 if (status == 0) 45 break; 46 } 47 n_buffers = test_buffs; 48 if ((n_buffers * (BLCKSZ / 1024)) % 1024 == 0) 49 printf("%dMB\n", (n_buffers * (BLCKSZ / 1024)) / 1024); 50 else 51 printf("%dkB\n", n_buffers * (BLCKSZ / 1024)); 52 }
setup_config函数创建所有的配置文件
1 static void setup_config(void) { 2 char **conflines; 3 char repltok[100]; 4 char path[MAXPGPATH]; 5 fputs(_("creating configuration files ... "), stdout); 6 fflush(stdout); 7 /* postgresql.conf */ 8 conflines = readfile(conf_file); 9 snprintf(repltok, sizeof(repltok), "max_connections = %d", n_connections); 10 conflines = replace_token(conflines, "#max_connections = 100", repltok); 11 if ((n_buffers * (BLCKSZ / 1024)) % 1024 == 0) 12 snprintf(repltok, sizeof(repltok), "shared_buffers = %dMB", (n_buffers * (BLCKSZ / 1024)) / 1024); 13 else 14 snprintf(repltok, sizeof(repltok), "shared_buffers = %dkB", n_buffers * (BLCKSZ / 1024)); 15 conflines = replace_token(conflines, "#shared_buffers = 32MB", repltok); 16 #if DEF_PGPORT != 5432 17 snprintf(repltok, sizeof(repltok), "#port = %d", DEF_PGPORT); 18 conflines = replace_token(conflines, "#port = 5432", repltok); 19 #endif 20 snprintf(repltok, sizeof(repltok), "lc_messages = '%s'", escape_quotes(lc_messages)); 21 conflines = replace_token(conflines, "#lc_messages = 'C'", repltok); 22 snprintf(repltok, sizeof(repltok), "lc_monetary = '%s'",escape_quotes(lc_monetary)); 23 conflines = replace_token(conflines, "#lc_monetary = 'C'", repltok); 24 snprintf(repltok, sizeof(repltok), "lc_numeric = '%s'",escape_quotes(lc_numeric)); 25 conflines = replace_token(conflines, "#lc_numeric = 'C'", repltok); 26 snprintf(repltok, sizeof(repltok), "lc_time = '%s'", escape_quotes(lc_time)); 27 conflines = replace_token(conflines, "#lc_time = 'C'", repltok); 28 29 switch (locale_date_order(lc_time)){ 30 case DATEORDER_YMD: 31 strcpy(repltok, "datestyle = 'iso, ymd'"); 32 break; 33 case DATEORDER_DMY: 34 strcpy(repltok, "datestyle = 'iso, dmy'"); 35 break; 36 case DATEORDER_MDY: 37 default: 38 strcpy(repltok, "datestyle = 'iso, mdy'"); 39 break; 40 } 41 conflines = replace_token(conflines, "#datestyle = 'iso, mdy'", repltok); 42 43 snprintf(repltok, sizeof(repltok),"default_text_search_config = 'pg_catalog.%s'",escape_quotes(default_text_search_config)); 44 conflines = replace_token(conflines, "#default_text_search_config = 'pg_catalog.simple'", repltok); 45 snprintf(path, sizeof(path), "%s/postgresql.conf", pg_data); 46 47 writefile(path, conflines); 48 chmod(path, 0600); 49 free(conflines); 50 51 /* pg_hba.conf */ 52 conflines = readfile(hba_file); 53 #ifndef HAVE_UNIX_SOCKETS 54 conflines = filter_lines_with_token(conflines, "@remove-line-for-nolocal@"); 55 #else 56 conflines = replace_token(conflines, "@remove-line-for-nolocal@", ""); 57 #endif 58 #ifdef HAVE_IPV6 59 /* 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. */ 60 { 61 struct addrinfo *gai_result; 62 struct addrinfo hints; 63 int err = 0; 64 #ifdef WIN32 65 /* need to call WSAStartup before calling getaddrinfo */ 66 WSADATA wsaData; 67 err = WSAStartup(MAKEWORD(2, 2), &wsaData); 68 #endif 69 /* for best results, this code should match parse_hba() */ 70 hints.ai_flags = AI_NUMERICHOST; 71 hints.ai_family = PF_UNSPEC; 72 hints.ai_socktype = 0; 73 hints.ai_protocol = 0; 74 hints.ai_addrlen = 0; 75 hints.ai_canonname = NULL; 76 hints.ai_addr = NULL; 77 hints.ai_next = NULL; 78 if (err != 0 || 79 getaddrinfo("::1", NULL, &hints, &gai_result) != 0) 80 conflines = replace_token(conflines, 81 "host all all ::1", 82 "#host all all ::1"); 83 } 84 #else /* !HAVE_IPV6 */ 85 /* If we didn't compile IPV6 support at all, always comment it out */ 86 conflines = replace_token(conflines, 87 "host all all ::1", 88 "#host all all ::1"); 89 #endif /* HAVE_IPV6 */ 90 91 /* Replace default authentication methods */ 92 conflines = replace_token(conflines, "@authmethod@", authmethod); 93 94 conflines = replace_token(conflines,"@authcomment@",strcmp(authmethod, "trust") ? "" : AUTHTRUST_WARNING); 95 snprintf(path, sizeof(path), "%s/pg_hba.conf", pg_data); 96 writefile(path, conflines); 97 chmod(path, 0600); 98 free(conflines); 99 100 /* pg_ident.conf */ 101 conflines = readfile(ident_file); 102 snprintf(path, sizeof(path), "%s/pg_ident.conf", pg_data); 103 writefile(path, conflines); 104 chmod(path, 0600); 105 free(conflines); 106 check_ok(); 107 }