PostgreSQL 环境变量相关代码解析

PostgreSQL 启动和运行过程中会依据环境变量做某些操作或设置,比如 initdb 时默认使用环境变量设置数据库的编码方式。在 Linux Shell 上无论是启动 PostgreSQL 或者某个独立进程(比如 initdb、pgdump 等),Shell 作为它们的父进程 fork 出子进程,fork 会把父进程的环境变量复制给子进程,然后子进程调用 exec() 函数启动相应的程序,这样我们的 PostgreSQL 就拿到了所有的环境变量了。

基本的原理清楚了,那从具体代码角度讲,PostgreSQL 是如何获取到环境变量的呢?

某个具体的环境变量是一个 key=value 模式的字符串,所有的 key=value 模式的字符串构成了环境变量表。在 libc 库中定义了一个全局环境变量表的指针 environ,在代码中只要访问该指针即可获取到环境变量。

程序中如何使用环境变量

与环境变量相关的 libc 库函数包含了 getenv()、setenv()、unsetenv() 这三个函数,顾名思义不再详细叙述,但需要注意的是它们的使用需要引用 stdlib.h 头文件,

也可以直接解析 environ 指针,需要在源文件中 extern 一下;或者引入 unistd.h 头文件,但要提前声明 __USE_GNU 宏。

extern char ** environ;
#define __USE_GNU
#include <unistd.h>

当然,也可以使用另外一种 main() 函数的声明方法,引入环境变量的指针。

int main(int argc, char *argv[], char *env[])

PostgreSQL 中的环境变量

打印输出环境变量

在 PostmasterMain() 函数中打印输出了所有的环境变量,代码如下所示:

/* For debugging: display postmaster environment */
{
	extern char **environ;
	char	  **p;

	ereport(DEBUG3,
			(errmsg_internal("%s: PostmasterMain: initial environment dump:",
							 progname)));
	ereport(DEBUG3,
			(errmsg_internal("-----------------------------------------")));
	for (p = environ; *p; ++p)
		ereport(DEBUG3,
				(errmsg_internal("\t%s", *p)));
	ereport(DEBUG3,
			(errmsg_internal("-----------------------------------------")));
}

设置 ps 输出的标题

PostgreSQL 会实时更改 ps 命令输出中的标题,用以提示 PostgreSQL 的进程当前的状态,这个功能的主要代码逻辑在 ps_status.c 文件中。更改 ps 输出标题的方法因操作系统平台的不同而各不相同,但 Linux 平台和大多数的 System-V 平台都可以使用覆写入参和环境变量区域的方法来实现。

在这些平台上,main() 函数中的 argv 和 environ 环境变量表都在一块连续的内存区域内,不同的字符串用 ‘\0’ 或空格隔开。主要代码逻辑集中在 save_ps_display_args() 函数中。

未完待续。

分类:PostgreSQL

Tagged as: ,

发表评论

Fill in your details below or click an icon to log in:

WordPress.com 徽标

You are commenting using your WordPress.com account. Log Out /  更改 )

Google photo

You are commenting using your Google account. Log Out /  更改 )

Twitter picture

You are commenting using your Twitter account. Log Out /  更改 )

Facebook photo

You are commenting using your Facebook account. Log Out /  更改 )

Connecting to %s

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理