19.8. 错误报告和记录

19 .8.1. 在哪里记录

  • log_destination ( string )
    • PostgreSQL 支持几种记录服务器消息的方法,包括 stderr,csvlog 和 syslog。在 Windows 上,也支持 eventlog。将此参数设置为所需的日志目标列表,以逗号分隔。默认为仅登录到 stderr。此参数只能在postgresql.conf文件或服务器命令行中设置。

如果log_destination中包含 csvlog,则日志条目以“逗号分隔值”(CSV)格式输出,这便于将日志加载到程序中。有关详情,请参见Section 19.8.4。必须启用logging_collector才能生成 CSV 格式的日志输出。

当包括 stderr 或 csvlog 时,将创建文件current_logfiles来记录日志收集器和关联的日志目标当前正在使用的日志文件的位置。这提供了一种方便的方法来查找实例当前正在使用的日志。这是此文件内容的示例:

stderr log/postgresql.log
csvlog log/postgresql.csv

当由于轮换而创建新的日志文件时以及重新加载log_destination时,将重新创建current_logfiles。当log_destination中既不包含 stderr 也不包含 csvlog 时,并且禁用了日志收集器时,将其删除。

Note

在大多数 Unix 系统上,您需要更改系统 syslog 守护程序的配置,以便使用log_destination的 syslog 选项。 PostgreSQL 可以登录LOCAL0LOCAL7到 syslog 工具(请参阅syslog_facility),但是大多数平台上的默认 syslog 配置将丢弃所有此类消息。您将需要添加以下内容:

local0.*    /var/log/postgresql

到 syslog 守护程序的配置文件以使其正常工作。

在 Windows 上,当对log_destination使用eventlog选项时,应在 os 上注册事件源及其库,以便 Windows Event Viewer 可以干净地显示事件日志消息。有关详情,请参见Section 18.11

  • logging_collector ( boolean )
    • 此参数启用* logging collector *,这是一个后台进程,用于捕获发送到 stderr 的日志消息并将它们重定向到日志文件中。这种方法通常比登录 syslog 更有用,因为某些类型的消息可能不会出现在 syslog 输出中。 (一个常见的示例是动态链接器失败消息;另一个是由诸如archive_command之类的脚本产生的错误消息.)只能在服务器启动时设置此参数。

Note

无需使用日志收集器就可以登录到 stderr。日志消息将仅到达服务器 stderr 指向的任何位置。但是,该方法仅适用于较小的日志量,因为它不提供旋转日志文件的简便方法。另外,在某些不使用日志收集器的平台上,可能会导致日志输出丢失或出现乱码,因为同时写入同一日志文件的多个进程可能会覆盖彼此的输出。

Note

日志收集器旨在永不丢失消息。这意味着在负载极高的情况下,当收集器落后时,尝试发送其他日志消息时服务器进程可能会被阻塞。相反,如果 syslog 无法写入消息,则倾向于删除消息,这意味着在这种情况下它可能无法记录某些消息,但不会阻塞系统的其余部分。

  • log_directory ( string )

    • 启用logging_collector时,此参数确定将在其中创建日志文件的目录。可以将其指定为绝对路径,也可以相对于集群数据目录指定。只能在postgresql.conf文件或服务器命令行中设置此参数。默认值为log
  • log_filename ( string )

    • 启用logging_collector时,此参数设置创建的日志文件的文件名。该值被视为strftime模式,因此% -escapes 可用于指定随时间变化的文件名。 (请注意,如果有任何与时区有关的% -escapes,则在log_timezone指定的区域中进行计算。)支持的% -escapes 与 Open Group 的strftime规范中列出的类似。请注意,系统的strftime不能直接使用,因此特定于平台的(非标准)extensions 不起作用。默认值为postgresql-%Y-%m-%d_%H%M%S.log

如果指定的文件名没有转义符,则应计划使用日志轮换 Util 以避免最终填满整个磁盘。在 8.4 之前的版本中,如果不存在%转义符,PostgreSQL 将附加新日志文件创建时间的纪元,但现在不再如此。

