乐于分享
好东西不私藏

PostgreSQL从安装到调优实战指南

PostgreSQL从安装到调优实战指南

做后端开发这些年,我见过太多项目因为数据库选型不当或者配置错误,上线后直接被流量压垮。前阵子有个朋友跑来找我,说他们的 MySQL 扛不住高并发,问我怎么办。我只问了一句:"试过 PostgreSQL 没有?"

他愣了一下:"那不是个学术型数据库吗?生产环境能用?"

我说:你大概还停留在十年前的印象里。今天这篇,我就带你从零开始,把 PostgreSQL 装到生产环境上,调好安全配置,再优化到能扛高并发。看完你自然就明白,为什么现在越来越多大厂把核心业务从 MySQL 切到 PG。

一、PostgreSQL 是什么?为什么值得用?

PostgreSQL(简称 PG)是一个开源的对象关系型数据库,诞生于 1986 年的加州大学伯克利分校,到现在已经活了将近 40 年。它是目前功能最强大、最接近 SQL 标准的开源数据库。

很多人拿它和 MySQL 比,简单说几句核心区别:

• ACID 事务支持更强:PG 的 MVCC(多版本并发控制)实现得非常干净,高并发场景下不会出现 MySQL 那种"幻读"问题

• 数据类型更丰富:原生支持 JSONB、数组、几何、IP 地址、UUID 等类型,不用像 MySQL 那样用 varchar 硬凑

• 扩展性强:PostGIS(地理信息)、pgvector(向量搜索)、TimescaleDB(时序数据)—— 这些都是 PG 生态的杀手级插件

• 复杂查询能力强:窗口函数、CTE(WITH 语句)、递归查询,写复杂报表的时候 PG 能让你少掉很多头发

说白了,MySQL 适合"够用就行"的场景,PostgreSQL 适合"我要把这件事做到极致"的场景。

二、方式一:二进制安装(推荐生产环境)

二进制安装是最快的方式,直接用包管理器装,几分钟搞定。适合绝大多数生产场景。下面分别给出 RHEL 系和 Debian 系的安装方法。

2.1 RHEL / CentOS / Rocky / AlmaLinux

先添加 PostgreSQL 官方 YUM 仓库,再安装最新版本(以 PG 17 为例):

# 安装官方 YUM 仓库

sudo dnf install -y https://download.postgresql.org/pub/repos/yum/reporpms/EL-9-x86_64/pgdg-redhat-repo-latest.noarch.rpm

# 禁用系统自带的 postgresql 模块

sudo dnf -qy module disable postgresql

# 安装 PostgreSQL 17 服务端

sudo dnf install -y postgresql17-server

# 初始化数据库

sudo /usr/pgsql-17/bin/postgresql-17-setup --initdb

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

sudo systemctl enable postgresql-17

sudo systemctl start postgresql-17

安装完成后验证:

# 查看版本

psql --version

# 输出: psql (PostgreSQL) 17.4

2.2 Ubuntu / Debian

Debian 系更简单,官方仓库直接装:

# 导入官方仓库签名密钥

sudo apt install -y postgresql-common

sudo /usr/share/postgresql-common/pgdg/apt.postgresql.org.sh

# 安装 PostgreSQL 17

sudo apt install -y postgresql-17

# 服务会自动启动,验证一下

sudo systemctl status postgresql

Ubuntu/Debian 的好处是安装后服务已经自动启动并设为开机自启,不需要额外的初始化步骤。这一点比 RHEL 系省心不少。

三、方式二:源码编译安装(适合深度定制)

什么时候需要从源码编译?三种场景:一是官方仓库没有你需要的版本;二是你要开启某些编译时选项(比如 DTrace 支持、特定文件系统支持);三是你想把 PG 装到自定义路径,不影响系统已有的包。

3.1 安装编译依赖

RHEL 系:

sudo yum groupinstall -y "Development Tools"

sudo yum install -y zlib-devel readline-devel libicu-devel openssl-devel

Debian 系:

sudo apt install -y gcc build-essential zlib1g-dev libreadline-dev libicu-dev libssl-dev pkg-config

