在 CentOS 上部署 PostgreSQL 时,调优通常分为 系统层、数据库参数层、SQL 与应用层、监控与维护 四个方面。下面给你一套较完整、可落地的调优思路(适用于 PostgreSQL 12/13/14/15,CentOS 7/8/Stream)。
编辑 /etc/sysctl.conf 或 /etc/sysctl.d/99-postgres.conf:
# 内存与交换
vm.swappiness = 1
vm.overcommit_memory = 2
vm.overcommit_ratio = 80
# 共享内存
kernel.shmmax = 17179869184 # 16GB,按实际内存调整
kernel.shmall = 4194304
# 网络
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 65535
net.ipv4.ip_local_port_range = 1024 65535
# 文件句柄
fs.file-max = 2097152
应用:
sysctl -p
编辑 /etc/security/limits.conf:
postgres soft nofile 65535
postgres hard nofile 65535
CentOS 8 / Stream 还要确保 systemd 生效:
systemctl edit postgresql
添加:
[Service]
LimitNOFILE=65535
推荐:
noatime,nodiratime,data=ordered
磁盘调度器(SSD):
echo noop > /sys/block/sda/queue/scheduler
echo never > /sys/kernel/mm/transparent_hugepage/enabled
加入开机自动执行。
# 物理内存 的 25%~40%
shared_buffers = 4GB
# 用于排序、哈希等
work_mem = 16MB
# 维护操作(VACUUM、CREATE INDEX)
maintenance_work_mem = 512MB
# 大页支持(可选)
huge_pages = try
经验值(16GB 内存服务器)
| 参数 | 建议 |
|---|---|
| shared_buffers | 4GB |
| work_mem | 8–32MB |
| maintenance_work_mem | 512MB |
⚠️
work_mem不是全局,而是 每个操作 × 连接数,不要设太大。
wal_buffers = 16MB
checkpoint_timeout = 15min
max_wal_size = 2GB
min_wal_size = 512MB
高写入场景:
synchronous_commit = off
⚠️ 可能丢 1 秒内的事务(不推荐金融系统)
max_connections = 200
强烈建议:
max_worker_processes = 8
max_parallel_workers = 8
max_parallel_workers_per_gather = 4
track_io_timing = on
autovacuum = on
autovacuum_max_workers = 4
autovacuum_vacuum_scale_factor = 0.1
autovacuum_analyze_scale_factor = 0.05
SELECT * FROM pg_stat_user_indexes
WHERE idx_scan = 0;
SELECT *OFFSET 分页PREPARE / 绑定变量❌:
WHERE DATE(create_time) = '2024-01-01'
✅:
WHERE create_time >= '2024-01-01'
AND create_time < '2024-01-02'
pool_mode = transaction
max_client_conn = 1000
default_pool_size = 50
-- 慢查询
SELECT * FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;
启用:
shared_preload_libraries = 'pg_stat_statements'
vacuumdb -az
或设置合理的 autovacuum。
shared_buffers = 4GB
work_mem = 16MB
maintenance_work_mem = 512MB
max_connections = 200
checkpoint_timeout = 15min
max_wal_size = 2GB
autovacuum = on
如果你愿意,我可以:
pg_stat_statements 的慢 SQL你可以直接贴:
服务器配置 + PostgreSQL 版本 + 主要业务类型