一、 GUC参数简介

1. 参数分类

GUC(Grand Unified Configuration)参数,其实指的就是pg中的各类参数。如果按生效时分类,主要有以下6类(guc.h文件):

typedef enum
{PGC_INTERNAL,   // 只能通过内部进程设置的参数,用户不能设置PGC_POSTMASTER, // 只能在postmaster启动时,通过读取配置文件或解析命令行参数配置(重启生效)PGC_SIGHUP,     // 只能在postmaster启动时,或者改变配置文件后发送SIGHUP信号设置(重启或执行pg_reload_conf();生效)PGC_SU_BACKEND, //只能在postmaster启动时,或者客户端新建连接时生效,已建立的连接会忽略(这类参数只能由超级用户设置)PGC_BACKEND,    // 只能在postmaster启动时,或者客户端新建连接时生效,已建立的连接会忽略PGC_SUSET,      // 只能在postmaster启动时,或者由超级用户通过SQL(set命令)设置PGC_USERSET     // 任何用户任何时候均可配置
} GucContext;

2. 参数来源

参数来源由GucSource描述(guc.h文件),按照优先级从低到高的顺序排列,相同参数优先级更高的来源值会生效。

typedef enum
{PGC_S_DEFAULT,              /* 默认值 */PGC_S_DYNAMIC_DEFAULT,      /* 通过初始化计算得到 */PGC_S_ENV_VAR,              /* 来自环境变量 */PGC_S_FILE,                 /* 来自postgresql.conf */PGC_S_ARGV,                 /* 来自postmaster命令行 */PGC_S_GLOBAL,               /* 数据库全局设置 */PGC_S_DATABASE,             /* 数据库安装时设置 */PGC_S_USER,                 /* 用户设置 */PGC_S_DATABASE_USER,        /* 用户在单个数据库中的设置*/PGC_S_CLIENT,               /* 通过客户端连接请求传送过来的数据包设置 */PGC_S_OVERRIDE,             /* 特殊场景强制覆盖默认值 */PGC_S_INTERACTIVE,          /* 仅作为错误报告的分界线 */PGC_S_TEST,                 /* 仅用作测试 */PGC_S_SESSION               /* SET命令设置 */
} GucSource;  // 以上来源优先级从低到高

3. 参数组成

每种类型的GUC参数都有两部分组成:共性部分+特性部分。

  • 共性部分:由config_generic结构体描述
  • 特性部分:每种具体数据类型(boolean,int,float,string)的参数都有对应结构体(例如config_int),且结构体的第一项都是指向共性部分的指针。

共性部分代码(以下均在guc_tables.h)

struct config_generic
{/* constant fields, must be set correctly in initial value
常量区域,必须正确设置为初始化值 */const char *name;           /* 参数名 - MUST BE FIRST */GucContext  context;        /* 参数类型(按生效时间,即前面提到的GucContext) */enum config_group group;    /* 参数分组 */const char *short_desc;     /* 简单描述 */const char *long_desc;      /* 详细描述 */int         flags;          /* 标志位, see guc.h *//* variable fields, initialized at runtime
变量区域,在运行时初始化 */enum config_type vartype;   /* 参数值数据类型 */int         status;         /* 参数状态 */GucSource   source;         /* 参数来源 */GucSource   reset_source;   /* 参数值为reset_value时的参数来源*/GucContext  scontext;       /* 参数设置上下文 */GucContext  reset_scontext; /* 参数值为reset_value时的上下文 */GucStack   *stack;          /* 堆栈,用于保存前一个值 */void       *extra;          /* "extra" pointer 指向当前真实值 */char       *last_reported;  /* if variable is GUC_REPORT, value last sent to client (NULL if not yet sent) */char       *sourcefile;     /* 配置所在源文件 */int         sourceline;     /* 在源文件中的行号 */
};

按数据类型分类如下:

enum config_type
{PGC_BOOL,PGC_INT,PGC_REAL,  // 实数PGC_STRING,PGC_ENUM
};

特性部分,以config_int为例

struct config_int
{/* 第一部分一定指向共性结构 */struct config_generic gen;/* constant fields, must be set correctly in initial value: */int        *variable;   /* 参数当前被设置值 */int         boot_val;   /* 参数初始值 */int         min;         /* 参数最小值 */int         max;         /* 参数最大值 */GucIntCheckHook check_hook;GucIntAssignHook assign_hook;  /* 用于设置reset_val */GucShowHook show_hook;/* variable fields, initialized at runtime: */int         reset_val;void       *reset_extra;
};

4. 参数配置基本过程

  • 初始化GUC参数:将参数设置为默认值
  • 解析postmaster命令行参数:根据postmaster命令行参数进行配置
  • 读取参数文件:根据postgresql.conf文件中的设置值再次配置

铺垫了这么多,终于又回到PostmasterMain函数上,我们接着上次的代码继续往下看。

二、 初始化GUC参数

这个对应的只有一句

    /** Options setup*/InitializeGUCOptions();opterr = 1;

