PostgreSQL數據庫集簇初始化——initdb初始化數據庫(命令行參數處理)


  template1和template0數據庫用於創建數據庫。PG中采用從模板數據庫復制的方法來創建新的數據庫,在創建數據庫的命令中可以用-T選項來指定以哪個數據庫為模板來創建新數據庫。template1數據庫是創建數據庫命令默認的模板,也就是說通過不帶-T選項的命令創建的用戶數據庫和template1一模一樣。template1是可以修改的,如果對tempalte1進行了修改,那么在修改之后創建的用戶數據庫中也能體現出這些修改的結果。template1的存在允許用戶可以制作一個自定義的模板數據庫,在其中用戶可以創建一些應用需要的表、數據、索引等,在日后需要多次創建相同內容的數據庫時,都可以用template1作為模板生成。

src\bin\initdb

  initdb是PG中一個獨立的程序,它的主要工作就是對數據集簇進行初始化,創建模板數據庫和系統表,並向系統表中插入初始元組。在這以后,用戶創建各種數據庫、表、視圖、索引等數據庫對象和進行其他操作時,都是在模板數據庫和系統表的基礎上進行的。執行initdb程序時,將從發initdb.c文件中的main函數開始執行,initdb執行時將按照順序執行下列工作:

1. 根據用戶輸入的命令行參數獲取輸入的命令名。

initdb把用戶指定的選項轉換成對應的參數,通過外部程序調用的方式執行postgres程序。postgres程序在這種方式下將進入bootstrap模式創建數據集簇,並讀取后端接口postgres.bki文件來創建模板數據庫。

initdb [option...] --pgdata|-D directory 常用option選項如下:

-A METHOD | --auth = METHOD 指定本地連接的默認用戶認證方式

-D DATADIR | --pgdata = DATADIR 數據目錄的路徑,必須是對當前用戶可讀寫的空目錄,也可以使用環境變量PGDATA來指定而省略本選項

-E ENCODING | --encoding = ENCODING 指定默認數據庫編碼方式

-U NAME | --username = NAME 指定數據庫超級用戶名

-W | --pwprompt 提示超級用戶設置口令

-d | --debug 以調試模式運行,可以打印出很多調試消息

-L directory 指定輸入文件(比如postgres.bki)位置

 1     static struct option long_options[] = {
 2         {"pgdata", required_argument, NULL, 'D'},
 3         {"encoding", required_argument, NULL, 'E'},
 4         {"locale", required_argument, NULL, 1},
 5         {"lc-collate", required_argument, NULL, 2},
 6         {"lc-ctype", required_argument, NULL, 3},
 7         {"lc-monetary", required_argument, NULL, 4},
 8         {"lc-numeric", required_argument, NULL, 5},
 9         {"lc-time", required_argument, NULL, 6},
10         {"lc-messages", required_argument, NULL, 7},
11         {"no-locale", no_argument, NULL, 8},
12         {"text-search-config", required_argument, NULL, 'T'},
13         {"auth", required_argument, NULL, 'A'},
14         {"pwprompt", no_argument, NULL, 'W'},
15         {"pwfile", required_argument, NULL, 9},
16         {"username", required_argument, NULL, 'U'},
17         {"help", no_argument, NULL, '?'},
18         {"version", no_argument, NULL, 'V'},
19         {"debug", no_argument, NULL, 'd'},
20         {"show", no_argument, NULL, 's'},
21         {"noclean", no_argument, NULL, 'n'},
22         {"xlogdir", required_argument, NULL, 'X'},
23         {NULL, 0, NULL, 0}
24     };

 getopt_long函數用於處理命令行參數,代碼處於src/port/getopt_long.c。

1 while ((c = getopt_long(argc, argv, "dD:E:L:nU:WA:sT:X:", long_options, &option_index)) != -1){
2     switch (c){
3         case 'A':
4             authmethod = xstrdup(optarg);
5             break;
6 ...

 

2. 設置系統編碼為LC_ALL,查找執行命令的絕對路徑並設置該路徑。

set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("initdb"));

設置指定應用的locale和service目錄,函數獲取argv[0]的值而不是全路徑

 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 }

 

3. 設置環境變量(pg_data等),獲取系統配置文件的源文件路徑(postgres.bki、postgresql.conf. sample等文件),並檢查該路徑下各文件的可用性。

4. 設置中斷信號處理函數,對終端命令行SIGHUP、程序中斷SIGINT、程序退出SIGQUIT、軟件中斷SIGTERM和管道中斷SIGPIPE等信號進行屏蔽,保證初始化工作順利進行。

5. 創建數據目錄,以及該目錄下一些必要的子目錄,如base、global、base/1等。

6. 測試當前服務器系統性能,由測試結果創建配置文件postgresql.conf、pg_hba.conf、pg_ident.conf,並對其中定義的參數做一些設置。

7. 在bootstrap模式下創建數據庫template1,存儲在數據目錄的子目錄base/1/中

3141行

1     /* Bootstrap template1 */
2     bootstrap_template1(short_version);
3 
4     /*
5      * Make the per-database PG_VERSION for template1 only after init'ing it
6      */
7     set_short_version(short_version, "base/1");

8. 創建系統視圖、系統表TOAST表等,復制template1來創建template0和postgres,這些操作都用普通的SQL命令來完成。

    setup_auth();
    if (pwprompt || pwfilename)
        get_set_pwd();
    setup_depend();
    setup_sysviews();
    setup_description();
    setup_conversion();
    setup_dictionary();
    setup_privileges();
    setup_schema();
    vacuum_db();
    make_template0();
    make_postgres();

9. 打印操作成功等相關信息,退出。

    if (authwarning != NULL)
        fprintf(stderr, "%s", authwarning);
    /* Get directory specification used to start this executable */
    strcpy(bin_dir, argv[0]);
    get_parent_directory(bin_dir);
    printf(_("\nSuccess. You can now start the database server using:\n\n"
             "    %s%s%spostgres%s -D %s%s%s\n"
             "or\n"
             "    %s%s%spg_ctl%s -D %s%s%s -l logfile start\n\n"),
       QUOTE_PATH, bin_dir, (strlen(bin_dir) > 0) ? DIR_SEP : "", QUOTE_PATH,
           QUOTE_PATH, pg_data_native, QUOTE_PATH,
       QUOTE_PATH, bin_dir, (strlen(bin_dir) > 0) ? DIR_SEP : "", QUOTE_PATH,
           QUOTE_PATH, pg_data_native, QUOTE_PATH);

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM