PostgreSQL通過插件可以集成許多擴(kuò)展,比如auth_delay。添加插件時(shí),會(huì)引入一些guc配置變量,比如auth_delay的auth_delay.milliseconds。那么這些變量是如何隨著插件的安裝集成到server中呢?在系統(tǒng)中又是如何管理的呢?
我們先看下guc參數(shù)是如何管理的。

首先初始化GUC選項(xiàng),將其設(shè)置為默認(rèn)值;然后讀取命令行配置,最后讀取配置文件postgresql.conf中的配置項(xiàng)。
1 初始化默認(rèn)值
有5類參數(shù):ConfigureNamesBool、ConfigureNamesInt、ConfigureNamesReal、ConfigureNamesReal、ConfigureNamesEnum。

build_guc_variables完成空間申請:循環(huán)計(jì)算出所有變量個(gè)數(shù),申請一個(gè)大空間config_generic *guc_vars[]數(shù)組,將所有變量值都放到這個(gè)數(shù)組里面,然后按字母順序排序。最終將全局變量guc_variables也指向guc_vars數(shù)組,變量個(gè)數(shù)num_guc_variables。guc_variables[]數(shù)組大小為當(dāng)前參數(shù)總數(shù)的1.25倍,主要方便以后參數(shù)的擴(kuò)充。例如:

InitializeOneGUCOption初始化默認(rèn)值:循環(huán)調(diào)用該函數(shù),將所有參數(shù)設(shè)置為默認(rèn)值。
InitializeGUCOptionsFromEnvironment完成環(huán)境變量 值的獲。簭腜GPORT、PGDATESTYLE、PGCLIENTENCODING中獲取,不為空則調(diào)用SetConfigOption函數(shù)來設(shè)置這三個(gè)變量對于的參數(shù)值。最后檢查系統(tǒng)最大安全棧深度。如果這個(gè)深度大于100KB并且不超過2MB,則用它設(shè)置max_stack_depth參數(shù)。
2 命令行配置GUC參數(shù)
如果啟動(dòng)PG進(jìn)程時(shí),通過命令行參數(shù)指定了一些GUC的參數(shù)值,那需要從命令行中將這些參數(shù)值解析出來并設(shè)置到相應(yīng)GUC參數(shù)中。根據(jù)命令行配置主要調(diào)用函數(shù)getopt和SetConfigOption來配置,比如:

3 配置文件讀取
最后調(diào)用SelectConfigFiles讀取配置文件中值重新配置參數(shù)。需要注意,配置文件中設(shè)置的參數(shù)都不能修改之前通過命令行已經(jīng)設(shè)置的參數(shù),因其優(yōu)先級沒有命令行優(yōu)先級高。
至此,了解到配置項(xiàng)是如何管理的。接著看下auth_delay插件中如何新增一個(gè)變量。
4 auth_delay新增配置項(xiàng)

該插件在_PG_init函數(shù)中新增定義一個(gè)GUC變量。上圖所示,由函數(shù)DefineCustomIntVariable來完成,auth_delay新增的配置項(xiàng)是auth_delay.millisenconds,對應(yīng)到程序中是auth_delay_milliseconds變量。

主要調(diào)用函數(shù)init_custom_variable和define_custom_variable。init_custom_variable函數(shù)主要申請一個(gè)config_generic空間,并初始化generic域。define_custom_variable函數(shù)完成新變量的定義與增加:

該函數(shù)會(huì)先從guc_variables數(shù)組中查詢,看有沒有已經(jīng)加載,比如在postgresql.conf中配置了。未配置的的調(diào)用InitializeOneGUCOption和add_guc_variable新增一個(gè)變量。它也是先初始化為默認(rèn)值,然后添加到guc_variables數(shù)組中,最后排序。若在postgresql.conf中配置,則將其值重新配置到變量中。
至此,插件中新定義的配置項(xiàng)及其值加載到了server中。