把 PostgreSQL 日志文件配置理顺:log_directory、log_filename 与 log_file_mode

2026-08-28 32 预计阅读时间: 1 分钟
来源: postgr.es AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:8 分钟

PostgreSQL 的 log_directorylog_filenamelog_file_mode 经常被当成三个独立的配置项,但它们其实共同描述了日志采集器写入文件时的三个问题:日志放在哪里、文件叫什么,以及哪些用户可以读取。还有一个容易被忽略的前提:logging_collector 没有开启时,这三个参数都不会产生实际效果。

默认值在个人电脑上通常足够省心,但放到服务器上就未必合适。问题不只是“日志能不能写出来”,还涉及轮转、采集器发现路径、文件权限和运维人员的排障效率。

先确认日志采集器是否工作

这三个 GUC 描述的是日志采集器写入的文件,而不是所有 PostgreSQL 日志输出路径。可以先在数据库中检查当前状态:

SELECT name, setting, unit, context, sourcefile, sourceline
FROM pg_settings
WHERE name IN (
  'logging_collector',
  'log_directory',
  'log_filename',
  'log_file_mode'
)
ORDER BY name;

如果 logging_collectoroff,PostgreSQL 可能仍会通过标准错误输出日志,由外部服务管理这些内容,但上面三个文件相关参数不会决定日志最终写到哪里。

logging_collector 通常需要重启 PostgreSQL 才能启用;其他参数的生效方式应以 pg_settings.context 为准。修改前可以查看配置来源,避免把一个由命令行、包含文件或自动化系统管理的值直接覆盖掉。

三个参数分别控制什么

log_directory:目录路径

log_directory 指定日志文件目录。使用相对路径时,它通常相对于数据库集群的数据目录;使用绝对路径则可以把日志放到专门的文件系统中。

相对路径适合简单的单机部署,例如:

log_directory = 'log'

服务器上可以考虑使用独立挂载点,例如:

log_directory = '/var/log/postgresql'

独立目录更便于设置磁盘配额、监控空间使用情况和配置外部日志采集器。代价是目录必须提前创建,并且 PostgreSQL 运行用户必须拥有写权限。日志目录放在数据目录之外时,还要确认备份、清理和安全策略是否覆盖了这条新路径。

log_filename:文件名模式

log_filename 是日志文件名模板,可以使用时间格式字段生成按时间变化的文件名。一个常见的实践是按日期和时间生成文件:

log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log'

文件名设计需要服务于实际运维流程:

  • 外部采集器通常需要稳定的目录和可预测的文件后缀。
  • 文件名包含日期后,人工查找和按日期归档更直观。
  • 文件名包含秒级时间戳时,可以减少同名覆盖,但也可能产生更多文件。
  • 文件轮转策略应与文件名模式一起检查,避免文件数量持续增长。

不要只关注“文件名看起来是否清楚”。还需要验证 PostgreSQL 的轮转行为、操作系统的清理任务,以及日志采集器是否能识别新文件。

log_file_mode:Unix 文件权限

log_file_mode 控制采集器创建日志文件时使用的 Unix 权限模式。可以把它理解为日志文件的初始访问边界,而不是目录权限的替代品。

例如,服务器上通常希望只有 PostgreSQL 运行用户能够读取日志:

log_file_mode = 0600

如果确实需要同一组运维用户读取,可以在经过验证的 Unix 用户组和目录权限模型下使用更宽松的模式,例如:

log_file_mode = 0640

这里的风险很具体:日志可能包含 SQL 文本、用户名、客户端地址、错误详情,甚至应用误写入的敏感数据。把权限放宽到所有本机用户,往往意味着把数据库运行信息暴露给不需要它的人。

修改该参数通常只影响新创建的日志文件。已经存在的文件不会因为配置值改变而自动收紧权限,因此变更后要检查旧文件和轮转文件的权限。

一个可直接改造的配置示例

下面是一份面向 Linux 服务器的示例。假设 PostgreSQL 运行用户是 postgres,日志目录由系统管理员创建,且外部采集器会读取这个目录:

sudo install -d -o postgres -g postgres -m 0750 /var/log/postgresql

sudo -u postgres psql -d postgres <<'SQL'
ALTER SYSTEM SET logging_collector = 'on';
ALTER SYSTEM SET log_directory = '/var/log/postgresql';
ALTER SYSTEM SET log_filename = 'postgresql-%Y-%m-%d_%H%M%S.log';
ALTER SYSTEM SET log_file_mode = '0600';
SQL

sudo systemctl restart postgresql

重启后检查配置和实际文件:

sudo -u postgres psql -d postgres -c \
  "SELECT name, setting, context FROM pg_settings WHERE name IN ('logging_collector', 'log_directory', 'log_filename', 'log_file_mode') ORDER BY name;"

sudo find /var/log/postgresql -maxdepth 1 -type f -printf '%M %u %g %p\n'

请根据发行版调整服务名和 PostgreSQL 数据库名。ALTER SYSTEM 会写入 postgresql.auto.conf,适合集中记录实例级配置,但不要让它和配置管理系统同时管理同一组参数。生产环境还应补充日志轮转、磁盘空间告警和采集器权限验证。

采用前检查这几件事

一套可用的服务器配置不只是在 postgresql.conf 中填三个值,还应确认:

  1. logging_collector 已开启,并且确实完成了需要的重启。
  2. log_directory 存在,路径对 PostgreSQL 运行用户可写。
  3. log_filename 产生的文件能被日志轮转和采集系统发现。
  4. log_file_mode 与实际排障人员的读取需求匹配,默认优先选择最小权限。
  5. 旧日志文件的权限、磁盘占用和清理周期已经单独检查。
  6. 配置来源明确,不会被 postgresql.auto.conf、配置管理工具或启动参数互相覆盖。

核心原则很简单:先确认谁负责写日志,再决定目录、文件名和权限。桌面环境可以接受默认值;服务器环境则应该把这三个 GUC 放进完整的日志生命周期设计中一起评估。


相关推荐