# 25.3.日志文件维护

最好将数据库服务器的日志输出保存在某个地方,而不是通过/dev/null.在诊断问题时,日志输出非常宝贵。然而,日志输出往往是大量的(尤其是在较高的调试级别),所以您不想无限期地保存它。你需要旋转在一段合理的时间后,启动新的日志文件并删除旧的日志文件。

如果你直接指挥博士后在文件中,您将有日志输出,但截断日志文件的唯一方法是停止并重新启动服务器。如果在开发环境中使用PostgreSQL,这可能是可以接受的,但很少有生产服务器会认为这种行为是可以接受的。

更好的方法是将服务器的stderr输出发送到某种类型的日志旋转程序。有一个内置的日志旋转功能,可以通过设置配置参数来使用日志采集器符合事实的在里面postgresql。形态.本程序的控制参数如所述第20.8.1节。您还可以使用这种方法以机器可读的CSV(逗号分隔值)格式捕获日志数据。

或者,如果您有一个已与其他服务器软件一起使用的外部日志轮换程序,您可能更愿意使用该程序。例如,Apache发行版中包含的rotatelogs工具可以与PostgreSQL一起使用。一种方法是通过管道将服务器的stderr输出传输到所需的程序。如果你用pg_ctl,那么stderr已经重定向到stdout,所以您只需要一个pipe命令,例如:

pg_ctl start | rotatelogs /var/log/pgsql_log 86400

通过设置logrotate来收集PostgreSQL内置日志收集器生成的日志文件,可以将这些方法结合起来。在这种情况下,日志收集器定义日志文件的名称和位置,而logrotate会定期归档这些文件。启动日志旋转时,logrotate必须确保应用程序向新文件发送进一步的输出。这通常是通过一个后旋转发送消息的脚本叹气向应用程序发送信号,然后应用程序重新打开日志文件。在PostgreSQL中,您可以运行pg_ctl对数旋转选项。当服务器收到此命令时,服务器要么切换到新的日志文件,要么重新打开现有文件,具体取决于日志记录配置(请参阅第 20.8.1 节)。

# 笔记

使用静态日志文件名时,如果达到最大打开文件限制或发生文件表溢出,服务器可能无法重新打开日志文件。在这种情况下,日志消息将发送到旧日志文件,直到日志轮换成功。如果将 logrotate 配置为压缩日志文件并将其删除,则服务器可能会丢失在此时间范围内记录的消息。为避免此问题,您可以将日志收集器配置为动态分配日志文件名并使用预旋转脚本忽略打开的日志文件。

另一种管理日志输出的生产级方法是将其发送到 syslog 并让 syslog 处理文件轮换。为此,请设置配置参数日志目的地系统日志(仅登录到系统日志)在postgresql.conf.然后你可以发送一个SIGHUP每当您想强制它开始写入新的日志文件时,都会向 syslog 守护程序发出信号。如果您想自动化日志轮换,可以将 logrotate 程序配置为使用来自 syslog 的日志文件。

然而,在许多系统上,syslog 并不是很可靠,尤其是对于大型日志消息。它可能会在您最需要的时候截断或丢弃消息。此外,在 Linux 上,syslog 会将每条消息刷新到磁盘,从而导致性能不佳。(您可以使用“-” 在 syslog 配置文件中的文件名开头以禁用同步。)

请注意,上述所有解决方案都负责以可配置的时间间隔启动新的日志文件,但它们不处理旧的、不再有用的日志文件的删除。您可能需要设置一个批处理作业来定期删除旧的日志文件。另一种可能性是配置轮换程序,以便循环覆盖旧的日志文件。

(opens new window)是一个执行复杂日志文件分析的外部项目。查看_postgres (opens new window)当日志文件中出现重要消息时提供 Nagios 警报,以及检测许多其他异常情况。