3.4. 运行时配置 #
有大量配置参数以各种方式影响数据库系统的行为。这里我们描述如何设置它们,随后的小节将逐一详细讨论。
所有参数名都不区分大小写。每个参数取以下四种类型之一的值:布尔、整数、浮点、字符串,如下所述。布尔值可以是
ON、OFF、TRUE、FALSE、YES、NO、1、0(不区分大小写)或其中任何一个无歧义的前缀。
设置这些选项的一种方法是编辑数据目录中的
postgresql.conf 文件。(安装时会在此处放置一个默认文件。)该文件的内容可能类似于:
# This is a comment log_connections = yes syslog = 2
如你所见,选项每行一个。名称和值之间的等号是可选的。空白无关紧要,空行会被忽略。井号(“#”)可在任何位置引入注释。
每当 postmaster 收到 SIGHUP 信号时(用
pg_ctl reload 发送最为简单),配置文件就会被重新读取。postmaster 还会把该信号传播给所有已在运行的后端进程,使现有会话也获得新的默认值。另外,你也可以只把信号直接发送给单个后端进程。
设置这些配置参数的第二种方法是把它们作为命令行选项传给 postmaster,例如:
postmaster -c log_connections=yes -c syslog=2
其效果与前面的例子相同。命令行选项覆盖
postgresql.conf 中任何与之冲突的设置。
有时,只给某个特定的后端会话指定命令行选项也很有用。为此可以在客户端一侧使用环境变量 PGOPTIONS:
env PGOPTIONS='-c geqo=off' psql
(这适用于任何客户端应用程序,不只是 psql。)注意,对那些在服务器启动后必然固定的选项(例如端口号),这种方式不起作用。
最后,有些选项可以在单个 SQL 会话中用 SET
命令更改,例如:
=> SET ENABLE_SEQSCAN TO OFF;语法的细节参见 SQL 命令语言参考。
3.4.1. 规划器和优化器调整 #
CPU_INDEX_TUPLE_COST(floating point)设置查询优化器对索引扫描期间处理每个索引元组的代价的估计。它以顺序获取一个页面的代价的一个比例来计量。
CPU_OPERATOR_COST(floating point)设置优化器对处理 WHERE 子句中每个操作符的代价的估计。它以顺序获取一个页面的代价的一个比例来计量。
CPU_TUPLE_COST(floating point)设置查询优化器对查询期间处理每个元组的代价的估计。它以顺序获取一个页面的代价的一个比例来计量。
EFFECTIVE_CACHE_SIZE(floating point)设置优化器关于磁盘缓存有效大小的假设(即内核磁盘缓存中将被用于 PostgreSQL 数据文件的部分)。它以磁盘页为单位计量,每页通常为 8 kB。
ENABLE_HASHJOIN(boolean)启用或禁用查询规划器对哈希连接计划类型的使用。默认是打开的。这主要用于调试查询规划器。
ENABLE_INDEXSCAN(boolean)启用或禁用查询规划器对索引扫描计划类型的使用。默认是打开的。这主要用于调试查询规划器。
ENABLE_MERGEJOIN(boolean)启用或禁用查询规划器对归并连接计划类型的使用。默认是打开的。这主要用于调试查询规划器。
ENABLE_NESTLOOP(boolean)启用或禁用查询规划器对嵌套循环连接计划的使用。不可能完全压制嵌套循环连接,但关闭此变量会使规划器在有其他方法可用时不去使用它。默认是打开的。这主要用于调试查询规划器。
ENABLE_SEQSCAN(boolean)启用或禁用查询规划器对顺序扫描计划类型的使用。不可能完全压制顺序扫描,但关闭此变量会使规划器在有其他方法可用时不去使用它。默认是打开的。这主要用于调试查询规划器。
ENABLE_SORT(boolean)启用或禁用查询规划器对显式排序步骤的使用。不可能完全压制显式排序,但关闭此变量会使规划器在有其他方法可用时不去使用它。默认是打开的。这主要用于调试查询规划器。
ENABLE_TIDSCAN(boolean)启用或禁用查询规划器对 TID 扫描计划类型的使用。默认是打开的。这主要用于调试查询规划器。
GEQO(boolean)启用或禁用遗传查询优化,它是一种试图不做穷举搜索就完成查询规划的算法。默认是打开的。另见其他各种
GEQO_设置。GEQO_EFFORT(integer)GEQO_GENERATIONS(integer)GEQO_POOL_SIZE(integer)GEQO_RANDOM_SEED(integer)GEQO_SELECTION_BIAS(floating point)遗传查询优化算法的各种调整参数:池大小(pool size)是一个种群中个体的数量。有效值在 128 到 1024 之间。如果设置为 0(默认值),则取池大小为 2^(QS+1),其中 QS 是查询中 FROM 项的数量。effort 用于计算 generations 的默认值。有效值在 1 到 80 之间,默认为 40。generations 指定算法中迭代的次数。该数必须是正整数。如果指定为 0,则使用
Effort * Log2(PoolSize)。算法的运行时间大致与池大小和 generations 之和成正比。选择偏差(selection bias)是种群内的选择压力。取值可以从 1.50 到 2.00;后者是默认值。随机种子(random seed)可以设置,以从算法获得可复现的结果。如果设置为 -1,则算法的行为是非确定性的。GEQO_THRESHOLD(integer)当查询涉及的
FROM项至少达到此数量时,使用遗传查询优化进行规划。(注意,一个JOIN结构只算一个FROM项。)默认值是 11。对较简单的查询,通常最好使用确定性的穷举规划器。此参数还控制优化器将子查询的FROM子句合并到上层查询的积极程度。KSQO(boolean)键集查询优化器(KSQO)使查询规划器把
WHERE子句包含许多 OR 连接的 AND 子句的查询(例如WHERE (a=1 AND b=2) OR (a=2 AND b=3) ...)转换为联合查询。这种方法可以比默认实现更快,但它不一定会给出完全相同的结果,因为UNION隐式添加了一个SELECT DISTINCT子句来消除相同的输出行。使用 Microsoft Access 之类的产品时通常会用到 KSQO,它们倾向于生成这种形式的查询。KSQO 算法过去对包含许多 OR 连接的 AND 子句的查询绝对不可或缺,但在 PostgreSQL 7.0 及更高版本中,标准规划器已经能相当好地处理这些查询。因此默认是关闭的。
RANDOM_PAGE_COST(floating point)设置查询优化器对非顺序获取一个磁盘页的代价的估计。它以顺序获取一个页面的代价的倍数来计量。
注意
遗憾的是,没有定义良好的方法来确定刚才描述的这组 “COST” 变量的理想值。鼓励你进行实验并分享你的发现。
3.4.2. 日志和调试 #
DEBUG_ASSERTIONS(boolean)打开各种断言检查。这是一种调试辅助。如果你遇到奇怪的问题或崩溃,可能需要打开它,因为它可能暴露编程错误。要使用此选项,构建 PostgreSQL 时必须定义宏
USE_ASSERT_CHECKING(见 configure 选项--enable-cassert)。注意,如果 PostgreSQL 是以这种方式构建的,DEBUG_ASSERTIONS默认是打开的。DEBUG_LEVEL(integer)此值设置得越高,服务器运行期间在服务器日志中生成的各种“调试”输出就越多。此选项默认为 0,表示没有调试输出。目前大约最高到 4 的值是有意义的。
DEBUG_PRINT_QUERY(boolean)DEBUG_PRINT_PARSE(boolean)DEBUG_PRINT_REWRITTEN(boolean)DEBUG_PRINT_PLAN(boolean)DEBUG_PRETTY_PRINT(boolean)这些标志启用向服务器日志发送各种调试输出。对每个执行的查询,打印查询文本、所得的语法解析树、查询重写器输出或执行计划之一。
DEBUG_PRETTY_PRINT会对这些显示进行缩进,产生更可读但也长得多的输出格式。把DEBUG_LEVEL设置为大于零会隐式打开其中一些标志。HOSTNAME_LOOKUP(boolean)默认情况下,连接日志只显示连接主机 IP 地址。如果想让它显示主机名,可以打开此选项,但取决于你的主机名解析配置,这可能带来不可忽视的性能损失。此选项只能在服务器启动时设置。
LOG_CONNECTIONS(boolean)在服务器日志中打印一行,告知每个成功的连接。默认是关闭的,尽管它可能非常有用。此选项只能在服务器启动时或在
postgresql.conf配置文件中设置。LOG_PID(boolean)在服务器日志的每条消息前加上后端进程的进程 ID。这有助于分清哪些消息属于哪个连接。默认是关闭的。
LOG_TIMESTAMP(boolean)在服务器日志的每条消息前加上时间戳。默认是关闭的。
SHOW_QUERY_STATS(boolean)SHOW_PARSER_STATS(boolean)SHOW_PLANNER_STATS(boolean)SHOW_EXECUTOR_STATS(boolean)对每个查询,把相应模块的性能统计写入服务器日志。这是一种粗略的性能剖析工具。
SHOW_SOURCE_PORT(boolean)在连接日志消息中显示连接主机的源端口号。你可以追溯端口号,找出是哪个用户发起的连接。除此之外它没什么用处,因此默认是关闭的。此选项只能在服务器启动时设置。
STATS_COMMAND_STRING(boolean)STATS_BLOCK_LEVEL(boolean)STATS_ROW_LEVEL(boolean)这些标志决定后端向统计收集器进程发送什么信息:当前命令、块级活动统计或行级活动统计。全部默认关闭。启用统计收集会让每个查询花费少量时间,但对调试和性能调优非常宝贵。
STATS_RESET_ON_SERVER_START(boolean)如果打开,收集到的统计信息在服务器每次重启时清零。如果关闭,统计信息跨服务器重启累计。默认是打开的。此选项只能在服务器启动时设置。
STATS_START_COLLECTOR(boolean)控制服务器是否应启动统计收集子进程。默认是打开的,但如果你确定对收集统计信息没有兴趣,可以把它关闭。此选项只能在服务器启动时设置。
SYSLOG(integer)PostgreSQL 允许使用 syslog 记录日志。如果此选项设置为 1,消息会同时发送到 syslog 和标准输出。设置为 2 则只把输出发送到 syslog。(有些消息仍会发送到标准输出/错误。)默认值是 0,表示 syslog 关闭。此选项必须在服务器启动时设置。
要使用 syslog,PostgreSQL 的构建必须用
--enable-syslog选项配置。SYSLOG_FACILITY(string)此选项决定启用 syslog 时所使用的 syslog “设施”。可以从 LOCAL0、LOCAL1、LOCAL2、LOCAL3、LOCAL4、LOCAL5、LOCAL6、LOCAL7 中选择;默认值是 LOCAL0。另见你的系统的 syslog 文档。
SYSLOG_IDENT(string)如果启用了记录到 syslog,此选项决定在 syslog 日志消息中用于标识 PostgreSQL 消息的程序名。默认值是
postgres。TRACE_NOTIFY(boolean)为
LISTEN和NOTIFY命令生成大量调试输出。
3.4.3. 常规操作 #
AUSTRALIAN_TIMEZONES(bool)如果设置为真,
CST、EST和SAT会被解释为澳大利亚时区,而不是北美中部/东部时区和星期六。默认是假。AUTHENTICATION_TIMEOUT(integer)完成客户端认证的最长时间,以秒为单位。如果一个潜在客户端没有在这段时间里完成认证协议,服务器会毫不客气地断开连接。这防止了挂起的客户端无限期占用连接。此选项只能在服务器启动时或在
postgresql.conf文件中设置。DEADLOCK_TIMEOUT(integer)这是在等待锁多长时间(以毫秒计)之后才检查是否存在死锁条件。死锁检查相对较慢,所以我们不想在每次等待锁时都运行它。我们(乐观地?)假设生产应用中死锁并不常见,先在锁上等待一会儿,然后才开始追问它究竟还能否被解锁。增大此值可以减少无谓的死锁检查所浪费的时间,但会减慢真实死锁错误的报告。默认值是 1000(即一秒),这大概是你实践中想要的最小值。在负载很重的服务器上,你可能需要提高它。理想情况下,该设置应当超过你的典型事务时间,以便提高在等待者决定检查死锁之前锁就被释放的机会。此选项只能在服务器启动时设置。
DEFAULT_TRANSACTION_ISOLATION(string)每个 SQL 事务都有一个隔离级别,可以是“读已提交”或“可串行化”。此参数控制每个新事务的隔离级别被设置为什么。默认是读已提交。
更多信息参见 PostgreSQL 用户指南以及命令
SET TRANSACTION。DYNAMIC_LIBRARY_PATH(string)当需要打开一个动态可加载模块而指定的名称不含目录部分(即名称中不含斜杠)时,系统会在此路径中搜索指定的文件。(所用的名称是
CREATE FUNCTION或LOAD命令中指定的名称。)dynamic_library_path 的值必须是一个冒号分隔的绝对目录名列表。如果目录名以特殊值
$libdir开头,则替换为编译时确定的 PostgreSQL 包库目录,PostgreSQL 发行版提供的模块就安装在那里。(使用pg_config --pkglibdir可以打印此目录的名称。)示例值:dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir'
此参数的默认值是
$libdir。如果值设置为空字符串,则关闭自动路径搜索。超级用户可以在运行时更改此参数,但注意以那种方式做的设置只会保持到客户端连接结束,因此这种方法应仅保留用于开发目的。设置此参数的推荐方式是在
postgresql.conf配置文件中。FSYNC(boolean)如果此选项打开,PostgreSQL 后端会在多处使用
fsync()系统调用,确保更新被物理写入磁盘,而不是滞留在内核缓冲区缓存中。这会大大增加数据库安装在操作系统或硬件崩溃之后仍然可用的机会。(数据库服务器自身的崩溃不影响此考虑。)不过,此操作会减慢 PostgreSQL,因为在所有那些位置它都必须阻塞并等待操作系统刷新缓冲区。不使用
fsync时,操作系统被允许尽其所能地对写操作进行缓冲、排序和延迟,这可以带来可观的性能提升。但是,如果系统崩溃,最近若干已提交事务的结果可能部分或全部丢失;最坏情况下,可能发生不可恢复的数据损坏。此选项是 PostgreSQL 用户和开发者社区中一场永恒争论的主题。有些始终关闭它,有些只在批量装载时关闭它(批量装载出问题时存在明确的重启点),还有些只是为保险起见而保持打开。因为它是安全的一侧,打开也是默认值。如果你信任你的操作系统、硬件和电力公司(更好的是你有 UPS),可能需要禁用
fsync。应当指出,做
fsync的性能损失在 PostgreSQL 7.1 版中已比以前的版本显著降低。如果你过去因性能问题禁用了fsync,可以重新考虑你的选择。此选项只能在服务器启动时或在
postgresql.conf文件中设置。KRB_SERVER_KEYFILE(string)设置 Kerberos 服务器密钥文件的位置。详情见第 4.2.3 节。
MAX_CONNECTIONS(integer)决定数据库服务器允许的并发连接数。默认值是 32(除非在构建服务器时被更改)。这个参数只能在服务器启动时设置。
MAX_EXPR_DEPTH(integer)设置解析器可接受的最大表达式嵌套深度。默认值对任何正常查询都足够高,但如有需要可以提高它。(但如果提得太高,就有因栈溢出而导致后端崩溃的风险。)
MAX_FILES_PER_PROCESS(integer)设置每个服务器子进程允许同时打开的最大文件数。默认值是 1000。代码实际使用的限制是此设置与
sysconf(_SC_OPEN_MAX)结果中的较小者。因此,在sysconf返回合理限制的系统上,你无需担心此设置。但在某些平台上(特别是大多数 BSD 系统),sysconf返回的值远大于当大量进程都试图打开那么多文件时系统真正能够支持的值。如果你发现出现 “Too many open files”失败,可尝试调低此设置。此选项只能在服务器启动时或在postgresql.conf配置文件中设置;如果在配置文件中更改,只影响随后启动的服务器子进程。MAX_FSM_RELATIONS(integer)设置共享空闲空间映射中为其跟踪空闲空间的关系(表)的最大数量。默认值是 100。这个选项只能在服务器启动时设置。
MAX_FSM_PAGES(integer)设置共享空闲空间映射中为其跟踪空闲空间的磁盘页最大数量。默认值是 10000。这个选项只能在服务器启动时设置。
MAX_LOCKS_PER_TRANSACTION(integer)共享锁表的大小基于这样的假设:任意时刻最多有
max_locks_per_transaction*max_connections个不同的对象需要加锁。默认值 64 历史上已被证明是足够的,但如果你的客户端在单个事务中会接触许多不同的表,可能需要提高此值。此选项只能在服务器启动时设置。PASSWORD_ENCRYPTION(boolean)在
CREATE USER或ALTER USER中指定口令,且既没有写 ENCRYPTED 也没有写 UNENCRYPTED 时,此标志决定口令是否被加密。默认是关闭的(不加密口令),但这一选择在未来的版本中可能改变。PORT(integer)服务器监听的 TCP 端口,默认是 5432。这个选项只能在服务器启动时设置。
SHARED_BUFFERS(integer)设置数据库服务器将使用的共享内存缓冲区数量。默认值是 64。每个缓冲区通常为 8192 字节。这个选项只能在服务器启动时设置。
SILENT_MODE(bool)让 postmaster 静默运行。如果设置了此选项,postmaster 将自动在后台运行,并脱离任何控制终端,这样,不会有任何消息写到标准输出或标准错误(效果与 postmaster 的 -S 选项相同)。除非启用了 syslog 之类的日志系统,否则不建议使用此选项,因为它会使你无法看到错误消息。
SORT_MEM(integer)指定内部排序和哈希在切换到临时磁盘文件之前可使用的内存量。值以千字节为单位指定,默认为 512 千字节。注意,对于复杂查询,可能同时运行多个排序和/或哈希,每一个在被允许开始把数据放入临时文件之前,都可以使用多达该值所指定的内存。而且别忘了,每个运行中的后端可能正在做一个或多个排序。因此所需的总内存可能是
SORT_MEM值的许多倍。SQL_INHERITANCE(bool)此参数控制继承语义,特别是各种命令在考虑范围中是否默认包含子表。7.1 之前的版本不是这样。如果你需要旧行为,可以把此变量设置为关闭,但长远来看,建议你修改应用程序,用
ONLY关键字排除子表。关于继承的更多信息,参见 SQL 语言参考和用户指南。SSL(boolean)启用SSL连接。使用前请阅读第 3.7 节。默认是关闭的。
TCPIP_SOCKET(boolean)如果为真,服务器将接受 TCP/IP 连接。否则只接受本地 Unix 域套接字连接。默认是关闭的。这个选项只能在服务器启动时设置。
TRANSFORM_NULL_EQUALS(boolean)打开时,形如
(或expr= NULLNULL =)的表达式会被当作expr处理,即当exprIS NULLexpr求值为 NULL 值时返回真,否则返回假。的正确行为是总是返回 NULL(未知)。因此此选项默认是关闭的。expr= NULL不过,Microsoft Access 中的筛选形式生成的查询看起来是用
来测试 NULL,因此如果你用该界面访问数据库,可能需要打开此选项。由于形如expr= NULL的表达式(按正确解释)总是返回 NULL,它们不是很有用,在正常应用中也不常出现,所以此选项实际上没什么害处。但新用户经常对涉及 NULL 的表达式的语义感到困惑,所以我们不默认打开此选项。expr= NULL注意,此选项只影响字面上的
=操作符,不影响其他比较操作符,也不影响在计算上等价于某个涉及等号操作符表达的其他表达式(例如IN)。因此,此选项不是对不良编程的通用修复。相关信息参见用户指南。
UNIX_SOCKET_DIRECTORY(string)指定 postmaster 用于监听来自客户端应用连接的 Unix 域套接字所在的目录。默认值通常是
/tmp,但可以在构建时更改。UNIX_SOCKET_GROUP(string)设置 Unix 域套接字的所属组。(套接字的所属用户总是启动 postmaster 的用户。)与选项
UNIX_SOCKET_PERMISSIONS组合,可以作为这种套接字类型的一种附加访问控制机制。默认是一个空字符串,表示使用当前用户的默认组。这个选项只能在服务器启动时设置。UNIX_SOCKET_PERMISSIONS(integer)设置 Unix 域套接字的访问权限。Unix 域套接字使用通常的 Unix 文件系统权限集。选项值应是以
chmod和umask系统调用所接受格式指定的数字权限模式。(要使用惯用的八进制格式,数字必须以0(零)开头。)默认权限是
0777,表示任何人都可以连接。合理的其他取值可以是0770(仅用户和组,另见UNIX_SOCKET_GROUP)和0700(仅用户)。(注意,对 Unix 套接字而言,实际上只有写权限起作用,设置或撤销读权限和执行权限没有意义。)此访问控制机制独立于第 4 章中描述的机制。
这个选项只能在服务器启动时设置。
VACUUM_MEM(integer)指定
VACUUM用于跟踪待回收元组所用的最大内存量。值以千字节为单位指定,默认为 8192 千字节。对包含大量已删除元组的大表进行清理时,更大的设置可能提升清理速度。VIRTUAL_HOST(string)指定 postmaster 用于监听来自客户端应用连接的 TCP/IP 主机名或地址。默认监听所有已配置的地址(包括 localhost)。
3.4.4. WAL #
关于 WAL 调优的细节另见第 11.3 节。
CHECKPOINT_SEGMENTS(integer)自动 WAL 检查点之间的最大距离,以日志文件段为单位(每段通常为 16 兆字节)。这个选项只能在服务器启动时或在
postgresql.conf文件中设置。CHECKPOINT_TIMEOUT(integer)自动 WAL 检查点之间的最长时间,以秒为单位。这个选项只能在服务器启动时或在
postgresql.conf文件中设置。COMMIT_DELAY(integer)向 WAL 缓冲区写入提交记录与把缓冲区刷到磁盘之间的时间延迟,以微秒为单位。非零的延迟允许多个事务只通过一次
fsync系统调用提交,前提是系统负载足够高,在给定的时间间隔内有额外的事务准备好提交。但如果没有其他事务准备好提交,该延迟就只是白白浪费时间。因此,只有当一个后端写入其提交记录的瞬间,至少有 COMMIT_SIBLINGS 个其他事务处于活跃状态时,才执行该延迟。COMMIT_SIBLINGS(integer)执行
COMMIT_DELAY延迟之前所要求的最少并发打开事务数。更大的值使在延迟间隔内至少有另一个事务准备好提交更有可能。WAL_BUFFERS(integer)共享内存中用于 WAL 日志的磁盘页缓冲区数量。这个选项只能在服务器启动时设置。
WAL_DEBUG(integer)如果非零,在标准错误上打开与 WAL 相关的调试输出。
WAL_FILES(integer)检查点时预先创建的日志文件数量。这个选项只能在服务器启动时或在
postgresql.conf文件中设置。WAL_SYNC_METHOD(string)用于强制把 WAL 更新刷到磁盘的方法。可能的取值有
FSYNC(每次提交时调用fsync())、FDATASYNC(每次提交时调用fdatasync())、OPEN_SYNC(以open()选项O_SYNC写 WAL 文件)或OPEN_DATASYNC(以open()选项O_DSYNC写 WAL 文件)。并非所有平台上这些选择都可用。这个选项只能在服务器启动时或在postgresql.conf文件中设置。
3.4.5. 短选项 #
为方便起见,许多参数还有单字母的选项开关。它们在下表中描述。
表 3.1. 短选项对照
| 短选项 | 等价形式 | 备注 |
|---|---|---|
-B | shared_buffers = | |
-d | debug_level = | |
-F | fsync = off | |
-h | virtual_host = | |
-i | tcpip_socket = on | |
-k | unix_socket_directory = | |
-l | ssl = on | |
-N | max_connections = | |
-p | port = | |
-fi, -fh, -fm, -fn, -fs, -ft | enable_indexscan=off, enable_hashjoin=off,
enable_mergejoin=off, enable_nestloop=off, enable_seqscan=off,
enable_tidscan=off | * |
-S | sort_mem = | * |
-s | show_query_stats = on | * |
-tpa, -tpl, -te | show_parser_stats=on, show_planner_stats=on, show_executor_stats=on | * |
由于历史原因,标有 “*” 的选项必须通过
-o postmaster 选项传给单个后端进程,例如:
$ postmaster -o '-S 1024 -s'
或者从客户端一侧通过 PGOPTIONS 传递,如上文所述。