ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

PG实战笔记 | 07 PostgreSQL常见编译项及其作用

PG实战笔记 | 07 PostgreSQL常见编译项及其作用

PG实战笔记 | 07 PostgreSQL常见编译项及其作用

上一篇我们完成了三大平台的安装部署。大多数情况下,包管理器安装已经足够。但有时候,你需要自己编译 PostgreSQL——可能是为了启用某个实验性特性,可能是为了针对性优化性能,也可能只是想在开发环境里调试内核代码。这一篇,我们把./configure的常用选项逐一拆开,弄清楚每个参数到底改变了什么。

一、什么情况下需要自己编译?

在动手之前,先确认你是否真的需要源码编译。

场景包安装源码编译
日常开发与测试✅ 足够不必要
生产环境标准部署✅ 足够不必要
需要最新开发版(如 PG 19 的 beta 特性)❌ 仓库滞后✅
需要启用某个默认关闭的编译特性(如 LZ4 压缩)❌✅
为特定 CPU 架构优化(如 ARM64、龙芯)❌✅
开发 PG 扩展,需要调试符号和 assertion❌✅
学习内核源码,想修改并验证❌✅

核心判断标准:包安装的编译选项是否覆盖了你的需求。如果覆盖了,就不要重复造轮子。源码编译的代价是升级麻烦、依赖手动处理、编译选项一旦设错可能需要重新编译整个集群。

下面进入正题。PostgreSQL 使用 Autoconf 风格的./configure脚本,可以通过./configure --help查看全部选项。我们按用途分类,挑选最常用的逐一说明。

二、安装路径:决定文件落在哪里

./configure--prefix=/usr/local/pgsql

--prefix是最基础的选项,决定安装目录。默认值是/usr/local/pgsql。安装后,可执行文件在$PREFIX/bin,库文件在$PREFIX/lib,头文件在$PREFIX/include。

如果你需要更细粒度的控制,可以使用--bindir、--libdir、--includedir分别指定可执行文件、库文件和头文件的目录。但在大多数场景下,只设--prefix就够了。

生产建议:使用独立的--prefix路径,比如/opt/pgsql/17,便于同一机器上并行运行多个 PG 版本,也便于升级时保留旧版本。

三、功能开关:启用或禁用特定能力

–with-openssl:SSL 加密连接

./configure --with-openssl

启用 SSL 支持,允许客户端通过加密连接访问数据库。这是生产环境几乎必开的选项。它要求系统安装 OpenSSL 开发包(libssl-dev或openssl-devel),configure 阶段会检查头文件和库是否满足要求。

PostgreSQL 编译时唯一支持的 SSL 库就是 OpenSSL。启用后,你可以配置ssl = on并设置证书路径,客户端通过sslmode=require强制加密连接。

–with-pam:PAM 认证

./configure --with-pam

启用 PAM(Pluggable Authentication Modules)支持,允许 PostgreSQL 使用操作系统级别的认证机制。在 Linux 上,这意味着你可以用系统用户密码登录数据库,适合统一身份管理的企业环境。需要安装libpam0g-dev或pam-devel。

–with-libxml 和 --with-libxslt:XML 支持

./configure --with-libxml --with-libxslt

--with-libxml启用 SQL/XML 支持,允许在 SQL 中生成和查询 XML 数据。--with-libxslt进一步支持 XSLT 转换。这两个选项在处理 XML 数据的场景下有用,但如果你的业务不涉及 XML,可以跳过,减少依赖。

–with-python:PL/Python 存储过程

./configure --with-python

启用 PL/Python 服务端语言,允许你用 Python 编写存储函数和触发器。这对数据科学、机器学习场景很有价值——你可以在数据库内部调用 Python 库做数据预处理或模型推理。

configure 会探测python3和python,优先使用python3。你也可以通过环境变量PYTHON指定具体解释器路径。注意,PL/Python 使用哪个 Python 版本,取决于编译时探测到的版本,后续无法在运行时切换。

–with-llvm:JIT 编译

./configure --with-llvm

