postgresql.conf 主配置
postgresql.conf 是 PostgreSQL 实例的主配置文件,所有与实例行为相关的设置(内存、连接、WAL、日志、优化器代价)默认都从它读取。理解它的语法规则、参数上下文(context)、include 拆分机制与优先级顺序,是后续所有性能调优工作的地基。本节把该文件的每一处细节讲透,并给出可直接落地的工程化组织方案。
前置知识
阅读本节前,建议先了解:PL/Java 与 PL/V8、PostgreSQL 架构概览
基础概念
配置文件的位置
PostgreSQL 的数据目录(data directory,通常称为 PGDATA)里默认放着三个核心配置文件。配置文件不在 PGDATA 中也是允许的,此时需要通过 -c config_file= 显式指定。
| 文件名 | 作用 | 对应参数 | 修改后生效方式 |
|---|---|---|---|
postgresql.conf | 主配置:内存、WAL、连接、日志、优化器 | config_file | 大部分 SIGHUP,部分需重启 |
pg_hba.conf | 客户端认证规则 | hba_file | SIGHUP |
pg_ident.conf | 操作系统用户到数据库用户的映射 | ident_file | SIGHUP |
postgresql.auto.conf | ALTER SYSTEM 写入,由系统维护 | 自动读取 | SIGHUP |
三个文件的真实路径可以用 SQL 直接查出来,不要靠猜:
SHOW config_file; -- /var/lib/postgresql/18/main/postgresql.conf
SHOW hba_file; -- /var/lib/postgresql/18/main/pg_hba.conf
SHOW ident_file; -- /var/lib/postgresql/18/main/pg_ident.conf
SHOW data_directory;-- /var/lib/postgresql/18/main postgresql.conf
│ (解析)
▼
┌──────────────────────┐
│ 参数定义表(GUC) │ ◀── 编译时的 boot_val 默认值
└──────────────────────┘
│
▼
┌──────────────────────┐
│ postgresql.auto.conf │ ◀── ALTER SYSTEM 写入,优先级更高
└──────────────────────┘
│
▼
┌──────────────────────┐
│ 命令行 -c 覆盖 │ ◀── 优先级最高
└──────────────────────┘参数上下文(context)
每个参数都有一个「上下文」,决定了谁能在什么时候改它。这是 postgresql.conf 里最容易被忽略、但在排查「改了没生效」时最关键的概念。官方在 pg_settings 视图中定义了七类:
| context 取值 | 含义 | 修改手段 | 例子 |
|---|---|---|---|
internal | 编译期固定,不可直接修改 | 只能改代码重编译 | block_size、wal_block_size |
postmaster | 只能在实例启动时设置 | 改配置 + 重启 | shared_buffers、max_connections |
sighup | 发 SIGHUP(reload)即可 | 改配置 + pg_ctl reload | log_min_duration_statement、work_mem 的默认值 |
superuser-backend | 超级用户可在连接建立时设置 | 在 postgresql.conf 或连接参数中设置 | session_preload_libraries |
backend | 后端进程启动时设定 | 由连接来源决定 | log_connections(新机制下) |
superuser | 超级用户可随时 SET,无需重启 | SET / ALTER SYSTEM | work_mem、maintenance_work_mem |
user | 普通用户也能为自己的会话设置 | SET | search_path、statement_timeout |
常说的「五类上下文」是把
backend与superuser-backend合并、把user与superuser合并后的简化说法。排查问题时请以pg_settings.context的实际取值为准。
查询某个参数的上下文:
SELECT name, setting, unit, context, vartype
FROM pg_settings
WHERE name IN ('shared_buffers', 'work_mem', 'max_connections', 'block_size')
ORDER BY name; name | setting | unit | context | vartype
-----------------+-----------+------+-------------+---------
block_size | 8192 | | internal | integer
max_connections | 100 | | postmaster | integer
shared_buffers | 16384 | 8kB | postmaster | integer
work_mem | 4096 | kB | user | integer
(4 rows)block_size 是 internal,所以你永远无法在配置里改它;shared_buffers 是 postmaster,改了必须重启;work_mem 是 user,每个连接都能自己 SET。
语法规则
postgresql.conf 的语法非常宽松,但要记住四条硬规则:
| 规则 | 正确写法 | 错误写法 |
|---|---|---|
| 参数名大小写不敏感 | shared_buffers / SHARED_BUFFERS | —— |
| 参数名内部的连字符等价下划线 | max_connections / max-connections | —— |
| 值用单引号是安全的(推荐) | shared_buffers = '4GB' | shared_buffers = 4 GB(散落 token) |
空白与注释(#)随意 | # 注释 | —— |
# ---- 数值型:可带单位 ----
shared_buffers = 4GB
work_mem = '16MB'
maintenance_work_mem = 512MB
# ---- 布尔型:on/off/true/false/yes/no/1/0 都可 ----
log_min_duration_statement = 1000
fsync = on
autovacuum = 'true'
# ---- 枚举型:不加引号时值必须是单个标识符 ----
wal_level = replica
log_destination = 'csvlog'
# ---- 字符串型:含特殊字符时务必加引号 ----
log_line_prefix = '%m [%p] %q%u@%d '
search_path = '"$user", public'单位规则(来自官方 config-setting 文档):
- 内存单位:
B、kB、MB、GB、TB,全部是 1024 的倍数(1MB = 1024kB)。 - 时间单位:
us、ms、s、min、h、d。只有毫秒(ms)与秒(s)可以带小数。 - 不带单位时为该参数的「默认单位」,例如
shared_buffers默认单位是 8kB 块。
优先级顺序
当一个参数在多个地方出现时,后读取的覆盖先读取的。完整优先级从低到高:
1. 编译默认值(pg_settings.boot_val)
2. postgresql.conf(含 include 进来的文件)
3. postgresql.auto.conf ← ALTER SYSTEM 写入,总能覆盖 postgresql.conf
4. 启动命令行 -c name=value / 环境变量 PGOPTIONS
5. 角色级 / 数据库级 ALTER {ROLE|DATABASE} ... SET
6. 会话级 SET / 事务级 SET LOCALpostgresql.auto.conf 的覆盖是「无条件」的
只要一个参数在 postgresql.auto.conf 里出现过,postgresql.conf 里对它的设置就会被完全忽略——即使 postgresql.conf 在文件顺序上更靠后也没用。postgresql.auto.conf 是最后读取的,与文件位置无关。
想清掉它,只能使用 ALTER SYSTEM RESET 参数名;,或直接删除该行。
语法与用法
基本格式
# 单行注释用 #
# 参数名 = 值
max_connections = 200
# 值可加引号(推荐用于带空格或特殊字符的值)
log_line_prefix = '%m [%p] user=%u,db=%d,app=%a,client=%h '
# 同一参数可以写多次,最后一次生效(前面的是「废弃/被覆盖」状态)
# 这会被 pg_file_settings 标记出来同一个参数写多遍时,最后一条生效,并且 pg_file_settings 视图会把前面的记录标记为 applied = f 并给出原因,这是排查「我明明写了却没用」的第一手证据。
include 机制
为了把几千行配置拆成可维护的小文件,PostgreSQL 提供三条指令:
| 指令 | 行为 | 文件不存在时 |
|---|---|---|
include '文件路径' | 在此处插入该文件内容 | 报错,启动/reload 失败 |
include_if_exists '文件路径' | 同上 | 静默忽略 |
include_dir '目录路径' | 按文件名排序插入目录下所有 *.conf | 静默忽略 |
# postgresql.conf 末尾常见写法
include 'shared.conf' # 共享内存相关
include_if_exists 'local.conf' # 本机专属覆盖,不存在也不报错
include_dir 'conf.d' # 目录里所有 *.conf 按名排序读入include 的路径若为相对路径,相对于当前配置文件所在目录解析,而不是 PGDATA。嵌套 include 允许,且没有深度限制。
include_dir 的排序与过滤规则
include_dir 的行为细节很容易踩坑,官方文档明确规定了三点:
- 只读取以
.conf结尾的文件。 - 跳过以
.开头的隐藏文件(如.bak.conf不会被读)。 - 文件按 C locale(即字节序) 排序,不是按操作系统的语言环境影响后的词典序。
因此社区约定用数字前缀控制顺序:
PGDATA/conf.d/
├── 00shared.conf # 最先读,基础内存/连接
├── 10logging.conf # 日志
├── 20planner.conf # 优化器代价
├── 90local.conf # 最后的本机覆盖
└── postgresql.conf.bak # 不会读(不是 .conf 结尾)常用参数速查表
| 参数 | 默认值 | 上下文 | 说明 |
|---|---|---|---|
max_connections | 100 | postmaster | 最大客户端连接数(+ superuser_reserved_connections) |
superuser_reserved_connections | 3 | postmaster | 保留给超级用户的连接槽 |
shared_buffers | 128MB | postmaster | 共享缓冲池大小 |
work_mem | 4MB | user | 每个排序/哈希节点的可用内存 |
maintenance_work_mem | 64MB | user | VACUUM / CREATE INDEX 等使用 |
wal_level | replica | postmaster | WAL 详细程度(minimal/replica/logical) |
fsync | on | sighup | 是否强制刷盘 |
synchronous_commit | on | user | 提交是否等待 WAL 刷盘 |
log_min_duration_statement | -1 | superuser | 慢查询阈值(-1 = 关闭) |
log_destination | stderr | sighup | 日志输出目标 |
logging_collector | off | postmaster | 是否启用日志收集进程 |
listen_addresses | localhost | postmaster | 监听地址 |
port | 5432 | postmaster | 监听端口 |
timezone | 系统决定 | user | 时区 |
default_transaction_isolation | read committed | user | 默认隔离级别 |
random_page_cost | 4.0 | user | 随机页读取代价 |
详细说明
一、查看「参数到底从哪里来」
这是排查配置问题的第一招:不要看文件,要看视图。pg_settings 提供 source、sourcefile、sourceline 三个字段,直接告诉你生效来源。
SELECT name, setting, unit, source, sourcefile, sourceline, pending_restart
FROM pg_settings
WHERE name IN ('shared_buffers', 'work_mem', 'max_connections'); name | setting | unit | source | sourcefile | sourceline | pending_restart
-----------------+---------+------+--------------------+-------------------------------+------------+-----------------
max_connections | 200 | | configuration file | /etc/postgresql/18/main/postgresql.conf | 64 | f
shared_buffers | 1048576 | 8kB | configuration file | /etc/postgresql/18/main/postgresql.conf | 66 | f
work_mem | 16384 | kB | configuration file | /etc/postgresql/18/main/postgresql.conf | 71 | f若把值改成通过 ALTER SYSTEM 设置,sourcefile 会变成 .../postgresql.auto.conf,这就是最直接的「谁覆盖了谁」的证据。
二、pg_file_settings:reload 前的预检
pg_file_settings 视图逐行列出所有被读到的配置行,并在 applied / error 中给出结果。它只反映文件内容,不反映内存中的实际值,因此非常适合在 reload 之前预检拼写错误。
SELECT sourcefile, sourceline, name, setting, applied, error
FROM pg_file_settings
WHERE error IS NOT NULL OR applied = false
ORDER BY sourcefile, sourceline; sourcefile | sourceline | name | setting | applied | error
---------------------+------------+---------------+----------+---------+---------------------
/etc/.../postgresql.conf | 120 | shared_buffers | 4GB | f | setting is overridden by a later entry
/etc/.../postgresql.conf | 240 | work_mem | 8MB | f | setting is overridden by a later entry
/etc/.../postgresql.conf | 305 | log_min_duraton_statement | 1000 | f | unrecognized configuration parameter
(3 rows)第三行是典型的拼写错误(log_min_duraton_statement 少了一个 i)。这种错误在 reload 时不会导致失败,PostgreSQL 只会记一条警告然后忽略它——所以只看日志经常漏掉,必须查这个视图。
三、pending_restart:哪些改动还没生效
postgresql 上下文(如 shared_buffers、max_connections)的参数改了文件、reload 也不会生效,pg_settings.pending_restart = true 就是提示你还欠一次重启。
SELECT name, setting, unit, pending_restart
FROM pg_settings
WHERE pending_restart
ORDER BY name; name | setting | unit | pending_restart
-------------------+---------+------+-----------------
max_connections | 200 | | t
shared_buffers | 1048576 | 8kB | t
shared_memory_size| 1048576 | 8kB | t在自动化运维里,把这个查询挂到监控上,就能在「用户以为已生效、实际没生效」的窗口期发出告警。
四、boot_val / reset_val 与恢复默认值
三个容易混淆的「默认值」概念:
| 字段 | 含义 | 用途 |
|---|---|---|
boot_val | 编译时的默认值 | 想知道「原始出厂值」 |
reset_val | RESET 之后会变成的值(即配置文件里的值) | 会话里想恢复配置 |
setting | 当前实际生效值 | 日常排查 |
SELECT name, setting, boot_val, reset_val, source
FROM pg_settings
WHERE name = 'work_mem'; name | setting | boot_val | reset_val | source
----------+---------+----------+-----------+--------------------
work_mem | 32768 | 4096 | 16384 | session这里 setting = 32768(当前会话 SET 成了 32MB),reset_val = 16384(配置文件的 16MB),boot_val = 4096(编译默认 4MB)。
五、用 ALTER SYSTEM / SET 临时覆盖
不想动文件时,可以用两种方式临时改:
-- 方式一:写进 postgresql.auto.conf(需要 reload 或自动生效),影响所有会话
ALTER SYSTEM SET work_mem = '32MB';
SELECT pg_reload_conf();
-- 方式二:只影响当前会话
SET work_mem = '64MB';
-- 只影响当前事务,事务结束自动还原
BEGIN;
SET LOCAL work_mem = '128MB';
SELECT ...;
COMMIT; -- work_mem 自动回到之前的值ALTER SYSTEM 会成为持久配置;SET 只活在会话里。生产环境做临时救火推荐 SET,因为它的作用范围可控、不留垃圾。
六、配置文件的读取顺序演示
把优先级写进一个可复现的实验:
# postgresql.conf
work_mem = '16MB'ALTER SYSTEM SET work_mem = '8MB';
SELECT pg_reload_conf();-- 结果:auto.conf 赢了
SHOW work_mem; -- 8MB
SELECT setting, source, sourcefile FROM pg_settings WHERE name = 'work_mem'; setting | source | sourcefile
---------+--------------------+--------------------------------------
8192 | configuration file | /var/lib/postgresql/18/main/postgresql.auto.conf即使 postgresql.conf 里也写了 16MB,postgresql.auto.conf 依然覆盖它。要恢复,执行:
ALTER SYSTEM RESET work_mem;
SELECT pg_reload_conf();七、角色级与数据库级默认值
PostgreSQL 允许为某个角色或某个数据库设置默认参数,作用范围介于 postgresql.conf 与 SET 之间:
-- 给批处理角色单独放大内存
ALTER ROLE etl_worker SET work_mem = '256MB';
ALTER ROLE etl_worker SET maintenance_work_mem = '2GB';
-- 给报表库单独设置
ALTER DATABASE analytics SET work_mem = '64MB';
ALTER DATABASE analytics SET jit = off;这些设置存储在系统目录里(不是配置文件),并且会在会话建立时应用。优先级:SET > 角色级 > 数据库级 > postgresql.auto.conf > postgresql.conf。
查看某角色/数据库的专属设置:
SELECT rolname, rolconfig FROM pg_roles WHERE rolconfig IS NOT NULL;
SELECT datname, datconfig FROM pg_database WHERE datconfig IS NOT NULL;八、SHOW ALL 与 SET 的可用范围
SHOW ALL 会列出所有参数及其当前值,但输出很长,建议过滤:
-- 只看与内存相关的
SELECT name, setting, unit FROM pg_settings WHERE name LIKE '%mem%' OR name LIKE '%buffer%';
-- SHOW ALL 的 SQL 等价写法
SELECT name, setting, unit, category, short_desc FROM pg_settings ORDER BY name;pg_settings 的 setting 列可以直接 UPDATE,效果等同于 SET:
UPDATE pg_settings SET setting = '32MB' WHERE name = 'work_mem';
-- 等价于 SET work_mem = '32MB';这在用只能执行 SELECT/UPDATE 的工具(如某些 BI 客户端)调参时偶尔有用,但脚本里不要这么写,可读性差且容易被误认为是改了系统表。
九、配置文件中的特殊值写法
有些参数的值包含特殊字符(如 search_path、log_line_prefix、TimeZone),引号策略需要特别注意:
# 含空格/逗号/特殊字符,必须引号
log_line_prefix = '%m [%p] %q%u@%d '
search_path = '"$user", public, extensions'
timezone = 'Asia/Shanghai'
DateStyle = 'ISO, MDY'
# 枚举值只有单个标识符时可以不引号,但引号更安全
wal_level = 'replica'
synchronous_commit = 'on'在 SQL 里设置时,因为要用字符串字面量,需要双层引号:
SET search_path = '"$user", public';
ALTER SYSTEM SET log_line_prefix = '%m [%p] %q%u@%d ';十、用 pg_settings 做配置基线审计
最后给一个实战用的「配置快照 + 差异对比」查询,用于比对主库与从库、生产与测试:
SELECT name, setting, unit, context, source, sourcefile
FROM pg_settings
WHERE source <> 'default'
ORDER BY name;把两个实例的这个结果导出来做 diff,就能快速发现「从库配置没跟主库对齐」这类问题。配合 \copy 直接导出:
psql -c "\copy (SELECT name, setting, unit, source FROM pg_settings WHERE source <> 'default' ORDER BY name) TO 'prod.conf.snapshot' WITH CSV HEADER"实战示例
场景:把散乱的 postgresql.conf 重构为 conf.d 分片管理
一家公司的主库 postgresql.conf 已经 900 多行,运维改一处参数要翻半天,且多人合并时常冲突。目标是拆成 4 个职责清晰的分片,并保证 local.conf 能随时覆盖。
第一步,在主配置末尾加 include 指令(保留原文件其余内容不动):
# ---------- 分片配置 ----------
# 基础资源(内存、连接数):最先读取
include 'conf.d/00resources.conf'
# 日志与审计
include 'conf.d/10logging.conf'
# 优化器与并行
include 'conf.d/20planner.conf'
# 本机/本环境覆盖:最后读取,优先级最高
include_if_exists 'conf.d/99local.conf'第二步,把原文件里对应段落剪切到分片中:
# conf.d/00resources.conf
listen_addresses = '0.0.0.0'
port = 5432
max_connections = 400
superuser_reserved_connections = 5
shared_buffers = '8GB'
work_mem = '8MB'
maintenance_work_mem = '1GB'
effective_cache_size = '24GB'
wal_buffers = '16MB'# conf.d/10logging.conf
logging_collector = on
log_directory = 'log'
log_filename = 'postgresql-%Y-%m-%d.log'
log_rotation_age = '1d'
log_rotation_size = '200MB'
log_line_prefix = '%m [%p] %q%u@%d,%a '
log_min_duration_statement = 1000
log_checkpoints = on
log_lock_waits = on
log_temp_files = 0# conf.d/20planner.conf
random_page_cost = 1.1 # SSD 环境
effective_io_concurrency = 200
default_statistics_target = 200
jit = on
max_parallel_workers_per_gather = 4# conf.d/99local.conf(不纳入版本库,按机器定制)
# 这台是内存受限的从库,压低内存
shared_buffers = '2GB'
work_mem = '4MB'第三步,reload 并核对生效情况:
pg_ctl reload -D /var/lib/postgresql/18/main
# 或 sudo systemctl reload postgresql-- 核对:本机覆盖是否生效
SELECT name, setting, unit, sourcefile
FROM pg_settings
WHERE name IN ('shared_buffers', 'work_mem', 'random_page_cost', 'work_mem'); name | setting | unit | sourcefile
------------------+----------+------+-------------------------------------------------
random_page_cost | 1.1 | | /var/lib/postgresql/18/main/conf.d/20planner.conf
shared_buffers | 262144 | 8kB | /var/lib/postgresql/18/main/conf.d/99local.conf
work_mem | 4096 | kB | /var/lib/postgresql/18/main/conf.d/99local.conf
(3 rows)结果解读:shared_buffers 与 work_mem 都来自 99local.conf,说明「后面的分片覆盖前面的分片」符合预期(排序靠后 → 后读取 → 生效);random_page_cost 来自 20planner.conf。
第四步,reload 前做一次预检,确保没有拼写错误:
SELECT sourcefile, sourceline, name, error
FROM pg_file_settings
WHERE error IS NOT NULL; sourcefile | sourceline | name | error
------------+------------+------+-------
(0 rows)零行代表分片全部解析成功,可以放心 reload。
注意事项
不要直接编辑 postgresql.auto.conf。 该文件由 ALTER SYSTEM 管理,手工编辑的内容会在下次 ALTER SYSTEM 操作时被重写覆盖。
# 错误!手工改 auto.conf 会被系统覆盖
echo "work_mem = 64MB" >> $PGDATA/postgresql.auto.conf正确做法是用 ALTER SYSTEM:
ALTER SYSTEM SET work_mem = '64MB';include 的路径不要写相对路径含 .. 的绕行写法。 相对路径是相对于当前配置文件所在目录,写成 include '../shared.conf' 在不同部署方式下会指向不同位置,极易出错。
# 不推荐:依赖当前文件位置,脆
include '../shared.conf'
# 推荐:使用绝对路径或与 PGDATA 明确的相对关系
include '/etc/postgresql/shared.conf'改了 postmaster 上下文参数后不要以为 reload 就行。 shared_buffers、max_connections、logging_collector 等必须重启,否则你改的值只躺在文件里。
-- 错误认知:reload 后 shared_buffers 就变了
SELECT pg_reload_conf();
SHOW shared_buffers; -- 依然是旧值
-- 正确检查
SELECT name, pending_restart FROM pg_settings WHERE name = 'shared_buffers';不要在参数名里用驼峰或随意缩写。 PostgreSQL 参数名是 <prefix>_<unit> 风格,大小写不敏感但不认「近似拼写」。拼错的参数会被静默忽略(只在日志留警告),造成「配置没生效」的假象。
# 错误!这些都不是合法参数名
ShareBuffers = '4GB'
log_min_duration = 1000 # 正确的是 log_min_duration_statement
bogus_param = 'x'include_dir 里放备份文件是一个隐蔽的坑。 只要文件名以 .conf 结尾就会被读入,把 postgresql.conf.20250101.conf 放在 conf.d/ 里,等于把一份旧配置也叠加进来。
# 错误!备份文件被当成有效分片
cp conf.d/00resources.conf conf.d/backup/00resources.conf.bak # 安全(非 .conf 结尾)
cp conf.d/00resources.conf conf.d/old.conf # 危险!会被读入不要用超长的单行配置,尤其 log_line_prefix、search_path 这类含空格与引号的值,抄错一个引号就会导致整行解析失败。
# 不推荐:一行塞太多,易错
log_line_prefix='%m [%p] %q%u@%d,%a,%h,%r '
# 推荐:换行 + 明确引号(注意:值本身不能跨行,只是排版建议)生产环境改配置前务必先做 pg_file_settings 预检。 存在 error 行时,reload 不会中断服务,但会让你以为改了实际没改。
-- reload 前的强制自检
SELECT count(*) AS errors FROM pg_file_settings WHERE error IS NOT NULL;
-- 必须为 0 才 reload不要把 postgresql.conf 纳入 include_dir 自身。 如果 include_dir 指向 PGDATA 根目录,会递归读到 postgresql.conf 自己(假设它不以 . 开头且以某些方式匹配),造成重复与混乱。分片一律单独放子目录。
# 错误!可能读到自身或其他非预期文件
include_dir '.'
# 正确
include_dir 'conf.d'从库 postgresql.conf 不要盲目复制主库。 从库的 shared_buffers、max_connections、work_mem 通常应单独设定;复制主库配置会导致从库内存超配或参数不匹配。
-- 对比主从差异
SELECT name, setting FROM pg_settings WHERE source <> 'default';
-- 分别导出后 diff最佳实践
统一用 conf.d/ 分片管理,并用数字前缀固化顺序。 顺序即优先级,数字前缀让「谁覆盖谁」一眼可读。
include 'conf.d/00resources.conf'
include 'conf.d/10logging.conf'
include 'conf.d/20planner.conf'
include_if_exists 'conf.d/99local.conf'把「稳定配置」纳入版本库,把「本机差异」放进不纳入版本库的 99local.conf。 这样多机部署时只维护一份基线,机器差异留在本地文件里。
# conf.d/99local.conf — 加入 .gitignore
shared_buffers = '2GB'所有数值参数都显式带单位。 不带单位时依赖参数的默认单位,极易误读(例如把 shared_buffers = 16384 当成 16GB,实际是 16384 × 8kB = 128MB)。
# 推荐
shared_buffers = '4GB'
work_mem = '16MB'
# 不推荐
shared_buffers = 524288 # 到底是 8kB 块还是字节?改动后固定执行三步校验:预检 → reload → 核对。 把它写成一个脚本,杜绝人肉遗漏。
# 1. 预检
psql -Atc "SELECT count(*) FROM pg_file_settings WHERE error IS NOT NULL"
# 2. reload
psql -c "SELECT pg_reload_conf()"
# 3. 核对关键参数
psql -c "SELECT name, setting, unit, pending_restart FROM pg_settings WHERE name IN ('shared_buffers','work_mem','max_connections')"把 pending_restart 纳入监控。 任何 pending_restart = true 都意味着「配置与实际不一致」,应当在维护窗口内尽快重启消化。
SELECT name, setting, pending_restart FROM pg_settings WHERE pending_restart;尽量用 ALTER SYSTEM 而不是手工编辑文件来改线上参数。 ALTER SYSTEM 会安全地写入 postgresql.auto.conf、自动 reload,并且可以用 ALTER SYSTEM RESET 干净回滚。
ALTER SYSTEM SET log_min_duration_statement = 500;
-- 回滚
ALTER SYSTEM RESET log_min_duration_statement;把「每会话临时调参」交给角色级默认值或连接池,而不是写进全局配置。 例如批处理需要大 work_mem,用角色级设置比全局放大更安全。
ALTER ROLE etl_worker SET work_mem = '256MB';
ALTER ROLE report_ro SET statement_timeout = '30s';shared_buffers 改动一定配合操作系统共享内存参数评估。 使用 sysv 共享内存时需同步调整 kernel.shmmax;用默认 mmap 则不必,但仍要评估整体内存预算。
SHOW shared_memory_type; -- mmap(默认)
SHOW huge_pages; -- try保留一份「配置变更记录」。 每次调整写下「改了什么、为什么、预期效果、验证方法」,并用 pg_settings 快照作为附件。配置调优最常见的失败模式是「半年后没人知道当初为什么这么设」。
\copy (SELECT name, setting, unit, source FROM pg_settings WHERE source <> 'default' ORDER BY name) TO 'config-snapshot.csv' WITH CSV HEADERrandom_page_cost 这类优化器参数要按存储介质设定,不要照抄网上的值。 SSD 上常见 1.0~1.5,机械盘保持默认 4.0;改完必须用 EXPLAIN (ANALYZE) 验证计划确实变好了。
# SSD 环境(示例,需实测验证)
random_page_cost = 1.1
effective_io_concurrency = 200永远保留一份可回滚的配置备份。 改之前先复制一份带时间戳的备份,出问题秒回滚。
cp postgresql.conf postgresql.conf.bak.$(date +%Y%m%d%H%M)定期审计 source <> 'default' 的参数集合。 时间一长,配置里会累积大量「已无必要」的调整,定期清理能避免「参数之间互相打架」。
SELECT name, setting, unit, source FROM pg_settings WHERE source <> 'default' ORDER BY name;下一节
继续学习:pg_hba.conf 客户端认证
参考链接
- PostgreSQL 官方文档:Setting Parameters(config-setting)
- PostgreSQL 官方文档:The pg_settings View(view-pg-settings)
- PostgreSQL 官方文档:The pg_file_settings View(view-pg-file-settings)
- PostgreSQL 官方文档:Managing Databases / Database File Layout
- PostgreSQL 官方文档:Resource Consumption(runtime-config-resource)
- PostgreSQL 官方文档:Connection Settings(runtime-config-connection)
- PostgreSQL 官方文档:Logging(runtime-config-logging)
- PostgreSQL 官方文档:ALTER SYSTEM