Ubuntu 22.04 安装 PostgreSQL 18 指南

在 Ubuntu 22.04 上通过 PostgreSQL 官方 PGDG 源安装最新稳定版 PostgreSQL 18(18.6),完成初始化、启动、远程访问配置与基本安全加固,并给出验证明细

PostgreSQLPostgreSQL安装部署数据库2026/09/27

Ubuntu 22.04 安装 PostgreSQL 18 指南

目标:在 Ubuntu 22.04 上通过 PostgreSQL 官方 PGDG 源安装最新稳定版 PostgreSQL 18(18.6),完成初始化、启动、远程访问配置与基本安全加固,并给出验证明细。

环境信息

  • 操作系统:Ubuntu 22.04.5 LTS
  • 系统架构:x86_64
  • 内核版本:6.8.0-138-generic
  • 包管理器:apt
  • PostgreSQL 版本:18.6-1.pgdg22.04+2(PostgreSQL Community Server)
  • 软件源:PostgreSQL 官方 PGDG 源 apt.postgresql.org/pub/repos/apt
  • 数据目录:/opt/data/postgresql(已从默认的 /var/lib/postgresql/18/main 迁移)
  • 配置文件:/etc/postgresql/18/main/postgresql.conf

前置条件

  • 拥有 root 权限或 sudo 权限
  • 网络可访问 PostgreSQL 官方 PGDG 源(apt.postgresql.org)
  • 服务器已更新到最新状态:sudo apt update && sudo apt upgrade -y
  • 已安装基础工具:curl、ca-certificates、gnupg(用于下载并校验 GPG 密钥)

版本选型说明

PostgreSQL 官方提供了两个主要安装来源:

来源版本特点
Ubuntu 默认源(archive.ubuntu.com)PostgreSQL 14(Ubuntu 22.04 固定)老版本,缺少新特性,缺乏安全更新节奏
PGDG 官方源(apt.postgresql.org)PostgreSQL 18.6(最新稳定版)含全部小版本安全修复,支持新特性

💡 说明:Ubuntu 22.04 的默认源只提供 PostgreSQL 14(已处于维护期尾声)。如需使用最新稳定版,必须添加 PGDG 官方源。本文档采用 PGDG 源安装 PostgreSQL 18.6(当前最新稳定版本,18 系列)。


部署步骤

步骤 1. 更新软件源

安装前先刷新 apt 软件包索引,确保能获取最新的软件包信息。

执行命令:

sudo apt-get update

执行结果:

Get:1 http://archive.ubuntu.com/ubuntu jammy InRelease [270 kB]
Get:2 http://security.ubuntu.com/ubuntu jammy-security InRelease [110 kB]
Fetched 48.2 MB in 10s (4748 kB/s)
Reading package lists... Done

💡 命令解释:apt-get update 从配置的软件源下载最新的软件包索引列表,不安装任何软件,只更新"可安装软件"的目录。

💡 说明:Reading package lists... Done 表示本地软件包索引已更新完成,可以开始安装。

步骤 2. 安装前置工具

安装下载 GPG 密钥和 HTTPS 传输所需的工具。

执行命令:

sudo apt-get install -y curl ca-certificates gnupg lsb-release

执行结果:

ca-certificates is already the newest version.
curl is already the newest version.
gnupg is already the newest version.
0 upgraded, 0 newly installed, 0 to remove.
Running hooks in /etc/ca-certificates/update.d...
done.

💡 命令解释:curl 用于下载 GPG 密钥文件;ca-certificates 提供 HTTPS 证书校验;gnupg 提供 GPG 签名校验能力;lsb-release 用于识别发行版代号;-y 自动确认安装。

💡 说明:这些工具在多数 Ubuntu 22.04 系统中已预装。若均为最新版本,则输出 0 newly installed。

步骤 3. 导入 PGDG 官方 GPG 密钥

导入 PostgreSQL 官方仓库的签名密钥,用于验证软件包的完整性与来源。

执行命令:

sudo install -d /usr/share/postgresql-common/pgdg
sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc

执行结果:

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  4812  100  4812    0     0   4970      0 --:--:-- --:--:-- --:--:--  4971

💡 命令解释:install -d 创建 PGDG 密钥存放目录;curl -o 将密钥文件下载到指定路径;--fail 表示服务器返回错误时静默失败(避免写入错误内容);ACCC4CF8.asc 是 PostgreSQL Apt 仓库的官方 GPG 公钥。

