1. 程式人生 > 資料庫 >PostgreSQL資料庫集簇初始化——initdb初始化資料庫(檢查系統配置檔案)

PostgreSQL資料庫集簇初始化——initdb初始化資料庫(檢查系統配置檔案)

  設定環境變數(pg_data等),獲取系統配置檔案的原始檔路徑(postgres.bki、postgresql.conf. sample等檔案),並檢查該路徑下各檔案的可用性。

一、設定環境變數

  set_pglocale_pgservice函式設定應用指定的locale和service目錄。對於第一個if判斷,如果在後端postgres中,則不需要設定LC_ALL,目前在initdb中則執行setlocale(LC_ALL, "")。如果定義了ENABLE_NLS,則需要呼叫get_locale_path,如果getenv("PGLOCALEDIR")為NULL,需要將PGLOCALEDIR和路徑放入extern char **environ所指向的記憶體,用於後續設定環境變數。如果getenv("PGSYSCONFDIR")為NULL,需要將PGSYSCONFDIR和路徑放入extern char **environ所指向的記憶體,用於後續設定環境變數。

 1 void set_pglocale_pgservice(const char *argv0, const char *app){
 2     char        path[MAXPGPATH];
 3     char        my_exec_path[MAXPGPATH];
 4     char        env_path[MAXPGPATH + sizeof("PGSYSCONFDIR=")];    /* longer than PGLOCALEDIR */
 5     /* don't set LC_ALL in the backend */
 6     if (strcmp(app, PG_TEXTDOMAIN("postgres")) != 0)
 7         setlocale(LC_ALL, "");
 8     if (find_my_exec(argv0, my_exec_path) < 0)
 9         return;
10 #ifdef ENABLE_NLS
11     get_locale_path(my_exec_path, path);
12     bindtextdomain(app, path);
13     textdomain(app);
14     if (getenv("PGLOCALEDIR") == NULL){
15         /* set for libpq to use */
16         snprintf(env_path, sizeof(env_path), "PGLOCALEDIR=%s", path);
17         canonicalize_path(env_path + 12);
18         putenv(strdup(env_path));
19     }
20 #endif
21     if (getenv("PGSYSCONFDIR") == NULL){
22         get_etc_path(my_exec_path, path);
23         /* set for libpq to use */
24         snprintf(env_path, sizeof(env_path), "PGSYSCONFDIR=%s", path);
25         canonicalize_path(env_path + 13);
26         putenv(strdup(env_path));
27     }
28 }

  如果pg_data為空的話,則需要設定pg_data,後續的程式就是用於處理這樣的情況,從環境變數取出PGDATA。這裡屬於引數處理部分,因為可以不指定資料目錄,通過指定環境變數PGDATA來指定資料目錄。

 1     if (strlen(pg_data) == 0){
 2         pgdenv = getenv("PGDATA");
 3         if (pgdenv && strlen(pgdenv)){
 4             /* PGDATA found */
 5             pg_data = xstrdup(pgdenv);
 6         }else{
 7             fprintf(stderr,
 8                     _("%s: no data directory specified\n"
 9                       "You must identify the directory where the data for this database system\n"
10                       "will reside.  Do this with either the invocation option -D or the\n"
11                       "environment variable PGDATA.\n"),
12                     progname);
13             exit(1);
14         }
15     }

  通過設定PGDATA環境變數來傳送資料目錄給其他程式,而不通過命令列以避免windows的dumb quoting檔案

1     /* we have to set PGDATA for postgres rather than pass it on the command
2      * line to avoid dumb quoting problems on Windows, and we would especially
3      * need quotes otherwise on Windows because paths there are most likely to
4      * have embedded spaces. */
5     pgdenv = pg_malloc(8 + strlen(pg_data));
6     sprintf(pgdenv, "PGDATA=%s", pg_data);
7     putenv(pgdenv);

 

二、獲取系統配置檔案的原始檔路徑

  提取bin的路徑儲存到bin_path中,提取share的路徑儲存到share_path中(下面程式碼中沒有列出),獲取執行程式的使用者id

 1     if ((ret = find_other_exec(argv[0], "postgres", PG_BACKEND_VERSIONSTR, backend_exec)) < 0){
 2         char        full_path[MAXPGPATH];
 3         if (find_my_exec(argv[0], full_path) < 0)
 4             strlcpy(full_path, progname, sizeof(full_path));
 5         if (ret == -1)
 6             fprintf(stderr,
 7                     _("The program \"postgres\" is needed by %s "
 8                       "but was not found in the\n"
 9                       "same directory as \"%s\".\n"
10                       "Check your installation.\n"),
11                     progname, full_path);
12         else
13             fprintf(stderr,
14                     _("The program \"postgres\" was found by \"%s\"\n"
15                       "but was not the same version as %s.\n"
16                       "Check your installation.\n"),
17                     full_path, progname);
18         exit(1);
19     }
/* store binary directory */
strcpy(bin_path, backend_exec);
*last_dir_separator(bin_path) = '\0';
canonicalize_path(bin_path);
...
  effective_user = get_id();
if (strlen(username) == 0)
  username = effective_user;

  設定初始化過程中的需要使用的一些檔案,將這些檔案的檔名設定到程式變數中。

 1     set_input(&bki_file, "postgres.bki");
 2     set_input(&desc_file, "postgres.description");
 3     set_input(&shdesc_file, "postgres.shdescription");
 4     set_input(&hba_file, "pg_hba.conf.sample");
 5     set_input(&ident_file, "pg_ident.conf.sample");
 6     set_input(&conf_file, "postgresql.conf.sample");
 7     set_input(&conversion_file, "conversion_create.sql");
 8     set_input(&dictionary_file, "snowball_create.sql");
 9     set_input(&info_schema_file, "information_schema.sql");