3.2 下载、编译、安装

# 下载源码包

wget https://ftp.postgresql.org/pub/source/v17.4/postgresql-17.4.tar.bz2

# 解压

tar -xvf postgresql-17.4.tar.bz2

cd postgresql-17.4

# 配置(指定安装路径)

./configure --prefix=/usr/local/pgsql

# 编译(用 -j 加速,多核并行)

make -j $(nproc)

# 安装

sudo make install

3.3 编译 contrib 扩展(推荐)

contrib 目录里有很多实用扩展,比如 pg_stat_statements(慢查询分析)、uuid-ossp、hstore 等。建议一起编译:

cd contrib

make -j$(nproc)

sudo make install

3.4 配置环境变量

编译安装完成后,需要把 PG 的二进制路径加到 PATH 里:

echo 'export PATH=/usr/local/pgsql/bin:$PATH' >> ~/.bashrc

source ~/.bashrc

四、PostgreSQL 初始化与安全配置

不管是二进制安装还是源码安装,装好之后还有几件必须要做的事。这一步做不好,你的数据库就是裸奔状态,上线就是安全隐患。

4.1 创建 postgres 系统用户

PG 要求用一个专用的系统用户来运行数据库服务,默认叫 postgres。如果用 root 运行,PG 会直接拒绝启动。二进制安装时这个用户已经自动创建了,但源码安装需要你手动创建:

sudo useradd -m -s /bin/bash postgres

4.2 初始化数据库集群

切换到 postgres 用户,用 initdb 初始化数据目录:

sudo mkdir -p /pgdata/data

sudo chown -R postgres:postgres /pgdata

sudo chmod 700 /pgdata/data

su - postgres

initdb -D /pgdata/data -U postgres -W

参数说明:-D 指定数据目录,-U 指定超级用户,-W 会在初始化时提示你设置密码。

4.3 启动服务

# 源码安装用 pg_ctl 启动

pg_ctl -D /pgdata/data -l /pgdata/logfile start

# 二进制安装(RHEL)用 systemctl

sudo systemctl start postgresql-17

4.4 安全配置(CRITICAL)

这一步非常关键,很多人就是漏了它导致数据库被攻击。PostgreSQL 有两个核心配置文件:

• postgresql.conf:数据库主配置文件,控制监听地址、端口、连接数等

• pg_hba.conf:主机认证配置文件,控制谁能连接、用什么方式认证

4.4.1 修改监听地址

默认 PG 只监听 localhost,外部连不上。如果需要远程连接:

# 编辑配置文件

vi /pgdata/data/postgresql.conf

# 修改这一行:

listen_addresses = '*'

# 或者指定具体 IP:

listen_addresses = '192.168.1.100'

4.4.2 配置 pg_hba.conf 访问控制

这是安全配置的核心!pg_hba.conf 控制哪些主机可以连接、用什么认证方式。默认配置通常比较宽松,生产环境必须收紧:

# TYPE  DATABASE    USER     ADDRESS        METHOD

local   all         postgres                peer

local   all         all                     md5

host    all         all     192.168.1.0/24  md5

host    all         all     10.0.0.0/8      md5

# 禁止其他所有远程连接

host    all         all     0.0.0.0/0       reject

解释一下:

• peer:本地通过系统用户认证,只有系统用户 postgres 能以 postgres 身份登录

• md5:密码认证,远程连接必须提供密码

• reject:拒绝所有不在允许范围内的 IP

4.4.3 修改 postgres 用户密码

初始化后第一步,给超级用户设置强密码:

su - postgres

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

4.4.4 重启生效

# 修改配置后需要重启

sudo systemctl restart postgresql-17

# 或者

pg_ctl -D /pgdata/data restart

五、高并发性能优化

默认配置下的 PostgreSQL 能跑,但性能很差。就像一辆跑车出厂时默认用经济模式,你不调参数,根本跑不出它的实力。下面以一台 16 核、32GB 内存的生产服务器为例,讲讲最关键的调优参数。

5.1 内存相关参数

shared_buffers(共享缓冲区)

