18.1. 设置参数

18.1.1. 参数名称和值

所有参数名都是大小写不敏感的。每个参数都可以接受五种类型之一的值: 布尔、整数、浮点数、字符串或枚举。布尔值可以被写作onofftruefalseyesno10 (都是大小写不敏感的)或者这些值的任何无歧义前缀。

一些设置指定内存或时间值,每一种都有一种隐含单位,可能是千字节、块(通常是 8KB)、 毫秒、秒或分钟。默认单位可以通过引用pg_settings.unit来找到。为了方便,也可以显式地指定一个不同的单位。可用的内存单位是kB(千字节)、MB(兆字节)和GB(吉字节);可用的时间单位是ms(毫秒)、s(秒)、min(分钟)、 h(小时)和d(天)。注意内存单位的乘数是 1024 而不是 1000。

"枚举"类型的参数以与字符串参数相同的方式指定,但被限制到一组有限的值。 可用的值可以在pg_settings.enumvals中找到。枚举参数值是大小写无关的。

18.1.2. 通过配置文件设置参数

设置这些参数的一个方法是编辑postgresql.conf文件, 它通常被保存在数据目录中(当数据库集簇目录被初始化时,一个默认的拷贝将会被安装在那里)。一个该文件的例子看起来是:

# This is a comment
log_connections = yes
log_destination = 'syslog'
search_path = '"$user", public'
shared_buffers = 128MB

每一行指定一个参数。名称和值之间的等号是可选的。空白是无意义的并且空行被忽略。井号(#)指示该行的剩余部分是一个注释。非简单标识符或者数字的参数值必须用单引号包围。要在参数值里嵌入单引号, 要么写两个单引号(首选)或者在引号前放反斜线。

主服务器进程每次收到SIGHUP信号(最简单的方法是从命令行运行pg_ctl reload或调用 SQL 函数pg_reload_conf()后都会重新读取这个配置文件。主服务器进程还会把这个信号传播给所有正在运行的服务器进程,这样现有的会话也能得到新值。另外,你可以直接向一个单一服务器进程发送该信号。有些参数只能在服务器启动时设置,在配置文件中对这些条目的修改将被忽略,直到下次服务器重启。配置文件中的非法参数设置也会在SIGHUP处理过程中被忽略(但是会记录日志)。

18.1.3. 其他设置参数的方法

第二种设置这些配置参数的方法是把它们作为命令行参数传递给postgres命令,例如:

postgres -c log_connections=yes -c log_destination='syslog'

命令行选项覆盖postgresql.conf中任何的冲突设置。注意这意味着你将不能通过编辑postgresql.conf随时改变参数的值,因此虽然命令行方法可能很方便,但是它会牺牲灵活性。

有时候,给一个特定会话一个命令行参数也是很有用的。可以在客户端使用环境变量PGOPTIONS来实现这个目的:

env PGOPTIONS='-c geqo=off' psql

(这对任何基于libpq的客户端应用都有效,不仅仅是psql)。注意这对那些在服务器启动时固定的参数以及那些必须在postgresql.conf中指定的参数无效。

此外,我们可以给一个用户或者一个数据库赋予一组参数设置。在一个会话开始时,所涉及到的用户和数据库的默认设置将被载入。命令 ALTER ROLEALTER DATABASE分别用于配置这些设置。针对每个数据库的设置将覆盖任何来自 postgres命令行或者配置文件的设置,并且接着又被针对每个用户的设置所覆盖;它们最后又会都被针对每个会话的设置覆盖。

一些选项可以在独立的SQL会话中用SET命令修改,例如:

SET ENABLE_SEQSCAN TO OFF;

如果允许用SET设置,它会覆盖所有其他来源的参数值。有些参数不能通过SET改变:例如, 如果这些参数控制着不重启动整个PostgreSQL服务器就无法改变的行为。 同样,有些参数需要超级用户权限来通过SETALTER修改。

18.1.4. 检查参数设置

SHOW命令允许检查所有参数的当前值。

我们也可以用虚拟表pg_settings(细节和不同变量类型的描述以及它们何时能被改变,见Section 47.66)来显示和更新当前会话的运行 时参数。pg_settings等效于SHOWSET,但是用起来更方便, 因为它可以和其它表连接起来使用,或者用任何想要的选择条件来选择。相对从SHOW中可以得到的信息,它也包含更多关于每个参数的信息。

18.1.5. 配置文件包括

除了参数设置,postgresql.conf文件可以包含包括指令,它指定要读入和处理的另一个文件,就好像该文件被插入到配置文件的这个点。这个特性允许一个配置文件被划分成物理上独立的部分。包括指令看起来像:

include 'filename'

如果文件名不是一个绝对路径,它将作为包含引用配置文件的目录的相对位置。包括可以被嵌套。

也有一个include_if_exists指令,它的作用和include指令一样,不过当被引用的文件不存在或者无法被读取时其行为不同。一个通常的include将认为这是一个错误情况,而include_if_exists仅仅记录一个消息并且继续处理引用配置文件。

postgresql.conf文件也可以包含include_dir指令,它指定要被包含的配置文件的一整个目录。它的用法类似:

 include_dir 'directory'
 

非绝对目录名遵循单个文件包括指令的相同规则:它们是包含引用配置文件的目录的相对路径。在那个目录中,只有以后缀名.conf结尾的非目录文件才会被包括。以.字符开头的文件名也被排除,以防止在某些平台上它们是隐藏文件。一个包括目录中的多个文件被以文件名顺序处理。文件名以 C 区域规则排序,即数字在字母之前并且大写字母在小写字母之前。

包括文件或目录可以被用来在逻辑上分隔数据库配置的各个部分,而不是用一个很大的postgresql.conf文件。考虑一个有两台数据库服务器的公司,每一个都有不同的内存量。很可能配置的元素都会被共享,例如用于日志的参数。但是两者关于内存的参数将会不同。并且还可能会有服务器相关的自定义。一种管理这类情况的方法是将你的站点的自定义配置修改分成三个文件。你可以把下面的内容加入到你的postgresql.conf文件末尾来包括它们:

 include 'shared.conf'
 include 'memory.conf'
 include 'server.conf'
 

所有的系统将会有相同的shared.conf。每个有特定内存量的服务器可以共享相同的memory.conf。你可能对所有 8GB 内存的服务器有一个,而对那些 16GB 内存的服务器有另一个。并且最后server.conf可以装有真正服务器相关的配置信息。

另一中可能性是创建一个配置文件目录并把这个信息放到其中的文件里。例如,一个conf.d目录可以在postgresql.conf的末尾被引用:

 include_dir 'conf.d'
 

然后你可以这样命名conf.d目录中的文件:

 00shared.conf
 01memory.conf
 02server.conf
 

这显示了这些文件将被载入的清晰的顺序。这是很重要的,因为只有在服务器读取配置时最后碰到的一个设置才会被使用。这个例子中在conf.d/02server.conf设置的东西将会覆盖在conf.d/01memory.conf中相同参数的值。

你还可以使用这种配置目录方法,但在命名文件时更有描述性:

 00shared.conf
 01memory-8GB.conf
 02server-foo.conf
 

这种形式的安排为每个配置文件变体给定了一个唯一的名称。当多个服务器把它们的配置全部存储在一个位置(例如在一个版本控制仓库中)时,这可以帮助消除歧义(在版本控制下存储数据库配置文件是另一个值得考虑的好方法)。