postgresql.conf 关键参数调优
High Contrast
Dark Mode
Light Mode
Sepia
Forest
1 min read273 words

postgresql.conf 关键参数调优

PostgreSQL 默认配置面向最小内存的通用场景,生产服务器需要根据硬件和工作负载调整关键参数。本节提供一套系统性的调优框架——不是盲目套公式,而是理解每个参数的作用原理后按场景调整。


调优前:了解你的硬件

-- 查看 PostgreSQL 服务器的当前配置
SELECT name, setting, unit, short_desc
FROM pg_settings
WHERE name IN (
'max_connections', 'shared_buffers', 'effective_cache_size',
'work_mem', 'maintenance_work_mem', 'wal_buffers',
'checkpoint_completion_target', 'random_page_cost'
)
ORDER BY name;
-- 查看服务器内存总量(PostgreSQL 视角)
SELECT pg_size_pretty(setting::bigint * 8192) AS shared_buffers_size
FROM pg_settings WHERE name = 'shared_buffers';
# 查看系统资源
free -h          # 总内存
nproc            # CPU 核心数
df -h /var/lib/postgresql  # 磁盘类型
# SSD vs HDD 对 random_page_cost 参数影响很大

内存相关参数

shared_buffers(最重要)

# shared_buffers:PostgreSQL 的缓冲区大小
# 作用:缓存数据页,减少磁盘 I/O
# 规则:设为系统总内存的 25%(不超过 8GB)
# 为什么不设更大?PostgreSQL 还依赖 OS Page Cache
# 8GB 内存的服务器:
shared_buffers = 2GB
# 32GB 内存的服务器:
shared_buffers = 8GB  # 上限约 8GB,更多交给 OS cache
# 修改后需要重启:
# sudo systemctl restart postgresql

effective_cache_size(查询规划器提示)

# effective_cache_size:告诉查询规划器可用的总缓存大小
# 作用:影响规划器是否选择索引扫描(值越大,越倾向于索引)
# 规则:设为 shared_buffers + OS Page Cache(约系统内存的 50-75%)
# 注意:这只是提示,不分配实际内存
# 8GB 内存服务器:
effective_cache_size = 6GB
# 32GB 内存服务器:
effective_cache_size = 24GB

work_mem(排序和哈希操作)

# work_mem:每个排序/哈希操作可用的内存
# 作用:避免排序落盘(Disk Sort),提升 ORDER BY、GROUP BY、JOIN 性能
# 危险:每个连接每个操作都可能使用 work_mem
#       500 连接 × 10 个并发排序 × 16MB = 80GB!!
# 规则:(总内存 × 25%) / (max_connections × 平均并发查询数)
# 保守设置(高并发 OLTP):
work_mem = 4MB     # 默认值,避免内存溢出
# 中等设置(普通 Web 应用):
work_mem = 16MB    # 大多数应用的合理值
# 激进设置(低并发分析查询):
work_mem = 256MB   # 报表/分析场景,连接数少
# 按会话临时调整(最安全):
SET work_mem = '64MB';  -- 只对当前会话生效

maintenance_work_mem(维护操作)

# maintenance_work_mem:VACUUM、CREATE INDEX、ALTER TABLE 等维护操作的内存
# 规则:设为系统内存的 5-10%(上限 2GB 左右)
# 8GB 内存:
maintenance_work_mem = 512MB
# 32GB 内存:
maintenance_work_mem = 2GB

WAL 与检查点参数

# wal_buffers:WAL 缓冲区大小
# 规则:通常 16MB-64MB 就够了
wal_buffers = 16MB  # auto(默认)通常是 1/32 of shared_buffers,最大 16MB
# checkpoint_completion_target:检查点期间刷盘的时间比例
# 默认 0.9(在下一个检查点开始前完成 90% 的时间内完成刷盘)
# 越高 = 刷盘越平滑,I/O 越均匀
checkpoint_completion_target = 0.9
# max_wal_size:触发检查点的 WAL 大小阈值
# 增大可以减少检查点频率(写入密集型应用)
max_wal_size = 4GB  # 默认 1GB,写密集型应用可调大
# min_wal_size:最小保留 WAL 大小
min_wal_size = 1GB  # 默认 80MB