💡 说明:下载成功(4812 字节),这是 PostgreSQL 官方用于签名 APT 软件包的 GPG 公钥,为后续验证软件包来源提供保障。

步骤 4. 添加 PGDG 软件源

将 PGDG 仓库地址写入 apt 源列表,并指定使用刚导入的 GPG 密钥进行签名验证。

执行命令:

sudo sh -c 'echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] https://apt.postgresql.org/pub/repos/apt jammy-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
sudo apt-get update

执行结果:

Get:1 https://apt.postgresql.org/pub/repos/apt jammy-pgdg InRelease [158 kB]
Get:2 https://apt.postgresql.org/pub/repos/apt jammy-pgdg/main amd64 Packages [302 kB]
Fetched 460 kB in 1s (312 kB/s)
Reading package lists... Done

💡 命令解释:[signed-by=...] 指定用导入的 GPG 公钥验证该仓库的软件包签名;jammy-pgdg 是 Ubuntu 22.04(jammy)对应的 PGDG 仓库分支;main 是仓库组件。执行后再次 apt-get update 让新源生效。

💡 说明:成功从 PGDG 源拉取索引。现在可以通过 apt-cache policy postgresql-18 查看可用版本。

步骤 5. 确认可用版本

执行命令:

apt-cache policy postgresql-18

执行结果:

postgresql-18:
  Installed: (none)
  Candidate: 18.6-1.pgdg22.04+2
  Version table:
     18.6-1.pgdg22.04+2 500
        500 https://apt.postgresql.org/pub/repos/apt jammy-pgdg/main amd64 Packages
     18.4-1.pgdg22.04+1 500
        500 https://apt.postgresql.org/pub/repos/apt jammy-pgdg/main amd64 Packages

💡 说明:Candidate: 18.6-1.pgdg22.04+2 是当前最新稳定版本,验证 PGDG 源已正确生效。

步骤 6. 安装 PostgreSQL 18

安装数据库服务端和命令行客户端。

执行命令:

sudo apt-get install -y postgresql-18 postgresql-client-18

执行结果:

Creating new PostgreSQL cluster 18/main ...
/usr/lib/postgresql/18/bin/initdb -D /var/lib/postgresql/18/main --auth-local peer --auth-host scram-sha-256 --no-instructions
The files belonging to this database system will be owned by user "postgres".
The database cluster will be initialized with locale "C.UTF-8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".

Data page checksums are enabled.

creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok
syncing data to disk ... ok
Setting up postgresql-18-jit (18.6-1.pgdg22.04+2) ...
Processing triggers for libc-bin (2.35-0ubuntu3.14) ...

💡 命令解释:postgresql-18 是数据库服务端;postgresql-client-18 是命令行客户端(psql、pg_dump 等);-y 自动确认。Debian/Ubuntu 的 PGDG 包会自动调用 initdb 初始化一个名为 18/main 的数据库集群。

💡 说明:

  • --auth-local peer:本地 socket 连接采用 peer 认证(以操作系统用户身份匹配数据库用户)。
  • --auth-host scram-sha-256:远程 TCP 连接采用 SCRAM-SHA-256 密码认证(较 md5 更安全)。
  • Data page checksums are enabled:默认启用数据页校验和,能检测磁盘位翻转损坏。
  • 安装过程中同时创建了系统用户 postgres,用于运行数据库进程。

步骤 7. 启动并查看集群状态

安装完成后,PGDG 包通常会自动启动集群。可用 pg_lsclusters 查看状态,若未启动则手动启动。

执行命令:

sudo pg_ctlcluster 18 main start
pg_lsclusters

执行结果:

Ver Cluster Port Status Owner    Data directory              Log file
18  main    5432 online postgres /var/lib/postgresql/18/main /var/log/postgresql/postgresql-18-main.log

💡 命令解释:pg_ctlcluster 18 main start 启动版本为 18、名为 main 的集群;pg_lsclusters 列出本机所有 PostgreSQL 集群及其状态、端口、数据目录和日志文件。

💡 说明:集群状态为 online,监听默认端口 5432,数据目录为 /var/lib/postgresql/18/main。

步骤 8. 验证安装与版本

切换到 postgres 系统用户,连接数据库并查询版本号。

执行命令:

sudo -u postgres psql --version
sudo -u postgres psql -c "SELECT version();"

