背景
He3DB for PostgreSQL是受Aurora论文启发,基于开源数据库PostgreSQL 改造的数据库产品。架构上实现计算存储分离,并进一步支持数据的冷热分层,大幅提升产品的性价比。
He3DB for PostgreSQL中GUC是一套用于控制数据库配置的参数系统。GUC 参数允许数据库管理员根据需要调整数据库的行为和性能。
一、GUC介绍
1.1 参数分类
GUC(Grand Unified Configuration)参数,其实指的就是pg中的各类参数。如果按生效时分类,主要有以下7类(guc.h文件):
1.typedef enum
2.{
3. PGC_INTERNAL, // 只能通过内部进程设置的参数,用户不能设置
4. PGC_POSTMASTER, // 只能在postmaster启动时,通过读取配置文件或解析命令行参数配置(重启生效)
5. PGC_SIGHUP, // 只能在postmaster启动时,或者改变配置文件后发送SIGHUP信号设置(重启或执行pg_reload_conf();生效)
6. PGC_SU_BACKEND, //只能在postmaster启动时,或者客户端新建连接时生效,已建立的连接会忽略(这类参数只能由超级用户设置)
7. PGC_BACKEND, // 只能在postmaster启动时,或者客户端新建连接时生效,已建立的连接会忽略
8. PGC_SUSET, // 只能在postmaster启动时,或者由超级用户通过SQL(set命令)设置
9. PGC_USERSET // 任何用户任何时候均可配置
10.} GucContext;
1.2 参数来源
参数来源由GucSource
描述(guc.h文件),按照优先级从低到高的顺序排列,相同参数优先级更低或相等时才会生效。
1.typedef enum
2.{
3. PGC_S_DEFAULT, /* 默认值 */
4. PGC_S_DYNAMIC_DEFAULT, /* 通过初始化计算得到 */
5. PGC_S_ENV_VAR, /* 来自环境变量 */
6. PGC_S_FILE, /* 来自postgresql.conf */
7. PGC_S_ARGV, /* 来自postmaster命令行 */
8. PGC_S_GLOBAL, /* 数据库全局设置 */
9. PGC_S_DATABASE, /* 数据库安装时设置 */
10. PGC_S_USER, /* 用户设置 */
11. PGC_S_DATABASE_USER, /* 用户在单个数据库中的设置*/
12. PGC_S_CLIENT, /* 通过客户端连接请求传送过来的数据包设置 */
13. PGC_S_OVERRIDE, /* 特殊场景强制覆盖默认值 */
14. PGC_S_INTERACTIVE, /* 仅作为错误报告的分界线 */
15. PGC_S_TEST, /* 仅用作测试 */
16. PGC_S_SESSION /* SET命令设置 */
17.} GucSource; // 以上来源优先级从低到高
1.3 参数组成
每种类型的GUC参数都有两部分组成:共性部分+特性部分。
共性部分
:由config_generic
结构体描述
特性部分
:每种具体数据类型(boolean,int,float,string)的参数都有对应结构体(例如config_int),且结构体的第一项都是指向共性部分的指针。
共性部分代码
(以下均在guc_tables.h)
1.struct config_generic
2.{
3. /* constant fields, must be set correctly in initial value
4.常量区域,必须正确设置为初始化值 */
5. const char *name; /* 参数名 - MUST BE FIRST */
6. GucContext context; /* 参数类型(按生效时间,即前面提到的GucContext) */
7. enum config_group group; /* 参数分组,使得它们可以在用户界面(如 pg_settings 视图)中以分组的方式展示,方便用户浏览和理解 */
8. const char *short_desc; /* 简单描述 */
9. const char *long_desc; /* 详细描述 */
10. int flags; /* 标志位, see guc.h */
11.
12. /* variable fields, initialized at runtime
13.变量区域,在运行时初始化 */
14. enum config_type vartype; /* 参数值数据类型 int,bool等 */
15. int status; /* 参数状态 */
16. GucSource source; /* 参数来源 */
17. GucSource reset_source; /* 参数值为reset_value时的参数来源*/
18. GucContext scontext; /* 参数设置上下文 */
19. GucContext reset_scontext; /* 参数值为reset_value时的上下文 */
20. GucStack *stack; /* 堆栈,用于保存前一个值 */
21. void *extra; /* "extra" pointer 指向当前真实值 */
22. char *last_reported; /* 如果变量是 GUC_REPORT 类型,这个指针存储了最后一次发送给客户端的值(如果还没有发送,则为 NULL */
23. char *sourcefile; /* 配置所在源文件 */
24. int sourceline; /* 在源文件中的行号 */
25.};
按数据类型分类如下:
1.enum config_type
2.{
3. PGC_BOOL,
4. PGC_INT,
5. PGC_REAL, // 实数
6. PGC_STRING,
7. PGC_ENUM
8.};
特性部分,以config_int为例
1.struct config_int
2.{
3. /* 第一部分一定指向共性结构 */
4. struct config_generic gen;
5.
6. /* constant fields, must be set correctly in initial value: */
7. int *variable; /* 参数当前被设置值 */
8. int boot_val; /* 参数初始值 */
9. int min; /* 参数最小值 */
10. int max; /* 参数最大值 */
11. /*三个钩子函数 */
12. GucIntCheckHook check_hook; /*检查钩子 */
13. GucIntAssignHook assign_hook; /*赋值钩子 */
14. GucShowHook show_hook; /*展示钩子 */
15. /* variable fields, initialized at runtime: */
16. int reset_val; /*存储了 GUC 变量的重置值 */
17. void *reset_extra; /*指向额外的数据,这些数据可以在重置 GUC 变量时使用 */
18.};
二、GUC参数配置过程
参数配置基本过程
:
- 初始化GUC参数:将参数设置为默认值
- 解析postmaster命令行参数:根据postmaster命令行参数进行配置
- 读取参数文件:根据postgresql.conf文件中的设置值再次配置
主要函数调用:
1.postmasterMain(); //主入口点,启动 PostgreSQL 服务
2. |->InitializeGUCOptions(); //初始化全局配置参数(GUC)
3. |->build_guc_variables(); // 构建 GUC 变量的内部数据结构
4. |->InitializeOneGUCOption(); // 初始化单个 GUC 选项的默认值
5. |->SetConfigOption(); //设置相应的 GUC 选项
6. |->InitializeGUCOptionsFromEnvironment(); // 从环境变量中初始化 GUC 选项
7. |->getopt(); // 解析命令行参数
8. |->SetConfigOption(); //设置相应的 GUC 选项
9. |->SelectConfigFiles(); //确定配置文件的位置
10. |->ProcessConfigFile(); // 处理配置文件
11. |->SetConfigOption(); //设置相应的 GUC 选项
2.1 GUC初始化
GUC的初始化主要由函数InitializeGUCOptions()
(位于guc.c)实现。
1.void InitializeGUCOptions(void)
2.{
3. int i; /* 声明循环计数器变量 */
4.
5. /*
6. * 初始化时区处理,
7. * 以确保在设置 log_line_prefix 之前时区处理是可用的。
8. */
9. pg_timezone_initialize();
10.
11. /*
12. * 构建所有GUC变量的排序数组,
13. * 这有助于后续的查找和初始化。
14. */
15. build_guc_variables();
16.
17. /*
18. * 遍历所有GUC变量,使用编译时的默认值进行初始化,
19. * 并设置必要的状态字段。
20. */
21. for (i = 0; i < num_guc_variables; i++)
22. {
23. InitializeOneGUCOption(guc_variables[i]); /* 初始化单个GUC选项 */
24. }
25.
26. /* 重置GUC变更标志,初始时没有变更 */
27. guc_dirty = false;
28.
29. /* 初始时禁用报告功能 */
30. reporting_enabled = false;
31.
32. /*
33. * 防止从非交互式来源覆盖事务模式设置,
34. * 这些设置对数据库的一致性和隔离级别至关重要。
35. */
36. SetConfigOption("transaction_isolation", "read committed", PGC_POSTMASTER, PGC_S_OVERRIDE);
37.