2.4.2 配置参数(2)

Postmaster配置参数的基本过程包括图2-7所示的三个步骤。

图2-7 Postmaster配置参数的过程

1.初始化GUC参数

Postmaster将首先调用InitializeGUCOptions函数将参数设置为默认值:

1)首先调用build_guc_variables函数来统计参数个数并分配相应的config_generic类型的全局指针数组guc_variables以保存每个参数结构体的地址,并且对该数组进行排序。由于参数是通过全局静态数组ConfigureNamesBool、ConfigureNamesInt、ConfigureNamesReal、ConfigureNamesString、ConfigureNamesEnum存储的,因此在build_guc_variables函数中只需要遍历相应的数组,统计参数的个数并将参数结构体中config_generic域的参数vartype设置为相应的参数类型。当遍历完所有参数后,根据总的参数个数分配config_generic指针数组guc_vars,然后再次遍历静态参数数组,将每个参数结构的首地址保存到guc_vars数组中(这里分配的数组个数为当前参数总数的1.25倍,主要是为了方便以后参数的扩充)。接着将全局变量guc_variables也指向guc_vars数组。最后通过快速排序法把guc_variables按照参数名进行排序。

2)接下来将每个参数设置为默认值。对于guc_variables中的每个参数,initializeGUCOptions函数先将其config_generic域中的status设置为0,将reset_source、tentative_source、source设置为PGC_S_DEFAULT表示默认;stack、sourcefile设置为NULL;然后根据参数值vartype的不同类型分别调用相应的assign_hook函数(如果该参数设置了该函数),assign_hook函数用来设置boot_val,最后将boot_val赋值给reset_val和variable指向的变量,通过这样一系列的步骤就将参数设置为了默认值。

3)通过系统调用getenv来获得环境变量PGPORT、PGDATESTYLE、PGCLIENTENCODING的值,不为空则调用SetConfigOption函数来设置这三个变量对应的参数的值。

4)最后,检测系统的最大安全栈深度,如果这个深度值大于100KB且不超过2MB,则用它设置max_stack_depth参数。

2.配置GUC参数

如果用户启动Postmaster进程时通过命令行参数指定了一些GUC的参数值,那么Postmaster需要从命令行参数中将这些GUC参数的值解析出来并且设置到相应的GUC参数中,这一部分的代码在Postmaster.c文件的509~674行中。根据命令行设置参数主要是通过getopt和SetConfigOption这两个函数来完成的。

用getopt解析命令行参数

getopt(nargc,nargv,ostr)函数主要用来解析命令行参数,这里主要用到了3个全局变量optind、optopt和optarg:

optind用来保存当前将要解析的参数在参数数组中的下标,其初始值为1,最后的值应该等于参数个数argc。

optopt用来指向正被解析到的参数选项。

optarg则用来保存optopt选项对应的参数值。

每当解析到一个参数选项optopt时,将检查optopt是否出现参数ostr中,如果没有出现,则说明该参数为非法参数,出错;如果该参数在ostr中出现,且后面紧跟符号“:”,则说明该参数将不带参数值,这时候我们将optarg赋值为NULL,然后将optind加1以进行下一次处理,函数本身返回optopt;如果上述情况都没有发生,那么说明该参数选项将带参数。这时候又有两种情况:一种是参数直接跟在参数选项后面,另一种是参数和参数选项之间用空格隔开。对于第一种情况,只需要将optarg指向optopt后面的一个字符即可;对于第二种情况,则将optind加1,然后将argv[optind]赋值给optarg。上述工作都完成后增加optind的值,然后函数返回optopt。

对于getopt返回的每一个参数选项及其参数值,通过一个switch语句根据参数选项的不同分别调用SetConfigOption函数设置相应的参数。

SetConfigOption函数的第一个参数为参数名;第二个参数为参数值,其值存放在getopt函数返回的optarg字符串中;第三个参数为参数类型;最后一个参数为参数来源。由于在这里Postmaster是在处理命令行参数,所以这里的参数类型和参数来源分别设置为PGC_POSTMASTER和PGC_S_ARGV。

SetConfigOption函数是通过调用set_config_option(const char *name,const char *value,GucContext context,GucSource source,bool isLocal,bool changeVal)函数来实现的,其中最后2个参数统一设置为false和true。该函数首先从guc_variables指向的参数数组中搜索参数名为name的参数,如果没找到则出错;否则将找到的参数的结构体中GucContext的值与传过来的参数context比较,判断在当前的上下文中参数是否可以设置,如果不能设置的话就报错,否则再将参数结构体中的GucSource与传过来的参数source进行比较,判断当前操作的优先级是否大于或等于先前的优先级,如果大于或等于先前优先级的话则根据具体参数值的类型将value转化为相应的数据,然后设置参数结构体中的相应数据项即可。

【责任编辑:云霞 TEL:(010)68476606】

results matching ""

    No results matching ""