PostgreSQL的 initdb 源代码分析之十三-阿里云开发者社区

开发者社区> 嗯哼9925> 正文

PostgreSQL的 initdb 源代码分析之十三

简介:
+关注继续查看

继续分析:

    /* Bootstrap template1 */
    bootstrap_template1();

展开:

我这里读入的文件是:/home/pgsql/project/share/postgres.bki 

复制代码
/*
 * run the BKI script in bootstrap mode to create template1
 */
static void
bootstrap_template1(void)
{
    PG_CMD_DECL;
    char      **line;
    char       *talkargs = "";
    char      **bki_lines;
    char        headerline[MAXPGPATH];
    char        buf[64];

    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",
             PG_MAJORVERSION);

    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();
    }

    /* Substitute for various symbols used in the BKI file */

    sprintf(buf, "%d", NAMEDATALEN);
    bki_lines = replace_token(bki_lines, "NAMEDATALEN", buf);

    sprintf(buf, "%d", (int) sizeof(Pointer));
    bki_lines = replace_token(bki_lines, "SIZEOF_POINTER", buf);

    bki_lines = replace_token(bki_lines, "ALIGNOF_POINTER",
                              (sizeof(Pointer) == 4) ? "i" : "d");

    bki_lines = replace_token(bki_lines, "FLOAT4PASSBYVAL",
                              FLOAT4PASSBYVAL ? "true" : "false");

    bki_lines = replace_token(bki_lines, "FLOAT8PASSBYVAL",
                              FLOAT8PASSBYVAL ? "true" : "false");

    bki_lines = replace_token(bki_lines, "POSTGRES", username);

    bki_lines = replace_token(bki_lines, "ENCODING", encodingid);

    bki_lines = replace_token(bki_lines, "LC_COLLATE", escape_quotes(lc_collate));

    bki_lines = replace_token(bki_lines, "LC_CTYPE", escape_quotes(lc_ctype));

    /*
     * 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",
             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();
}
复制代码

其中,  bki_lines = readfile(bki_file) ,是得到了要读取的文件的每一行。

再展开看 replace_token 函数:

这个函数就是用 replacement指向的字符串,替换在 lines所代表的文件内容行数组中所有token值。

比如:

sprintf(buf, "%d", NAMEDATALEN);
bki_lines = replace_token(bki_lines, "NAMEDATALEN", buf);

把 postgres.bki  文件中 类似于 

insert OID = 19 ( name 11 10 NAMEDATALEN f b S f t \054 0 18 1003 namein nameout namerecv namesend - - - c p f 0 -1 0 0 _null_ _null_ )

这样的句子,在内存中替换为(根据宏定义、NAMEDATALEN为64):

insert OID = 19 ( name 11 10 64 f b S f t \054 0 18 1003 namein nameout namerecv namesend - - - c p f 0 -1 0 0 _null_ _null_ )

复制代码
/*
 * make a copy of the array of lines, with token replaced by replacement
 * the first time it occurs on each line.
 *
 * This does most of what sed was used for in the shell script, but
 * doesn't need any regexp stuff.
 */
static char **
replace_token(char **lines, const char *token, const char *replacement)
{
    int            numlines = 1;
    int            i;
    char      **result;
    int            toklen,
                replen,
                diff;

    for (i = 0; lines[i]; i++)
        numlines++;

    result = (char **) pg_malloc(numlines * sizeof(char *));

    toklen = strlen(token);
    replen = strlen(replacement);
    diff = replen - toklen;

    for (i = 0; i < numlines; i++)
    {
        char       *where;
        char       *newline;
        int            pre;

        /* just copy pointer if NULL or no change needed */
        if (lines[i] == NULL || (where = strstr(lines[i], token)) == NULL)
        {
            result[i] = lines[i];
            continue;
        }

        /* if we get here a change is needed - set up new line */

        newline = (char *) pg_malloc(strlen(lines[i]) + diff + 1);

        pre = where - lines[i];

        strncpy(newline, lines[i], pre);

        strcpy(newline + pre, replacement);

        strcpy(newline + pre + replen, lines[i] + pre + toklen);

        result[i] = newline;
    }

    return result;
}
复制代码

综合上述两段,加入调试信息后,可以看到:

复制代码
---------------replace for   NAMEDATALEN ------start
===============lines[2301] OLD is : insert OID = 19 ( name 11 10 NAMEDATALEN f b S f t \054 0 18 1003 namein nameout namerecv namesend - - - c p f 0 -1 0 0 _null_ _null_ )

===============result[2301] NEW is : insert OID = 19 ( name 11 10 64 f b S f t \054 0 18 1003 namein nameout namerecv namesend - - - c p f 0 -1 0 0 _null_ _null_ )


===============lines[2458] OLD is : insert ( 1255 proname 19 -1 NAMEDATALEN 1 0 -1 -1 f p c t f f t 0 0 _null_ _null_)

===============result[2458] NEW is : insert ( 1255 proname 19 -1 64 1 0 -1 -1 f p c t f f t 0 0 _null_ _null_)


===============lines[2490] OLD is : insert ( 1247 typname 19 -1 NAMEDATALEN 1 0 -1 -1 f p c t f f t 0 0 _null_ _null_)

===============result[2490] NEW is : insert ( 1247 typname 19 -1 64 1 0 -1 -1 f p c t f f t 0 0 _null_ _null_)


===============lines[2527] OLD is : insert ( 1249 attname 19 -1 NAMEDATALEN 2 0 -1 -1 f p c t f f t 0 0 _null_ _null_)

===============result[2527] NEW is : insert ( 1249 attname 19 -1 64 2 0 -1 -1 f p c t f f t 0 0 _null_ _null_)


===============lines[2552] OLD is : insert ( 1259 relname 19 -1 NAMEDATALEN 1 0 -1 -1 f p c t f f t 0 0 _null_ _null_)

===============result[2552] NEW is : insert ( 1259 relname 19 -1 64 1 0 -1 -1 f p c t f f t 0 0 _null_ _null_)


---------------replace for   NAMEDATALEN ------end

---------------replace for   SIZEOF_POINTER ------start
===============lines[2428] OLD is : insert OID = 2281 ( internal 11 10 SIZEOF_POINTER t p P f t \054 0 0 0 internal_in internal_out - - - - - ALIGNOF_POINTER p f 0 -1 0 0 _null_ _null_ )

===============result[2428] NEW is : insert OID = 2281 ( internal 11 10 8 t p P f t \054 0 0 0 internal_in internal_out - - - - - ALIGNOF_POINTER p f 0 -1 0 0 _null_ _null_ )


---------------replace for   SIZEOF_POINTER ------end

---------------replace for   ALIGNOF_POINTER ------start
===============lines[2428] OLD is : insert OID = 2281 ( internal 11 10 8 t p P f t \054 0 0 0 internal_in internal_out - - - - - ALIGNOF_POINTER p f 0 -1 0 0 _null_ _null_ )

===============result[2428] NEW is : insert OID = 2281 ( internal 11 10 8 t p P f t \054 0 0 0 internal_in internal_out - - - - - d p f 0 -1 0 0 _null_ _null_ )


---------------replace for   ALIGNOF_POINTER ------end

---------------replace for   FLOAT4PASSBYVAL ------start
===============lines[2328] OLD is : insert OID = 700 ( float4 11 10 4 FLOAT4PASSBYVAL b N f t \054 0 0 1021 float4in float4out float4recv float4send - - - i p f 0 -1 0 0 _null_ _null_ )

===============result[2328] NEW is : insert OID = 700 ( float4 11 10 4 true b N f t \054 0 0 1021 float4in float4out float4recv float4send - - - i p f 0 -1 0 0 _null_ _null_ )


===============lines[2462] OLD is : insert ( 1255 procost 700 -1 4 5 0 -1 -1 FLOAT4PASSBYVAL p i t f f t 0 0 _null_ _null_)

===============result[2462] NEW is : insert ( 1255 procost 700 -1 4 5 0 -1 -1 true p i t f f t 0 0 _null_ _null_)


===============lines[2463] OLD is : insert ( 1255 prorows 700 -1 4 6 0 -1 -1 FLOAT4PASSBYVAL p i t f f t 0 0 _null_ _null_)

===============result[2463] NEW is : insert ( 1255 prorows 700 -1 4 6 0 -1 -1 true p i t f f t 0 0 _null_ _null_)