执行结果:

psql (PostgreSQL) 18.6 (Ubuntu 18.6-1.pgdg22.04+2)

PostgreSQL 18.6 (Ubuntu 18.6-1.pgdg22.04+2) on x86_64-pc-linux-gnu, compiled by gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0, 64-bit

💡 命令解释:sudo -u postgres 以 postgres 系统用户身份执行命令(peer 认证下只有该用户能本地免密登录);psql --version 查看客户端版本;SELECT version(); 查询服务端详细版本信息。

💡 说明:成功返回 PostgreSQL 18.6 版本信息,证明安装、初始化、启动全部正确。


配置说明

配置项 1:数据目录迁移到 /opt/data/postgresql

PostgreSQL 默认数据目录位于系统盘 /var/lib/postgresql/18/main。生产环境通常将数据目录迁移到独立数据盘(如 /opt/data/postgresql),便于容量管理与备份。

⚠️ 注意:迁移需在初始化集群时指定数据目录,或迁移已存在集群(先停库)。安装包自带的默认集群在安装时已自动初始化到 /var/lib/postgresql/18/main,如需换目录需先删除默认集群再重建。

方式一:初始化集群时直接指定(推荐,需在安装后立刻执行)

# 1. 删除安装包自动创建的默认集群
sudo pg_dropcluster 18 main

# 2. 创建数据目录并授权给 postgres 用户
sudo mkdir -p /opt/data/postgresql
sudo chown postgres:postgres /opt/data/postgresql

# 3. 用 -d 指定数据目录重建集群并启动
sudo pg_createcluster 18 main -d /opt/data/postgresql --start

执行结果:

Ver Cluster Port Status Owner    Data directory       Log file
18  main    5432 online postgres /opt/data/postgresql /var/log/postgresql/postgresql-18-main.log

💡 命令解释:pg_dropcluster 18 main 删除版本 18 的默认集群(连同其数据目录);pg_createcluster 18 main -d /opt/data/postgresql --start 用指定数据目录创建新集群并立即启动;--start 等价于创建后执行 pg_ctlcluster 18 main start。

验证数据目录已生效:

sudo -u postgres psql -c "SHOW data_directory;"

执行结果:

/opt/data/postgresql

💡 说明:SHOW data_directory 返回 /opt/data/postgresql,说明集群已运行在新数据目录。配置文件仍位于 /etc/postgresql/18/main/postgresql.conf(Debian 系配置文件独立于数据目录)。

方式二:迁移已有集群(数据目录含历史数据)

# 1. 停止集群
sudo pg_ctlcluster 18 main stop

# 2. 整目录复制数据(保留权限)
sudo rsync -av /var/lib/postgresql/18/main/ /opt/data/postgresql/

# 3. 修改权限与配置文件
sudo chown -R postgres:postgres /opt/data/postgresql
sudo sed -i "s|data_directory = '/var/lib/postgresql/18/main'|data_directory = '/opt/data/postgresql'|" /etc/postgresql/18/main/postgresql.conf

# 4. 启动并验证
sudo pg_ctlcluster 18 main start
sudo -u postgres psql -c "SHOW data_directory;"

配置项 2:创建业务用户与数据库(真实环境实测)

生产环境不应直接使用超级用户 postgres 执行业务,建议按"最小权限"原则创建独立业务账号与数据库。以下 SQL 在 PostgreSQL 18.6 真实环境执行验证通过。

执行命令:

sudo -u postgres psql
-- 1. 创建业务用户(LOGIN 权限,密码加密存储)
CREATE USER app_user WITH PASSWORD 'App@2026#Secure';

-- 2. 创建业务数据库(指定属主与 UTF8 编码,避免继承模板库的本地化设置)
CREATE DATABASE app_db OWNER app_user ENCODING 'UTF8' TEMPLATE template0;

-- 3. 授权:将数据库全部权限授予业务用户
GRANT ALL PRIVILEGES ON DATABASE app_db TO app_user;

-- 4. 可选:为该数据库设置默认时区
ALTER DATABASE app_db SET timezone TO 'Asia/Shanghai';

执行结果:

CREATE ROLE
CREATE DATABASE
GRANT
ALTER DATABASE