并行查询参数

# max_parallel_workers_per_gather:每个查询最多用几个并行 worker
# 规则:不超过 CPU 核心数的 1/2
max_parallel_workers_per_gather = 4  # 8 核服务器
# max_parallel_workers:全局并行 worker 总数
max_parallel_workers = 8
# parallel_tuple_cost:并行扫描的单元代价(影响规划器是否启用并行)
# 默认 0.1;降低可让规划器更积极地使用并行
parallel_tuple_cost = 0.1

I/O 代价参数(SSD vs HDD)

# random_page_cost:随机 I/O 的相对代价(影响索引选择)
# 默认 4.0(面向 HDD,随机 I/O 比顺序 I/O 慢 4 倍)
# SSD 上随机/顺序差异小,应降低此值
# HDD(机械硬盘):
random_page_cost = 4.0  # 默认值
# SSD(固态硬盘):
random_page_cost = 1.1  # 接近顺序 I/O 代价
# NVMe SSD(超快):
random_page_cost = 1.0
# 效果:降低 random_page_cost 后,规划器更倾向于使用索引

连接参数

# max_connections:最大连接数
# 注意:PostgreSQL 每个连接是独立进程,连接数不是越多越好
# 规则:使用 pgBouncer 后,max_connections 可以设小
# (pgBouncer 只用 20-50 个实际连接)
# 没有连接池时:
max_connections = 200
# 有 pgBouncer 时:
max_connections = 100  # pgBouncer 的实际连接数 × 2

完整调优配置示例

# 场景:16GB 内存,SSD,8 核,Web 应用(有 pgBouncer)
# 内存
shared_buffers = 4GB                    # 25% of 16GB
effective_cache_size = 12GB             # 75% of 16GB
work_mem = 32MB                         # (16GB × 25%) / (100 × 1.25) ≈ 32MB
maintenance_work_mem = 1GB              # 约 6% of 16GB
# WAL
wal_buffers = 64MB
checkpoint_completion_target = 0.9
max_wal_size = 4GB
# I/O
random_page_cost = 1.1                  # SSD
# 并行
max_parallel_workers_per_gather = 4     # 8 核的一半
max_parallel_workers = 8
# 连接
max_connections = 100                   # 配合 pgBouncer
# 日志
log_min_duration_statement = 1000       # 记录超过 1 秒的查询
log_line_prefix = '%t [%p] %u@%d '
log_checkpoints = on
log_connections = off                   # 高并发下关闭,避免日志刷盘
log_lock_waits = on
deadlock_timeout = 1s

在线调整配置(无需重启)

-- 某些参数可以用 ALTER SYSTEM 修改后 reload(无需重启)
ALTER SYSTEM SET work_mem = '32MB';
ALTER SYSTEM SET random_page_cost = 1.1;
ALTER SYSTEM SET log_min_duration_statement = 500;
-- 重新加载配置(无需重启,秒级生效)
SELECT pg_reload_conf();
-- 查看哪些参数需要重启
SELECT name, setting, pending_restart
FROM pg_settings
WHERE pending_restart = true;
-- 参数的 context 决定是否需要重启:
-- postmaster:需要重启(如 shared_buffers、max_connections)
-- sighup:reload 即可(如 work_mem、random_page_cost)
-- user:每个会话可以 SET
SELECT name, context FROM pg_settings
WHERE name IN ('shared_buffers', 'work_mem', 'random_page_cost');

PGTune:自动生成配置

https://pgtune.leopard.in.ua/
输入:
- 数据库版本
- 操作系统
- 内存大小
- CPU 核心数
- 连接数
- 工作负载类型(Web、OLTP、DW、Desktop)
自动输出优化后的 postgresql.conf 配置
(作为参考起点,不能完全替代理解)

下一节pg_stat 视图监控系统——配置调优后,如何知道有没有效果?pg_stat_* 系列视图是 PostgreSQL 内置的实时监控系统,让你看到每张表的缓存命中率、索引使用情况、等待事件等。