===============lines[2561] OLD is : insert ( 1259 reltuples 700 -1 4 10 0 -1 -1 FLOAT4PASSBYVAL p i t f f t 0 0 _null_ _null_)

===============result[2561] NEW is : insert ( 1259 reltuples 700 -1 4 10 0 -1 -1 true p i t f f t 0 0 _null_ _null_)


---------------replace for   FLOAT4PASSBYVAL ------end

---------------replace for   FLOAT8PASSBYVAL ------start
===============lines[2302] OLD is : insert OID = 20 ( int8 11 10 8 FLOAT8PASSBYVAL b N f t \054 0 0 1016 int8in int8out int8recv int8send - - - d p f 0 -1 0 0 _null_ _null_ )

===============result[2302] NEW is : insert OID = 20 ( int8 11 10 8 true b N f t \054 0 0 1016 int8in int8out int8recv int8send - - - d p f 0 -1 0 0 _null_ _null_ )


===============lines[2329] OLD is : insert OID = 701 ( float8 11 10 8 FLOAT8PASSBYVAL b N t t \054 0 0 1022 float8in float8out float8recv float8send - - - d p f 0 -1 0 0 _null_ _null_ )

===============result[2329] NEW is : insert OID = 701 ( float8 11 10 8 true b N t t \054 0 0 1022 float8in float8out float8recv float8send - - - d p f 0 -1 0 0 _null_ _null_ )


===============lines[2336] OLD is : insert OID = 790 ( money 11 10 8 FLOAT8PASSBYVAL b N f t \054 0 0 791 cash_in cash_out cash_recv cash_send - - - d p f 0 -1 0 0 _null_ _null_ )

===============result[2336] NEW is : insert OID = 790 ( money 11 10 8 true b N f t \054 0 0 791 cash_in cash_out cash_recv cash_send - - - d p f 0 -1 0 0 _null_ _null_ )


===============lines[2377] OLD is : insert OID = 1083 ( time 11 10 8 FLOAT8PASSBYVAL b D f t \054 0 0 1183 time_in time_out time_recv time_send timetypmodin timetypmodout - d p f 0 -1 0 0 _null_ _null_ )

===============result[2377] NEW is : insert OID = 1083 ( time 11 10 8 true b D f t \054 0 0 1183 time_in time_out time_recv time_send timetypmodin timetypmodout - d p f 0 -1 0 0 _null_ _null_ )


===============lines[2378] OLD is : insert OID = 1114 ( timestamp 11 10 8 FLOAT8PASSBYVAL b D f t \054 0 0 1115 timestamp_in timestamp_out timestamp_recv timestamp_send timestamptypmodin timestamptypmodout - d p f 0 -1 0 0 _null_ _null_ )

===============result[2378] NEW is : insert OID = 1114 ( timestamp 11 10 8 true b D f t \054 0 0 1115 timestamp_in timestamp_out timestamp_recv timestamp_send timestamptypmodin timestamptypmodout - d p f 0 -1 0 0 _null_ _null_ )


===============lines[2382] OLD is : insert OID = 1184 ( timestamptz 11 10 8 FLOAT8PASSBYVAL b D t t \054 0 0 1185 timestamptz_in timestamptz_out timestamptz_recv timestamptz_send timestamptztypmodin timestamptztypmodout - d p f 0 -1 0 0 _null_ _null_ )

===============result[2382] NEW is : insert OID = 1184 ( timestamptz 11 10 8 true b D t t \054 0 0 1185 timestamptz_in timestamptz_out timestamptz_recv timestamptz_send timestamptztypmodin timestamptztypmodout - d p f 0 -1 0 0 _null_ _null_ )


---------------replace for   FLOAT4PASSBYVAL ------end

---------------replace for   POSTGRES ------start
===============lines[4841] OLD is : insert OID = 10 ( "POSTGRES" t t t t t t t -1 _null_ _null_ )

===============result[4841] NEW is : insert OID = 10 ( "pgsql" t t t t t t t -1 _null_ _null_ )


---------------replace for   POSTGRES ------end

---------------replace for   ENCODING ------start
===============lines[4783] OLD is : insert OID = 1 ( template1 10 ENCODING "LC_COLLATE" "LC_CTYPE" t t -1 0 0 1663 _null_)

