先说结论:如果你指望装一个 PostgreSQL 18 就直接上生产,请先冷静。PostgreSQL 18 目前处于开发版阶段,稳定产出要等正式发布窗口,所以这篇文章适合三类人:想提前体验新特性、做周边工具适配、或者纯粹想在自己的机器上折腾源码编译流程的玩家。如果你只想稳定跑业务,老老实实用 PostgreSQL 16 或 17,别拿 18 的生产稳定性开玩笑。
我把 PostgreSQL 18 的安装分成三条路线来讲:源码编译、Docker 镜像、APT 二进制包。每一条都有自己的适用场景和绕不开的坑,我会把实际踩过的细节、命令参数的取舍逻辑都写清楚。这篇文章的内容不是你搜一下官方文档就能背下来的安装步骤,而是结合了我在编译过程中遇到的真实问题和排查思路的实操记录。
1. 动手前先想清楚:装 PostgreSQL 18 到底在装什么
1.1 版本现状与开发版的“新玩法”
PostgreSQL 的版本号策略和很多开源软件不一样,它的主版本号每年推进一次,18 就是在 17 的基础上的下一个大版本。按照社区节奏,PostgreSQL 18 一般会经历漫长的 Alpha、Beta、RC 阶段,然后才发正式版。所以在绝大多数公开源里,你搜postgresql-18可能什么都搜不到,或者只有开发分支的构建产物。
这套版本节奏有一个非常容易踩的坑:文档、博客、第三方工具往往比版本发布慢半拍。你在网上找到的 PostgreSQL 18 安装教程,很可能是作者拿源码仓库的master分支瞎编的,也可能只是把 17 的教程改了版本号。所以我建议你先确认自己获取安装包的渠道是否权威,不要随便从非官方 PPA 或来路不明的镜像站拉二进制包。
开发版最值得玩的东西,我觉得有这样几个:内置的 UUID v7 支持(如果你做过分布式系统 ID 设计,就知道这玩意儿多省事)、围绕 I/O 并行和资源调度的优化(具体性能数据要看正式发布的 release notes)、以及一些为了提升高并发场景稳定性的内部重构。这些特性对于生产环境来说可能“感知不强”,但如果你正在做数据库中间件、备份工具,提前适配这些变化就很重要了。
1.2 三条安装路线,各自适合什么人
在开始执行之前,先把三条路线适用场景说清楚,免得你装到一半发现选错了方向:
| 路线 | 适合场景 | 核心优势 | 主要风险 |
|---|---|---|---|
| 源码编译安装 | 开发环境、自定义编译参数、深度调试 | 灵活可控、不依赖发行版节奏 | 编译耗时长、依赖多、容易卡在缺库上 |
| Docker 容器部署 | 快速体验、隔离环境、团队协同时统一版本 | 一条命令拉起、环境干净 | 数据卷权限、性能损耗、不方便直接跑扩展 |
| APT 二进制包 | Debian/Ubuntu 用户、希望享受系统服务托管 | 有 systemd 脚本、升级方便 | 18 很可能没有发布包,得等正式版 |
我自己最常用、也最推荐的组合是:本机快速验证用 Docker,长期编译调试用源码安装。二进制包路线放到正式版发布后才会比较香,现在这个阶段它很容易扑空。
2. 源码编译安装:最硬核也最稳妥的自定义路线
2.1 编译前的准备:依赖和 configure 参数
源码编译是 PostgreSQL 安装的“正统路径”,虽然看起来麻烦,但它能让你看到整个数据库是怎么构建出来的,后面做二次开发或者定制扩展时会非常有底气。
先装编译工具和基本依赖。在 Debian/Ubuntu 系的系统上执行:
apt update apt install -y build-essential zlib1g-dev libreadline-dev libicu-dev \ libssl-dev pkg-config flex bison这里面每一个包都有它的用途,千万别缺。build-essential提供 gcc/g++ 和 make;libreadline-dev是 psql 交互命令行的基础,没有它编译也能过,但装出来的 psql 用起来会非常痛苦;libicu-dev提供 Unicode 排序规则支持,现代 PostgreSQL 默认就要它;libssl-dev是 SSL 加密连接的前提;flex和bison是解析器生成工具,PostgreSQL 的 SQL 语法分析离不开它们。
去 PostgreSQL 源码仓库拉取开发分支(官方仓库只保留稳定分支,18 的代码一般在master或专门的REL_18_STABLE分支上):
git clone --depth 1 https://github.com/postgres/postgres.git cd postgres git checkout REL_18_STABLE这里我建议你 checkout 到REL_18_STABLE而不是直接用默认分支。默认分支是面向下一个开发周期的,代码变动频繁,可能今天编译通过,明天就报错了。REL_18_STABLE是冻结了功能清单的版本,虽然还在修 bug,但至少功能上不会再翻天覆地。
接下来是 configure 配置:
./configure --prefix=/usr/local/pgsql18 \ --with-openssl \ --with-icu \ --with-llvm--prefix指定安装目录,我习惯把不同主版本的 PostgreSQL 安装到完全独立的目录,避免和系统自带的数据库冲突。--with-openssl和--with-icu是推荐开启的,这两个特性在现代部署中基本是必需品。--with-llvm是启用 JIT 编译加速,如果你机器上装了 llvm 工具链就开启,否则跳过也不影响功能。
2.2 make 与 make install:从源码到可执行文件
configure 通过之后,进入编译阶段:
make -j$(nproc)-j$(nproc)是让编译过程使用所有 CPU 核心并行执行。PostgreSQL 的源码量非常大,单核编译可能要二三十分钟,并行可以把时间压到五六分钟。如果编译过程中报错,优先检查是不是内存不足导致编译器进程被杀,这种情况下调低并行数:
make -j4编译完成后执行安装:
make install安装过程会把二进制文件放到/usr/local/pgsql18/bin,头文件放到/usr/local/pgsql18/include,文档放到/usr/local/pgsql18/share。这一步通常不会报错,如果报权限错误就加上 sudo。
验证安装是否成功:
/usr/local/pgsql18/bin/postgres --version /usr/local/pgsql18/bin/psql --version看到输出里显示 18.x 就说明二进制已经就绪了。
2.3 初始化数据目录与启动服务
编译安装只是把“程序”装好了,数据库还需要一个数据目录来存放所有数据。创建一个专用的系统用户来运行 PostgreSQL 是个好习惯,别用 root 跑数据库服务,不然文件权限会变得一团糟:
useradd -m postgres mkdir -p /data/pgdata chown -R postgres:postgres /data/pgdata切换到 postgres 用户初始化数据目录:
su - postgres /usr/local/pgsql18/bin/initdb -D /data/pgdata -E UTF8 --locale=C.UTF-8-E UTF8指定编码,--locale指定区域。这边要重点说一下--locale的选择:生产环境我推荐用C.UTF-8或en_US.UTF-8,用来避免跨语言排序规则带来的不一致问题。如果你在具名 locale 下建库,后面迁移到其他语言环境的服务器时,排序规则差异会引发一堆莫名其妙的问题。
初始化完成后启动服务:
/usr/local/pgsql18/bin/pg_ctl -D /data/pgdata -l /tmp/pglog.log start然后验证连接:
/usr/local/pgsql18/bin/psql -d postgres能进入postgres=#提示符,整个源码编译安装流程就算走通了。
3. Docker 路线:5 分钟跑起来,但要留意隐藏差异
3.1 拉取开发版镜像的坑
Docker 是快速体验 PostgreSQL 18 新功能最省事的路径,一条docker pull就能把环境拉起来,不用操心依赖库和编译流程。但这里有个现实问题:官方镜像仓库在正式版发布前一般不会推出带 18 主版本号的 stable 镜像,你大概率只能找到 Beta 标签的版本。
拉取命令:
docker pull postgres:18beta1或者直接拉最新开发镜像:
docker pull postgres:latest这两个选项的差异在于:18beta1是官方打出来的 beta 标签,相对稳定一点;latest默认指向最新发布的正式版,在 18 没发布前其实还是 17 的镜像。所以你想尝鲜 18,得明确指定 beta 标签,否则拉下来的版本会和自己预期不符。
一个小细节:如果你在公司网络或者国内访问 Docker Hub 比较慢,可以用配置镜像加速器的方式处理。启动运行的命令如下:
docker run --name pg18 \ -e POSTGRES_PASSWORD=mysecretpassword \ -p 5433:5432 \ -v pg18data:/var/lib/postgresql/data \ -d postgres:18beta1把映射端口设置成 5433 而不是默认的 5432,是为了避免和本机已有 PostgreSQL 实例冲突,这个操作习惯建议你保持,排查问题的时候能少费很多口舌。
3.2 挂载数据卷与参数配置
容器里的 PostgreSQL 会默认把数据存到/var/lib/postgresql/data,所以我用-v pg18data:/var/lib/postgresql/data做了一个命名数据卷,确保容器删掉后数据还在。这是 Docker 部署数据库最基础也是最容易忽略的一步——我在社区见过太多人直接用--rm跑容器,跑完容器销毁,数据全没了。
在容器里改配置也一样,可以用:
docker exec -it pg18 psql -U postgres如果需要修改 PostgreSQL 的文件配置,最佳实践不是直接进容器里改,而是先挂载配置目录:
docker run --name pg18 \ -v /custom/pgdata:/var/lib/postgresql/data \ -v /custom/config:/etc/postgresql \ -e POSTGRES_PASSWORD=mysecretpassword \ -d postgres:18beta1映射配置目录的好处是,你可以在宿主机上用熟悉的编辑器调整postgresql.conf,而且容器升级重建时配置不会丢失。不过这里有一个权限坑:宿主机上的目录必须让容器内的postgres用户(UID 999)有读写权限,否则容器启动时 PostgreSQL 会因为权限不匹配直接退出。处理办法很简单:
chown -R 999:999 /custom/pgdata /custom/config3.3 容器内外的性能与安全差异
Docker 跑 PostgreSQL 的便利性毋庸置疑,但它和物理机部署存在三层差异,你心里一定要有数。
第一层是性能损耗。默认的 Docker 网络桥接和存储驱动会带来额外的 I/O 和网络开销,如果你是做性能测试,测试结果会比物理机打折扣。当然,用--network=host可以消除网络层损耗,数据卷用本地目录而不是 Docker 管理卷也能改善磁盘性能,但要做到和物理机完全一致,不太可能。
第二层是数据安全。容器是“易碎品”,进程崩溃常见,但更重要的是容器重建时数据卷的归属。如果命名数据卷被误删,数据就真的没了。生产环境如果要用容器跑数据库,至少要做定时备份,而且要备份在宿主机之外的存储上。
第三层是扩展安装。很多 PostgreSQL 扩展在容器里需要额外编译,Docker 镜像默认包含的扩展有限。如果你准备做一些特殊扩展,建议使用包含编译工具链的镜像,或自己写带编译环境的 Dockerfile。
4. APT 二进制包路线:省事但版本可得碰运气
4.1 PGDG 仓库配置流程
对 Debian/Ubuntu 用户来说,官方 PostgreSQL 源码包通过 PGDG(PostgreSQL Global Development Group)仓库分发,这是最正规的二进制安装来源。不过需要提前声明:只要是 18 还在 Beta 阶段,PGDG 仓库大概率不会提供正式二进制包,但这套流程你仍然值得掌握,等 18 正式发布后立刻就能用。
配置 PGDG 仓库:
apt install -y curl gnupg curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | \ gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg echo "deb [arch=amd64] https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > \ /etc/apt/sources.list.d/pgdg.list apt update这里面$(lsb_release -cs)会自动识别系统版本代号,比如 Ubuntu 24.04 就是noble。如果你服务器用的不是标准 LTS 版本,很可能lsb_release -cs返回的代号在 PGDG 仓库里不存在,这时候需要手动换成对应的 LTS 代号。
仓库配好后搜索包:
apt search postgresql-18大概率你会得到提示“未找到相关结果”。这是正常的,说明 18 还没有正式进入包仓库。如果显示有postgresql-18,那说明你用的仓库镜像比较激进,或者已经接近正式发布了。
4.2 版本可用性判断与二进制方案的取舍
在没有 18 正式包的情况下,还有两种变通方案:
第一种,直接装 17 的生产稳定版,体验不了新特性,但保证系统稳定。这个方法对大多数业务场景反而是最理性的选择,因为 18 新增的特性在你真正需要它之前,对你来说就是零收益。
第二种,从 Postgres 官方 apt 仓库的测试分支里找 18 的候选构建。具体做法是编辑/etc/apt/sources.list.d/pgdg.list,增加-pgdg-testing的源,然后重新apt update去搜索。这种做法能提前拿到接近正式的构建产物,但本质上还是在用测试包,风险自担。
二进制包路线的核心优势是省心:它自带/etc/init.d/postgresql或 systemd 服务脚本,能够自动创建postgres用户和数据目录,还配套了/etc/postgresql/18/main/的标准配置文件结构。对于不熟悉 PostgreSQL 内部结构的用户来说,这条路径的学习成本最低。
但如果你问我要不要用二进制包跑 18 开发版,我的建议是不要在重要的开发环境上这样做。官方的 apt 包更新策略会随着版本迭代变动,可能你装完没多久,仓库里的 18 测试包就更新了,而apt upgrade可能会破坏你手动的配置。迁移到生产环境时,源码编译或新版本的官方包更值得依赖。
5. 配置检查与性能初调:装完不等于能用
5.1 postgresql.conf 里最该动的三个参数
不管是哪条路线装出来的 PostgreSQL 18,启动之后第一件事是检查postgresql.conf里的几个和性能强相关的参数。默认配置为通用场景做了保守估计,不调的话跑小型应用够了,但高并发读写会早早撞墙。
第一个参数是shared_buffers。它决定 PostgreSQL 用于缓存数据页的共享内存大小,建议设置为物理内存的 1/4,这是社区公认的一个安全上限。设得过大反而会因为系统换页导致性能下降。比如你有 32G 内存,设置成8GB是合理起点。重要提醒是:改变这个参数后需要重启数据库实例才能生效。
第二个是work_mem和maintenance_work_mem。前者用于排序、哈希连接等操作的单次内存上限,设得过大在多并发复杂查询时容易导致内存溢出的隐患;后者用于创建索引、VACUUM 等维护操作,可以设大一些。我的习惯是work_mem先设32MB,maintenance_work_mem设512MB,再根据实际的查询计划逐步调整。
第三个是max_connections。默认值是 100,如果你的应用用了连接池还好,如果每个请求都直连数据库,100 的连接数很快就会打满。但这个值也不是越大越好,因为 PostgreSQL 为每个连接都要分配固定内存和文件描述符,盲目调到 1000 以上可能会让系统 OOM。一般建议max_connections和shared_buffers联动调整,连接数多就适当降低单个连接的内存占用。
配置修改方式:
vim /data/pgdata/postgresql.conf shared_buffers = 8GB work_mem = 32MB maintenance_work_mem = 512MB max_connections = 200改完后重启服务或加载配置:
/usr/local/pgsql18/bin/pg_ctl -D /data/pgdata reloadreload不会中断现有连接,但对于shared_buffers这种需要重启的参数,reload 是没有用的,必须重启。
5.2 连接验证与基础 SQL 冒烟测试
参数调完,做一次完整的连接验证和冒烟测试很有必要,特别是在源码编译安装的环境里,这一步能帮你发现环境变量、客户端认证配置等隐藏问题。
服务启动后,先检查监听端口:
ss -tlnp | grep 5432看到监听在 5432 端口后,用 psql 测试本地连接:
/usr/local/pgsql18/bin/psql -h 127.0.0.1 -U postgres -d postgres如果连接失败,回显Peer authentication failed,说明 pg_hba.conf 里的认证方式不对。开发环境最简单的办法是改pg_hba.conf把本地连接方式改成trust,但这只适合开发环境,不能在公网上这么干。
连接成功后跑几条 SQL:
CREATE TABLE test(id serial primary key, note text, created_at timestamptz default now()); INSERT INTO test(note) VALUES ('hello pg18'), ('another row'); SELECT count(*) FROM test;用SELECT version();确认 PostgreSQL 18 的内核版本:
SELECT version();能看到PostgreSQL 18beta1 on x86_64-pc-linux-gnu这类输出就说明一切正常。
如果要做备份恢复测试,强烈建议趁现在就做一次:
/usr/local/pgsql18/bin/pg_dump -h 127.0.0.1 -U postgres -d postgres -F c -f /tmp/pg18_backup.dump开发版在功能迭代过程中引入数据格式变更的概率虽然不算高,但备份恢复流程跑通后,后面你心不慌。
6. 常见安装问题与解决实录
6.1 编译报错与依赖缺失
源码编译最大的拦路虎就是依赖库缺失,我把几类高频报错整理成了速查表:
| 报错信息 | 根因 | 解决方法 |
|---|---|---|
configure: error: readline library not found | 缺 readline-dev | apt install libreadline-dev |
configure: error: ICU library not found | 缺 ICU 开发包 | apt install libicu-dev |
fatal error: openssl/ssl.h: No such file or directory | 缺 OpenSSL 头文件 | apt install libssl-dev |
make: bison: No such file or directory | 缺语法分析器 | apt install bison flex |
could not load library "libpq.so.5" | 共享库路径未配置 | 在/etc/ld.so.conf.d/添加安装目录的lib路径,执行ldconfig |
最后一类报错很容易被忽略。源码编译安装到自定义--prefix后,动态库路径不在系统默认搜索范围,psql 一执行就提示找不到libpq.so。解决方式:
echo "/usr/local/pgsql18/lib" > /etc/ld.so.conf.d/pgsql18.conf ldconfig6.2 Docker 启动失败与权限排查
Docker 路线最典型的错误是容器启动后立刻退出。用docker logs pg18查看日志时,常见有两类:
第一类是目录权限问题,日志里会明确提示数据目录权限不对。解决方式是调整宿主机目录的 owner,让它归 UID 999:
chown -R 999:999 /custom/pgdata第二类是内存不足,日志里会有一条out of memory异常。开发版的默认配置可能对内存要求更高,检查宿主机可用内存,必要时给 Docker 设置--memory上限并调低shared_buffers。
如果容器一直处于 Starting 状态,先排除端口冲突:
ss -tlnp | grep 5433Docker 会静默地让新容器监听不了已被占用的端口,退出时不报错。我实际遇到过两三次这种情况,最后都发现是宿主机上另外的 PostgreSQL 实例占用了端口。
6.3 连接验证常见的认证问题
在调试连接的时候,我撞过最多的问题是pg_hba.conf配置错误导致的权限拒绝。默认配置里127.0.0.1/32的认证方式通常是scram-sha-256,如果你在 initdb 的时候指定了密码,连接时需要正确输入密码。我见过很多新手直接把pg_hba.conf里改成trust来跳过密码,这在本地开发可以,但只要机器能被外部访问,就是巨大的安全隐患。
更推荐的开发调试方案是设置一个明确的密码,然后部分网段保持加密认证:
host all all 127.0.0.1/32 scram-sha-256这样既不用折腾免密,又能保留安全底线。修改完pg_hba.conf不需要重启数据库,reload 即可:
/usr/local/pgsql18/bin/pg_ctl -D /data/pgdata reload6.4 独家避坑:版本标记和“幽灵配置”
最后分享两个别人不太会写的经验。第一个是安装完以后一定要检查pg_config的路径,源码编译安装和系统包安装的pg_config可能会指向不同位置,这在后续编译扩展时是致命的。如果你用源码安装,记得把/usr/local/pgsql18/bin加到 PATH 的最前面:
export PATH=/usr/local/pgsql18/bin:$PATH第二个是关于配置文件里的“幽灵配置”。开发版源码里有些配置项的默认值或语法可能在版本迭代中发生变化,旧的postgresql.conf里可能有已经不存在的参数。PostgreSQL 在加载配置时遇到不认识的参数会直接拒绝启动,所以你从旧版本拷贝配置时一定要谨慎,建议每次改动后用pg_ctl -D /data/pgdata -c做一个配置检查再重启。
经过这一整套安装与验证流程,PostgreSQL 18 的开发环境应该已经稳稳跑起来了。我个人实际测试下来的体验是,18 在安装流程层面和 17 没有本质差异,真正变化在编译选项、内部功能和新 SQL 函数的实现上。如果你要为了新特性专门搭一套环境,源码编译配合 Docker 双轨并行是效率最高的组合。本机快速改代码验证用 Docker,需要做扩展开发或性能基准测试时用源码编译的独立实例。这样既能保证环境干净,又不会因为容器隔离影响性能判断。