如果在log_destination中启用了 CSV 格式输出,则将.csv附加到带时间戳的日志文件名中,以创建 CSV 格式输出的文件名。 (如果log_filename.log结尾,则替换后缀.)

此参数只能在postgresql.conf文件或服务器命令行中设置。

  • log_file_mode ( integer )
    • 在 Unix 系统上,启用logging_collector时,此参数设置日志文件的权限。 (在 Microsoft Windows 上,将忽略此参数.)参数值应为数字模式,以chmodumask系统调用接受的格式指定。 (要使用常规的八进制格式,数字必须以0(零)开头。)

默认权限为0600,这意味着只有服务器所有者才能读取或写入日志文件。另一个常用的设置是0640,允许所有者组的成员读取文件。但是请注意,要使用此设置,您需要更改log_directory以将文件存储在群集数据目录之外的某个位置。无论如何,使日志文件具有 Global 可读性是不明智的,因为它们可能包含敏感数据。

此参数只能在postgresql.conf文件或服务器命令行中设置。

  • log_rotation_age ( integer )

    • 启用logging_collector时,此参数确定单个日志文件的最大生存期。在这几分钟之后,将创建一个新的日志文件。设置为零可禁用基于时间的新日志文件创建。只能在postgresql.conf文件或服务器命令行中设置此参数。
  • log_rotation_size ( integer )

    • 启用logging_collector时,此参数确定单个日志文件的最大大小。将这千字节发送到日志文件后,将创建一个新的日志文件。设置为零可禁用基于大小的新日志文件的创建。只能在postgresql.conf文件或服务器命令行中设置此参数。
  • log_truncate_on_rotation ( boolean )

    • 启用logging_collector时,此参数将导致 PostgreSQL 截断(覆盖)而不是附加到任何同名的现有日志文件中。但是,截断仅在由于基于时间的旋转而打开新文件时发生,而不是在服务器启动或基于大小的旋转过程中发生。禁用时,在所有情况下都将附加先前存在的文件。例如,结合使用此设置和postgresql-%H.log之类的log_filename会导致生成每小时 24 个日志文件,然后周期性地覆盖它们。此参数只能在postgresql.conf文件或服务器命令行中设置。

示例:要保留 7 天的日志,每天一个日志文件名为server_log.Monserver_log.Tue等,并使用本周的日志自动覆盖上周的日志,请将log_filename设置为server_log.%a,将log_truncate_on_rotation设置为on,并将log_rotation_age设置为1440

示例:要保留 24 小时的日志,每小时一个日志文件,但是如果日志文件大小超过 1GB,还可以更快地轮换,请将log_filename设置为server_log.%H%Mlog_truncate_on_rotation设置为onlog_rotation_age设置为60log_rotation_size设置为1000000。在log_filename中包含%M允许任何可能发生的大小驱动旋转来选择与小时的初始文件名不同的文件名。

  • syslog_facility ( enum )

    • 启用登录到 syslog 时,此参数确定要使用的 syslog“设备”。您可以选择LOCAL0LOCAL1LOCAL2LOCAL3LOCAL4LOCAL5LOCAL6LOCAL7;默认值为LOCAL0。另请参阅系统 syslog 守护程序的文档。只能在postgresql.conf文件或服务器命令行中设置此参数。
  • syslog_ident ( string )

    • 启用登录到 syslog 后,此参数确定用于在 syslog 日志中标识 PostgreSQL 消息的程序名称。默认值为postgres。只能在postgresql.conf文件或服务器命令行中设置此参数。
  • syslog_sequence_numbers ( boolean )

    • 登录到 syslog 并启用该功能(默认设置)后,每条消息都将以递增的序列号作为前缀(例如[2])。这可以避免许多系统日志实现默认执行的“ ---最后消息重复 N 次---”抑制。在更现代的 syslog 实现中,可以配置重复消息抑制(例如,rsyslog 中的$RepeatedMsgReduction),因此可能没有必要。另外,如果您确实想抑制重复的消息,则可以将其关闭。