===============result[4783] NEW is : insert OID = 1 ( template1 10 6 "LC_COLLATE" "LC_CTYPE" t t -1 0 0 1663 _null_)


---------------replace for   ENCODING ------end

---------------replace for   LC_COLLATE ------start
===============lines[4783] OLD is : insert OID = 1 ( template1 10 6 "LC_COLLATE" "LC_CTYPE" t t -1 0 0 1663 _null_)

===============result[4783] NEW is : insert OID = 1 ( template1 10 6 "en_US.UTF-8" "LC_CTYPE" t t -1 0 0 1663 _null_)


---------------replace for   LC_COLLATE ------end

---------------replace for   LC_CTYPE ------start
===============lines[4783] OLD is : insert OID = 1 ( template1 10 6 "en_US.UTF-8" "LC_CTYPE" t t -1 0 0 1663 _null_)

===============result[4783] NEW is : insert OID = 1 ( template1 10 6 "en_US.UTF-8" "en_US.UTF-8" t t -1 0 0 1663 _null_)


---------------replace for   LC_CTYPE ------end
复制代码

这些被替换以后的信息,如何被使用呢?

看前面的  
bootstrap_template1 函数中的这一段:

复制代码
    /*
     * 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",
             backend_exec, boot_options, talkargs);
复制代码

我可以得到 cmd是: "/home/pgsql/project/bin/postgres" --boot -x1 -F  

而后面的一段:

则是一次一次的逐行带参数执行 Postgresql.bki中所有行(包括被替换的和没有被替换的行)

可以理解为特殊的模式下,向postgresql 的template 数据库中逐条写入数据。

复制代码
    PG_CMD_OPEN;

    for (line = bki_lines; *line != NULL; line++)
    {
        PG_CMD_PUTS(*line);
        free(*line);
    }

    PG_CMD_CLOSE;
复制代码

需要注意的是,对各个系统表的建立,都是在此处,通过执行 postgres.bki文件中的各行脚本来完成的。








本文转自健哥的数据花园博客园博客,原文链接:http://www.cnblogs.com/gaojian/p/3178151.html,如需转载请自行联系原作者


版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
ML之catboost:catboost模型中常用的Pool类型数据结构源代码解读、案例应用之详细攻略(一)
ML之catboost:catboost模型中常用的Pool类型数据结构源代码解读、案例应用之详细攻略
13 0
Java 读写锁 ReentrantReadWriteLock 源码分析
原文出处:https://javadoop.com/post/reentrant-read-write-lock 本文内容:读写锁 ReentrantReadWriteLock 的源码分析,基于 Java7/Java8。
789 0
检查HTTP 的 Digest 认证代码示例-JSP
检查HTTP 的 Digest  认证. since http1.1 代码如下所示:(此代码还不完善, RFC2617算法未实现).
743 0
借助 Resharper 和 StyleCop 让代码更整洁
一:工具安装 Resharper 和 StyleCop 必须安装。 Resharper 的配置文件如下:Resharper.zip 请按如下步骤导入, 1: 2: 3:   StyleCope 的配置文件如下:Settings.zip 请直接包含到项目中,如: (PS:从源码服务器上获取的解决方案,Leader 已经包含)。
764 0
Unity3D热更新之LuaFramework篇[09]--资源热更新与代码热更新的具体实现
Unity3D热更新之LuaFramework篇[09]--资源热更新与代码热更新的具体实现一、准备工作1、制作一个用于热更新的界面此前我制作了一个大厅界面,并且放置了两个按钮:”排行榜“和”商城“,排行榜按钮已经用于打开排行榜页面。
1103 0
Solrflux源码分析-Sql Support within Solr-类Sql的solr搜索实现(2)
Solrflux 开源code google 地址 http://code.google.com/p/solrflux/ 1.Solrflux 概述    Solrflux 主要工作是完成 Sql 语法到solr语法的转换,并执行查询,保存结果。    当前solrflux已经停止更新了,
1837 0
+关注
4098
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
文娱运维技术
立即下载
《SaaS模式云原生数据仓库应用场景实践》
立即下载
《看见新力量:二》电子书
立即下载