10     set_input(&features_file, "sql_features.txt");
11     set_input(&system_views_file, "system_views.sql");
12         ...
13     check_input(bki_file);
14     check_input(desc_file);
15     check_input(shdesc_file);
16     check_input(hba_file);
17     check_input(ident_file);
18     check_input(conf_file);
19     check_input(conversion_file);
20     check_input(dictionary_file);
21     check_input(info_schema_file);
22     check_input(features_file);
23     check_input(system_views_file);

 

三、設定本地化locale

  先需要執行setlocale(LC_ALL,""),呼叫setlocales()函式

 1 static void setlocales(void){
 2     /* set empty lc_* values to locale config if set */
 3     if (strlen(locale) > 0) {
 4         if (strlen(lc_ctype) == 0)
 5             lc_ctype = locale;
 6         if (strlen(lc_collate) == 0)
 7             lc_collate = locale;
 8         if (strlen(lc_numeric) == 0)
 9             lc_numeric = locale;
10         if (strlen(lc_time) == 0)
11             lc_time = locale;
12         if (strlen(lc_monetary) == 0)
13             lc_monetary = locale;
14         if (strlen(lc_messages) == 0)
15             lc_messages = locale;
16     }
17     /* override absent/invalid config settings from initdb's locale settings */
18     if (strlen(lc_ctype) == 0 || !check_locale_name(lc_ctype))
19         lc_ctype = xstrdup(setlocale(LC_CTYPE, NULL));
20     if (strlen(lc_collate) == 0 || !check_locale_name(lc_collate))
21         lc_collate = xstrdup(setlocale(LC_COLLATE, NULL));
22     if (strlen(lc_numeric) == 0 || !check_locale_name(lc_numeric))
23         lc_numeric = xstrdup(setlocale(LC_NUMERIC, NULL));
24     if (strlen(lc_time) == 0 || !check_locale_name(lc_time))
25         lc_time = xstrdup(setlocale(LC_TIME, NULL));
26     if (strlen(lc_monetary) == 0 || !check_locale_name(lc_monetary))
27         lc_monetary = xstrdup(setlocale(LC_MONETARY, NULL));
28     if (strlen(lc_messages) == 0 || !check_locale_name(lc_messages))
29 #if defined(LC_MESSAGES) && !defined(WIN32)
30     {
31         /* when available get the current locale setting */
32         lc_messages = xstrdup(setlocale(LC_MESSAGES, NULL));
33     }
34 #else
35     {
36         /* when not available, get the CTYPE setting */
37         lc_messages = xstrdup(setlocale(LC_CTYPE, NULL));
38     }
39 #endif
40 }

  檢查encoding設定,如果沒有設定,就進行設定

 1     if (strlen(encoding) == 0){
 2         int            ctype_enc;
 3         ctype_enc = pg_get_encoding_from_locale(lc_ctype);
 4         if (ctype_enc == PG_SQL_ASCII &&
 5             !(pg_strcasecmp(lc_ctype, "C") == 0 ||
 6               pg_strcasecmp(lc_ctype, "POSIX") == 0)){
 7             /* Hmm, couldn't recognize the locale's codeset */
 8             fprintf(stderr, _("%s: could not find suitable encoding for locale %s\n"),
 9                     progname, lc_ctype);
10             fprintf(stderr, _("Rerun %s with the -E option.\n"), progname);
11             fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
12                     progname);
13             exit(1);
14         }
15         else if (!pg_valid_server_encoding_id(ctype_enc)){
16             /* We recognized it, but it's not a legal server encoding */
17             fprintf(stderr,
18                     _("%s: locale %s requires unsupported encoding %s\n"),
19                     progname, lc_ctype, pg_encoding_to_char(ctype_enc));
20             fprintf(stderr,
21                   _("Encoding %s is not allowed as a server-side encoding.\n"
22                     "Rerun %s with a different locale selection.\n"),
23                     pg_encoding_to_char(ctype_enc), progname);
24             exit(1);
25         }else{
26             encodingid = encodingid_to_string(ctype_enc);
27             printf(_("The default database encoding has accordingly been set to %s.\n"),
28                    pg_encoding_to_char(ctype_enc));
29         }
30     }
31     else
32         encodingid = get_encoding_id(encoding);
33     user_enc = atoi(encodingid);
34     if (!check_locale_encoding(lc_ctype, user_enc) ||
35         !check_locale_encoding(lc_collate, user_enc))
36         exit(1);                /* check_locale_encoding printed the error */
37     if (strlen(default_text_search_config) == 0)
38     {
39         default_text_search_config = find_matching_ts_config(lc_ctype);
40         if (default_text_search_config == NULL)
41         {
42             printf(_("%s: could not find suitable text search configuration for locale %s\n"),
43                    progname, lc_ctype);
44             default_text_search_config = "simple";
45         }
46     }
47     else
48     {
49         const char *checkmatch = find_matching_ts_config(lc_ctype);
50 
51         if (checkmatch == NULL)
52         {
53             printf(_("%s: warning: suitable text search configuration for locale %s is unknown\n"),
54                    progname, lc_ctype);
55         }
56         else if (strcmp(checkmatch, default_text_search_config) != 0)
57         {
58             printf(_("%s: warning: specified text search configuration \"%s\" might not match locale %s\n"),
59                    progname, default_text_search_config, lc_ctype);
60         }
61     }