
最近在一台新到的 Ubuntu 22.04 LTS 服务器上搭开发环境把 PostgreSQL 从零开始安装、配置到正式跑起来整个过程我觉得值得完整记录一下。老实说在 Ubuntu 上装 PostgreSQL 本身并不难真正容易翻车的是装完之后的环节——认证方式搞不清楚、远程连接不上、内存参数不知道怎么调、备份恢复从来没验证过。这篇文章就按我实际操作的时间线来写每一步都贴出命令和结果顺便把踩过的坑也交代清楚。如果你正准备在 Ubuntu 上安装 PostgreSQL或者装完之后面对配置一脸懵这篇文章正好能帮你把整个链路打通。1. 装之前先搞清楚环境版本与安装源选型很多人上来就apt install postgresql装完才发现版本不对、目录不对、认证方式不对最后只能推倒重来。我建议动手之前先花两分钟确认三件事系统版本、CPU 架构、需要哪个 PostgreSQL 大版本。1.1 确认 Ubuntu 版本和系统架构我这次用的是 22.04 LTS检查命令如下lsb_release -a cat /etc/os-release uname -mlsb_release -a和/etc/os-release能看到系统版本号和代号uname -m能看到架构x86_64 就是 64 位 x86 架构aarch64 就是 ARM 架构。这一步不是走过场原因有两个第一不同 Ubuntu 版本的默认软件源里 PostgreSQL 版本不一样22.04 默认源大概率是 1424.04 默认源大概率是 16你心里要有数第二后续如果要用第三方源或者源码编译架构会影响二进制包的选择ARM 机器的有些编译依赖和 x86 不太一样。1.2 PostgreSQL 版本怎么选PostgreSQL 社区差不多一年一个大版本奇数版本偏尝鲜、偶数版本更稳实际生产环境里 14、15、16 都大量存在17 也在快速普及新出的 18 则属于前沿玩家会去折腾的对象。我的建议很简单生产环境选偶数大版本中成熟度最高的比如 16 或 17避免用刚发布的 .0 版本起码等它出到 .2 或 .3 再上。开发环境选新不选旧直接用当前最新稳定版方便体验新特性。特殊场景如果是要对接 ArcGIS Pro、PowerDesigner、QGIS 这类行业软件先查它们的官方兼容性矩阵再定版本别装了个太新的版本结果软件不认。PostgreSQL 和 MySQL 的选型争论这里不展开简单说一句如果你需要复杂查询、JSON/JSONB 处理、地理位置计算、数据仓库类分析PostgreSQL 的扩展性和功能深度通常更合适如果业务就是简单的 CRUD、读多写少、团队只会 MySQL那也没必要盲目迁移。1.3 安装源的三种选择思路Ubuntu 上装 PostgreSQL 常见有四种路径安装方式适合场景优点缺点apt 直接装 Ubuntu 默认源新手、快速体验一条命令完成和系统集成好版本通常不是最新官方 PGDG 源需要特定/最新版本版本丰富官方维护需要手动添加源Docker 容器开发测试、隔离环境干净、可反复创建数据持久化要额外处理源码编译定制化需求、特殊平台完全可控编译耗时升级麻烦我这次先用的 apt 默认源不是因为 PGDG 源不好而是为了展示最通用的路径。如果你要装指定版本可以直接跳到 2.2 节看 PGDG 源的方式两者的后续配置逻辑完全一样。2. 三种主流安装方式逐个实测2.1 最快的方式apt 直接安装Ubuntu 的默认软件源里就有 PostgreSQL直接装sudo apt update sudo apt install -y postgresql postgresql-contribpostgresql是数据库本体postgresql-contrib是官方扩展包包含很多常用模块。安装完成后系统会自动完成初始化并创建一个默认的 PostgreSQL 数据库集群cluster。先看一眼状态systemctl status postgresql pg_lsclusters输出里会有一个类似main 16 (Ubuntu 16.4-0ubuntu0.24.04.1) 5432 online的记录这就是默认集群。这里有个关键概念要理解Ubuntu 的 PostgreSQL 包引入了一层“集群”管理机制一个 PostgreSQL 实例可以跑多个集群每个集群有独立的端口、数据目录和配置。默认集群叫main端口 5432数据目录在/var/lib/postgresql/16/main配置文件在/etc/postgresql/16/main/下主配置是postgresql.conf客户端认证配置是pg_hba.conf。这一点非常重要因为网上很多教程直接让你去/var/lib/pgsql/data/postgresql.conf里改配置那是 CentOS/RHEL 的路径在 Ubuntu 上配置文件在/etc/postgresql/目录下别找错了地方。2.2 用官方 PGDG 源安装指定版本如果你想装新版本或者一台机器上同时跑多个大版本官方源是最省心的。官方提供了一键添加脚本sudo apt install -y postgresql-common sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh -y这个脚本会自动添加签名密钥和源地址。添加完以后你可以直接指定版本安装sudo apt update sudo apt install -y postgresql-16PGDG 源的好处不只是版本新而是同一个大版本的补丁更新很及时比 Ubuntu 默认源积极得多。多版本共存时pg_lsclusters会列出所有集群比如Ver Cluster Port Status Owner Data directory Log file 16 main 5432 online postgres /var/lib/postgresql/16/main /var/log/postgresql/postgresql-16-main.log 17 main 5433 online postgres /var/lib/postgresql/17/main /var/log/postgresql/postgresql-17-main.log我目前用 PGDG 源装过 16 和 17 共存不同集群用不同端口互不干扰适合要做版本兼容测试的场景。2.3 Docker 方式开发环境真的省心如果只是本地开发我其实最推荐 Dockerdocker run -d \ --name postgres-dev \ -e POSTGRES_PASSWORDdevpassword \ -e TZAsia/Shanghai \ -p 5432:5432 \ -v pgdata:/var/lib/postgresql/data \ --restart unless-stopped \ postgres:16几个参数说明一下POSTGRES_PASSWORD是初始化时给postgres超级用户设置的密码TZ设置时区避免数据库时间和本地对不上-v pgdata:/var/lib/postgresql/data是数据卷持久化这样删掉容器数据还在--restart unless-stopped让 Docker 守护进程启动时自动拉起容器。注意一点新版 PostgreSQL 官方镜像的数据目录已经从/var/lib/postgresql/data变成了/var/lib/postgresql/16/docker这类带版本的路径不同镜像版本可能不一样挂载数据卷之前先进容器看一眼echo $PGDATA最保险。Docker 方式的另一层便利在于你会发现 Ubuntu 上 pgvector、PostGIS 这些扩展的安装很轻松选对带插件的镜像就行。3. 安装之后的核心配置安装只是开始配置才是这篇文章的主角。我会按“认证 → 监听 → 内存 → 日志”的顺序来每一步都解释为什么这么改。3.1 修改 postgres 用户密码与认证方式apt 安装后系统会自动创建一个名为postgres的系统用户同时 PostgreSQL 里也有一个同名的超级用户。默认情况下本地连接走的是peer认证也就是说操作系统用户名必须和数据库用户名一致才能免密登录。所以你要先用系统用户身份进入数据库sudo -u postgres psql进去之后修改密码ALTER USER postgres WITH PASSWORD 你的强密码;这里要特别提醒PostgreSQL 14 及以上版本默认的密码认证方式是scram-sha-256比老的md5安全得多不要为了兼容老客户端把认证方式降级成 md5除非你有明确的兼容需求。密码设置完要确认pg_hba.conf里本地连接的认证方式是peer远程连接的方式是scram-sha-256后面讲远程配置的时候细说。这时候很多人会问为什么不能直接用psql -U postgres登录因为在默认peer认证下当前操作系统用户如果不是 postgres就会直接报Peer authentication failed for user postgres。这不是密码错是认证方式不匹配理解了这一点很多问题就迎刃而解了。3.2 监听地址与远程连接配置新装好的 PostgreSQL 默认只监听本地回环地址127.0.0.1这是出于安全考虑。如果你需要从其他机器连过来必须改两个地方。第一步修改postgresql.confsudo sed -i s/#listen_addresses localhost/listen_addresses */ /etc/postgresql/16/main/postgresql.conf也可以编辑文件找到listen_addresses这一行改成listen_addresses *第二步修改pg_hba.conf在文件末尾追加host all all 0.0.0.0/0 scram-sha-256这一行的意思是允许所有 IPv4 地址0.0.0.0/0通过密码认证访问所有数据库。IPv6 地址再追一条::0/0也可以。改完后重启服务sudo systemctl restart postgresql验证监听状态ss -tlnp | grep 5432然后从另一台机器上试连psql -h 服务器IP -U postgres -d postgres这里我强烈建议如果是公网服务器pg_hba.conf里不要写0.0.0.0/0应该精确到你允许的来源 IP比如203.0.113.5/32。同时配合云防火墙或ufw只放行 5432 端口双保险。3.3 内存参数调整PostgreSQL 的性能很大程度取决于内存参数但新手最容易在这上面犯错——要么不敢动要么乱调到系统直接 OOM。我常用的做法是把配置分成两类一类是全局缓存最核心的是shared_buffersPostgreSQL 的共享缓冲区默认值通常是 128MB太小了。官方建议设为物理内存的 25% 左右。另一类是单查询内存比如work_mem它决定了排序、哈希操作能用多少内存设太大会导致并发连接多时内存爆炸。以一台 4G 内存的机器为例我会这样调shared_buffers 1GB effective_cache_size 3GB work_mem 16MB maintenance_work_mem 256MBeffective_cache_size不是 PostgreSQL 实际分配的内存而是告诉优化器“系统总共能给你多少缓存”这会影响执行计划对索引扫描的偏好通常设为物理内存的 50%~75%。maintenance_work_mem是 VACUUM、CREATE INDEX 这类维护操作能用的内存适当调大能明显加速索引创建。注意改配置后不用重启重载即可sudo systemctl reload postgresql或者直接在 psql 里执行SELECT pg_reload_conf();我个人更推荐pg_reload_conf()因为重启数据库会断开所有连接生产环境代价太大而绝大多数参数是支持热加载的。想确认当前参数值直接SHOW shared_buffers; SHOW work_mem;3.4 日志与 WAL 设置简述日志这块日常开发不一定用得上但排查问题的时候没有日志会非常痛苦。PostgreSQL 的日志默认写在/var/log/postgresql/下文件名类似postgresql-16-main.log。如果你想记录所有执行的 SQL比如调试 ORM 问题可以打开log_statement all log_destination stderr logging_collector on生产环境不建议开all日志量会很大用ddl或mod更合理。WAL预写日志这部分单机场景保持默认就好只有要做流复制或调性能时才需要针对性修改wal_level、max_wal_size等参数这里先不展开。4. 日常管理与数据备份恢复4.1 服务管理常用命令Ubuntu 上 PostgreSQL 的服务管理已经和 systemd 打通了常用命令sudo systemctl start postgresql # 启动 sudo systemctl stop postgresql # 停止 sudo systemctl restart postgresql # 重启 sudo systemctl reload postgresql # 重载配置 sudo systemctl enable postgresql # 开机自启 sudo systemctl status postgresql # 查看状态注意Ubuntu 12.10 之后默认是 systemd但有些云镜像或精简系统可能没有postgresql服务而是postgresql16-main这种实例化服务。遇到服务启不来的情况journalctl -u postgresql16-main能看到具体报错。psql 是 PostgreSQL 自带的命令行客户端日常操作基本靠它。常用内部命令有\l 列出所有数据库 \du 列出所有用户及权限 \dt 列出当前数据库的所有表 \d 表名 查看表结构 \c 数据库名 切换数据库 \conninfo 查看当前连接信息4.2 pg_dump / pg_restore 备份与恢复实战备份这事没出事的时候觉得多余出了事才知道是救命稻草。PostgreSQL 最常用的逻辑备份工具是pg_dump备份单个数据库pg_dump -h localhost -U postgres -d mydb -F c -f mydb.dump参数说明-F c表示自定义格式这种格式支持压缩、支持选择性恢复比纯 SQL 格式灵活-f指定输出文件。如果要备份所有数据库和全局角色用pg_dumpallpg_dumpall -h localhost -U postgres all.sql恢复的时候先建好目标数据库sudo -u postgres createdb mydb_restore pg_restore -h localhost -U postgres -d mydb_restore mydb.dump如果是纯 SQL 格式的备份也可以直接psql -h localhost -U postgres -d mydb_restore all.sql实际恢复中最容易踩的坑是目标数据库不存在或者备份时包含扩展但目标库没有相应插件导致恢复报错。所以在备份前就要规划好恢复测试必须在从零搭建的环境上演练一遍。另外一个习惯是定时备份别只写命令要验证备份文件能恢复。我自己踩过一次定时任务跑了半年从没验证过恢复结果真的出故障时发现备份文件是坏的从那以后我每个月的第一个周末都会做一次真实恢复演练。定时备份可以简单用 cron0 2 * * * /usr/bin/pg_dump -h localhost -U postgres -F c -f /backup/mydb_$(date \%F).dump mydb注意 cron 里%要转义成\%否则命令会出错。更好的方案是写成一个脚本再用 systemd timer 管理但 cron 对于小项目完全够用。4.3 安全加固要点安全这块我总结几条实操经验。第一永远别让业务应用用postgres超级用户连接数据库。正确的做法是创建一个专用用户只授予需要的权限CREATE USER app_user WITH PASSWORD 复杂密码; CREATE DATABASE app_db OWNER app_user; GRANT ALL PRIVILEGES ON DATABASE app_db TO app_user;第二修改默认端口。把postgresql.conf里的port 5432改成其他端口能在一定程度上减少恶意扫描。注意改了之后pg_hba.conf和防火墙都要同步调整。第三定期检查pg_hba.conf的配置原则是最小授权。顺带提一句云上环境一定要配合安全组和防火墙单靠数据库侧配置是不够的。第四不要轻易开启trust认证。trust意味着不需要密码就能连接只适合本机调试环境千万别用在任何可被外部访问的场景。5. 常见问题与排查实录这一节把我在多个环境里实际踩过的问题整理成清单有些是从零安装时遇到的有些是给朋友远程排查时发现的都非常典型。5.1 服务起不来或端口被占用服务状态显示 failed 时先看日志journalctl -u postgresql16-main -n 50 tail -n 50 /var/log/postgresql/postgresql-16-main.log最常见的两个原因端口被占用和数据目录权限不正确。端口被占用先查ss -tlnp | grep 5432 sudo lsof -i :5432如果有个不明的进程占着 5432要么换端口要么处理掉冲突进程。数据目录权限问题一般出现在手动移动数据目录或者从别处拷贝数据目录的场景记住 PostgreSQL 数据目录的属主和属组必须是postgres:postgres权限通常是 700sudo chown -R postgres:postgres /var/lib/postgresql/16/main sudo chmod 700 /var/lib/postgresql/16/main5.2 两个经典的认证失败报错报错一Peer authentication failed for user postgres。原因和解决方法前面已经说了——当前系统用户不是 postgres解决方法是sudo -u postgres psql或者修改pg_hba.conf把本地连接改成scram-sha-256并用密码登录。后者适合你习惯直接psql -U postgres的场景但不建议在只有本机访问需求的机器上改peer 认证更安全。报错二password authentication failed for user xxx。这个验证顺序是确认密码真没输错确认pg_hba.conf里对应规则的认证方式是scram-sha-256而不是md5确认用户确实已存在因为pg_hba.conf规则匹配到了但用户不存在也会报这错。在 Kali、Parrot 这类基于 Debian 的滚动发行版上PostgreSQL 安装失败很多时候是系统库版本太新、和 PostgreSQL 编译依赖冲突出现了就别硬扛直接改用 Docker 跑数据库比跟依赖作斗争省时间得多。5.3 远程连接超时或拒绝连接远程连接不上排查顺序是数据库监听地址有没有改ss -tlnp | grep 5432确认监听在0.0.0.0:5432还是127.0.0.1:5432。防火墙有没有放行Ubuntu 自带的 ufw 执行sudo ufw allow 5432/tcp。pg_hba.conf有没有加远程授权规则这一点最容易漏。云服务器的安全组规则有没有放行端口云上环境经常卡在最后这一步。我在一次帮人排查时发现前三步全对但数据库跑在 Docker 容器里宿主机端口映射没做导致外部访问不到。这类“容器内外端口映射”的问题用 Docker 部署时尤其常见。5.4 psql 命令找不到或环境变量错误刚装上 PostgreSQL 时直接执行psql有时候会提示 command not found因为 PostgreSQL 客户端工具目录/usr/lib/postgresql/16/bin不一定在你的 PATH 里。解决方式有两种简单的方式是直接用sudo -u postgres psql它会通过系统用户环境变量找到正确路径。另一种是把 bin 目录加进 PATHecho export PATH/usr/lib/postgresql/16/bin:$PATH ~/.bashrc source ~/.bashrc这里要特别提醒网上有些教程让新手把/usr/local/pgsql/bin或/opt/PostgreSQL/bin加进 PATH但实际上这些路径可能根本不存在。在看 Path 相关的报错时先ls确认目录到底在哪再决定怎么配环境变量不然越配越乱。5.5 其他系统变体里的相似问题除了标准 Ubuntu我在一些国产系统上也有实测经历比如麒麟 V10 虽然基于 Debian但软件源里的 PostgreSQL 包经常很旧或者干脆没有。这种情况最省事的是去 PostgreSQL 官网下载官方编译好的二进制包解压后直接执行initdb和pg_ctl或者直接用 Docker。思路其实都一样发行版源不可用时就绕开发行版源用官方二进制包或容器。6. 再往前走一步插件、集群与常用工具装好了、配好了、也能备份恢复了最后聊几个高频的扩展方向。这些都是我在实际项目中用过的顺便把踩过的坑一并说了。6.1 安装 pgvector赶上 AI 应用这趟车pgvector 是目前热度最高的 PostgreSQL 扩展之一专门做向量存储和相似度检索特别适合搞 AI 应用、RAG 这类项目。在 Ubuntu 上装 pgvector 很简单sudo apt install postgresql-16-pgvector如果源里没有对应版本也可以源码编译本质上就是make make install。装完进入数据库执行CREATE EXTENSION vector;然后就能建带向量字段的表了。这里我特别想对比一下在 Windows 上装 pgvector 相对费劲往往要下载预编译包或者自己配 Visual Studio 编译环境在 Linux 上一条 apt 命令就搞定。这也是我为什么推荐在 Linux 环境做 Ai 相关开发。6.2 主从流复制从单机到集群的思路单节点 PostgreSQL 扛到一定程度就会开始考虑高可用。PostgreSQL 原生支持物理流复制主库写 WAL 日志从库通过pg_basebackup拉一份基础备份后持续接收 WAL 变更。最简单的配置思路是主库wal_level replicamax_wal_senders 10从库用pg_basebackup -h 主库IP -U repl_user -D /var/lib/postgresql/16/main -P -R拉取数据-R会自动生成standby.signal文件和连接主库的参数。这个方向如果大家感兴趣可以单独写一篇集群搭建实录这里先把概念和命令抛出来。6.3 常用连接工具与行业软件对接命令行虽然强大但日常开发用图形化工具会更高效。我常用的有三类psql命令行首选轻量、无处不装。pgAdmin 4官方出品的 Web 管理工具功能全适合直观管理。DBeaver通用数据库客户端支持所有主流数据库适合多库并存的场景。行业软件对接这块我也被问过几次ArcGIS Pro 连接 PostgreSQL 时要去 Esri 官网查支持矩阵PostgreSQL 版本太新或者太旧都可能不被官方认可PowerDesigner 反向工程 PostgreSQL 时通过 ODBC 驱动连接注意表空间和表大小的设置要在数据库内先定义好PowerDesigner 只是读取元数据。这些场景的共性问题是“客户端版本和数据库版本兼容性”出了连接问题先查版本矩阵能少走很多弯路。说到最后我个人的体会是在 Ubuntu 上装 PostgreSQL路径选择其实大于技巧本身。开发环境直接用 Docker 是最快的生产环境老老实实走 apt 或 PGDG 源、用 systemd 托管遇到问题会有最完整的社区支持。而且安装这东西真的不难真正的功夫在于装完之后的配置、备份、安全和日常运维细节。最后分享一个小习惯每次改完postgresql.conf先执行SELECT pg_reload_conf();能热加载就不重启能不动服务就不动服务数据库这种基础组件少一次重启就少一分风险。