PostgreSQL 数据库安装部署教程(Linux 多发行版 + Windows + Docker 全覆盖)

PostgreSQL 数据库安装部署教程(Linux 多发行版 + Windows + Docker 全覆盖)

PostgreSQL 是排名最靠前的开源关系型数据库,性能、功能直逼商业库:窗口函数、分区表、JSON/JSONB、全文检索、物化视图、逻辑复制、外表(FDW)一应俱全,还支持 C/Python/Java 写自定义函数。很多 DBA 从 Oracle/SQL Server 转过来,最头疼的不是 SQL(超级像),而是安装方式和那些隐藏的坑。本文一篇讲透 PostgreSQL 在各种环境下的安装、初始化、配置与验证。


一句话总结

PostgreSQL 安装的核心套路 = 官方源安装(yum/apt,推荐)+ initdb 初始化 + postgresql.conf 优化 + pg_hba.conf 放行 + systemd 托管 。记住三个"和 Oracle 不一样":超级用户叫 postgres、数据目录用 initdb 生成、默认只监听 localhost,其余都是日常。


一、先认识 PostgreSQL

1.1 它是什么

PostgreSQL(简称 PG)是一款有 30 余年历史的开源对象关系型数据库,由全球社区维护,采用 PostgreSQL License(类 MIT,可商用无费用)。它在 DB-Engines 排名中常年稳居开源数据库第一。

1.2 和常见商业库的定位对比

特性 PostgreSQL Oracle SQL Server
授权 开源免费(类 MIT) 商业授权 商业授权
运营商 社区 + 多家商业支持 甲骨文 微软
高可用方案 流复制 + Patroni(托管)/ repmgr / 逻辑复制 RAC / Data Guard Always On
自带读写分离 流复制原生支持 Active Data Guard 只读副本
JSON 支持 JSONB(索引查询) JSON 有限 有限
全文检索 原生(中文需分词插件) Oracle Text Full-Text
与 Oracle 兼容性 有 oracle_fdw、兼容插件 原生 原生

对 DBA 来说最有吸引力的两点:功能接近商业库 + 零授权成本。国内信创、降本增效背景下,Oracle→PG 的迁移需求近几年暴涨。


二、版本选择与环境准备

2.1 版本怎么选

PostgreSQL 每年 9 月发布一个大版本,奇数版本(17、19)会引入较多新特性,偶数版本(16、18)主打稳定优化。截至本文,最新版本为 19.x。

版本 发布时间 定位 适合场景
14.x 2021-09 老稳定版 存量环境
15.x 2022-10 稳定版 保守生产
16.x 2023-09 成熟稳定 生产首选(推荐)
17.x 2024-09 新特性较多 新项目可选
18.x 2025-09 最新稳定大版 新项目推荐
19.x 2026-09 刚发布 测试、尝鲜
markdown 复制代码
选型口诀:生产求稳 → 16 / 18;新项目尝新 → 17 / 18;
刚发布的版本(19)至少等 2~3 个补丁(19.2+)再上生产。

2.2 环境确认清单

bash 复制代码
# 确认操作系统
cat /etc/os-release | head -3

# 确认内存/磁盘
free -h && df -h /data

# 确认内核架构
uname -m

# 确认端口占用(PG 默认 5432)
ss -lntp | grep 5432 || echo "5432 未被占用"
项目 最低要求 生产建议
CPU 1 核 4 核+
内存 1 GB 16 GB+(大小为数据量的 1/8~1/4)
磁盘 10 GB(系统) 数据盘独立,SSD,容量=预估 1.5 倍
系统 RHEL 8/9、Rocky、Ubuntu 20.04+ 与业务环境一致
端口 5432 内网可达,防火墙放行

三、四种安装方式怎么选

安装方式 优点 缺点 适合场景
官方 yum/apt 源 一键安装、自动建服务、便于升级 使用发行版官方源的版本可能偏旧 生产首选
源码编译 版本自由、可定制编译参数 步骤多、无自动服务、编译耗时长 特殊版本、定制环境
Windows 安装器 图形向导、自带 pgAdmin 生产服务器很少用 Windows 学习、测试、Windows 环境
Docker 秒级部署、环境隔离 数据持久化需挂卷,性能有微弱损失 开发测试、CI

