Ubuntu下PostgreSQL安装与生产环境配置指南

发布时间:2026/6/23 15:20:46
Ubuntu下PostgreSQL安装与生产环境配置指南 1. 项目概述为什么在 Ubuntu 上装 PostgreSQL 不是“点几下就完事”的事PostgreSQL这个被开发者私下称为“开源数据库里的瑞士军刀”的关系型数据库它和 Ubuntu 的组合表面上看就是一条sudo apt install postgresql命令的事。但我在过去十年里给上百个团队做过数据库部署从初创公司的小型 API 服务到金融客户跑实时风控的 OLAP 平台再到高校科研团队处理 TB 级基因测序数据——每一次看似简单的“安装”背后都藏着至少三个必须回答清楚的问题装哪个版本装完能不能直接用装完之后第一件事该做什么这三个问题答错一个后面轻则连不上数据库、重则数据目录权限混乱导致服务起不来、再严重些新同事接手时面对一堆psql: error: connection to server on socket /var/run/postgresql/.s.PGSQL.5432 failed的报错直接怀疑人生。你搜“postgresql安装”出来的教程90% 都卡在“执行完命令就结束了”但真实世界里Ubuntu 系统的默认安装策略、PostgreSQL 的多版本共存机制、以及 Ubuntu 各发行版20.04/22.04/24.04对 systemd 服务管理的细微差异全都会在你敲下回车后立刻跳出来给你上课。比如 Ubuntu 22.04 默认装的是 PostgreSQL 14但如果你的项目文档明确要求 15 或 16直接apt install就会踩进版本陷阱再比如sudo apt install postgresql实际上只装了服务端二进制文件客户端工具psql和管理包postgresql-contrib是分开的漏装一个你连基本的\l查看数据库列表都做不到。更隐蔽的是权限问题Ubuntu 安装后会自动创建postgres系统用户并把数据目录/var/lib/postgresql/的所有权设为该用户但很多新手会习惯性用sudo su -切换到 root 再去操作结果发现psql -U postgres死活连不上——不是密码错了而是 root 用户根本没被允许通过本地 socket 连接。所以这篇内容不是教你怎么复制粘贴命令而是带你把整个安装链路拆开从系统环境判断、源配置逻辑、服务启动原理、到首次登录验证每一步都告诉你“为什么这么设计”、“不这么做的后果是什么”、“我当年在客户现场是怎么快速定位问题的”。适合三类人刚转行的后端新人别再被role ubuntu does not exist折磨了、运维同学需要理解 Ubuntu 包管理与 PostgreSQL 官方包的冲突点、还有那些正在写 CI/CD 脚本却总在docker build阶段失败的 DevOps 工程师你遇到的E: Unable to locate package postgresql-16其实和 APT 缓存策略强相关。核心关键词PostgreSQL、Ubuntu、install不是孤立存在的它们共同指向一个动作在特定 Linux 发行版上构建一个可立即投入开发或生产使用的数据库运行时环境。2. 安装方案深度拆解APT 默认安装 vs 官方源 vs 手动编译选哪条路2.1 Ubuntu APT 仓库安装最省心但有“隐形枷锁”Ubuntu 官方仓库提供的 PostgreSQL 包本质是 Canonical 团队基于上游源码打过补丁、适配过 Ubuntu 系统路径和 systemd 单元文件的“定制版”。它的优势极其明显一键安装、自动依赖解析、和系统更新同步。执行sudo apt update sudo apt install postgresql后你会得到一个开箱即用的服务数据目录在/var/lib/postgresql/配置文件在/etc/postgresql/*/main/日志默认写入/var/log/postgresql/。但这个“省心”背后有三道硬性枷锁第一道是版本锁定。Ubuntu LTS 版本的软件包策略是“稳定优先”这意味着 20.04Focal默认提供 PostgreSQL 1222.04Jammy是 1424.04Noble才是 16。如果你的项目强制要求 PostgreSQL 15比如要用GENERATED ALWAYS AS IDENTITY的增强语法APT 仓库里根本找不到postgresql-15这个包名。此时apt search postgresql返回的全是postgresql-14相关条目新手很容易误以为“系统不支持”其实只是源里没收录。第二道是组件分离。sudo apt install postgresql这个命令实际只安装了postgresql-14以 22.04 为例主包它包含postgres服务进程、基础 SQL 引擎和initdb工具。但日常开发必备的psql命令行客户端被放在独立的postgresql-client-14包里而像pg_dump备份、pg_restore还原、vacuumdb维护这些工具又分散在postgresql-client-common和postgresql-common中。更关键的是postgresql-contrib-14它提供了pg_stat_statements性能分析、hstore键值存储、uuid-osspUUID 生成等几十个扩展模块。漏装contrib你在CREATE EXTENSION pg_stat_statements;时就会收到ERROR: could not open extension control file /usr/share/postgresql/14/extension/pg_stat_statements.control。这不是 bug是 Ubuntu 的模块化设计哲学——把核心功能和可选扩展彻底解耦。第三道是服务管理逻辑。APT 安装后PostgreSQL 服务由 systemd 管理服务名是postgresql.service但它是个“元服务”meta-service真正控制具体实例的是postgresql14-main.service这样的模板单元。你可以用sudo systemctl status postgresql看整体状态但要重启某个实例得用sudo systemctl restart postgresql14-main。很多教程教sudo service postgresql restart这在旧版 SysVinit 系统上有效但在现代 Ubuntu 上service命令只是systemctl的兼容层底层调用的仍是 systemd而postgresql这个服务名本身并不对应一个真实的.service文件它只是个符号链接。这就解释了为什么有些人在systemctl list-units | grep postgres里找不到postgresql.service——因为list-units默认只显示已加载的单元而postgresql.service是个“生成式”服务只有在systemctl start postgresql时才会动态生成。提示判断当前系统是否已安装 PostgreSQL不要只看which psql。因为psql可能来自其他渠道如手动编译安装或 Docker 容器内。最可靠的方法是sudo systemctl list-unit-files | grep postgresql它会列出所有与 PostgreSQL 相关的 systemd 单元文件状态enabled/disabled这才是服务是否被系统承认的铁证。2.2 PostgreSQL 官方 APT 源安装解锁最新版但需亲手“拧紧螺丝”当你需要 Ubuntu 仓库之外的版本比如 15、16、甚至测试版 17beta就必须切换到 PostgreSQL Global Development GroupPGDG官方维护的 APT 源。这个源的核心价值在于“版本自由”——它为每个 Ubuntu 发行版都提供了从 9.6 到最新版的完整包矩阵。但自由是有代价的你需要手动添加 GPG 密钥、配置源地址、并理解其与 Ubuntu 官方源的优先级冲突。第一步是添加密钥。PGDG 使用独立的 GPG 密钥签名所有包防止中间人篡改。执行wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -是旧方法Ubuntu 22.04 已弃用apt-key因其将密钥全局信任存在安全风险。正确姿势是下载密钥文件到/etc/apt/trusted.gpg.d/目录curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo gpg --dearmor -o /usr/share/keyrings/postgresql-archive-keyring.gpg这里gpg --dearmor是关键它把 ASCII 格式的公钥转换成二进制.gpg文件这是新版 APT 认可的格式。第二步是配置源。PGDG 提供两种源地址https://apt.postgresql.org/pub/repos/apt/主源和https://apt-archive.postgresql.org/pub/repos/apt/归档源用于旧版。你需要根据 Ubuntu 版本代号focal/jammy/noble和架构amd64/arm64构造 URL。例如 Ubuntu 22.04jammy的源地址是deb [archamd64 signed-by/usr/share/keyrings/postgresql-archive-keyring.gpg] https://apt.postgresql.org/pub/repos/apt/ jammy-pgdg main。注意signed-by参数它明确指定了该源使用的密钥文件路径这是新版 APT 的强制要求。如果漏掉这行apt update时会报NO_PUBKEY ACCC4CF8错误。第三步是解决包冲突。PGDG 源和 Ubuntu 官方源都提供postgresql包APT 默认按Package: postgresql的版本号决定安装哪个。PGDG 的版本号通常更高如16244.pgdg22.041vs Ubuntu 的14244ubuntu2.1所以apt install postgresql会自动选 PGDG 的。但如果你想精确安装 15必须显式指定包名sudo apt install postgresql-15。这里有个坑postgresql-15包依赖postgresql-client-15和postgresql-contrib-15但postgresql-client-15又依赖postgresql-client-common而这个包在 Ubuntu 仓库里也有同名版本。APT 会智能选择版本号更高的那个但如果你之前手动安装过旧版postgresql-client-common可能会因依赖不满足而失败。此时apt policy postgresql-client-common能清晰显示所有可用版本及其来源500 http://archive.ubuntu.com/ubuntu jammy/main amd64 Packagesvs500 https://apt.postgresql.org/pub/repos/apt jammy-pgdg/main amd64 Packages让你一眼看出哪个版本会被选中。注意PGDG 源的main组件只包含 PostgreSQL 主程序和扩展不包含postgresql-doc-*文档或postgresql-plperl-*Perl 语言支持等可选包。这些包在main组件里不存在必须去pgdg源的main组件找。很多新手在apt search perl后找不到postgresql-plperl-15就是因为没确认源组件名。2.3 手动编译安装掌控一切但代价是“时间税”当 APT 和官方源都无法满足需求时——比如你需要启用--with-icuICU 国际化支持编译选项或者想在 ARM 架构的树莓派上跑 PostgreSQL又或者你的生产环境严格禁止使用任何第三方源——手动编译就是唯一出路。它给了你上帝视角从 C 编译器参数到共享内存段大小一切皆可调。但代价是巨大的“时间税”一次完整编译含configure、make、make install在普通笔记本上耗时 15-30 分钟在 CI/CD 流水线里更是灾难。编译前的依赖检查是生死线。./configure脚本会扫描系统检查gcc、make、readline命令行编辑、zlib压缩、opensslSSL 加密、python3PL/Python 支持等是否齐全。少一个configure就会报错退出并告诉你缺什么。但这里有个经典陷阱readline库在 Ubuntu 上叫libreadline-dev而zlib叫zlib1g-dev名字不统一。更隐蔽的是python3-dev它提供 Python 头文件没有它--with-python选项会静默失效编译出的 PostgreSQL 就不支持 PL/Python。所以标准依赖安装命令是sudo apt update sudo apt install -y build-essential libreadline-dev zlib1g-dev libssl-dev python3-dev注意-y参数它自动确认所有交互提示这对自动化脚本至关重要。./configure的参数设计是核心艺术。--prefix/usr/local/pgsql指定安装根目录--datadir/usr/local/pgsql/data指定数据目录这两个路径必须不同否则初始化会失败。--with-openssl启用 SSL--with-python启用 Python 支持--enable-debug开启调试符号仅开发环境用会显著增大二进制体积。最关键的参数是--with-systemd它让 PostgreSQL 编译时生成 systemd 兼容的启动脚本。没有它你得自己手写.service文件而手写的脚本往往在RestartSec重启间隔、StartLimitIntervalSec启动频率限制等细节上出错导致服务反复崩溃后被 systemd 拉黑。编译完成后sudo make install会把二进制文件、库、头文件复制到--prefix指定的目录。此时 PostgreSQL 还不能运行必须用initdb初始化数据目录sudo -u postgres /usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data这里sudo -u postgres是强制要求因为数据目录的所有权必须是postgres用户否则postgres进程启动时会因权限不足而拒绝运行。initdb的-D参数指定数据目录路径必须和--datadir一致。初始化成功后你会看到The database cluster will be initialized with locale en_US.UTF-8这样的提示说明字符集已正确设置。实操心得手动编译最大的“反直觉”点在于——它不创建任何 systemd 服务。你必须自己写/etc/systemd/system/postgresql-custom.service内容要严格遵循 PostgreSQL 官方推荐的模板尤其是Typenotify通知类型和NotifyAccessall通知权限这两行。漏掉Typenotifysystemd 会认为服务“启动完成”但实际上postgres进程还在后台初始化导致systemctl start返回成功但psql连接超时。这是我帮某电商客户排查三天才定位到的坑。3. 安装后必做的五件关键事从“装上了”到“能用了”的临门一脚3.1 验证服务状态与端口监听别信“active (running”要看真数据sudo systemctl status postgresql显示active (running)只是 systemd 层面的状态它只保证postgres进程被拉起来了不保证数据库引擎真的在响应请求。真正的验证必须落到网络层和应用层。首先检查 PostgreSQL 是否在监听 TCP 端口默认 5432sudo ss -tlnp | grep :5432ss命令比netstat更快更准-tlnp参数表示tTCP、l监听、n数字端口、p显示进程。正常输出应该是LISTEN 0 128 127.0.0.1:5432 0.0.0.0:* users:((postgres,pid1234,fd6))这表示postgres进程PID 1234正在127.0.0.1:5432监听。如果看到::1:5432IPv6 地址说明它只监听 IPv6而你的psql默认走 IPv4就会连接失败。此时要检查postgresql.conf中的listen_addresses参数。其次用psql进行本地 socket 连接测试。Ubuntu 安装后默认配置是local连接方式通过 Unix domain socket路径是/var/run/postgresql/.s.PGSQL.5432。执行sudo -u postgres psql -c SELECT version();sudo -u postgres切换到数据库超级用户-c执行 SQL 命令。如果返回类似PostgreSQL 14.12 (Ubuntu 14.12-0ubuntu0.22.04.1) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0, 64-bit的结果说明数据库引擎完全就绪。如果报错psql: error: connection to server on socket /var/run/postgresql/.s.PGSQL.5432 failed常见原因有三一是postgres进程根本没起来systemctl status显示 inactive二是 socket 文件路径不对postgresql.conf的unix_socket_directories设成了/tmp三是权限问题/var/run/postgresql/目录的所有者不是postgres用户。提示psql连接时的-hhost和-pport参数是灵魂。psql -h localhost -p 5432强制走 TCP/IPpsql -h /var/run/postgresql强制走 Unix socket。前者会触发pg_hba.conf的host规则后者触发local规则。很多连接问题根源就在你没搞清自己用的是哪种连接方式。3.2 修改默认密码与创建新用户别让“postgres”账号裸奔Ubuntu 安装后postgres系统用户和数据库超级用户postgres是两个概念。前者是 Linux 系统账户后者是 PostgreSQL 内部的数据库角色。默认情况下postgres数据库用户的密码是空的且pg_hba.conf配置允许local连接无需密码trust认证。这在开发机上方便但在任何联网环境都是巨大风险。修改密码的第一步必须先用peer认证Linux 系统用户身份登录sudo -u postgres psql进入psql后执行ALTER USER postgres PASSWORD MyStr0ngPssw0rd!;注意单引号包裹密码且密码必须包含大小写字母、数字、特殊字符PostgreSQL 14 默认启用password_encryption scram-sha-256要求强密码。执行后postgres用户的密码就被加密存储在pg_authid系统表中。但仅改密码还不够。生产环境严禁用postgres账号做日常开发。你应该创建一个专属用户CREATE USER myapp WITH PASSWORD AppPss2024! CREATEDB;CREATEDB权限允许该用户创建自己的数据库LOGIN权限默认开启允许登录。然后创建数据库CREATE DATABASE myapp_db OWNER myapp;最后赋予该用户对数据库的全部权限GRANT ALL PRIVILEGES ON DATABASE myapp_db TO myapp;这样应用连接字符串就可以是postgresql://myapp:AppPss2024!localhost:5432/myapp_db完全隔离于postgres超级用户。注意pg_hba.conf的认证规则必须匹配。如果你创建了myapp用户但pg_hba.conf里local行还是trust那么任何人只要能sudo -u postgres就能连上myapp_db。所以改完密码后必须编辑/etc/postgresql/*/main/pg_hba.conf把local all all trust改成local all all md5密码认证然后sudo systemctl reload postgresql重载配置。reload不重启服务只重新读取配置文件这是运维黄金法则。3.3 配置远程访问打开防火墙但别打开“所有门”默认配置下PostgreSQL 只监听127.0.0.1localhost外部机器无法连接。要让其他设备如你的开发笔记本、前端服务器访问必须做两件事修改postgresql.conf和pg_hba.conf。第一步编辑/etc/postgresql/*/main/postgresql.conf找到#listen_addresses localhost取消注释并改为listen_addresses localhost,192.168.1.100192.168.1.100是你的 Ubuntu 服务器在局域网内的 IP 地址用ip a命令查看。绝对不要写成listen_addresses *这会让 PostgreSQL 监听所有网络接口包括公网 IP一旦防火墙没配好等于把数据库直接暴露在互联网上。最小权限原则在这里是生命线。第二步编辑/etc/postgresql/*/main/pg_hba.conf在文件末尾添加一行host all all 192.168.1.0/24 md5这行规则的意思是允许来自192.168.1.0/24子网即192.168.1.1到192.168.1.254的所有用户用md5密码认证方式连接所有数据库。host表示 TCP/IP 连接all数据库名和all用户是通配符生产环境应替换为具体数据库名和用户名。第三步开放 Ubuntu 防火墙端口。Ubuntu 默认用ufwUncomplicated Firewallsudo ufw allow from 192.168.1.50 to any port 5432192.168.1.50是你的开发机 IP。这条命令比sudo ufw allow 5432更安全因为它只允许特定 IP 访问而不是整个子网。执行后sudo ufw status verbose应显示5432 ALLOW IN Anywhere (v6)和具体的 IPv4 规则。实操心得我见过太多客户因为listen_addresses *ufw allow 5432的组合导致数据库被暴力破解脚本扫到postgres账号被撞库成功。后来我们强制推行“三步法”1.listen_addresses只写业务必需的 IP2.pg_hba.conf用hostssl强制 SSLhostssl all all 0.0.0.0/0 rejecthostssl all all 192.168.1.0/24 md53.ufw规则精确到源 IP。这三道锁缺一不可。3.4 启用常用扩展让 PostgreSQL 从“能用”变成“好用”postgresql-contrib包提供的扩展是 PostgreSQL 区别于 MySQL 的核心竞争力。安装后必须手动在每个数据库中启用它们。以最常用的pg_stat_statements为例它记录所有 SQL 的执行次数、耗时、命中率是性能调优的基石sudo -u postgres psql -d myapp_db -c CREATE EXTENSION pg_stat_statements;-d myapp_db指定目标数据库CREATE EXTENSION是 DDL 命令必须在具体数据库内执行。启用后SELECT * FROM pg_stat_statements LIMIT 5;就能看到最近执行的 SQL 统计。另一个高频扩展是hstore键值对存储CREATE EXTENSION hstore; -- 创建一个带 hstore 字段的表 CREATE TABLE products ( id SERIAL PRIMARY KEY, name TEXT, attributes HSTORE ); -- 插入数据 INSERT INTO products (name, attributes) VALUES (Laptop, brandDell, ram16GB, cpui7); -- 查询 brand 为 Dell 的产品 SELECT * FROM products WHERE attributes - brand Dell;hstore的-操作符让 JSON-like 查询变得极其简洁。对于地理空间应用postgis扩展是标配需额外安装postgis包sudo apt install postgis postgresql-14-postgis-3 sudo -u postgres psql -d myapp_db -c CREATE EXTENSION postgis;启用后geometry和geography数据类型、ST_Distance等函数就可用了。注意扩展启用是数据库级别的不是集群级别的。如果你有myapp_db和analytics_db两个库必须分别执行CREATE EXTENSION。pg_stat_statements还有一个坑它默认只统计top层查询嵌套在函数或视图里的 SQL 不会被捕获。要开启全量统计需在postgresql.conf中设置pg_stat_statements.track all然后sudo systemctl reload postgresql。3.5 配置日志与监控让数据库“开口说话”PostgreSQL 的日志是故障排查的唯一真相源。默认配置log_destination stderr把日志输出到标准错误由 systemd 捕获到journalctl。但这种方式不利于长期分析。最佳实践是切换到文件日志编辑postgresql.conf设置log_destination csvlog logging_collector on log_directory /var/log/postgresql log_filename postgresql-%Y-%m-%d_%H%M%S.log log_statement ddl # 记录所有 DDLCREATE/DROP/ALTER log_min_duration_statement 1000 # 记录执行超 1 秒的 SQLcsvlog格式是逗号分隔的 CSV便于用awk、grep或 ELK 栈解析。log_min_duration_statement 1000是性能监控的黄金参数它帮你自动揪出慢查询。配置生效后sudo systemctl restart postgresql然后用sudo journalctl -u postgresql -f实时跟踪日志。你会看到类似2024-05-20 10:30:45.123 UTC,myapp,myapp_db,192.168.1.50:54321,56789,1,SELECT,2024-05-20 10:30:45 CST,3/15,0,LOG,00000,duration: 1245.678 ms execute unnamed: SELECT * FROM products WHERE price $1,,,,,,,,psql这行日志包含了时间、用户、数据库、客户端 IP、进程 ID、事务 ID、SQL 类型、执行时长、SQL 文本等全部信息。对于生产环境建议搭配pgBadger工具做日志分析sudo apt install pgbadger sudo -u postgres pgbadger /var/log/postgresql/*.log -o /var/www/html/pgbadger_report.html它会生成一个交互式 HTML 报告直观展示慢查询 Top 10、错误率趋势、客户端分布等。实操心得日志配置的最大误区是log_statement all。它会记录每一条 SQL包括SELECT 1这样的心跳检测日志体积爆炸式增长磁盘很快写满。我在线上环境只开ddl和modDMLINSERT/UPDATE/DELETE配合log_min_duration_statement既能抓到问题又不拖垮 I/O。4. 常见问题与排查技巧实录那些让我凌晨三点爬起来的报错4.1 “psql: error: connection to server on socket ... failed” 全场景排查这个报错是 PostgreSQL 新手的“噩梦入口”但背后原因高度结构化。我把它拆解成四层检查清单按顺序执行95% 的问题都能秒解。第一层服务进程是否存在sudo systemctl status postgresql # 如果显示 inactive直接启动 sudo systemctl start postgresql # 如果启动失败看详细日志 sudo journalctl -u postgresql --since 1 hour ago | tail -20常见失败原因是data directory权限错误。journalctl日志里会出现FATAL: data directory /var/lib/postgresql/14/main has group or world access。解决方案sudo chmod 700 /var/lib/postgresql/14/main sudo chown -R postgres:postgres /var/lib/postgresql/14/main第二层socket 文件是否存在ls -la /var/run/postgresql/ # 正常应有 .s.PGSQL.5432 和 .s.PGSQL.5432.lock # 如果没有说明 postgres 进程没成功创建 socket # 检查 postgresql.conf 的 unix_socket_directories sudo grep unix_socket_directories /etc/postgresql/*/main/postgresql.conf # 默认是 /var/run/postgresql确保该目录存在且权限正确 sudo mkdir -p /var/run/postgresql sudo chown postgres:postgres /var/run/postgresql sudo chmod 2775 /var/run/postgresql第三层pg_hba.conf 认证规则是否匹配sudo cat /etc/postgresql/*/main/pg_hba.conf | grep -v ^# | grep -v ^$ # 找到 local 行确认是 md5 或 peer不是 reject # 如果是 trust但你想用密码登录必须改成 md5 # 修改后 reload sudo systemctl reload postgresql第四层psql 连接参数是否正确# 用 -h 显式指定 host psql -h /var/run/postgresql -U postgres # 或者用 -d 指定数据库 psql -d postgres -U postgres # 如果还失败用 strace 看底层系统调用 sudo strace -e traceconnect,openat psql -U postgres 21 | grep -E (connect|openat) # 这会显示 psql 尝试连接哪个 socket 路径一目了然排查技巧当psql报错时永远先执行echo $PGHOST和echo $PGPORT。环境变量会覆盖命令行参数如果$PGHOST被设为localhostpsql就会走 TCP 而非 socket即使你没加-h参数。4.2 “Role ubuntu does not exist”Ubuntu 用户与数据库用户的认知鸿沟这个报错源于一个根本误解Ubuntu 系统用户ubuntu和 PostgreSQL 数据库角色ubuntu是完全独立的实体。psql默认尝试用当前 Linux 用户名作为数据库用户名连接所以当你以ubuntu用户登录系统执行psql它等价于psql -U ubuntu。但 PostgreSQL 初始化时只创建了postgres角色ubuntu角色并不存在。解决方案有二方案一推荐创建同名数据库用户sudo -u postgres psql -c CREATE USER ubuntu WITH PASSWORD YourPass123! LOGIN; sudo -u postgres psql -c ALTER USER ubuntu CREATEDB;LOGIN权限是关键没有它ubuntu用户无法登录数据库。方案二显式指定用户psql -U postgres # 进入后创建数据库和用户 CREATE DATABASE ubuntu_db OWNER ubuntu;但方案二有个隐藏坑psql -U postgres要求postgres用户有密码而默认是空密码。所以必须先按 3.2 节修改postgres密码。注意CREATE USER和CREATE ROLE是等价的CREATE USER是CREATE ROLE ... LOGIN的语法糖。sudo -u postgres psql进入后SELECT rolname FROM pg_roles;可以查看所有角色。4.3 “Failed to start postgresql.service: Unit postgresql.service not found”systemd 服务名迷雾这个报错说明你试图启动一个不存在的 systemd 服务。在 Ubuntu 22.04postgresql.service是一个“模板服务”template unit真实的服务名是postgresql14-main.service。符号后的14-main是实例标识符14是主版本号main是集群名cluster name。正确启动方式# 查看所有 postgresql 实例 sudo systemctl list-units | grep postgresql # 启动默认实例通常是 14-main sudo systemctl start postgresql14-main # 设置开机自启 sudo systemctl enable postgresql14-main如果你不确定实例名可以用pg_lsclusters命令来自postgresql-common包sudo pg_lsclusters # 输出 # Ver Cluster Port Status Owner Data directory Log file # 14 main 5432 online postgres /var/lib/postgresql/14/main