↑↓ 选择↵ 打开⌫ 切换范围完整搜索

PG.CENTER 连接 PostgreSQL 文档、百科与生态知识。由 Pigsty 维护。

支持中的版本: 当前版本 (18) / 17 / 16 / 15 / 14
开发中的版本: 19 / 20devel
已结束支持的版本: 13 / 12 / 11 / 10 / 9.6 / 9.5 / 9.4 / 9.3 / 9.2 / 9.1 / 9.0 / 8.4 / 8.3 / 8.2 / 8.1
历史版本。 PostgreSQL 9.1 已结束支持。 2016-10-27. 请参阅 当前版本手册.

18.8. 错误报告和日志 #

18.8.1. 日志记录到哪里 #

log_destination (string) #

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

如果csvlog被包括在log_destination中,日志项会以“逗号分隔值”(CSV)格式被输出,这样可以很方便地把日志载入到程序中。详见第 18.8.4 节。要产生 CSV 格式的日志输出,必须启用logging_collector。

注意

在大多数 Unix 系统上,你将需要修改系统的syslog守护进程的配置来使用log_destination的syslog选项。PostgreSQL可以在syslog设施LOCAL0到LOCAL7中记录(见syslog_facility),但是大部分平台上的默认syslog配置会丢弃所有这种消息。你将需要增加这样的内容:

local0.*    /var/log/postgresql

到syslog守护进程的配置文件来让它工作。

logging_collector (boolean) #

这个参数启用日志收集器,它是一个捕捉被发送到stderr的日志消息的后台进程,并且它会将这些消息重定向到日志文件中。这种方法比记录到syslog通常更有用,因为某些类型的消息可能不会在syslog输出中出现(一个常见的示例是动态链接器错误消息;另一个示例是由archive_command等脚本产生的错误消息)。这个参数只能在服务器启动时设置。

注意

也可以不使用日志收集器而把日志记录到stderr,日志消息将只会去到服务器的stderr被定向到的位置。不过,那种方法只适合于低日志量,因为它没有提供便捷的方法来轮转日志文件。还有,在某些平台上,不使用日志收集器可能会导致日志输出丢失或混杂,因为多个进程并发写入同一个日志文件时会覆盖彼此的输出。

注意

日志收集器被设计成从来不会丢失消息。这意味着在极高的负载下,如果服务器进程试图在收集器已经落后时发送更多的日志消息,那么它可能会被阻塞。相反,syslog倾向于在无法写入消息时丢掉消息,这意味着在这样的情况下它可能会无法记录某些消息,但是它不会阻塞系统的其他部分。

log_directory (string) #

当logging_collector被启用时,这个参数决定日志文件将被在哪个目录下创建。它可以被指定为一个绝对路径,也可以被指定为一个相对于集簇数据目录的相对路径。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。默认是pg_log。

log_filename (string) #

当logging_collector被启用时,这个参数设置被创建的日志文件的文件名。该值被视为一种strftime模式,因此%转义可以被用来指定根据时间变化的文件名(注意如果有任何依赖时区的%转义,计算将在由log_timezone指定的时区中完成)。被支持的%转义和开放组织的strftime说明中列举的类似。注意系统的strftime不会被直接使用,因此平台相关(非标准)的扩展无法工作。默认是postgresql-%Y-%m-%d_%H%M%S.log。

如果你不使用转义来指定一个文件名,你应该计划使用一个日志轮转工具来避免最终填满整个磁盘。在 8.4 发行之前,如果不存在%转义,PostgreSQL将追加新日志文件创建时间的纪元,但是现在已经不再这样做了。

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

这个参数只能在postgresql.conf文件中或通过服务器命令行进行设置。

log_file_mode (integer) #

在 Unix 系统上,当logging_collector被启用时,这个参数设置日志文件的权限(在微软 Windows 上这个参数将被忽略)。这个参数值应当是一个数字形式的模式,它可以被chmod和umask系统调用接受(要使用通常的八进制格式,该数字必须以一个0(零)开始)。

默认的权限是0600,表示只有服务器拥有者才能读取或写入日志文件。其他常用的设置是0640,它允许拥有者的组成员读取文件。不过要注意你需要修改log_directory为将文件存储在集簇数据目录之外的某个位置,才能利用这个设置。在任何情况下,让日志文件变成任何人都可读是不明智的,因为日志文件中可能包含敏感数据。

