24.3. 日志文件维护

把数据库服务器的日志输出保存在一个地方是个好主意, 而不是仅仅通过/dev/null丢弃它们。 在进行问题诊断的时候,日志输出是非常宝贵的。不过,日志输出可能很庞大(特别是在比较高的调试级别上), 因此你不会希望无休止地保存它们。你需要轮转日志文件, 这样在一段合理的时间后会开始新的日志文件并且移除旧的。

如果你简单地把postgresstderr定向到一个文件中,你会得到日志输出, 但是截断该日志文件的唯一方法是停止并重起服务器。这样做对于开发环境中使用的PostgreSQL可能是可接受的,但是你肯定不想在生产环境上这么干。

一个更好的办法是把服务器的stderr输出发送到某种日志轮转程序里。 我们有一个内建的日志轮转程序,你可以通过在 postgresql.conf里设置配置参数logging_collectortrue的办法启用它。该程序的控制参数在 Section 19.8.1里描述。你也可以使用这种方法把日志数据捕捉成机器可读的CSV(逗号分隔值)格式。

另外,如果在你已经使用的其他服务器软件中有一个外部日志轮转程序,你可能更喜欢使用它。 比如,包含在Apache发布里的rotatelogs工具就可以用于PostgreSQL。 要这么做,只需要把服务器的stderr用管道重定向到要用的程序。 如果你用pg_ctl启动服务器,那么stderr已经重定向到stdout, 因此你只需要一个管道命令,比如:

pg_ctl start | rotatelogs /var/log/pgsql_log 86400

另外一种生产级的管理日志输出的方法就是把它们发送给syslog,让syslog处理文件轮转。 要利用这个工具,我们需要设置postgresql.conf里的log_destination配置参数设置为syslog(记录syslog日志)。然后在你想强迫syslog守护进程开始写入一个新日志文件的时候, 你就可以发送一个 SIGHUP信号给它。 如果你想自动进行日志轮转,可以配置logrotate程序处理 来自syslog的日志文件。

不过,在很多系统上,syslog不是非常可靠,特别是在面对大量日志消息的情况下; 它可能在你最需要那些消息的时候截断或者丢弃它们。另外,在Linuxsyslog会把每个消息刷写到磁盘上, 这将导致很差的性能(你可以在syslog配置文件里面的文件名开头使用一个-来禁用这种行为)。

请注意上面描述的所有解决方案关注的是在可配置的间隔上开始一个新的日志文件, 但它们并没有处理对旧的、不再需要的日志文件的删除。你可能还需要设置一个批处理任务来定期地删除旧日志文件。 另一种可能的方法是配置日志轮转程序,让它循环地覆盖旧的日志文件。

pgBadger是一个外部项目,它可以进行日志文件的深度分析。 check_postgres可在重要消息出现在日志文件中时向Nagios提供警告,也可以探测很多其他的特别情况。