这期内容当中小编将会给大家带来有关PostgreSQL如何初始定义及初始化,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。
配置参数(或者叫GUC变量,grand unified configuration)常见的就是出现在 postgresql.conf
中的设置项,更多信息可查看文档 19. Server Configuration
,我主要讲他们在代码中是如何设置和发挥作用。
主要讲不同类型的初始定义。
1、不同类型对应的结构体
除了前篇提到的通用结构体,每个类型都有自己的定义,例如布尔型:
struct config_bool { struct config_generic gen; /* constant fields, must be set correctly in initial value: */ bool *variable; bool boot_val; GucBoolCheckHook check_hook; GucBoolAssignHook assign_hook; GucShowHook show_hook; /* variable fields, initialized at runtime: */ bool reset_val; void *reset_extra; };
所有类型结构体的第一个成员都是名为gen的 config_generic 结构体,再比如整型:
struct config_int { struct config_generic gen; /* constant fields, must be set correctly in initial value: */ ...
这样的代码设计在PG里随处可见,可以理解为类似C++的继承,在使用过程中可以根据gen成员的值知道一个结构体指针实际对应的类型,比如:
struct config_generic *conf; ... conf = guc_variables[varnum]; ... /* now get the type specific attributes */ switch (conf->vartype) { case PGC_BOOL: { struct config_bool *lconf = (struct config_bool *) conf; ... /* boot_val */ values[12] = pstrdup(lconf->boot_val ? "on" : "off"); ...
读到一个 config_generic
结构体成员 vartype 是 PGC_BOOL,既可以知道它实际指向的是一个 config_bool 类型结构体。
2、配置参数初始定义(src/backend/utils/misc/guc.c
)
布尔型配置参数定义为结构体数组 ConfigureNamesBool:
static struct config_bool ConfigureNamesBool[] = { { {"enable_seqscan", PGC_USERSET, QUERY_TUNING_METHOD, gettext_noop("Enables the planner's use of sequential-scan plans."), NULL }, &enable_seqscan, true, NULL, NULL, NULL }, ...
第一部分是 gen 成员定义,分别是上篇提到的:配置参数名、所处上下文、分类、短描述、长描述,它们的值分别为:enable_seqscan、PGC_USERSET(允许普通用户设置)、QUERY_TUNING_METHOD(Query Tuning / Planner Method Configuration)、等等。
其他类型也都各有自己的定义数组:
static struct config_int ConfigureNamesInt[] = static struct config_real ConfigureNamesReal[] =
等等,不再赘述。
每个参数都有一个成员boot_val
,启动时的初始值,它的类型跟参数一致,比如config_bool中是bool,而config_int中是int。上例中 enable_seqscan 的初始值是 true,这个值跟postgresql.conf中的默认值一致。
3、启动时的类型初始化
函数 build_guc_variables()
for (i = 0; ConfigureNamesInt[i].gen.name; i++) { struct config_int *conf = &ConfigureNamesInt[i]; conf->gen.vartype = PGC_INT; num_vars++; }
在这里赋予参数类型,每个数组容纳不同类型参数,不需要在定义时挨个指定,只定义前几个成员的值即可。
所有不同类型的参数指针放在同一个数组中,并按名字排序。
4、启动时的值初始化
类型初始化函数在 InitializeGUCOptions()
中调用,随后马上为每个参数调用 InitializeOneGUCOption
。
以字符串参数为例
if (conf->boot_val != NULL) newval = guc_strdup(FATAL, conf->boot_val); else newval = NULL; if (!call_string_check_hook(conf, &newval, &extra, PGC_S_DEFAULT, LOG)) elog(FATAL, "failed to initialize %s to \"%s\"", conf->gen.name, newval ? newval : ""); if (conf->assign_hook) conf->assign_hook(newval, extra); *conf->variable = conf->reset_val = newval; conf->gen.extra = conf->reset_extra = extra;
这里很简单,就是以 boot_val 初始化其他成员。
大家肯定注意到结构体里还有三个hook的定义,这里用到了两个,有兴趣可以自行了解。
5、环境变量对配置的影响
见函数 InitializeGUCOptionsFromEnvironment
,这里不再展开,回头跟SET
命令或者配置文件的读取一起讲。
上边是数据库进程启动时(包括后端进程的启动)配置参数初始化,写得很粗,可能有遗漏。
上述就是小编为大家分享的PostgreSQL如何初始定义及初始化了,如果刚好有类似的疑惑,不妨参照上述分析进行理解。如果想知道更多相关知识,欢迎关注亿速云行业资讯频道。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。