这个参数只能在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.Mon,server_log.Tue,等等,并自动用本周的日志覆盖上周的日志,将log_filename设置为server_log.%a,将log_truncate_on_rotation设置为on,将log_rotation_age设置为1440。

示例:要保留 24 小时的日志,每个小时一个日志文件,如果日志文件尺寸超过 1GB,也会提前轮转。可以这样做:将log_filename设置为server_log.%H%M、将log_truncate_on_rotation设置为on、将log_rotation_age设置为60并且将log_rotation_size设置为1000000。在log_filename中包含%M,可让按文件大小触发的轮转选用与整点初始文件名不同的新文件名。

syslog_facility (enum) #

当启用了向syslog记录时,这个参数决定要使用的syslog“设施”。你可以在LOCAL0、LOCAL1、LOCAL2、LOCAL3、LOCAL4、LOCAL5、LOCAL6、LOCAL7中选择,默认值是LOCAL0。还请参阅系统的syslog守护进程的文档。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。

syslog_ident (string) #

当启用了向syslog记录时,这个参数决定用来标识syslog中的PostgreSQL消息的程序名。默认值是postgres。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。

silent_mode (boolean) #

静默地运行服务器。如果设置了这个参数,服务器将自动在后台运行并脱离控制终端。这个参数只能在服务器启动时设置。

小心

当设置了这个参数时,服务器的标准输出和标准错误会被重定向到数据目录中的postmaster.log文件。没有任何轮转这个文件的机制,所以除非服务器日志输出被其他设置重定向到别处,它将无限增长。建议在使用这个选项时将log_destination设置为syslog或者启用logging_collector。即使采取这些措施,启动早期报告的错误也可能出现在postmaster.log中而不是正常的日志目标中。

18.8.2. 什么时候记录日志 #

client_min_messages (enum) #

控制哪些消息级别被发送给客户端。有效值是DEBUG5、DEBUG4、DEBUG3、DEBUG2、DEBUG1、LOG、NOTICE、WARNING、ERROR、FATAL和PANIC。每个级别都包括其后的所有级别。级别越靠后,被发送的消息越少。默认值是NOTICE。注意LOG在这里的排序与log_min_messages中的不同。

log_min_messages (enum) #

控制哪些消息级别被写入服务器日志。有效值为DEBUG5、DEBUG4、DEBUG3、DEBUG2、DEBUG1、INFO、NOTICE、WARNING、ERROR、LOG、FATAL和PANIC。每个级别包括其后的所有级别。级别越靠后,发送到日志的消息越少。默认值为WARNING。注意LOG在这里的排序与client_min_messages中的不同。只有超级用户能更改这个设置。

log_min_error_statement (enum) #

控制在服务器日志中记录哪些导致错误条件的SQL语句。对于达到指定严重级别或更高级别的消息,其日志条目中会包含当前 SQL 语句。有效值为DEBUG5、DEBUG4、DEBUG3、DEBUG2、DEBUG1、INFO、NOTICE、WARNING、ERROR、LOG、FATAL和PANIC。默认值为ERROR,这意味着导致错误、日志消息、致命错误或紧急情况的语句将被记录。要有效地关闭记录失败的语句,将此参数设置为PANIC。只有超级用户能更改这个设置。

log_min_duration_statement (integer) #

如果一条已完成语句的运行时间至少达到指定毫秒数,就记录其持续时间。将此值设置为零会打印所有语句的持续时间。负一(默认值)禁用语句持续时间记录。例如,如果设置为250ms,则会记录所有运行 250ms 或更长时间的 SQL 语句。启用此参数有助于发现应用中未优化的查询。只有超级用户能更改这个设置。

对于使用扩展查询协议的客户端,Parse、Bind 和 Execute 步骤的持续时间将被独立记录。

注意

当把这个选项和log_statement一起使用时,已经被log_statement记录的语句文本不会在持续时间日志消息中重复。如果你没有使用syslog,我们推荐你使用log_line_prefix记录 PID 或会话 ID,这样你可以使用进程 ID 或会话 ID 把语句消息链接到后来的持续时间消息。

表 18.1解释了PostgreSQL所使用的消息严重级别。如果日志输出被发送到syslog或 Windows 的eventlog,严重级别会按照表中所示进行转换。

表 18.1. 消息严重级别