这是 PG 最重要的内存参数,控制数据库用来缓存数据页的内存大小。默认值只有 128MB,对于生产环境来说太小了。建议设为物理内存的 25%-40%:

shared_buffers = 8GB

# 32GB内存的服务器,设为8GB(25%)

注意:这个参数改了之后需要重启数据库才能生效。

work_mem(工作内存)

每个查询操作(排序、哈希、聚合等)可以使用的内存。默认 4MB 太小,复杂查询会 spill 到磁盘。建议:

work_mem = 16MB

# OLTP场景4MB-16MB,OLAP场景可以更大

注意:work_mem 是按操作分配的,一个复杂查询可能有多个排序操作。设太大容易导致内存耗尽。计算公式参考:work_mem = (总内存 - shared_buffers) / max_connections / 4

effective_cache_size(有效缓存大小)

这个参数不实际分配内存,而是告诉查询优化器"操作系统大概有多少缓存可用"。值越大,优化器越倾向于走索引扫描。建议设为物理内存的 50%-75%:

effective_cache_size = 24GB

# 32GB内存,设为75%

maintenance_work_mem(维护工作内存)

用于 VACUUM、CREATE INDEX 等维护操作的内存。设大一些可以加快这些操作:

maintenance_work_mem = 512MB

5.2 连接数与WAL优化

max_connections(最大连接数)

默认 100,高并发场景远远不够。但也不是越大越好,每个连接都会消耗内存:

max_connections = 500

# 超过500建议用连接池(PgBouncer)

wal_buffers(WAL 日志缓冲区)

高写入场景下建议手动设置:

wal_buffers = 16MB

checkpoint 参数(PG 15+)

检查点会把内存中的脏页写入磁盘,频率太高会产生大量 IO。PG 15+ 用 max_wal_size 替代了老的 checkpoint_segments:

max_wal_size = 2GB

min_wal_size = 512MB

checkpoint_timeout = 10min

checkpoint_completion_target = 0.9

checkpoint_completion_target = 0.9 表示检查点的写入分散在 90% 的时间内完成,避免瞬时 IO 峰值。

5.3 完整优化配置清单

把下面的配置加到 postgresql.conf 末尾,重启即可生效:

# === 内存配置 ===

shared_buffers = 8GB

work_mem = 16MB

effective_cache_size = 24GB

maintenance_work_mem = 512MB

# === 连接配置 ===

max_connections = 500

# === WAL配置 ===

wal_buffers = 16MB

max_wal_size = 2GB

min_wal_size = 512MB

checkpoint_timeout = 10min

checkpoint_completion_target = 0.9

# === SSD优化 ===

random_page_cost = 1.1

effective_io_concurrency = 200

# === 慢查询日志 ===

log_min_duration_statement = 500

# === 自动清理 ===

autovacuum = on

autovacuum_vacuum_cost_delay = 20ms

5.4 优化效果验证

调优完成后,可以用 PG 自带的 pgbench 做压力测试:

# 初始化测试数据(100倍缩放,约1500万行)

pgbench -i -s 100 postgres

# 500并发,跑60秒

pgbench -c 500 -j 16 -T 60 postgres

在 16 核/32GB 环境下,默认配置的 TPS 大概在 800-900 左右,优化后可以达到 4000+,差距非常明显。你还可以通过缓存命中率来验证优化效果:

SELECT sum(blks_hit) / (sum(blks_hit) + sum(blks_read)) AS cache_hit_ratio FROM pg_stat_database;

优化前缓存命中率可能在 89% 左右,优化后应该达到 99% 以上。

总结一下

这篇我们走完了 PostgreSQL 从安装到生产调优的完整流程:

• 二进制安装适合 90% 的场景,简单快捷

• 源码编译适合需要深度定制的高级玩家

• 安全配置不能偷懒,pg_hba.conf 是最后一道防线

• 默认参数只够"能跑",shared_buffers、work_mem、max_connections 这三个参数调对了,性能提升 5 倍以上

数据库这东西,装上是第一步,调好才是真本事。

相关学习资料