💡 命令解释:CREATE USER 等价于 CREATE ROLE ... WITH LOGIN;OWNER app_user 直接让业务用户成为库属主;ENCODING 'UTF8' TEMPLATE template0 指定 UTF8 编码并绕过模板库的编码/本地化继承;GRANT ALL PRIVILEGES ON DATABASE 授予库级全部权限。

验证:

# 查看用户与数据库信息
sudo -u postgres psql -c "SELECT rolname, rolsuper, rolcanlogin FROM pg_roles WHERE rolname='app_user';"
sudo -u postgres psql -c "SELECT datname, datdba::regrole, pg_encoding_to_char(encoding) FROM pg_database WHERE datname='app_db';"

# 用业务账号远程连接(TCP)并建表插入测试
PGPASSWORD='App@2026#Secure' psql -h 127.0.0.1 -U app_user -d app_db -c "CREATE TABLE t_demo(id serial primary key, name text);"
PGPASSWORD='App@2026#Secure' psql -h 127.0.0.1 -U app_user -d app_db -c "INSERT INTO t_demo(name) VALUES ('postgresql测试');"
PGPASSWORD='App@2026#Secure' psql -h 127.0.0.1 -U app_user -d app_db -c "SELECT * FROM t_demo;"

执行结果:

app_user|f|t
app_db|app_user|UTF8
CREATE TABLE
INSERT 0 1
 id |      name
----+----------------
  1 | postgresql测试
(1 row)

💡 说明:rolsuper=f, rolcanlogin=t 表示 app_user 是非超级用户但可登录;datdba=app_user 表示库属主正确。业务账号远程连接、建表、插入、查询全部成功,证明授权完整可用。

配置项 3:设置 postgres 数据库用户密码(可选)

本地 peer 认证免密,但若要远程连接,需为 postgres 用户设置密码。

sudo -u postgres psql -c "ALTER USER postgres WITH PASSWORD '你的强密码';"

配置项 4:添加 IP 白名单(pg_hba.conf)

pg_hba.conf 是 PostgreSQL 的客户端认证控制文件,按"先匹配先生效"原则从上到下匹配。生产环境应使用白名单(指定网段)而非 0.0.0.0/0 全开放。

第一步:开启监听

编辑 /etc/postgresql/18/main/postgresql.conf,将监听地址改为 * 或指定内网 IP:

listen_addresses = '*'          # 监听所有网卡,或指定具体 IP

第二步:在 pg_hba.conf 追加白名单规则

编辑 /etc/postgresql/18/main/pg_hba.conf,在文件末尾追加:

# --- 自定义白名单(按需增删) ---
# 仅允许 app_user 从 192.168.146.0/24 访问 app_db 数据库
host    app_db      app_user        192.168.146.0/24        scram-sha-256
# 允许所有用户从内网 10.0.0.0/8 访问所有数据库
host    all         all             10.0.0.0/8              scram-sha-256

💡 格式说明:host 数据库 用户 地址段 认证方法。host 表示 TCP 连接;数据库/用户可写具体名称或 all;地址段支持 CIDR(192.168.146.0/24);认证方法使用 scram-sha-256(比 md5 更安全)。

第三步:重载配置并验证规则加载

sudo pg_ctlcluster 18 main reload
sudo -u postgres psql -c "SELECT type, database, user_name, address, auth_method FROM pg_hba_file_rules WHERE address IS NOT NULL;"

执行结果:

host|{all}|{all}|127.0.0.1|scram-sha-256
host|{all}|{all}|::1|scram-sha-256
host|{app_db}|{app_user}|192.168.146.0|scram-sha-256
host|{all}|{all}|10.0.0.0|scram-sha-256

💡 说明:pg_hba_file_rules 视图会即时反映 pg_hba.conf 的实际规则。自定义白名单(192.168.146.0/24、10.0.0.0/8)已加载生效。reload(SIGHUP)使 pg_hba.conf 修改立即生效,无需重启;而 listen_addresses 属于需要重启的参数,修改后需 sudo pg_ctlcluster 18 main restart(或 systemctl restart postgresql)。

第四步:确认监听并做真实远程验证

修改完成并重启后,先用 ss 确认已监听所有网卡(而非仅 127.0.0.1):

ss -ltnp | grep :5432

执行结果:

LISTEN 0      200          0.0.0.0:5432       0.0.0.0:*    users:(("postgres",pid=790655,fd=6))
LISTEN 0      200             [::]:5432          [::]:*    users:(("postgres",pid=790655,fd=7))