严重性用法syslogeventlog
DEBUG1..DEBUG5为开发者提供逐级更加详细的信息。DEBUGINFORMATION
INFO提供用户隐式要求的信息,例如来自VACUUM VERBOSE的输出。INFOINFORMATION
NOTICE提供可能对用户有用的信息,例如长标识符截断提示。NOTICEINFORMATION
WARNING提供可能出现的问题的警告,例如在一个事务块外COMMIT。NOTICEWARNING
ERROR报告一个导致当前命令中断的错误。WARNINGERROR
LOG报告管理员可能感兴趣的信息,例如检查点活动。INFOINFORMATION
FATAL报告一个导致当前会话中断的错误。ERRERROR
PANIC报告一个导致所有数据库会话中断的错误。CRITERROR

18.8.3. 记录哪些内容 #

application_name (string) #

application_name可以是任意小于NAMEDATALEN个字符(标准编译中是 64 个字符)的字符串。应用通常在连接服务器时设置此值。该名称将被显示在pg_stat_activity视图中并被包括在 CSV 日志项中。也可以通过log_line_prefix将其包括在普通日志项中。只有可打印 ASCII 字符能被使用在application_name之中。其他字符将被替换为问号(?)。

debug_print_parse (boolean)
debug_print_rewritten (boolean)
debug_print_plan (boolean)

这些参数将会让多种调试输出被发出。当被设置时,它们为每一个被执行的查询打印结果分析树、查询重写器输出或执行计划。这些消息在LOG消息级别上被发出,因此默认情况下它们将出现在服务器日志中但不会被发送到客户端。你可以通过调整client_min_messages和/或log_min_messages来改变这种情况。这些参数默认是关闭的。

debug_pretty_print (boolean)

当被设置时,debug_pretty_print会缩进由debug_print_parse、debug_print_rewritten或 debug_print_plan产生的输出。这将导致比关闭参数时使用的“紧凑”模式可读性更强但是更长的输出。它默认是打开的。

log_checkpoints (boolean) #

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

log_connections (boolean) #

记录每一次到服务器的连接尝试,以及客户端认证的成功完成。这个参数在会话开始后不能更改。默认为关闭。

注意

某些客户端程序(例如psql)在判断是否需要密码时会尝试连接两次,因此重复的“收到连接”消息并不一定表示一个错误。

log_disconnections (boolean) #

在会话终止时向服务器日志输出一行与log_connections类似的内容,并且包含会话的持续时间。默认情况下这是关闭的。这个参数在会话开始后不能更改。

log_duration (boolean) #

记录每个已完成语句的持续时间。默认值为off。只有超级用户能更改这个设置。

对于使用扩展查询协议的客户端,Parse、Bind 和 Execute 步骤的持续时间将被独立记录。

注意

启用这个选项和设置log_min_duration_statement为零之间的区别是,超过log_min_duration_statement指定的时长会强制记录查询文本,而这个选项不会。因此,如果log_duration为on并且log_min_duration_statement为正值,所有持续时间都将被记录,但是只有超过阈值的语句才会被记录查询文本。这种行为有助于在高负载安装中收集统计信息。

log_error_verbosity (enum) #

控制在服务器日志中记录的每条消息的详细程度。有效值为TERSE,DEFAULT和VERBOSE,它们依次在显示的消息中增加更多字段。TERSE不包括DETAIL,HINT,QUERY和CONTEXT错误信息的记录。VERBOSE输出包括SQLSTATE错误代码(另请参见附录 A)以及生成错误的源代码文件名、函数名和行号。只有超级用户能更改这个设置。

log_hostname (boolean) #

默认情况下,连接日志消息只显示连接主机的 IP 地址。打开这个参数将导致也记录主机名。注意根据你的主机名解析设置,这可能会导致不可忽视的性能开销。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。

log_line_prefix (string) #

这是一个printf风格的字符串,会输出在每个日志行的开头。%字符用于引入“转义序列”,它们会被替换为下表所述的状态信息。无法识别的转义会被忽略。其他字符会直接复制到日志行中。有些转义只被会话进程识别,后台进程(例如主服务器进程)会忽略它们。此参数只能在postgresql.conf文件中或在服务器命令行上设置。默认值是一个空字符串。