InitializeGUCOptions函数主要干两件事:

  • 循环调用InitializeOneGUCOption函数,为每个变量设置前面提到的共性和特性部分
  • 调用InitializeGUCOptionsFromEnvironment函数:根据环境变量的值进行初始化
/** Initialize GUC options during program startup.** Note that we cannot read the config file yet, since we have not yet* processed command-line switches.*/
void
InitializeGUCOptions(void)
{int         i;/* 时区初始化 */pg_timezone_initialize();/** 该函数统计参数个数并分配相应的config_generic类型的全局指针数组guc_variables以保存每个参数结构体的地址,并且对该数据进行排序。*/build_guc_variables();/** 遍历参数数组,并为每个参数的共性及特性结构体部分填充值*/for (i = 0; i < num_guc_variables; i++){InitializeOneGUCOption(guc_variables[i]);}guc_dirty = false;reporting_enabled = false;/* 避免事务相关设置被覆盖 */SetConfigOption("transaction_isolation", "read committed",PGC_POSTMASTER, PGC_S_OVERRIDE);SetConfigOption("transaction_read_only", "no",PGC_POSTMASTER, PGC_S_OVERRIDE);SetConfigOption("transaction_deferrable", "no",PGC_POSTMASTER, PGC_S_OVERRIDE);/* 由于历史原因,部分参数需要从环境变量中获取值 */InitializeGUCOptionsFromEnvironment();
}

三、 解析postmaster命令行参数

  1. 解析postmaster命令行参数,并用于设置GUC参数值。代码很长,这里省略一部分,有点类似shell的写法。
while ((opt = getopt(argc, argv, "B:bc:C:D:d:EeFf:h:ijk:lN:nOPp:r:S:sTt:W:-:")) != -1){switch (opt){case 'B':SetConfigOption("shared_buffers", optarg, PGC_POSTMASTER, PGC_S_ARGV);break;case 'b':/* Undocumented flag used for binary upgrades */IsBinaryUpgrade = true;break;
…case 'N':SetConfigOption("max_connections", optarg, PGC_POSTMASTER, PGC_S_ARGV);break;case 'n':/* Don't reinit shared mem after abnormal exit */Reinit = false;break;
…default:write_stderr("Try \"%s --help\" for more information.\n",progname);ExitPostmaster(1);}}

四、 读取参数文件

SelectConfigFiles函数首先在指定目录下找到配置文件,然后调用词法分析程序解析文件。对于解析到的每个参数及其参数值,调用SetConfigOption函数完成参数修改。

设置完成后还会进行参数合法性检验,如果一切合法,则将当前目录转入数据目录。进行后续操作。

    /** Locate the proper configuration files and data directory, and read postgresql.conf for the first time.*/if (!SelectConfigFiles(userDoption, progname))ExitPostmaster(2);

五、 杂七杂八

下面内容比较散也比较少,合在一部分。

1. 创建数据库集群锁定文件

调用CreateDataDirLockFile()函数在数据目录建立数据库集群的lock文件postmaster.pid,这样就能保证不会对同一个数据库集群"启动两次"。虽然也会建立socket lock文件,但仍是认为数据目录的锁文件更可信。

/** Create lockfile for data directory.** We want to do this before we try to grab the input sockets, because the data directory interlock is more reliable than the socket-file interlock.*/CreateDataDirLockFile(true);     /** Read the control file (for error checking and config info).*/LocalProcessControlFile(false);/** Register the apply launcher.  */ApplyLauncherRegister();

CreateDataDirLockFile函数定义

由于调用此函数前已经将目录切换至pg数据目录,因此函数中只需使用相对目录

void
CreateDataDirLockFile(bool amPostmaster)
{CreateLockFile(DIRECTORY_LOCK_FILE, amPostmaster, "", true, DataDir);
}

CreateLockFile这个函数很长,但它做的就是在数据目录中创建一个postmaster.pid文件

2. 共享库预加载

pg丰富的插件,其中不少就是通过共享库来实现的。这里就是调用process_shared_preload_libraries()函数来导入在shared_preload_libraries参数中指定的共享库。

/** process any libraries that should be preloaded at postmaster start*/process_shared_preload_libraries();/** Initialize SSL library, if specified.*/
#ifdef USE_SSLif (EnableSSL){(void) secure_initialize(true);LoadedSSL = true;}
#endif/** Now that loadable modules have had their chance to register background workers, calculate MaxBackends.*/InitializeMaxBackends();

3. 共享内存初始化

这里调用各模块的共享内存的使用量估计函数,计算总共所需的共享内存的量并申请。详细可以看CreateSharedMemoryAndSemaphores()函数。

    /** Set up shared memory and semaphores.*/reset_shared();

4. 启动syslogger子进程

    /** If enabled, start up syslogger collection subprocess*/SysLoggerPID = SysLogger_Start();

参考

《PostgreSQL数据库内核分析》第二章

Postgres中postmaster代码解析(上) - JavaShuo

