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

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

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中。