PostgreSQL 完全指南 / 22 - 最佳实践
第 22 章 · 最佳实践
本章汇总生产环境的连接池策略、SQL 编码规范、VACUUM 策略和上线 Checklist。
22.1 连接池最佳实践
| 参数 | 推荐值 | 说明 |
|---|
PgBouncer pool_mode | transaction | 最高复用率 |
default_pool_size | 20-50 | 每个数据库的连接池大小 |
max_client_conn | 1000-5000 | 最大客户端连接数 |
server_idle_timeout | 300-600 | 空闲后端连接超时 |
server_lifetime | 3600 | 后端连接最大生存时间 |
PG max_connections | 200-500 | 不超过 500 |
应用连接数 = max_client_conn (PgBouncer)
实际 PG 连接数 = default_pool_size × 数据库数
22.2 SQL 编码规范
命名规范
| 对象 | 规则 | 示例 |
|---|
| 表名 | 小写 + 下划线 | user_orders |
| 列名 | 小写 + 下划线 | created_at |
| 主键 | id 或 表名_id | id, order_id |
| 外键 | 引用表名_id | customer_id |
| 索引 | idx_表名_列名 | idx_orders_customer |
| 唯一索引 | uniq_表名_列名 | uniq_users_email |
| 约束 | chk_表名_描述 | chk_orders_positive_amount |
| 触发器 | trg_表名_事件 | trg_users_update_timestamp |
| 函数 | 小写 + 下划线 | calculate_total() |
SQL 编写规范
-- ✅ 关键字大写
SELECT id, name, email
FROM users
WHERE is_active = TRUE
ORDER BY created_at DESC
LIMIT 20;
-- ✅ 使用显式列名,避免 SELECT *
SELECT id, name, email FROM users;
-- ✅ 使用参数化查询,避免 SQL 注入
-- cursor.execute("SELECT * FROM users WHERE id = %s", (user_id,))
-- ✅ 使用 TIMESTAMPTZ
CREATE TABLE events (
created_at TIMESTAMPTZ DEFAULT NOW() NOT NULL
);
-- ✅ 外键必须有索引
CREATE TABLE orders (
customer_id INT REFERENCES customers(id)
);
CREATE INDEX idx_orders_customer ON orders (customer_id);
-- ✅ 大批量操作使用事务
BEGIN;
INSERT INTO ...;
INSERT INTO ...;
COMMIT;
-- ✅ 使用 EXPLAIN ANALYZE 验证慢查询
22.3 VACUUM 策略
autovacuum 配置
# postgresql.conf
autovacuum = on
autovacuum_max_workers = 3 # 并行工作者数
autovacuum_naptime = 1min # 检查间隔
autovacuum_vacuum_threshold = 50 # 最少死行数
autovacuum_vacuum_scale_factor = 0.1 # 死行比例(10%)
autovacuum_analyze_threshold = 50
autovacuum_analyze_scale_factor = 0.05 # 分析阈值(5%)
autovacuum_vacuum_cost_delay = 2ms # IO 限制延迟
autovacuum_vacuum_cost_limit = 200 # IO 限制
大表特殊配置
-- 为大表设置更低的触发阈值
ALTER TABLE large_table SET (
autovacuum_vacuum_scale_factor = 0.01, -- 1% 死行就触发
autovacuum_analyze_scale_factor = 0.005,
autovacuum_vacuum_cost_delay = 0 -- 不限速
);
监控 VACUUM
-- 查看表的 VACUUM 状态
SELECT
relname,
n_live_tup,
n_dead_tup,
round(n_dead_tup::numeric / NULLIF(n_live_tup + n_dead_tup, 0) * 100, 2) AS dead_pct,
last_vacuum,
last_autovacuum,
last_analyze,
last_autoanalyze
FROM pg_stat_user_tables
ORDER BY n_dead_tup DESC;
-- 查看正在进行的 VACUUM
SELECT pid, query, state, wait_event_type, wait_event
FROM pg_stat_activity
WHERE query LIKE 'autovacuum:%';
22.4 生产环境 Checklist
部署前
| ☐ | 检查项 |
|---|
| ☐ | PostgreSQL 版本为最新稳定版 |
| ☐ | shared_buffers 设置为总内存的 25% |
| ☐ | effective_cache_size 设置为总内存的 75% |
| ☐ | work_mem 合理设置(4-64MB) |
| ☐ | max_connections 不超过 500 |
| ☐ | wal_level = replica |
| ☐ | random_page_cost = 1.1(SSD) |
| ☐ | log_min_duration_statement = 1000(记录慢查询) |
| ☐ | autovacuum 已启用并正确配置 |
| ☐ | pg_hba.conf 安全配置(无 trust) |
| ☐ | SSL 已启用 |
| ☐ | 复制用户权限最小化 |
运维中
| ☐ | 检查项 |
|---|
| ☐ | 每日备份验证 |
| ☐ | 监控复制延迟 |
| ☐ | 监控表膨胀率 |
| ☐ | 监控连接数 |
| ☐ | 监控缓存命中率 |
| ☐ | 定期 ANALYZE |
| ☐ | 定期清理无用索引 |
| ☐ | 事务 ID 年龄监控 |
| ☐ | WAL 文件数量监控 |
| ☐ | 慢查询定期审查 |
22.5 配置参数速查
| 参数 | 4GB 内存 | 16GB 内存 | 64GB 内存 |
|---|
shared_buffers | 1GB | 4GB | 16GB |
effective_cache_size | 3GB | 12GB | 48GB |
work_mem | 8MB | 32MB | 64MB |
maintenance_work_mem | 256MB | 1GB | 2GB |
wal_buffers | 64MB | 64MB | 64MB |
max_connections | 200 | 300 | 500 |
max_wal_size | 2GB | 4GB | 8GB |
random_page_cost | 1.1 | 1.1 | 1.1 |
业务场景
| 场景 | 建议 |
|---|
| 新项目上线 | 参照 Checklist 逐项检查 |
| 性能调优 | pg_stat_statements + EXPLAIN ANALYZE |
| 容量规划 | 监控增长趋势 + 压测拐点 |
| 事故复盘 | 日志 + pg_stat_activity + 锁信息 |
扩展阅读