结论先行:Linux 生产环境 = 官方仓库 + rpm/deb 包;学习验证 = Docker 最省事。


四、Linux 安装(yum 源,RHEL/CentOS/Rocky/Alma)

4.1 添加官方 yum 仓库

以 PostgreSQL 17 为例(RHEL 系 8/9 通用,本文以 Rocky 9 演示):

bash 复制代码
# 1. 安装官方仓库 rpm(RedHat 系 9)
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm

# 2. 关闭系统自带仓库中的 postgresql
sudo dnf -qy module disable postgresql

# 3. 安装客户端与服务器
sudo dnf install -y postgresql17-server postgresql17-contrib postgresql17-libs

# 4. 确认版本
/usr/pgsql-17/bin/postgres --version

版本号对应表:postgresql17-server 对应 PG17;要装 16 把包名换成 postgresql16-server 即可。不要混装两个大版本。

4.2 初始化数据目录

bash 复制代码
# 数据目录默认是 /var/lib/pgsql/17/data,也可以指定其他路径
sudo -u postgres /usr/pgsql-17/bin/initdb -D /var/lib/pgsql/17/data \
    --encoding=UTF8 --locale=en_US.UTF-8 --data-checksums

# 查看帮确认生成了哪些文件
sudo ls /var/lib/pgsql/17/data/

初始化后的核心文件清单:

文件/目录 作用
postgresql.conf 主配置文件(性能、日志、连接)
pg_hba.conf 客户端访问认证配置
PG_VERSION 记录版本
base/ 默认数据库目录(postgres、template0/1)
postgresql.auto.conf ALTER SYSTEM 生成的高级配置
pg_ident.conf 身份映射(SSO 场景用)

template0/1 是模板库:template1 默认含你的扩展,新建库以它为蓝本(所以别在 template1 乱装插件)。

4.3 启动服务并设置开机自启

bash 复制代码
sudo systemctl enable postgresql-17
sudo systemctl start postgresql-17
systemctl status postgresql-17

验证进程与端口:

bash 复制代码
sudo -u postgres psql -c "SELECT version();"
ss -lntp | grep 5432

五、Ubuntu/Debian 安装(apt 源)

bash 复制代码
# 1. 添加官方 apt 仓库(以 22.04 LTS + PG17 为例)
sudo apt install -y wget gnupg ca-certificates
sudo install -d /usr/share/postgresql-common/pgdg
sudo wget -O /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc \
    https://www.postgresql.org/media/keys/ACCC4CF8.asc

echo "deb [signed-by=/usr/share/postgresql-common/pgdg/apt.postgresql.org.asc] \
https://apt.postgresql.org/pub/repos/apt jammy-pgdg main" \
| sudo tee /etc/apt/sources.list.d/pgdg.list

# 2. 安装
sudo apt update
sudo apt install -y postgresql-17 postgresql-contrib-17

# 3. 服务管理
sudo systemctl status postgresql@17-main
sudo systemctl enable postgresql@17-main

⚠️ Ubuntu 的坑:Debian 系把数据目录放在 /etc/postgresql/17/main/,配置文件分散在 /etc/postgresql/17/main/,和 RHEL 系(全在数据目录下)不一样。改配置要改 /etc 下的,不是数据目录下的。

发行版 服务名 配置文件位置 数据目录
RHEL/Rocky postgresql-17 /var/lib/pgsql/17/data/ 同上
Ubuntu/Debian postgresql@17-main /etc/postgresql/17/main/ /var/lib/postgresql/17/main/

六、Windows 安装(图形向导)

6.1 下载安装

  1. 到 EnterpriseDB 下载页 下载 EDB Installer(包含 pgAdmin 和 Stack Builder)
  2. 运行安装器,逐项确认:
步骤 选择
安装目录 C:\Program Files\PostgreSQL\17
数据目录 C:\Program Files\PostgreSQL\17\data
组件 勾选 PostgreSQL Server + pgAdmin 4 + Stack Builder
超级用户密码 ⚠️ 设置 postgres 的密码,记牢!
端口 5432
区域 Chinese (Simplified, China)
  1. 完成后自动注册 Windows 服务 postgresql-x64-17,开机自启

6.2 命令行验证(免安装 psql 客户端)

bat 复制代码
:: 把 pg 的 bin 加进 PATH(下次重启终端生效)
setx PATH "%PATH%;C:\Program Files\PostgreSQL\17\bin"

:: 连接测试
psql -U postgres -h localhost -p 5432

Windows 生产环境少见,但开发机、测试机、培训环境用 Windows 装 PG 是最快的上手方式。注意:Windows 下目录路径用反斜杠,配置文件路径和 Linux 有差异。


七、Docker 安装(最快上手)

7.1 单机快速跑起来

bash 复制代码
# 拉镜像并启动(-v 挂卷持久化,-e 设置密码)
docker run -d --name pg17 \
  -e POSTGRES_PASSWORD=mysecret \
  -e POSTGRES_USER=dba \
  -e POSTGRES_DB=testdb \
  -p 5432:5432 \
  -v pgdata:/var/lib/postgresql/data \
  postgres:17

# 进入容器执行 psql
docker exec -it pg17 psql -U dba -d testdb

7.2 docker-compose 规范版

yaml 复制代码
# docker-compose.yml
services:
  postgres:
    image: postgres:17
    container_name: pg17
    restart: always
    environment:
      POSTGRES_USER: dba
      POSTGRES_PASSWORD: "${DB_PASSWORD}"      # 用环境变量,别硬编码
      TZ: Asia/Shanghai
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data
      - ./init:/docker-entrypoint-initdb.d     # 第一次启动自动执行初始化 SQL
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U dba -d testdb"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  pgdata:

7.3 Docker 的坑

坑 说明
不挂卷 = 数据全没 容器删了数据就没了,必须挂 -v
官方镜像自动 initdb 首次启动自动初始化,POSTGRES_PASSWORD 只对初启用
容器内是 root 官方镜像默认 postgres 用户,进容器操作注意权限
版本 tag postgres:17 = 17 最新补丁;要挑特定补丁用 postgres:17.3
别对运行中的容器改密码 环境变量只在首次初始化生效,之后改要改数据配置

八、初始化后的关键配置

8.1 必须先改的 postgresql.conf 参数

bash 复制代码
sudo -u postgres vi /var/lib/pgsql/17/data/postgresql.conf
参数 默认值 建议 说明
listen_addresses localhost * 或内网 IP 允许远程连接(改完重启)
port 5432 5432 一般不用改
max_connections 100 按业务定,100~500 过高会吃内存(每连接约 5MB)
shared_buffers 128MB 内存 1/4 PG 的 Buffer 池,最重要参数
effective_cache_size 4GB 内存 3/4 给优化器的"可用缓存"参考
work_mem 4MB 4~64MB 排序/哈希内存,每条 SQL 每次分配
checkpoint_timeout 5min 15min 间隔越长,恢复点越稀疏
max_wal_size 1GB 2~8GB WAL 上限,影响恢复速度
wal_level replica replica 流复制/逻辑复制需要 replica 及以上
log_min_duration_statement -1(关) 1000(1s+ 记日志) 慢 SQL 追踪
timezone 系统 Asia/Shanghai 业务时区
bash 复制代码
# 一个 16G 内存服务器的快速示例(追加到 postgresql.conf 末尾即可)
shared_buffers = 4GB
effective_cache_size = 12GB
work_mem = 16MB
max_connections = 200
max_wal_size = 4GB
log_min_duration_statement = 1000

# 编辑完后重启生效
sudo systemctl restart postgresql-17

改参数的两条红线 :listen_addresses、shared_buffers 这类参数必须改在 postgresql.conf(或 ALTER SYSTEM SET),改后重启 ;而 work_mem 之类可用 SET 会话级临时调,不用重启。

8.2 pg_hba.conf:远程连接配置(90% 的"连不上"都是它)

bash 复制代码
sudo -u postgres vi /var/lib/pgsql/17/data/pg_hba.conf