转义效果只限会话
%a应用名是
%u用户名是
%d数据库名是
%r远程主机名或 IP 地址,以及远程端口是
%h远程主机名或 IP 地址是
%p进程 ID否
%t无毫秒的时间戳否
%m带毫秒的时间戳否
%i命令标签:会话当前命令的类型是
%eSQLSTATE 错误代码否
%c会话 ID:见下文否
%l对每个会话或进程的日志行号,从 1 开始否
%s进程开始的时间戳否
%v虚拟事务 ID (backendID/localXID)否
%x事务 ID(如果未分配则为 0)否
%q不产生输出,但是告诉非会话进程在字符串的这一点停止;会话进程忽略否
%%字面字符 %否

该%c转义会打印一个近乎唯一的会话标识符,由两个以点分隔的 4 字节十六进制数(不含前导零)组成。这两个数分别是进程启动时间和进程 ID,因此%c也可以用作节省空间的方式来打印这些信息。例如,要从pg_stat_activity生成会话标识符,可以使用以下查询:

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

提示

如果你为log_line_prefix设置了非空值,你通常应该让它的最后一个字符为空格,这样用以提供和日志行的剩余部分的视觉区别。也可以使用标点符号。

提示

Syslog产生自己的时间戳和进程 ID 信息,因此如果你记录到syslog你可能不希望包括那些转义。

log_lock_waits (boolean) #

控制会话为获取锁而等待的时间超过deadlock_timeout时是否生成日志消息。这对于确定锁等待是否导致性能不佳很有用。默认值为off。

log_statement (enum) #

控制哪些 SQL 语句被记录。有效值是 none (off)、ddl、mod和 all(所有语句)。ddl记录所有数据定义语句,例如CREATE、ALTER和 DROP语句。mod记录所有ddl语句,外加INSERT、UPDATE、DELETE、TRUNCATE和COPY FROM等数据修改语句。如果PREPARE、EXECUTE和 EXPLAIN ANALYZE包含合适类型的命令,它们也会被记录。对于使用扩展查询协议的客户端,当收到一个 Execute 消息时会产生日志并且会包括 Bind 参数的值(任何内嵌的单引号会被双写)。

默认值为none。只有超级用户能更改这个设置。

注意

即使使用log_statement = all设置,包含简单语法错误的语句也不会被记录。这是因为只有在完成基本语法解析并确定了语句类型之后才会发出日志消息。在扩展查询协议的情况下,在 Execute 阶段之前(即在解析分析或规划期间)出错的语句也不会被记录。将log_min_error_statement设置为ERROR(或更低)来记录这种语句。

log_temp_files (integer) #

控制临时文件名和大小的日志记录。临时文件可以用于排序、hash 和临时查询结果。每当删除临时文件时都会发出日志记录。值为零时记录所有临时文件信息,而正值仅记录大小大于或等于指定千字节数的文件。默认设置为-1,禁用此类日志记录。只有超级用户能更改这个设置。

log_timezone (string) #

设置在服务器日志中写入的时间戳的时区。和timezone不同,这个值是集簇范围的,因此所有会话将报告一致的时间戳。如果没有显式设置,服务器会将这个变量初始化为其系统环境指定的时区。详见第 8.5.3 节。这个参数只能在postgresql.conf文件中或在服务器命令行上设置。

18.8.4. 使用 CSV 格式的日志输出 #

将csvlog加入log_destination列表中,可以方便地将日志文件导入数据库表。此选项以逗号分隔值(CSV)格式输出日志行,包含以下列:带毫秒的时间戳、用户名、数据库名、进程 ID、客户端主机:端口号、会话 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 日志文件:

  1. 设置log_filename和log_rotation_age,为日志文件提供一致且可预测的命名方案。这样就能预测文件名,并知道单个日志文件何时已完成写入、可以导入。

  2. 将log_rotation_size设置为 0 来禁用基于尺寸的日志轮转,因为它使得日志文件名难以预测。

  3. 将log_truncate_on_rotation设置为on,这样在同一个文件中旧日志数据不会与新数据混杂。

  4. 上述表定义包括一个主键声明。这有助于避免意外地两次导入相同的信息。COPY命令一次提交所有它导入的数据,因此任何错误将导致整个导入失败。如果你导入一个部分完成的日志文件并且稍后当它完全完成后再次导入,主键冲突将导致导入失败。请等到日志完成且被关闭之后再导入。这个过程也可以避免意外地导入部分完成的行,这种行也将导致COPY失败。

报告文档问题

阅读 上游文档. 反馈更正前请先核对 当前版本手册.