Ilya Kosmodemiansky:默认的 postgresql.conf

Ilya Kosmodemiansky:默认的 postgresql.conf

💡 原文英文,约3900词,阅读约需14分钟。
📝

内容提要

本文是PostgreSQL配置系列第一篇,介绍配置机制与连接设置。配置来自postgresql.conf和postgresql.auto.conf,后者优先,命令行又覆盖两者。修改后应先用pg_file_settings检查错误再重载,仅postmaster类参数需重启,可用pg_settings查看生效值及来源。连接方面建议设置listen_addresses、max_connections为100或200并前置连接池、提高保留连接数,并将TCP keepalive调至约10秒检测死连接。

🔎

延伸解读

配置来源的优先级与常见陷阱

文章指出,PostgreSQL 配置来自 postgresql.conf 和 postgresql.auto.conf,后者由 ALTER SYSTEM 写入且优先级更高;命令行参数又覆盖两者。常见困惑是:手动编辑 postgresql.conf 后重载无效,因为之前有人用 ALTER SYSTEM 设置了同一参数。使用 Ansible 或 Patroni 等工具管理配置时,可设置 allow_alter_system = off 防止意外写入,但这并非安全功能。

重载与重启的风险差异

修改配置后,应先用 pg_file_settings 检查错误再重载。文章用引号错误示例说明:重载时服务器仅记录错误并继续运行,不应用任何更改;而重启时同样的错误会导致服务器无法启动,造成停机。因此,养成检查 pg_file_settings 的习惯,仅对 postmaster 类参数(如 shared_buffers、max_connections)才需要重启,可避免不必要的故障。

连接数管理:池化优于提高上限

每个客户端连接都会创建独立的后端进程,消耗内存且最多占用一个 CPU 核。文章建议将 max_connections 保持为 100 或设为 200,并在前面部署 PgBouncer 等连接池,以少量 PostgreSQL 进程服务数千客户端。单纯提高 max_connections 会加剧 CPU 竞争,导致所有查询变慢。同时,可提高 superuser_reserved_connections 和 reserved_connections,为 DBA 和监控保留连接槽位。

TCP keepalive 与代理环境下的注意事项

默认 keepalive 设置依赖操作系统,Linux 下死连接可能存活超过两小时。文章基线将 tcp_keepalives_idle、interval、count 分别设为 5、1、5,使死连接约 10 秒内被断开。但 keepalive 仅对空闲连接有效,且经过 HAProxy 时只覆盖 HAProxy 到 PostgreSQL 一侧,客户端侧需单独配置。HAProxy 自身会关闭空闲连接,keepalive 探测不被视为活动,需确保其超时长于连接池的空闲时间。

❓

Q&A

PostgreSQL 的配置文件 postgresql.conf 和 postgresql.auto.conf 哪个优先级更高?

postgresql.auto.conf 的优先级更高。PostgreSQL 先读取 postgresql.conf,再读取 postgresql.auto.conf,同一设置在文件中最后出现的值生效。因此通过 ALTER SYSTEM 设置的值会覆盖 postgresql.conf 中的值。此外,命令行参数会覆盖这两个文件。

修改 postgresql.conf 后,如何安全地让配置生效?

修改后应先查询 pg_file_settings 视图检查是否有语法错误,然后执行重载(reload)。只有 context 为 postmaster 的参数才需要重启。重载时若有错误,服务器会记录错误并继续运行,不应用任何更改;而重启时若有错误,服务器将无法启动。

如何查看 PostgreSQL 当前生效的配置值及其来源?

使用 pg_settings 视图。该视图为每个设置显示一行,包含当前生效值(setting)、单位(unit)、编译默认值(boot_val)、来源(source)、来源文件和行号(sourcefile, sourceline)以及是否需要重启(pending_restart)。这是了解运行中服务器真实配置的最佳方式。

max_connections 设置多少合适?为什么建议配合连接池?

建议保持默认 100 或设为 200,并在 PostgreSQL 前放置 PgBouncer 等连接池。每个连接都会启动一个后端进程,消耗内存且最多使用一个 CPU 核心。设置过高(如 1000)会导致大量进程竞争 CPU,反而降低性能。连接池可以用少量 PostgreSQL 进程服务数千客户端连接。

reserved_connections 和 superuser_reserved_connections 有什么区别?

两者都从 max_connections 中预留连接槽位。superuser_reserved_connections(默认 3,建议改为 5)仅允许超级用户使用;reserved_connections(PostgreSQL 16 引入,默认 0,建议设为 10)允许具有 pg_use_reserved_connections 角色权限的用户使用,适合监控和 DBA 非超级用户账户。当普通连接用尽时,这些预留槽位可确保管理访问。

TCP keepalive 参数应该如何设置以快速检测死连接?

建议设置 tcp_keepalives_idle = 5、tcp_keepalives_interval = 1、tcp_keepalives_count = 5。这样空闲连接在约 10 秒内(5 秒静默后发送 5 个间隔 1 秒的探测包)即可检测到对端死亡并关闭。默认值 0 表示使用操作系统设置(Linux 上约 2 小时),不利于快速释放连接槽位。这些参数可通过重载生效。

在 HAProxy 后面使用 PostgreSQL 时,keepalive 有什么需要注意的?

HAProxy 会终止 TCP 连接,因此 PostgreSQL 的 tcp_keepalives_* 只覆盖 HAProxy 到 PostgreSQL 这一段。客户端到 HAProxy 需要单独配置 keepalive(如 HAProxy 的 clitcpka 选项或 libpq 的 keepalives 参数)。此外,HAProxy 自身会关闭空闲连接(由 timeout client/server 控制),keepalive 探测不被视为活动,因此需确保 HAProxy 超时时间大于连接最大空闲时间,或设置 timeout tunnel。

🏷️

标签

➡️

继续阅读