规则格式:连接类型 数据库 用户 地址 认证方式,从上到下匹配,第一条命中即生效:

conf 复制代码
# 本机无需密码(默认已有)
local   all             all                                     trust

# 内网网段:192.168.1.0/24 用密码认证
host    all             all             192.168.1.0/24          scram-sha-256

# 特定用户只允许特定 IP
host    mydb            appuser         10.0.5.100/32           scram-sha-256

# 允许所有(不推荐生产,测试可用)
host    all             all             0.0.0.0/0               scram-sha-256
认证方式 安全级别 说明
trust 极低 不验证密码,仅限本机/测试
md5 低 已过时,明文传输哈希
scram-sha-256 高 PG10+ 生产推荐
cert 最高 SSL 证书认证

设置远程用户密码:

sql 复制代码
-- 设置/修改 postgres 用户密码
ALTER USER postgres WITH PASSWORD '新密码';

-- 建业务用户(生产别用 postgres 连程序)
CREATE USER appuser WITH PASSWORD 'apppass' LOGIN;
GRANT CONNECT ON DATABASE mydb TO appuser;

PG 三连检查清单 :① listen_addresses 是否放开 ② pg_hba.conf 是否加了网段行 ③ 防火墙/安全组是否放行 5432。很多同学只改其中一个,然后抓瞎半天。


九、开机自启与日常管理

9.1 systemd 服务管理(RHEL 系)

bash 复制代码
sudo systemctl enable postgresql-17   # 开机自启
sudo systemctl start   postgresql-17
sudo systemctl stop    postgresql-17
sudo systemctl restart postgresql-17
sudo systemctl status  postgresql-17

9.2 常用管理命令速查

bash 复制代码
# 连接
sudo -u postgres psql                      # 本地免密(trust)
psql -h 127.0.0.1 -p 5432 -U appuser -d mydb -W

# 列出数据库/用户
psql -c "\l"        # 或 \l+ 看大小
psql -c "\du"       # 用户列表

# 数据库管理 SQL
CREATE DATABASE testdb OWNER appuser ENCODING 'UTF8';
DROP DATABASE testdb;
\c testdb          # 切换库

9.3 验证安装完整性的检查脚本

sql 复制代码
-- 一套"体检"语句,装完必跑
SELECT version();                                    -- 版本
SHOW server_version;                                 -- 简版版本
SELECT current_database(), current_user;             -- 当前库和用户
SHOW listen_addresses;                               -- 监听配置
SHOW shared_buffers;                                 -- 内存配置
SELECT pg_is_in_recovery();                          -- 是否备库
SELECT count(*) FROM pg_stat_activity;               -- 当前连接数
SELECT * FROM pg_stat_activity WHERE state = 'active'; -- 活跃会话
SELECT pg_current_wal_lsn();                         -- 当前 WAL 位置

十、常见问题排查表(高频坑位)

