受支持版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发版本: devel

24.3. 日志文件维护 #

最好把数据库服务器的日志输出保存到某个地方,而不是简单地把它丢弃到 /dev/null。诊断问题时,日志输出极其宝贵。

Note

服务器日志可能包含敏感信息,因此无论它被如何、在何处存储,或被路由到什么目标, 都需要受到保护。例如,某些 DDL 语句可能包含明文密码或其他认证细节。 在 ERROR 级别记录的语句可能会暴露应用程序的 SQL 源代码, 也可能包含部分数据行。记录数据、事件及相关信息,正是该设施的设计目的, 因此这不属于信息泄露或程序错误。请确保服务器日志仅对获得适当授权的人可见。

日志输出往往十分庞大(尤其是在较高调试级别下),因此你不会希望无限期保存它。 你需要对日志文件进行轮转,以便周期性地启用新的日志文件, 并在合理时间后移除旧文件。

如果你只是把 postgresstderr 重定向到一个文件,那么虽然也能得到日志输出,但截断该日志文件的唯一办法是停止并重新启动服务器。 如果你是在开发环境中使用 PostgreSQL,这也许可以接受, 但几乎没有生产服务器会认为这种行为可以接受。

更好的办法是把服务器的 stderr 输出发送给某种日志轮转程序。 系统内置了日志轮转功能,你可以在 postgresql.conf 中将配置参数 logging_collector 设为 true 来使用它。该程序的控制参数见 Section 19.8.1。你还可以用这种方式以机器可读的 CSV(逗号分隔值)格式捕获日志数据。

另一种做法是,如果你已经在其他服务器软件上使用某个外部日志轮转程序, 也可以继续用它。例如,Apache 发行版中附带的 rotatelogs 工具就可以与 PostgreSQL 配合使用。一种办法是把服务器的 stderr 输出通过管道送给所需的程序。如果你使用 pg_ctl 启动服务器,那么 stderr 已经被重定向到 stdout,因此你只需要一个管道命令,例如:

pg_ctl start | rotatelogs /var/log/pgsql_log 86400

你也可以把这些方法结合起来,设置 logrotate 来收集 PostgreSQL 内置日志收集器生成的日志文件。 在这种情况下,日志收集器决定日志文件的名称和位置,而 logrotate 定期归档这些文件。发起日志轮转时, logrotate 必须确保应用程序后续输出转到新文件。 这通常通过一个 postrotate 脚本完成,它向应用程序发送 SIGHUP 信号,应用程序随后重新打开日志文件。 在 PostgreSQL 中,你也可以改为使用带 logrotate 选项的 pg_ctl。服务器收到该命令时, 会根据日志配置切换到新的日志文件,或者重新打开现有文件 (见 Section 19.8.1)。

Note

使用静态日志文件名时,如果达到最大打开文件数限制或发生文件表溢出, 服务器可能无法重新打开日志文件。在这种情况下,日志消息会继续发送到旧日志文件, 直到某次日志轮转成功为止。如果将 logrotate 配置为压缩日志文件并删除它,服务器可能会丢失这段时间内记录的消息。 为避免这个问题,你可以把日志收集器配置为动态分配日志文件名, 并使用一个 prerotate 脚本来忽略已打开的日志文件。

管理日志输出的另一种生产级方法,是把它发送给 syslog, 并让 syslog 负责文件轮转。为此,在 postgresql.conf 中把配置参数 log_destination 设为 syslog(如果只想记录到 syslog)。 之后,每当你想强制它开始写入新的日志文件时,都可以向 syslog 守护进程发送一个 SIGHUP 信号。 如果你想自动化日志轮转,也可以把 logrotate 配置为处理来自 syslog 的日志文件。

不过,在很多系统上,syslog 并不十分可靠, 尤其是在日志消息很大时;它可能恰恰在你最需要消息的时候截断或丢弃它们。 此外,在 Linux 上, syslog 会把每条消息都刷新到磁盘,导致性能较差。 (你可以在 syslog 配置文件的文件名开头使用一个 - 来禁用同步。)

请注意,上面描述的所有方案都处理了按可配置间隔启动新日志文件的问题, 但它们并不处理删除那些已经没有用处的旧日志文件。你很可能还需要设置一个批处理任务, 定期删除旧日志文件。另一种可能是把轮转程序配置为循环覆盖旧日志文件。

pgBadger 是一个进行复杂日志文件分析的外部项目。 check_postgres 可以在日志文件中出现重要消息时向 Nagios 发出警报,也能检测许多其他异常情况。

提交更正

如果您发现文档中有不正确的内容、与您使用特定功能的经验不符或需要进一步说明,请使用此表单来报告文档问题。