第 19 章 服务器配置
目录
有许多配置参数会影响数据库系统的行为。本章第一节将介绍如何与配置参数交互。后续各节将详细讨论每个参数。
19.1. 设置参数 #
19.1.1. 参数名称和值 #
所有参数名都是大小写不敏感的。每个参数都可以接受五种类型之一的值:布尔、字符串、整数、浮点数或枚举。该类型决定了设置该参数的语法:
布尔:值可以被写成
on,off,true,false,yes,no,1,0(都是大小写不敏感的)或者这些值的任何无歧义前缀。字符串:通常值被包括在单引号内,值内部的任何单引号都需要被双写。不过,如果值是一个简单数字或者标识符,引号通常可以被省略。
数字(整数和浮点数):只有浮点数参数才允许使用小数点。不要使用千位分隔符。不要求使用引号。
带单位的数字:一些数字参数具有隐含单位,因为它们描述的是内存或时间量。单位可能是字节、千字节、块(通常为 8 千字节)、毫秒、秒或分钟。这类设置若给出不带单位的数字值,就会使用该设置的默认单位,可以通过
pg_settings.unit了解该默认单位。为了方便,也可以显式指定单位,例如把时间值写成'120 ms',系统会将其转换为该参数的实际单位。注意,要使用这一特性,值必须写成字符串(带引号)。单位名称区分大小写,并且数字值与单位之间可以有空白。可用的内存单位是
B(字节)、kB(千字节)、MB(兆字节)、GB(吉字节)和TB(太字节)。内存单位的乘数是 1024,而不是 1000。可用的时间单位是
ms(毫秒)、s(秒)、min(分钟)、h(小时)和d(天)。
枚举:枚举类型的参数以与字符串参数相同的方式指定,但被限制到一组有限的值。这样一个参数可用的值可以在
pg_settings.enumvals中找到。枚举参数值是大小写无关的。
19.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 处理过程中被忽略(但是会记录日志)。
除了 postgresql.conf 之外,PostgreSQL
数据目录还包含文件
postgresql.auto.conf,它与 postgresql.conf 采用相同的格式,但设计为自动编辑而非手工编辑。这个文件保存了通过 ALTER SYSTEM 命令提供的设置。每当读取 postgresql.conf 时,也会读取该文件,并以同样的方式使其中设置生效。postgresql.auto.conf 中的设置会覆盖 postgresql.conf 中的设置。
外部工具也可以修改 postgresql.auto.conf。不建议在服务器运行时这样做,因为并发的 ALTER SYSTEM 命令可能会覆盖这些更改。这类工具可能只是简单地在文件末尾追加新设置,也可能选择删除重复设置和/或注释(正如 ALTER SYSTEM 那样)。
系统视图 pg_file_settings
可以有助于对配置文件中的更改进行提前测试,或者在 SIGHUP
信号没有达到预期效果时用来诊断问题。
19.1.3. 通过 SQL 影响参数 #
PostgreSQL 提供了三个 SQL 命令来建立配置默认值。已经提到过的 ALTER SYSTEM 命令提供了一种改变全局默认值的从 SQL 可访问的方法;它在功效上等效于编辑 postgresql.conf。此外,还有两个命令可以针对每个数据库或者每个角色设置默认值:
ALTER DATABASE 命令允许针对各个数据库覆盖全局设置。
ALTER ROLE 命令允许用针对特定用户设置的值来覆盖全局设置和数据库设置。
只有当开始一个新的数据库会话时,用 ALTER DATABASE 和
ALTER ROLE 设置的值才会被应用。它们会覆盖从配置文件或服务器命令行获得的值,并且作为该会话后续的默认值。注意某些设置在服务器启动后不能被更改,并且因此不能被这些命令(或者下文列举的命令)设置。
一旦一个客户端连接到数据库,PostgreSQL 会提供两个额外的 SQL 命令(以及等效的函数)用以影响会话本地的配置设置:
此外,系统视图 pg_settings 可以被用来查看和改变会话本地的值:
查询这个视图与使用
SHOW ALL相似,但是可以提供更多细节。它也更加灵活,因为可以为它指定过滤条件或者把它与其他关系进行连接。在这个视图上使用 UPDATE 并且指定更新
setting列,其效果等同于发出SET命令。例如,下面的命令SET configuration_parameter TO DEFAULT;
等效于:
UPDATE pg_settings SET setting = reset_val WHERE name = 'configuration_parameter';
19.1.4. 通过 Shell 影响参数
除了设置全局默认值或在数据库、角色级别覆盖默认值之外,你还可以通过 shell 工具把设置传递给 PostgreSQL。服务器和 libpq 客户端库都能通过 shell 接受参数值。
在服务器启动期间,可以通过
-c命令行参数把参数设置传递给postgres命令。例如:postgres -c log_connections=yes -c log_destination='syslog'
这种方式提供的设置会覆盖通过
postgresql.conf或者ALTER SYSTEM提供的设置,因此除了重启服务器之外无法从全局上改变它们。当通过 libpq 启动一个客户端会话时,可以使用
PGOPTIONS环境变量指定参数设置。这种方式建立的设置构成了会话生存期间的默认值,但是不会影响其他的会话。由于历史原因,PGOPTIONS的格式和启动postgres命令时用到的相似,特别是-c标志必须被指定。例如:env PGOPTIONS="-c geqo=off -c statement_timeout=5min" psql
通过 shell 或者其他方式,其他客户端和库可能提供它们自己的机制,以便允许用户在不直接使用 SQL 命令的前提下修改会话设置。
19.1.5. 管理配置文件内容 #
PostgreSQL 提供了一些特性用于把复杂的
postgresql.conf 文件分解成子文件。在管理多个具有相关但不完全相同配置的服务器时,这些特性特别有用。
除了单个参数设置之外,postgresql.conf 文件还可以包含
include 指令,用来指定另一个要读取和处理的文件,就像把该文件插入到配置文件的这个位置一样。这一特性允许把一个配置文件拆分成多个物理上独立的部分。include 指令的形式如下:
include 'filename'
如果文件名不是绝对路径,则会被解释为相对于引用它的配置文件所在目录的路径。include 可以嵌套。
还有一个 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
这种形式的安排为每个配置文件变体给定了一个唯一的名称。当多个服务器把它们的配置全部存储在一个位置(例如在一个版本控制仓库中)时,这可以帮助消除歧义(在版本控制下存储数据库配置文件是另一个值得考虑的好方法)。