症状 根因 解决
psql: could not connect to server: Connection refused 服务没起 / 端口没监听 systemctl status、查 5432 端口
No pg_hba.conf entry for host "x.x.x.x" pg_hba.conf 没放行该网段 加 host 行 + reload
could not connect: Password authentication failed 密码错 / 认证方式不匹配 检查用户密码和 pg_hba 认证方式
could not translate host name 主机名解析不了 用 IP 连接或加 hosts 记录
远程连不上但本地可以 listen_addresses 没改 改 * 后重启
pg_hba.conf 改完不生效 没 reload SELECT pg_reload_conf(); 或重启(config 变更需重启)
磁盘瞬间写满 WAL 增长 / 未设 max_wal_size 设合理 max_wal_size,及时清理归档
中文乱码 locale 不对 / 客户端编码 initdb 时用 --locale=en_US.UTF-8,客户端 SET client_encoding='UTF8'
initdb: could not find suitable text search configuration 缺少 libicu 等依赖 装 libicu、libicu-devel 再重跑
bash 复制代码
# 万能排查起手式:三连
systemctl status postgresql-17
sudo -u postgres psql -c "SHOW listen_addresses;"
tail -f /var/lib/pgsql/17/data/log/*.log

十一、给 Oracle/SQL Server DBA 的迁移注意点

习惯 Oracle/SQL Server PostgreSQL
默认实例 多个实例/库 一个集群多个数据库,无"实例"概念(单集群)
超级用户 sys/system/sa postgres
自增列 SEQUENCE/IDENTITY GENERATED BY DEFAULT AS IDENTITY 或 serial
字符串拼接 `
分页 OFFSET/FETCH LIMIT n OFFSET m(最快)
创建库 CREATE DATABASE 无参数 注意指定 ENCODING 'UTF8'
主从切换 DG/RAC/AlwaysOn pg_ctl promote 或 Patroni 自动
高可用工具 OEM/SSMS pgAdmin、Patroni、pgbackrest
sql 复制代码
-- Oracle 习惯 → PG 写法对照
-- 自增(PG 15+ 与 Oracle 相似)
CREATE TABLE emp (
    id   INT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
    name TEXT NOT NULL
);

-- 分页
SELECT * FROM emp ORDER BY id LIMIT 10 OFFSET 20;

-- 字符串拼接
SELECT '工号: ' || id || ' 姓名: ' || name FROM emp;

最大的认知差异:PG 是一个"集群 = 一套服务 + N 个库",没有 Oracle 的 CDB/PDB 那种多容器概念(多租户走扩展)。迁移时把"实例"思维换成"集群"思维,能少踩一半坑。


十二、安装完成后的安全清单

markdown 复制代码
□ 1. 修改 postgres 超级用户密码(默认没有强密码策略)
□ 2. 业务程序使用独立账号,禁止直接用 postgres 连接
□ 3. pg_hba.conf 最小化放行:只放业务网段,认证用 scram-sha-256
□ 4. 生产环境开启 SSL(ssl=on)或至少内网隔离
□ 5. 设置 log_min_duration_statement 做慢 SQL 追踪
□ 6. 配置定时备份(pg_dump / pg_basebackup / pgbackrest)
□ 7. 第一次连接成功 → 做一次全量备份,把"第一天"的基线留下
□ 8. 防火墙只放 5432,不给数据库服务器公网映射
bash 复制代码
# 一条命令完成 6:最简单的全库备份脚本
# crontab 里每天凌晨 2 点执行
0 2 * * * sudo -u postgres pg_dumpall -f /backup/pg_$(date +\%F).sql

DBA 夜话 :PostgreSQL 的安装没有 Oracle 那么多"平台准备 + 检查项无数"的花活,半小时能跑起来------但真正考验人的,是装完之后那三件事 :参数调没调、远程通不通、备份配没配。很多人装完 PG 就开始写业务 SQL,等某天磁盘报警或主库挂了,才发现 pg_hba.conf 还停在 trust、备份还是空的。装库这件事,"能连上"只是起点,"敢上线"才算完成。愿你装完的每个 PG,都是加了保险丝的那种。今夜,稳压器常亮,5432 永不打盹。

相关推荐
众链网络1 小时前
年卡跨淡旺季的有效期模型:不可用日期、次数与顺延规则
java·前端·数据库
shunwahma2 小时前
MySQL 替代选型,为什么首选 OceanBase 集中式?
数据库·mysql·oceanbase
n 55!w !1082 小时前
MySQL数据库笔记整理1
数据库·笔记·mysql
oyzz1202 小时前
CentOS Stream 9 配置静态 IP 口令是多少
linux·tcp/ip·centos
李兆龙的博客2 小时前
从一到无穷大 #104:面向 SSD 的数据库写入设计——从 FTL 到应用协同
数据库·ssd·存储引擎
千桐科技2 小时前
qData 数据中台开源版 v1.6.4 发布:聚焦使用反馈,功能细节与产品体验持续优化
数据库·开源·qdata
化雨成烟2 小时前
linux基础命令2
linux·运维·服务器
运维踩坑日记2 小时前
OpenStack 核心服务实战笔记
linux·运维·服务器·笔记·openstack
erzong2312 小时前
Linux操作系统:线程池&踩坑修复
linux·运维·算法