
最近在搞数据库选型,MySQL 用了十几年,PostgreSQL 这些年势头真的太猛了。从最直观的感受来说——周围越来越多的项目从 MySQL 往 PostgreSQL 迁移,连咱们博客用的 Spring Boot 生态里,PG 的支持也越来越顺手。趁这个机会,把 PostgreSQL 从安装到部署的完整流程走一遍,踩过的坑也都记下来。
在这之前先聊聊选型。PostgreSQL 这些年能火不是没道理的:
当然也不是说 MySQL 不好,各有适用场景。但如果你做的是数据完整性要求高、查询逻辑复杂、需要高级数据类型的项目,PostgreSQL 值得认真考虑。
本文以 Ubuntu 22.04 LTS 为例,安装 PostgreSQL 18(2026年最新稳定版)。
| 项目 | 版本 |
|---|---|
| 操作系统 | Ubuntu 22.04 LTS (x86_64) |
| PostgreSQL | 18(当前最新稳定版) |
| 安装方式 | Apt Repository(官方源) |
| 数据目录 | /var/lib/postgresql/18/main |
| 配置文件 | /etc/postgresql/18/main/postgresql.conf |
⚠️ 版本选择建议:建议一直用 PostgreSQL 官方仓库的最新稳定版,不要用系统自带的旧版。官方仓库会提供至少 5 年的支持。
Ubuntu 自带的 PostgreSQL 版本比较旧,我们要加上 PostgreSQL 官方的 Apt 源:
# 第一步:安装必要工具
sudo apt update
sudo apt install -y curl ca-certificates
# 第二步:导入官方 GPG 密钥
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
# 第三步:添加软件源
# Ubuntu 22.04 的代号是 jammy
echo "Types: deb deb-src
URIs: https://apt.postgresql.org/pub/repos/apt
Suites: jammy-pgdg
Architectures: amd64
Components: main
Signed-By: /usr/share/postgresql-common/pgdg/apt.postgresql.org.asc" | sudo tee /etc/apt/sources.list.d/pgdg.sources
# 第四步:更新并安装
sudo apt update
sudo apt install -y postgresql-18
装完检查一下:
# 查看版本
psql --version
# 查看服务状态
sudo systemctl status postgresql
看到输出类似 psql (PostgreSQL) 18.x 和 active (running) 就算成功了。
顺手把 CentOS 的也写上,方便查:
# 安装官方仓库 RPM
sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm
# 禁用系统自带版本
sudo dnf -qy module disable postgresql
# 安装 PostgreSQL 18
sudo dnf install -y postgresql18-server
# 初始化数据库
sudo /usr/pgsql-18/bin/postgresql-18-setup initdb
# 启动服务
sudo systemctl enable postgresql-18
sudo systemctl start postgresql-18
刚装好的 PostgreSQL 是"裸奔"状态,必须做的几件事:
PostgreSQL 默认创建了一个系统用户 postgres,以及一个同名数据库超级用户。先给它设个密码:
# 切换到 postgres 用户执行 SQL
sudo -u postgres psql -c "ALTER USER postgres PASSWORD '你的强密码';"
或者进入交互模式:
sudo -u postgres psql
然后在 psql 里输入:
ALTER USER postgres WITH PASSWORD '你的强密码';
\q
默认 PostgreSQL 只监听本地连接。如果需要远程访问(比如用 Navicat 或 DBeaver 连),需要改两个配置:
第一步:修改 postgresql.conf
sudo vim /etc/postgresql/18/main/postgresql.conf
找到 #listen_addresses = 'localhost',改成:
listen_addresses = '*'
第二步:修改 pg_hba.conf
sudo vim /etc/postgresql/18/main/pg_hba.conf
在文件末尾加上(或者修改 existing 行):
# IPv4 远程连接(密码认证)
host all all 0.0.0.0/0 scram-sha-256
第三步:重启服务
sudo systemctl restart postgresql
⚠️ 安全提醒:生产环境千万别直接用
0.0.0.0/0!应该只开放具体 IP,比如:host all all 192.168.1.0/24 scram-sha-256
如果服务器有防火墙,记得加规则:
# Ubuntu (ufw)
sudo ufw allow 5432/tcp
# CentOS (firewalld)
sudo firewall-cmd --add-port=5432/tcp --permanent
sudo firewall-cmd --reload
绝对不要用 postgres 超级用户跑业务!最佳实践是创建专用用户和库:
# 进入 psql
sudo -u postgres psql
-- 创建业务用户(设置密码)
CREATE USER myapp_user WITH PASSWORD 'myapp_password123';
-- 创建业务数据库
CREATE DATABASE myapp_db OWNER myapp_user;
-- 赋予权限
GRANT ALL PRIVILEGES ON DATABASE myapp_db TO myapp_user;
-- 退出
\q
测试一下是否能连上:
psql -h localhost -U myapp_user -d myapp_db -W
输入密码后成功进入,就代表配置正确。
PostgreSQL 默认配置偏保守(为了能在最低配机器上跑),生产环境必须调优。以下是我常用的几项:
这是 PostgreSQL 用来缓存数据页的内存,最重要的性能参数:
shared_buffers = 4GB # 物理内存的 25%,总内存 16GB 的机器推荐 4GB
规则:机器内存的 15%~25%,不要超过 8GB(超过后收益递减)。
告诉优化器有多少可用的文件系统缓存:
effective_cache_size = 12GB # 物理内存的 50%~75%
这个值设大一点没关系,设小了优化器会倾向于走索引扫描而不是顺序扫描。
每个查询排序或哈希操作能使用的内存:
work_mem = 64MB # 默认只有 4MB,太小了
⚠️ 这个参数是"每个排序操作"占用的,如果并发高的话要适当回调。
VACUUM、CREATE INDEX 等维护操作的内存:
maintenance_work_mem = 1GB # 物理内存的 5%~10%
VACUUM 对 PG 的健康至关重要,这个值设大点能显著提升维护效率。
WAL 日志缓冲区:
wal_buffers = 64MB # 默认只有 16MB
写密集型应用建议加大。
PostgreSQL 默认假设机械硬盘的随机 IO 代价 = 4(是顺序读取的 4 倍)。如果用的是 SSD:
random_page_cost = 1.1 # SSD 推荐 1.1;默认是 4
不调这个的话,PG 会倾向于走顺序扫描而不是索引扫描,在 SSD 上会损失性能。
把以上汇总一下,在 /etc/postgresql/18/main/postgresql.conf 中找到对应项修改:
# 内存配置
shared_buffers = 4GB
effective_cache_size = 12GB
work_mem = 64MB
maintenance_work_mem = 1GB
# WAL 配置
wal_buffers = 64MB
wal_level = replica # 生产环境必须 replica,否则无法做 WAL 归档和流复制
# 检查点
checkpoint_completion_target = 0.9
max_wal_size = 4GB
min_wal_size = 1GB
# 优化器
random_page_cost = 1.1 # SSD
effective_io_concurrency = 200 # SSD
# 连接
max_connections = 200
改完后重启:
sudo systemctl restart postgresql
写几个最常用的,方便以后翻:
# 启动/停止/重启
sudo systemctl start postgresql
sudo systemctl stop postgresql
sudo systemctl restart postgresql
# 查看状态
sudo systemctl status postgresql
# 查看端口监听
ss -tlnp | grep 5432
# 查看进程
ps aux | grep postgres
# 切换 postgres 用户
sudo -u postgres psql
# 查看数据库列表(在 psql 里)
\l
# 查看表空间(在 psql 里)
\db
# 查看当前连接(在 psql 里)
SELECT * FROM pg_stat_activity;
# 备份单个数据库
pg_dump -h localhost -U myapp_user -d myapp_db > myapp_db_$(date +%Y%m%d).sql
# 备份所有数据库
pg_dumpall -h localhost -U postgres > all_dbs_$(date +%Y%m%d).sql
# 恢复
psql -h localhost -U myapp_user -d myapp_db < myapp_db_20260714.sql
坑 1:端口被占用 有时候 5432 端口被之前残留的 PG 进程占了,检查:
sudo ss -tlnp | grep 5432
找到 PID 后 kill 掉,或者改默认端口。
坑 2:认证失败连不上
如果出现 FATAL: password authentication failed for user,常见原因:
pg_hba.conf 里认证方式不对——如果设了 ident 或 peer,需要改成 scram-sha-256 或者 md5ALTER USER 后需要新密码生效坑 3:系统参数优化
如果连接数多,可能会出现 could not send data to server,调一下系统参数:
# 临时生效
sudo sysctl -w kernel.sem="500 256000 250 1024"
# 永久生效
echo "kernel.sem = 500 256000 250 1024" | sudo tee -a /etc/sysctl.conf
坑 4:时区设置
PostgreSQL 默认时区可能是 UTC,如果应用在中国:
# 在 postgresql.conf 中设置
timezone = 'Asia/Shanghai'
# 或者对当前会话
SET timezone = 'Asia/Shanghai';
最后跑个完整的验收脚本:
-- 创建测试表
CREATE TABLE test_pg (
id SERIAL PRIMARY KEY,
name VARCHAR(50),
created_at TIMESTAMP DEFAULT NOW()
);
-- 插入测试数据
INSERT INTO test_pg (name) VALUES ('PostgreSQL 安装测试');
-- 查询
SELECT * FROM test_pg;
-- 查看版本
SELECT version();
如果返回正常,恭喜!PostgreSQL 部署完成 🎉
PostgreSQL 安装部署其实不复杂,关键几步:
pg_hba.conf 和系统日志就能解决 90% 的问题下一期准备写 PostgreSQL 的主从复制和读写分离,关注别走丢 😎
本文由老张整理编写,信息综合自 PostgreSQL 官方文档及个人踩坑经验。