在postgresql.conf中增加自定义配置项

PostgreSQL提供了postgresql.conf这个配置文件,通过它可以配置PostgreSQL启动、运行、性能优化、主备等各项参数,是PostgreSQL的核心配置文件。笔记简单分析了PostgreSQL是如何创建、应用、变更postgresql.conf的各种配置项,以及如何增加自定义的配置项。
先从PostgreSQL的启动开始说起。老生常谈,PostgreSQL在启动时,首先会启动一个Postmaster主进程,Postmaster主进程的入口函数PostmasterMain在初始化内存环境之后便进入处理数据库各项参数的GUC模块。

一、GUC

GUC名词解释:Grand Unified Configuration

GUC配置模块实现了五种数据类型(bool,int,real,string,enum)的变量配置。这些配置根据生效方式,定义了六种类型:

  • INTERNAL类型的选项可以通过内部进程,但完全不能由用户设置。这些GUC变量只能通过SHOW显示。
  • POSTMASTER类型的选项只能在postmaster进程启动时,通过读取命令行或配置文件设置被设置。
  • SIGHUP类型的选项只能在postmaster进程启动时被设置,或者当改变了配置文件并发送SIGHUP信号通知postmaster或postgres进程的时候进行配置。
  • BACKEND类型的选项只能在postmaster启动时通过读取配置文件被设置,或由客户端在进行连接时设置。已经启动的后台进程会忽略该类型的选项。
  • SUSET类型的选项只能在postmaster启动时由SUPERUSER通过SQL命令设置。
  • USERSET类型的选项可以由普通用户在任何时候进行设置。

GUC使用config_generic数据结构来定义postgresql.conf的各项参数,例如名称、分组、说明、选项的值的数据类型等等。
config_generic数据结构

二、初始化配置

在PostmasterMain中,GUC的配置过程如下:

两个主要步骤:InitializeGUCOptions()和SelectConfigFiles()。

初始化所有参数为默认值

从命令行参数读取到数据目录之后读取postgresql.conf文件,重新设置GUC的各项参数为postgresql.conf中的配置。

InitializeGUCOptions()的定义

处理时间及pg_log日志的时间;

num_guc_variables变量用来统计参数个数;

guc_variables是实际的config_generic类型的、已排序的、全局唯一的参数数组,通过它查找变量,我认为可以简单的将它理解为一个在内存中的postgresql.conf的映射。它的定义为:static struct config_generic **guc_variables;它是一个config_generic类型的数组。由以下步骤构造guc_variables数组

1) 定义了config_boolconfig_intconfig_realconfig_stringconfig_enum这几个数据类型,用它们保存不同类型的单个配置项。

2) 在guc_tables.h头文件中定义了ConfigureNamesBoolConfigureNamesIntConfigureNamesRealConfigureNamesStringConfigureNamesEnum这几个数组,数组中保存了boolintrealstringenum这几种类型的缺省值。

以上定义了

3) 接着对上述5个对应不同数据类型的数组进行了两次遍历,第一次遍历得到配置项的总数,设置了配置项的值的数据类型,并为guc_variables分配内存,分配内存时是分配了实际所需内存的1.25倍以方便扩充;第二次遍历从上述5个不同数据类型的数组的gen字段填充guc_variables数组(config_generic类型数组)并根据名称快排。

4) 接下来对上述步骤装载起来的guc_variables遍历,用InitializeOneGUCOptions()逐一设置缺省值,并且通过多个check_hook检查各个配置项是否有效的值。

设置3个重要的transaction的参数为默认值

从环境变量读取PGPORT,PGDATESTYLE,PGCLIENTENCODING的配置。

三、初始化配置之后

在PostmasterMain中

在PostmasterMain中还会根据postmaster进程启动时的参数进行选项的配置,详细的可配置参数信息查看帮助。

以一个-B参数为例:

举例说明

这里-B参数指定share buffers的page的数量,通过page数量乘以block_size的大小计算shared_buffers大小。

在PostgresMain中

在PostgresMain中完成初始化GUC配置之后,还会将配置报告给客户端。

四、增加一个postgresql.conf配置文件的选项

经过以上理论知识的准备,可以知道增加一个postgresql.conf配置文件的选项只需要两个步骤,在代码guc.c:662中有简单的说明:

  • 在guc_tables.h头文件中,根据配置项的值的类型,在不同的值类型数组中增加选项
  • 在src/backend/utils/misc/postgresql.conf.sample文件中增加示例。

五、测试

编辑postgresql.conf.sample增加自定义项

编辑代码增加自定义项

编译安装运行

不修改源码增加自定义的配置,会有什么问题?

六、精简的GUC初始化代码

七、参考资料

《PostgreSQL数据库内核分析(彭智勇 彭煜玮)》