启用基于 LLVM 的 JIT(即时编译)编译。这是 PostgreSQL 11 引入的重要特性,能将查询中的表达式和部分执行逻辑编译为本地机器码,对复杂分析查询有明显加速效果。它要求系统安装 LLVM 开发库,PostgreSQL 支持的最低 LLVM 版本随 PG 版本不同而变化,PG 17 要求 LLVM 14 或更高。

代价:编译时间更长,二进制体积更大,首次查询时 JIT 编译本身有开销。对于简单查询或高并发短事务,JIT 可能反而增加延迟。你可以通过jit = off在运行时关闭,但编译时必须先启用。

–with-icu:ICU 排序规则

./configure --with-icu

启用 ICU(International Components for Unicode)库支持,提供更丰富、更一致的排序和大小写转换规则。默认的Clocale 排序是字节序,不支持语言敏感的排序规则。如果你的业务需要按照特定语言(如中文拼音、德语字典序)排序,ICU 是更好的选择。

ICU 还支持大小写不敏感排序和更准确的多语言处理。代价是增加了 ICU 库依赖,初始化集群时如果使用 ICU collation,该集群就无法在不支持 ICU 的 PG 版本上启动。

–with-lz4 和 --with-zstd:压缩支持

这两个选项启用 LZ4 和 Zstandard 压缩算法的支持,用于 WAL 压缩(PG 15+)和 TOAST 数据压缩。

  • LZ4:压缩速度快,适合对写入延迟敏感的场景;
  • Zstandard:压缩比高,适合存储空间受限的场景。

两者默认都是auto——如果系统安装了对应的开发库,configure 会自动启用。如果你明确需要某种压缩算法,可以显式指定--with-lz4或--with-zstd。在 Meson 构建系统中,对应的选项是-Dlz4=enabled和-Dzstd=enabled。

–with-systemd:systemd 集成

./configure --with-systemd

启用 systemd 服务通知支持。编译后,PostgreSQL 可以在启动完成后向 systemd 发送READY=1信号,systemd 能更准确地判断服务是否真正就绪,而不是仅仅“进程已启动”。这对依赖 PostgreSQL 的服务编排(如 Kubernetes 中的 sidecar 模式)有实际意义。需要安装libsystemd-dev或systemd-devel。

四、开发者选项:调试与测试专用

以下选项仅建议在开发和测试环境使用,生产环境应避免。

–enable-debug:调试符号

./configure --enable-debug

让所有程序和库都携带调试符号(-g),你可以在 GDB 中运行 PostgreSQL 并设置断点、查看变量、单步执行。

注意:--enable-debug会关闭优化(-O0),这意味着性能显著下降,且不应在生产环境使用。如果你只想在优化版本上临时调试某个文件,可以在 make 阶段单独为特定文件关闭优化:

gmakePROFILE=-O0 file.o

–enable-cassert:断言检查

./configure --enable-cassert

开启 C 语言断言(assertion),在运行时检查大量内部一致性条件。如果某个假设被违反,程序会立即崩溃并报告断言失败的位置。这对发现内核 bug 非常有用,但性能开销巨大,因为每个断言都要执行。

在 Meson 构建中,对应选项是-Dcassert=true。开发 PostgreSQL 服务端代码时,官方建议同时启用 debug 构建和 cassert。

–enable-dtrace / --enable-injection-points

--enable-dtrace启用 DTrace 动态追踪支持,允许在运行时观察内核行为。在 Solaris 上需要额外指定DTRACEFLAGS="-64"以构建 64 位二进制。

--enable-injection-points允许在服务端预定义代码路径中注入用户自定义代码,用于测试并发场景。该选项默认关闭,仅供开发者使用。

–enable-depend:自动依赖追踪

./configure --enable-depend

启用自动依赖追踪。启用后,Makefile 会在头文件发生变化时自动重新编译所有依赖该头文件的源文件。对于频繁修改代码的开发者来说,这可以避免手动清理重建的麻烦。

五、环境变量:不通过 configure 选项的定制

除了命令行选项,configure 还响应一批环境变量。最常用的是CC和CFLAGS。