PG守护进程(Postmaster)——初始化GUC配置参数 - 肥叔菌 - 博客园

postgresql源码学习(45)—— PostmasterMain(2) GUC参数简介及设置相关推荐

  1. PostgreSQL源码学习(一)编译安装与GDB入门

    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 PostgreSQL源码学习(一)编译安装与GDB入门 前言 一.安装PostgreSQL 1.获取源码 2.配置 3.编译 3.安装 ...

  2. PostgreSQL源码学习(1)--PG13代码结构

    PostgreSQL源码学习(1)–PG13代码结构 PostgreSQL代码结构 Bootstrap:用于支持Bootstrap运行模式,该模式主要用来创建初始的模板数据库. Main:主程序模块, ...

  3. postgresql源码学习(27)—— 事务日志⑦-日志落盘上层函数 XLogFlush

    一. 预备知识 1. XLOG什么时候需要落盘 事务commit之前 log buffer被覆盖之前 后台进程定期落盘 2. 两个核心结构体 这两个结构体定义代码在xlog.c,它们在日志落盘过程中非 ...

  4. postgresql源码学习(51)—— 提交日志CLOG 原理 用途 管理函数

    一. CLOG是什么 CLOG(commit log)记录事务的最终状态. 物理上,是$PGDATA/pg_xact目录下的一些文件 逻辑上,是一个数组,下标为事务id,值为事务最终状态 1. 事务最 ...

  5. postgresql源码学习(49)—— MVCC⑤-cmin与cmax 同事务内的可见性判断

    一. 难以理解的场景 postgresql源码学习(十九)-- MVCC④-可见性判断 HeapTupleSatisfiesMVCC函数_Hehuyi_In的博客-CSDN博客 在前篇的可见性判断中有 ...

  6. postgresql源码学习(57)—— pg中的四种动态库加载方法

    一. 基础知识 1. 什么是库 库其实就是一些通用代码,可以在程序中重复使用,比如一些数学函数,可以不需要自己编写,直接调用相关函数即可实现,避免重复造轮子. 在linux中,支持两种类型的库: 1. ...

  7. postgresql源码学习(52)—— vacuum①-准备工作与主要流程

    关于vacuum的基础知识,参考,本篇从源码层继续学习 https://blog.csdn.net/Hehuyi_In/article/details/102992065 https://blog.c ...

  8. postgresql源码学习(53)—— vacuum②-lazy vacuum之heap_vacuum_rel函数

    一. table_relation_vacuum函数 1. 函数定义 前篇最后(https://blog.csdn.net/Hehuyi_In/article/details/128749517),我 ...

  9. postgresql源码学习(一)—— 源码编译安装与gdb调试入门

    一. postgresql源码编译安装 因为只是用来调试的测试环境,把基本的软件装好和库建好就可以,一切从简. 1. 创建用户和目录 mkdir -p /data/postgres/base/ mkd ...

最新文章

  1. CCS Font 知识整理总结
  2. 【Java 网络编程】UDP 服务器 客户端 通信 ( DatagramSocket | DatagramPacket | UDP 发送数据包 | UDP 接收数据包 | 端口号分配使用机制 )
  3. NTU 课程笔记 CV6422 假设检验
  4. 随笔汇总_索取资料请进入
  5. python代码解读软件_5种带你轻松分析Python代码的软件库
  6. Flag counter被博客园禁了的解决方法
  7. 一个关于Remoting的简单例子
  8. 计算机专业人毕业设计外文翻译,计算机专业毕业设计外文翻译.doc
  9. pytorch分布式训练(二):torch.nn.parallel.DistributedDataParallel
  10. Python3网络爬虫开发实战,抓包工具 Charles 的使用
  11. SpringCloud系列-Ribbon的基本应用
  12. java跨库调用存储_java-调用spring数据其余存储库方法不会返回...
  13. php 模拟客户端访问,PHP通过伪造和模拟客户端COOKIE登陆来采集抓取远程网址
  14. DataSet如何处理海量数据
  15. java语法让反编译报错_java 反编译
  16. 商城前端模板_新零售时代如何玩转微信商城
  17. 主流编程语言的特点以及优缺点(一)
  18. 在Excel中如何实现快速互换两列内容
  19. 巴塞尔协议中的计算公式_十分钟读懂巴塞尔协议
  20. 涨姿势!3D游戏里的男女性角色是这样建模出来的

热门文章

  1. AI养宠时代来临,铲屎官终于解放双手?
  2. 神经网络模型u-net 、VGG
  3. Python语音基础操作--11.2基于GMM的说话人识别模型
  4. 趣味c语言代码,趣味程序C语言
  5. 现代质量工程第五、六、八章课后习题答案
  6. 【Web】一种好用的浏览器页面打印(打印销售小票)方法
  7. 多IMU车载GNSS/INS数据集及介绍
  8. 物联网智能家居项目总结(全)
  9. asp.net夜话之九:验证控件
  10. JS基础 -- 大复习(阶段六:对象和内置对象及预解析)