此参数只能在postgresql.conf文件或服务器命令行中设置。

  • syslog_split_messages ( boolean )
    • 启用登录到 syslog 时,此参数确定如何将消息传递到 syslog。启用时(默认),消息将按行拆分,并且将长行拆分为适合于 1024 字节的长度,这是传统 syslog 实现的典型大小限制。如果禁用此选项,则 PostgreSQL 服务器日志消息将按原样传递到 syslog 服务,并且由 syslog 服务来处理可能庞大的消息。

如果 syslog 最终登录到文本文件,则效果将是相同的,最好保持设置不变,因为大多数 syslog 实现要么无法处理大消息,要么需要进行特殊配置以处理大消息。但是,如果 syslog 最终写入其他某种介质,则可能有必要或更有用的方法将消息逻辑上保持在一起。

此参数只能在postgresql.conf文件或服务器命令行中设置。

  • event_source ( string )
    • 启用记录到事件日志后,此参数确定用于在日志中标识 PostgreSQL 消息的程序名称。默认值为PostgreSQL。只能在postgresql.conf文件或服务器命令行中设置此参数。

19 .8.2. 何时登录

  • log_min_messages ( enum )

    • 控制将哪些message levels写入服务器日志。有效值为DEBUG5DEBUG4DEBUG3DEBUG2DEBUG1INFONOTICEWARNINGERRORLOGFATALPANIC。每个级别都包括其后的所有级别。级别越高,发送到日志的消息越少。默认值为WARNING。请注意,LOGclient_min_messages中的等级不同。只有超级用户可以更改此设置。
  • log_min_error_statement ( enum )

    • 控制哪些 SQL 语句导致错误情况记录在服务器日志中。对于指定的severity或更高的任何消息,当前 SQL 语句包含在日志条目中。有效值为DEBUG5DEBUG4DEBUG3DEBUG2DEBUG1INFONOTICEWARNINGERRORLOGFATALPANIC。默认值为ERROR,这意味着将记录导致错误,日志消息,致命错误或紧急情况的语句。要有效地关闭失败语句的日志记录,请将此参数设置为PANIC。只有超级用户可以更改此设置。
  • log_min_duration_statement ( integer )

    • 如果语句至少运行了指定的毫秒数,则导致记录每个完成的语句的持续时间。将此设置为零将打印所有语句持续时间。减一(默认)禁用日志记录语句的持续时间。例如,如果将其设置为250ms,则将记录所有运行 250ms 或更长时间的 SQL 语句。启用此参数有助于跟踪应用程序中未优化的查询。只有超级用户可以更改此设置。

对于使用扩展查询协议的 Client 端,“解析”,“绑定”和“执行”步骤的持续时间将独立记录。

Note

log_statement一起使用此选项时,由于log_statement而记录的语句文本将不会在持续时间日志消息中重复。如果不使用 syslog,建议您使用log_line_prefix记录 PID 或会话 ID,以便可以使用进程 ID 或会话 ID 将声明消息链接到以后的持续时间消息。

Table 19.1解释了 PostgreSQL 使用的消息严重性级别。如果将日志记录输出发送到 syslog 或 Windows 的事件日志,则严重性级别将按照表中所示进行转换。

表 19.1. 邮件严重性级别

SeverityUsagesyslogeventlog
DEBUG1..DEBUG5提供更多详细信息供开发人员使用。DEBUGINFORMATION
INFO提供用户隐式请求的信息,例如VACUUM VERBOSE的输出。INFOINFORMATION
NOTICE提供可能对用户有用的信息,例如,长标识符被截断的通知。NOTICEINFORMATION
WARNING提供有关可能出现问题的警告,例如,在 Transaction 代码块外的COMMITNOTICEWARNING
ERROR报告导致当前命令中止的错误。WARNINGERROR
LOG向 Management 员报告感兴趣的信息,例如检查点活动。INFOINFORMATION
FATAL报告导致当前会话中止的错误。ERRERROR
PANIC报告导致所有数据库会话中止的错误。CRITERROR

