1. 程式人生 > 實用技巧 >PostgreSQL資料庫集簇初始化——initdb初始化資料庫(資料庫初始設定二)

PostgreSQL資料庫集簇初始化——initdb初始化資料庫(資料庫初始設定二)

  資料庫初始設定包括建立系統檢視、系統表TOAST表等,複製template1來建立template0和postgres,這些操作都用普通的SQL命令來完成。

setup_sysviews函式建立系統檢視,從system_views_file指向的檔案讀取SQL,並控制子程序執行這些SQL。

 1 static void setup_sysviews(void) {
 2     PG_CMD_DECL;
 3     char      **line;
 4     char      **sysviews_setup;
 5     fputs(_("creating system views ... 
"), stdout); 6 fflush(stdout); 7 sysviews_setup = readfile(system_views_file); 8 /* We use -j here to avoid backslashing stuff in system_views.sql */ 9 snprintf(cmd, sizeof(cmd),"\"%s\" %s -j template1 >%s",backend_exec, backend_options,DEVNULL); 10 PG_CMD_OPEN; 11 for (line = sysviews_setup; *line != NULL; line++){
12 PG_CMD_PUTS(*line); 13 free(*line); 14 } 15 PG_CMD_CLOSE; 16 free(sysviews_setup); 17 check_ok(); 18 }

setup_description函式載入描述資料,程式碼中寫死了需要執行的SQL。

 1 static void setup_description(void){
 2     PG_CMD_DECL;
 3     fputs(_("loading system objects' descriptions ... 
"), stdout); 4 fflush(stdout); 5 snprintf(cmd, sizeof(cmd),"\"%s\" %s template1 >%s",backend_exec, backend_options,DEVNULL); 6 PG_CMD_OPEN; 7 PG_CMD_PUTS("CREATE TEMP TABLE tmp_pg_description ( " 8 " objoid oid, " 9 " classname name, " 10 " objsubid int4, " 11 " description text) WITHOUT OIDS;\n"); 12 PG_CMD_PRINTF1("COPY tmp_pg_description FROM E'%s';\n",escape_quotes(desc_file)); 13 PG_CMD_PUTS("INSERT INTO pg_description " 14 " SELECT t.objoid, c.oid, t.objsubid, t.description " 15 " FROM tmp_pg_description t, pg_class c " 16 " WHERE c.relname = t.classname;\n"); 17 PG_CMD_PUTS("CREATE TEMP TABLE tmp_pg_shdescription ( " 18 " objoid oid, " 19 " classname name, " 20 " description text) WITHOUT OIDS;\n"); 21 PG_CMD_PRINTF1("COPY tmp_pg_shdescription FROM E'%s';\n",escape_quotes(shdesc_file)); 22 PG_CMD_PUTS("INSERT INTO pg_shdescription " 23 " SELECT t.objoid, c.oid, t.description " 24 " FROM tmp_pg_shdescription t, pg_class c " 25 " WHERE c.relname = t.classname;\n"); 26 PG_CMD_CLOSE; 27 check_ok(); 28 }

setup_conversion函式載入轉換函式

static void setup_conversion(void){
    PG_CMD_DECL;
    char      **line;
    char      **conv_lines;
    fputs(_("creating conversions ... "), stdout);
    fflush(stdout);
    snprintf(cmd, sizeof(cmd), "\"%s\" %s template1 >%s",backend_exec, backend_options,DEVNULL);
    PG_CMD_OPEN;
    conv_lines = readfile(conversion_file);
    for (line = conv_lines; *line != NULL; line++){
        if (strstr(*line, "DROP CONVERSION") != *line)
            PG_CMD_PUTS(*line);
        free(*line);
    }
    free(conv_lines);
    PG_CMD_CLOSE;
    check_ok();
}

setup_dictionary函式載入外部字典(Snowball stemmers),從dictionary_file指向的檔案讀取SQL,並控制子程序執行這些SQL。

static void setup_dictionary(void){
    PG_CMD_DECL;
    char      **line;
    char      **conv_lines;
    fputs(_("creating dictionaries ... "), stdout);
    fflush(stdout);
    /* We use -j here to avoid backslashing stuff */
    snprintf(cmd, sizeof(cmd), "\"%s\" %s -j template1 >%s",backend_exec, backend_options,DEVNULL);
    PG_CMD_OPEN;
    conv_lines = readfile(dictionary_file);
    for (line = conv_lines; *line != NULL; line++){
        PG_CMD_PUTS(*line);
        free(*line);
    }
    free(conv_lines);
    PG_CMD_CLOSE;
    check_ok();
}

setup_privileges函式建立優先順序,mark一些系統表為world-readable,某些物件需要不同的permissions

 1 static void setup_privileges(void) {
 2     PG_CMD_DECL;
 3     char      **line;
 4     char      **priv_lines;
 5     static char *privileges_setup[] = {
 6         "UPDATE pg_class "
 7         "  SET relacl = E'{\"=r/\\\\\"$POSTGRES_SUPERUSERNAME\\\\\"\"}' "
 8         "  WHERE relkind IN ('r', 'v', 'S') AND relacl IS NULL;\n",
 9         "GRANT USAGE ON SCHEMA pg_catalog TO PUBLIC;\n",
10         "GRANT CREATE, USAGE ON SCHEMA public TO PUBLIC;\n",
11         NULL
12     };
13 
14     fputs(_("setting privileges on built-in objects ... "), stdout);
15     fflush(stdout);
16     snprintf(cmd, sizeof(cmd), "\"%s\" %s template1 >%s", backend_exec, backend_options, DEVNULL);
17     PG_CMD_OPEN;
18     priv_lines = replace_token(privileges_setup,                               "$POSTGRES_SUPERUSERNAME", username);
19     for (line = priv_lines; *line != NULL; line++)
20         PG_CMD_PUTS(*line);
21     PG_CMD_CLOSE;
22     check_ok();
23 }

setup_schema函式load info schema並且從features檔案中populate

 1 static void setup_schema(void){
 2     PG_CMD_DECL;
 3     char      **line;
 4     char      **lines;
 5     fputs(_("creating information schema ... "), stdout);
 6     fflush(stdout);
 7     lines = readfile(info_schema_file);
 8     /* We use -j here to avoid backslashing stuff in information_schema.sql */
 9     snprintf(cmd, sizeof(cmd),"\"%s\" %s -j template1 >%s",backend_exec, backend_options,DEVNULL);
10     PG_CMD_OPEN;
11     for (line = lines; *line != NULL; line++){
12         PG_CMD_PUTS(*line);
13         free(*line);
14     }
15     free(lines);
16     PG_CMD_CLOSE;
17     snprintf(cmd, sizeof(cmd),"\"%s\" %s template1 >%s",backend_exec, backend_options,DEVNULL);
18     PG_CMD_OPEN;
19     PG_CMD_PRINTF1("UPDATE information_schema.sql_implementation_info "
20                    "  SET character_value = '%s' "
21                    "  WHERE implementation_info_name = 'DBMS VERSION';\n",
22                    infoversion);
23     PG_CMD_PRINTF1("COPY information_schema.sql_features "
24                    "  (feature_id, feature_name, sub_feature_id, "
25                    "  sub_feature_name, is_supported, comments) "
26                    " FROM E'%s';\n",
27                    escape_quotes(features_file));
28     PG_CMD_CLOSE;
29     check_ok();
30 }

vacuum_db函式清除template1中的內容

 1 static void vacuum_db(void){
 2     PG_CMD_DECL;
 3     fputs(_("vacuuming database template1 ... "), stdout);
 4     fflush(stdout);
 5     snprintf(cmd, sizeof(cmd),"\"%s\" %s template1 >%s",backend_exec, backend_options,DEVNULL);
 6     PG_CMD_OPEN;
 7     PG_CMD_PUTS("ANALYZE;\nVACUUM FULL;\nVACUUM FREEZE;\n");
 8     PG_CMD_CLOSE;
 9     check_ok();
10 }

make_template0函式將template0複製到templae0中

 1 static void make_template0(void){
 2     PG_CMD_DECL;
 3     const char **line;
 4     static const char *template0_setup[] = {
 5         "CREATE DATABASE template0;\n",
 6         "UPDATE pg_database SET "
 7         "    datistemplate = 't', "
 8         "    datallowconn = 'f' "
 9         "    WHERE datname = 'template0';\n",
10         /* We use the OID of template0 to determine lastsysoid */
11         "UPDATE pg_database SET datlastsysoid = "
12         "    (SELECT oid FROM pg_database "
13         "    WHERE datname = 'template0');\n",
14         /* Explicitly revoke public create-schema and create-temp-table privileges in template1 and template0; else the latter would be on by default */
15         "REVOKE CREATE,TEMPORARY ON DATABASE template1 FROM public;\n",
16         "REVOKE CREATE,TEMPORARY ON DATABASE template0 FROM public;\n",
17         /* Finally vacuum to clean up dead rows in pg_database */
18         "VACUUM FULL pg_database;\n",
19         NULL
20     };
21 
22     fputs(_("copying template1 to template0 ... "), stdout);
23     fflush(stdout);
24     snprintf(cmd, sizeof(cmd),
25              "\"%s\" %s template1 >%s",
26              backend_exec, backend_options,
27              DEVNULL);
28     PG_CMD_OPEN;
29     for (line = template0_setup; *line; line++)
30         PG_CMD_PUTS(*line);
31     PG_CMD_CLOSE;
32     check_ok();
33 }

make_postgres函式將template1拷貝到postgres中

 1 static void make_postgres(void){
 2     PG_CMD_DECL;
 3     const char **line;
 4     static const char *postgres_setup[] = {
 5         "CREATE DATABASE postgres;\n",
 6         NULL
 7     };
 8     fputs(_("copying template1 to postgres ... "), stdout);
 9     fflush(stdout);
10     snprintf(cmd, sizeof(cmd),
11              "\"%s\" %s template1 >%s",
12              backend_exec, backend_options,
13              DEVNULL);
14     PG_CMD_OPEN;
15     for (line = postgres_setup; *line; line++)
16         PG_CMD_PUTS(*line);
17     PG_CMD_CLOSE;
18     check_ok();
19 }