PostgreSQL 日志看似只是“多打一点”或“少打一点”,实际由三个独立问题决定:什么严重程度的消息可以进入服务器日志,错误发生时是否附带触发它的 SQL,以及每条消息包含多少诊断字段。理解 log_min_messages、log_min_error_statement 和 log_error_verbosity 的边界,才能在排障信息与日志噪声之间取得平衡。
三个参数分别管什么
log_min_messages:日志的严重级别下限
log_min_messages 决定哪些服务器消息会写入日志。它是一个严重级别过滤器:配置为某个级别后,该级别及更严重的消息会保留,更低级别的消息会被丢弃。
常见级别包括:
DEBUG5到DEBUG1INFONOTICEWARNINGERRORLOGFATALPANIC
生产环境通常不会长期开启非常详细的 DEBUG 日志,因为高频路径上的调试消息可能快速放大日志量。排查特定问题时,可以临时降低门槛,并配合时间窗口和日志采集限流。
log_min_error_statement:错误日志是否带上触发 SQL
这个参数只关注“触发错误的 SQL”。当某条语句达到配置的错误严重级别时,PostgreSQL 会额外记录该语句文本。
它和 log_min_messages 不是同一个过滤器:
log_min_messages决定服务器消息本身是否写入日志。log_min_error_statement决定达到错误条件时,是否附加触发错误的 SQL。
例如,应用收到约束冲突或语法错误时,错误消息可能足以说明“发生了什么”,但触发 SQL 才能帮助定位“是哪一次操作导致的”。另一方面,SQL 中可能包含敏感参数,因此不能只为了方便排障就无期限地记录所有错误语句。
log_error_verbosity:每条消息打印多少字段
log_error_verbosity 控制错误和相关消息的详细程度,常用值为:
TERSE:尽量精简。DEFAULT:默认详细程度。VERBOSE:增加更多诊断信息,例如错误位置、内部位置或相关对象信息。
它不会决定哪些消息进入日志,也不会单独决定是否打印触发 SQL。它只影响消息进入日志之后,记录中包含多少字段。
用一个场景区分它们
假设应用执行了一条违反唯一约束的 INSERT:
INSERT INTO users (email) VALUES ('alice@example.com');
这时可以把日志行为拆成三层:
- 错误消息是否达到
log_min_messages的门槛。 - 触发错误的
INSERT是否达到log_min_error_statement的门槛。 - 错误记录采用
TERSE、DEFAULT还是VERBOSE格式。
因此,把 log_error_verbosity 调成 VERBOSE,并不会让原本被 log_min_messages 过滤掉的消息重新出现;把 log_min_error_statement 调低,也不会改变普通服务器消息的详细字段数量。
一个可复制的排障配置
下面的例子假设使用具有修改配置权限的 PostgreSQL 管理账号,并通过 psql 连接目标数据库。配置值可以按排障窗口调整:
psql "$DATABASE_URL" <<'SQL'
ALTER SYSTEM SET log_min_messages = 'WARNING';
ALTER SYSTEM SET log_min_error_statement = 'ERROR';
ALTER SYSTEM SET log_error_verbosity = 'VERBOSE';
SELECT pg_reload_conf();
SHOW log_min_messages;
SHOW log_min_error_statement;
SHOW log_error_verbosity;
SQL
这组设置表达的意图是:保留 WARNING 及以上的服务器消息;对 ERROR 及以上的错误记录触发 SQL;同时让错误记录包含更完整的诊断字段。具体生效方式取决于 PostgreSQL 版本和参数上下文,修改后应以 SHOW 和实际日志为准。
可以用一个临时表制造可控错误,检查日志中是否出现 SQL 文本和更详细字段:
psql "$DATABASE_URL" <<'SQL'
CREATE TEMP TABLE guc_demo (id integer PRIMARY KEY);
INSERT INTO guc_demo VALUES (1);
INSERT INTO guc_demo VALUES (1);
SQL
测试完成后,排障配置应恢复到符合生产策略的值。例如:
psql "$DATABASE_URL" <<'SQL'
ALTER SYSTEM RESET log_min_messages;
ALTER SYSTEM RESET log_min_error_statement;
ALTER SYSTEM RESET log_error_verbosity;
SELECT pg_reload_conf();
SQL
ALTER SYSTEM 会把设置写入实例的自动配置文件,因此不要把它当作一次性的会话级实验开关。只在当前连接验证行为时,可以使用会话级配置:
SET LOCAL log_error_verbosity = 'VERBOSE';
不过,配置是否允许在当前作用域修改,仍取决于具体参数和数据库权限。
生产环境的取舍
日志越详细,排障时越容易建立完整上下文,但代价也很明确:日志体积增加、存储成本上升,SQL 文本还可能暴露邮箱、令牌、业务标识或其他敏感数据。
可以按问题类型采用不同策略:
- 只想减少普通噪声时,调整
log_min_messages。 - 需要知道失败的是哪条 SQL 时,重点检查
log_min_error_statement。 - 需要定位错误发生位置或查看额外诊断信息时,临时使用
log_error_verbosity = 'VERBOSE'。 - 只为单个会话或短时间排障时,优先使用会话级配置或明确的恢复步骤。
- 应用层已经记录了完整、经过脱敏的请求信息时,不要默认在数据库日志中重复记录敏感 SQL。
上线前检查清单
- 明确日志要解决的是消息筛选、触发 SQL 追踪,还是诊断字段不足。
- 分开评估三个参数,不要把它们当成一个“日志详细程度”开关。
- 用可控错误验证实际输出,而不是只检查配置文件文本。
- 记录临时变更的开始时间、结束时间和恢复命令。
- 检查日志采集、保留周期和脱敏规则是否能承受新增 SQL 内容。
把三个 GUC 各自负责的层次分清后,PostgreSQL 日志配置就不再是盲目调大或调小,而是一组可以针对故障目标精确调整的过滤器。