19 .8.3. 要记录什么

  • application_name ( string )

    • application_name可以是少于NAMEDATALEN个字符(标准版本中为 64 个字符)的任何字符串。通常由应用程序在连接到服务器时设置。该名称将显示在pg_stat_activity视图中,并包含在 CSV 日志条目中。也可以通过log_line_prefix参数将其包含在常规日志条目中。 application_name值中只能使用可打印的 ASCII 字符。其他字符将替换为问号(?)。
  • debug_print_parse ( boolean )
    debug_print_rewritten ( boolean )
    debug_print_plan ( boolean )

    • 这些参数使得可以发出各种调试输出。设置后,它们将打印结果分析树,查询重写器输出或每个已执行查询的执行计划。这些消息以LOG消息级别发出,因此默认情况下它们将出现在服务器日志中,但不会发送给 Client 端。您可以通过调整client_min_messages和/或log_min_messages进行更改。这些参数默认情况下处于关闭状态。
  • debug_pretty_print ( boolean )

    • 设置后,debug_pretty_print缩进debug_print_parsedebug_print_rewrittendebug_print_plan生成的消息。与关闭时使用的“紧凑”格式相比,这将导致更具可读性的输出,但输出时间更长。默认情况下它是打开的。
  • log_checkpoints ( boolean )

    • 使检查点和重新启动点记录在服务器日志中。日志消息中包含一些统计信息,包括写入的缓冲区数量和写入它们所花费的时间。此参数只能在postgresql.conf文件或服务器命令行中设置。默认为关闭。
  • log_connections ( boolean )

    • 导致记录到服务器的每个尝试连接,以及成功完成 Client 端身份验证。只有超级用户才能在会话开始时更改此参数,并且在会话内完全不能更改。默认值为off

Note

某些 Client 端程序(例如 psql)会在确定是否需要密码时尝试两次连接,因此重复的“收到连接”消息不一定表示存在问题。

  • log_disconnections ( boolean )

    • 导致记录会话终止。日志输出提供类似于log_connections的信息以及会话持续时间。只有超级用户才能在会话开始时更改此参数,并且在会话内完全不能更改。默认值为off
  • log_duration ( boolean )

    • 导致记录每个完成的语句的持续时间。默认值为off。只有超级用户可以更改此设置。

对于使用扩展查询协议的 Client 端,“解析”,“绑定”和“执行”步骤的持续时间将独立记录。

Note

设置此选项与将log_min_duration_statement设置为零之间的区别是,超过log_min_duration_statement会强制记录查询文本,但不记录该文本。因此,如果log_durationonlog_min_duration_statement具有正值,则记录所有持续时间,但仅对超出阈值的语句包括查询文本。此行为对于收集高负载安装中的统计信息可能很有用。

  • log_error_verbosity ( enum )

    • 控制记录在服务器日志中的每条消息的详细信息量。有效值为TERSEDEFAULTVERBOSE,每个值都会向显示的消息中添加更多字段。 TERSE排除DETAILHINTQUERYCONTEXT错误信息的记录。 VERBOSE输出包括SQLSTATE错误代码(另请参见Appendix A)以及生成错误的源代码文件名,函数名和行号。只有超级用户可以更改此设置。
  • log_hostname ( boolean )

    • 默认情况下,连接日志消息仅显示连接主机的 IP 地址。启用此参数也会导致记录主机名。请注意,根据您的主机名解析设置,这可能会导致不可忽略的性能损失。此参数只能在postgresql.conf文件或服务器命令行中设置。
  • log_line_prefix ( string )

    • 这是在每个日志行的开头输出的printf样式的字符串。 %个字符以“转义序列”开头,被以下概述的状态信息取代。无法识别的转义将被忽略。其他字符直接复制到日志行。某些转义仅由会话进程识别,并且将由后台进程(例如主服务器进程)视为空。通过在%之后和该选项之前指定数字 Literals,可以左右对齐状态信息。负值将导致状态信息在右侧填充空格以使其具有最小宽度,而正值将在左侧填充。填充有助于提高日志文件的可读性。只能在postgresql.conf文件或服务器命令行中设置此参数。默认值为'%m [%p] ',它记录时间戳记和进程 ID。
