建议把数据库服务器的日志输出保存下来,而不是通过 /dev/null 直接丢弃。诊断问题时,日志极其有用。
注意:保护日志中的敏感信息
无论日志如何存储、存储在哪里,或者被发送到哪个目标,服务器日志都可能包含敏感信息,必须受到保护。例如,某些 DDL 语句可能包含明文密码或其他认证信息。以 ERROR 级别记录的语句可能显示应用的 SQL 源码,也可能包含数据行的部分内容。
记录数据、事件及相关信息正是这项功能的用途,因此这不属于信息泄漏或程序缺陷。请确保只有获得相应授权的人才能查看服务器日志。
日志往往体积很大,尤其是在较高的调试级别下,不宜无限期保留。因此需要轮转日志文件:定期开始写入新文件,并在经过合理的保留期后删除旧文件。
如果只是将 postgres 的标准错误输出重定向到文件,就能得到日志,但截断该文件的唯一办法是停止并重新启动服务器。这或许适合 PostgreSQL 开发环境,却很少能被生产服务器接受。
更好的办法是把服务器的标准错误输出交给某种日志轮转程序。PostgreSQL 自带日志轮转功能;在 postgresql.conf 中将 logging_collector 设为 true 即可启用。控制参数见 第 19.8.1 节。这种方式也可以把日志保存为机器可读的 CSV(逗号分隔值)格式。
如果已经为其他服务器软件使用了外部日志轮转程序,也可以继续采用它。例如,Apache 发行版中的 rotatelogs 可用于 PostgreSQL。实现方式之一是把服务器的标准错误输出通过管道交给该程序。使用 pg_ctl 启动时,标准错误已经重定向到标准输出,因此只需使用管道命令,例如:
pg_ctl start | rotatelogs /var/log/pgsql_log 86400
也可以结合这两种方法:让 logrotate 收集 PostgreSQL 内置日志收集器生成的文件。此时,日志收集器决定文件的名称与位置,logrotate 则定期归档。发起轮转时,logrotate 必须确保应用将后续输出写入新文件。通常通过 postrotate 脚本向应用发送 SIGHUP,使其重新打开日志文件。
在 PostgreSQL 中,可以改为执行带 logrotate 选项的 pg_ctl。服务器收到命令后,会根据日志配置切换到新日志文件,或者重新打开现有文件,参阅 第 19.8.1 节。
注意:固定日志文件名与重新打开失败
使用固定日志文件名时,如果达到最大打开文件数限制或发生文件表溢出,服务器可能无法重新打开文件。这种情况下,日志消息会继续写入旧文件,直到下一次轮转成功。如果 logrotate 配置为压缩并删除旧文件,服务器就可能丢失这一时段的日志。
为避免这个问题,可让日志收集器动态分配日志文件名,并通过 prerotate 脚本忽略仍处于打开状态的文件。
另一种适用于生产环境的方案是把日志发送给 syslog,交由它处理轮转。在 postgresql.conf 中将 log_destination 设为 syslog,即可只向 syslog 记录日志。需要强制开始写入新文件时,可向 syslog 守护进程发送 SIGHUP。若希望自动轮转,可配置 logrotate 来处理 syslog 生成的文件。
不过,在许多系统上,syslog 并不十分可靠,尤其是面对较大的日志消息:它可能恰在最需要日志时截断或丢弃消息。此外,Linux 上的 syslog 会将每条消息同步到磁盘,导致性能较差。可以在 syslog 配置文件中的文件名前添加 -,禁用这种同步行为。
注意,上述方案都只负责按可配置的间隔开始新日志文件,不会删除已经无用的旧文件。通常还应安排一个批处理任务定期删除旧日志。另一种选择是配置轮转程序,让旧日志文件被循环覆盖。
pgBadger 是一个外部项目,提供较为深入的日志文件分析。check_postgres 能在日志中出现重要消息时生成 Nagios 告警,也能检测多种其他异常情况。











暂无评论内容