PostgreSQL通过插件可以集成许多扩展,比如auth_delay。添加插件时,会引入一些guc配置变量,比如auth_delay的auth_delay.milliseconds。那么这些变量是如何随着插件的安装集成到server中呢?在系统中又是如何管理的呢?
我们先看下guc参数是如何管理的。
首先初始化GUC选项,将其设置为默认值;然后读取命令行配置,最后读取配置文件postgresql.conf中的配置项。
1 初始化默认值
有5类参数:ConfigureNamesBool、ConfigureNamesInt、ConfigureNamesReal、ConfigureNamesReal、ConfigureNamesEnum。
InitializeGUCOptions build_guc_variables(); InitializeOneGUCOption(guc_variables[i]); InitializeGUCOptionsFromEnvironment
build_guc_variables完成空间申请:循环计算出所有变量个数,申请一个大空间config_generic *guc_vars[]数组,将所有变量值都放到这个数组里面,然后按字母顺序排序。最终将全局变量guc_variables也指向guc_vars数组,变量个数num_guc_variables。guc_variables[]数组大小为当前参数总数的1.25倍,主要方便以后参数的扩充。例如:
InitializeOneGUCOption初始化默认值:循环调用该函数,将所有参数设置为默认值。
InitializeGUCOptionsFromEnvironment完成环境变量 值的获取:从PGPORT、PGDATESTYLE、PGCLIENTENCODING中获取,不为空则调用SetConfigOption函数来设置这三个变量对于的参数值。最后检查系统最大安全栈深度。如果这个深度大于100KB并且不超过2MB,则用它设置max_stack_depth参数。
2 命令行配置GUC参数
如果启动PG进程时,通过命令行参数指定了一些GUC的参数值,那需要从命令行中将这些参数值解析出来并设置到相应GUC参数中。根据命令行配置主要调用函数getopt和SetConfigOption来配置,比如:
3 配置文件读取
最后调用SelectConfigFiles读取配置文件中值重新配置参数。需要注意,配置文件中设置的参数都不能修改之前通过命令行已经设置的参数,因其优先级没有命令行优先级高。
至此,了解到配置项是如何管理的。接着看下auth_delay插件中如何新增一个变量。
4 auth_delay新增配置项
该插件在_PG_init函数中新增定义一个GUC变量。上图所示,由函数DefineCustomIntVariable来完成,auth_delay新增的配置项是auth_delay.millisenconds,对应到程序中是auth_delay_milliseconds变量。
主要调用函数init_custom_variable和define_custom_variable。init_custom_variable函数主要申请一个config_generic空间,并初始化generic域。define_custom_variable函数完成新变量的定义与增加:
该函数会先从guc_variables数组中查询,看有没有已经加载,比如在postgresql.conf中配置了。未配置的的调用InitializeOneGUCOption和add_guc_variable新增一个变量。它也是先初始化为默认值,然后添加到guc_variables数组中,最后排序。若在postgresql.conf中配置,则将其值重新配置到变量中。
至此,插件中新定义的配置项及其值加载到了server中。