EscapeEffectSession only
%aApplication nameyes
%uUser nameyes
%dDatabase nameyes
%r远程主机名或 IP 地址以及远程端口yes
%h远程主机名或 IP 地址yes
%pProcess IDno
%t没有毫秒的时间戳no
%m时间戳(以毫秒为单位)no
%n以毫秒为单位的时间戳(作为 Unix 时代)no
%i命令标签:会话当前命令的类型yes
%eSQLSTATE 错误代码no
%c会话 ID:请参见下文no
%l每个会话或进程的日志行号,从 1 开始no
%s流程开始时间戳no
%v虚拟 TransactionID(后端 ID/localXID)no
%xTransactionID(如果未分配,则为 0)no
%q不产生任何输出,但是告诉非会话进程在字符串中的这一点停止。会话进程忽略no
%%字面%no

%c转义符输出一个准唯一的会话标识符,该标识符由两个 4 个字节的十六进制数字(无前导零)组成,并用点分隔。这些数字是进程开始时间和进程 ID,因此%c也可以用作节省空间来打印这些项目。例如,要从pg_stat_activity生成会话标识符,请使用以下查询:

SELECT to_hex(trunc(EXTRACT(EPOCH FROM backend_start))::integer) || '.' ||
       to_hex(pid)
FROM pg_stat_activity;

Tip

如果为log_line_prefix设置了非空值,则通常应将其最后一个字符作为空格,以与日志行的其余部分视觉上分开。也可以使用标点符号。

Tip

Syslog 会产生自己的时间戳和进程 ID 信息,因此,如果您要登录 syslog,则可能不想包含这些转义符。

Tip

包括仅在会话(后端)上下文中可用的信息(例如用户或数据库名称)时,%q转义很有用。例如:

log_line_prefix = '%m [%p] %q%u@%d/%a '
  • log_lock_waits ( boolean )

    • 控制在会话 await 时间长于deadlock_timeout以获得锁定时是否生成日志消息。这对于确定锁定 await 是否导致性能下降很有用。默认值为off。只有超级用户可以更改此设置。
  • log_statement ( enum )

    • 控制记录哪些 SQL 语句。有效值为none(关闭),ddlmodall(所有语句)。 ddl记录所有数据定义语句,例如CREATEALTERDROP语句。 mod记录所有ddl语句,以及INSERTUPDATEDELETETRUNCATECOPY FROM等数据修改语句。如果PREPAREEXECUTEEXPLAIN ANALYZE语句包含的命令具有适当的类型,则也会记录它们。对于使用扩展查询协议的 Client 端,当接收到 Execute 消息并包含 Bind 参数的值(所有嵌入的单引号都加倍)时,就会发生日志记录。

默认值为none。只有超级用户可以更改此设置。

Note

即使是log_statement = all设置,也不会记录包含简单语法错误的语句,因为只有在完成基本分析以确定语句类型之后,才会发出日志消息。在扩展查询协议的情况下,此设置同样不会记录在执行阶段之前(即在分析分析或计划期间)失败的语句。将log_min_error_statement设置为ERROR(或更低)以记录此类语句。

  • log_replication_commands ( boolean )

    • 使每个复制命令记录在服务器日志中。有关复制命令的更多信息,请参见Section 53.4。默认值为off。只有超级用户可以更改此设置。
  • log_temp_files ( integer )

    • 控制临时文件名和大小的日志记录。可以为排序,哈希和临时查询结果创建临时文件。删除每个临时文件后,都会为其创建一个日志条目。零值记录所有临时文件信息,而正值仅记录大小大于或等于指定千字节数的文件。默认设置为-1,它将禁用此类日志记录。只有超级用户可以更改此设置。
  • log_timezone ( string )

    • 设置用于写入服务器日志的时间戳的时区。与TimeZone不同,此值在整个群集范围内,因此所有会话将一致地报告时间戳。内置默认值为GMT,但通常会在postgresql.conf中覆盖; initdb 将在其中安装与其系统环境相对应的设置。有关更多信息,请参见Section 8.5.3。此参数只能在postgresql.conf文件或服务器命令行中设置。