💡 说明:同时出现 0.0.0.0:5432(IPv4 全网卡)与 [::]:5432(IPv6 全网卡)即表示远程监听已生效。

最后用超管 postgres 账号 + 密码 + 真实服务器 IP(非回环)发起远程连接,验证远程访问链路端到端可用:

# 取本机非回环 IP(也可用 ifconfig / ip addr 确认)
PGPASSWORD='q1w2e3r4' psql -h 192.168.146.128 -p5432 -U postgres -Atc \
  "SELECT 'remote_ok', current_user, inet_server_addr();"

执行结果:

remote_ok|postgres|192.168.146.128

💡 说明:current_user=postgres 表示用超级用户成功登录;inet_server_addr()=192.168.146.128 证实连接是经真实远程地址(非回环)建立的,远程+localhost 密码登录均验证通过。生产环境建议把 pg_hba 的 0.0.0.0/0 收窄为真实内网网段,并配合防火墙放行 5432。

配置项 5:主配置文件结构(有效配置示例)

安装并将数据目录迁移到 /opt/data/postgresql 后,/etc/postgresql/18/main/postgresql.conf 中去注释后的有效配置如下:

data_directory = '/opt/data/postgresql'
hba_file = '/etc/postgresql/18/main/pg_hba.conf'
port = 5432
max_connections = 100
unix_socket_directories = '/var/run/postgresql'
ssl = on
ssl_cert_file = '/etc/ssl/certs/ssl-cert-snakeoil.pem'
ssl_key_file = '/etc/ssl/private/ssl-cert-snakeoil.key'
shared_buffers = 128MB
dynamic_shared_memory_type = posix
max_wal_size = 1GB
min_wal_size = 80MB
log_line_prefix = '%m [%p] %q%u@%d '
log_timezone = 'Etc/UTC'
cluster_name = '18/main'
datestyle = 'iso, mdy'
timezone = 'Etc/UTC'
default_text_search_config = 'pg_catalog.english'

💡 说明:data_directory = '/opt/data/postgresql' 为迁移后的数据目录。shared_buffers = 128MB 为默认值,生产环境一般建议调整为物理内存的 25% 左右(见《PostgreSQL 18 配置参数详解》文档)。ssl = on 默认启用 SSL,但使用系统自带的 snakeoil 自签名证书,生产环境应替换为正式证书。


注意事项

  • 端口冲突:PostgreSQL 默认占用 5432 端口,若被占用需修改 port 配置或停止旧服务。
  • 防火墙规则:如需远程访问,需放行 5432 端口(sudo ufw allow 5432/tcp)。
  • GPG 密钥:若提示 NO_PUBKEY 或签名验证失败,需重新导入官方密钥(步骤 3)。
  • 认证方式:默认本地 peer 免密、远程 scram-sha-256;生产环境严禁对 0.0.0.0/0 开放无密码访问。
  • 内存调优:shared_buffers、effective_cache_size、work_mem 等参数默认值偏保守,上线前应按服务器规格调整。
  • 数据校验:本版本默认启用 data checksums,从偏移量上提供了数据损坏检测能力,生产部署建议保持开启。

常见问题

问题 1:安装时提示 GPG 密钥错误(NO_PUBKEY ACCC4CF8)

原因: PGDG 软件的签名公钥未正确导入或已过期。

解决:

sudo curl -o /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc --fail https://www.postgresql.org/media/keys/ACCC4CF8.asc
sudo apt-get update

问题 2:远程连接被拒(no pg_hba.conf entry for host)

原因: pg_hba.conf 未配置允许该主机的认证规则,或 listen_addresses 未包含对应网卡。

解决: 按"配置项 2"修改 listen_addresses 与 pg_hba.conf,并重启服务。

问题 3:could not connect to server: No such file or directory

原因: 集群未启动,或 socket 目录路径不一致。

解决:

pg_lsclusters              # 查看集群状态
sudo pg_ctlcluster 18 main start

卸载方式

如需彻底卸载 PostgreSQL 18:

sudo apt-get remove --purge -y postgresql-18 postgresql-client-18
sudo rm -rf /var/lib/postgresql/18 /etc/postgresql/18

💡 说明:--purge 会同时删除配置文件;数据目录 /var/lib/postgresql/18 需手动删除以释放空间。若仅卸载软件而保留数据目录,重装后可复用原数据。

参考链接


本文档由 www.quzuo.net 平台开发