指定编译器

./configureCC=/opt/bin/gcc

默认情况下,configure 优先选择 GCC,如果不可用则使用平台的默认 C 编译器(通常是cc)。如果你需要使用 Clang 或特定版本的 GCC,通过CC变量指定。

覆盖编译优化选项

./configureCFLAGS='-O2 -pipe'

CFLAGS传递给 C 编译器的优化选项。默认情况下,PostgreSQL 使用-O2级别的优化。你可以覆盖它:

  • -O1:较低优化,便于调试;
  • -O3:激进优化,可能提升性能但增加编译时间和二进制体积;
  • -march=native:针对当前 CPU 架构优化,但二进制不可移植到其他 CPU。

重要提醒:使用-O0(完全关闭优化)会禁用一些重要的编译器警告(如未初始化变量的使用),因此不建议在生产构建中这样做。如果确实需要-O0来调试,只对特定文件使用,而不是全局设置。

其他有用的环境变量包括:CPPFLAGS(预处理器选项)、LDFLAGS(链接器选项)、PYTHON(Python 解释器路径)、PERL(Perl 解释器路径)、XML2_CONFIG(libxml2 配置工具路径)。

六、Autoconf 还是 Meson?

PostgreSQL 从 16 版本开始支持 Meson 构建系统。Meson 构建速度更快,配置语法更清晰,且是 Visual Studio 在 Windows 上构建的唯一选项。

Autoconf 和 Meson 的选项对应关系:

AutoconfMeson
--with-openssl-Dssl=openssl
--with-python-Dplpython=enabled
--with-llvm-Dllvm=enabled
--with-icu-Dicu=enabled
--enable-debug--buildtype=debug
--enable-cassert-Dcassert=true

Meson 构建的基本流程:

meson setup build--prefix=/usr/local/pgsql\-Dssl=openssl\-Dicu=enabled\-Dllvm=enabledcdbuild ninjasuninjainstall

Meson 的默认构建类型是debugoptimized(-O2加调试符号),这对开发和生产都是一个不错的平衡点。

选择建议:如果你不熟悉 Meson,继续用 Autoconf;如果你在 Windows 上构建,或追求更快的编译速度和更清晰的配置管理,Meson 是更好的选择。

七、一个典型的生产编译配置

综合以上选项,一个面向生产环境的编译配置可能长这样:

./configure\--prefix=/opt/pgsql/17\--with-openssl\--with-pam\--with-libxml\--with-libxslt\--with-llvm\--with-icu\--with-lz4\--with-zstd\--with-systemd\CFLAGS='-O2 -pipe'

这个配置启用了 SSL 加密、PAM 认证、XML 支持、JIT 编译、ICU 排序、两种压缩算法和 systemd 集成,同时保持-O2优化级别。没有启用任何开发者选项。

如果你只是想在本地测试某个新特性,可以简化为:

./configure--prefix=/tmp/pg-test --enable-debug --enable-cassert

八、总结

PostgreSQL 的编译选项很多,但核心逻辑清晰:

  • 路径选项(--prefix)决定文件位置;
  • 功能选项(--with-*)决定启用哪些能力,生产环境优先 SSL、ICU、LLVM、压缩;
  • 开发者选项(--enable-debug、--enable-cassert)只用于调试,切勿在生产开启;
  • 环境变量(CC、CFLAGS)用于精细控制编译器和优化级别;
  • Meson是未来的趋势,尤其是 Windows 平台。

一句话:编译选项是数据库能力的“出厂设置”——一旦编译完成,运行时无法改变。所以在 configure 阶段做选择时,想清楚你的业务到底需要什么。

下一篇,我们进入性能基础调优:shared_buffers、work_mem、max_connections这些参数到底该设多少?背后的依据是什么?


思考题:
你在生产环境编译 PostgreSQL 时,会启用哪些选项?有没有遇到过因为编译选项选择不当导致的问题——比如忘开 ICU 导致中文排序错误,或者开了 cassert 导致性能骤降?欢迎在评论区分享你的经历。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进