19 .8.4. 使用 CSV 格式的日志输出

log_destination列表中包括csvlog提供了一种将日志文件导入数据库表的便捷方法。此选项以逗号分隔值(CSV)格式发出日志行,其中包含以下列:时间戳(毫秒),用户名,数据库名,进程 ID,Client 端主机:端口号,会话 ID,每个会话行号,命令标签,会话开始时间,虚拟事务 ID,常规事务 ID,错误严重性,SQLSTATE 代码,错误消息,错误消息详细信息,提示,导致错误的内部查询(如果有),其中错误位置的字符数,错误上下文,导致错误的用户查询(如果有的话并由log_min_error_statement启用),错误位置的字符数,错误在 PostgreSQL 源代码中的位置(如果log_error_verbosity设置为verbose)以及应用程序名称。这是用于存储 CSV 格式日志输出的示例表定义:

CREATE TABLE postgres_log
(
  log_time timestamp(3) with time zone,
  user_name text,
  database_name text,
  process_id integer,
  connection_from text,
  session_id text,
  session_line_num bigint,
  command_tag text,
  session_start_time timestamp with time zone,
  virtual_transaction_id text,
  transaction_id bigint,
  error_severity text,
  sql_state_code text,
  message text,
  detail text,
  hint text,
  internal_query text,
  internal_query_pos integer,
  context text,
  query text,
  query_pos integer,
  location text,
  application_name text,
  PRIMARY KEY (session_id, session_line_num)
);

要将日志文件导入此表,请使用COPY FROM命令:

COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;

您需要做一些事情来简化 CSV 日志文件的导入:

  • 设置log_filenamelog_rotation_age为您的日志文件提供一致的,可预测的命名方案。这使您可以预测文件名,并知道单个日志文件何时完成并因此可以导入。

  • log_rotation_size设置为 0 以禁用基于大小的日志轮换,因为这会使日志文件名难以预测。

  • log_truncate_on_rotation设置为on,以便旧日志数据不会与同一文件中的新日志数据混合。

  • 上面的表定义包括主键规范。这对于防止两次意外导入相同信息很有用。 COPY命令一次提交它导入的所有数据,因此任何错误都将导致整个导入失败。如果您导入部分日志文件,然后在完成后再次导入该文件,则主键冲突将导致导入失败。await 直到日志完成并关闭,然后再导入。此过程还将防止意外导入尚未完全写入的部分行,这也将导致COPY失败。

19 .8.5. 流程标题

这些设置控制如何修改服务器进程的进程标题。通常使用 ps 之类的程序或在 Windows 中使用 Process Explorer 查看进程标题。有关详情,请参见Section 28.1

  • cluster_name ( string )

    • 设置出现在该群集中所有服务器进程的进程标题中的群集名称。该名称可以是少于NAMEDATALEN个字符(标准版本中为 64 个字符)的任何字符串。 cluster_name值中只能使用可打印的 ASCII 字符。其他字符将替换为问号(?)。如果此参数设置为空字符串''(默认值),则不会显示任何名称。该参数只能在服务器启动时设置。
  • update_process_title ( boolean )

    • 每次服务器接收到新的 SQL 命令时,即可更新进程标题。在大多数平台上,此设置默认为on,但在 Windows 上默认为off,因为该平台用于更新进程标题的开销较大。只有超级用户可以更改此设置。