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

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 11 已结束支持。 2023-11-09. 请参阅 当前版本手册.

19.8. 错误报告和日志 #

19.8.1. 日志记录到哪里 #

log_destination (string) #

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

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

如果包含 stderr 或 csvlog,就会创建文件 current_logfiles,记录日志收集器当前使用的日志文件位置及相关日志目的地。这样便于找到实例当前使用的日志。以下是此文件内容的示例:

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

current_logfiles 会在日志轮转产生新日志文件时重新创建,也会在重新载入 log_destination 时重新创建。如果 stderr 和 csvlog 均未包含在 log_destination 中,或者禁用了日志收集器,则会移除此文件。

注意

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

local0.*    /var/log/postgresql

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

在 Windows 上,当你使用 log_destination 的 eventlog 选项时,你应该在操作系统中注册一个事件源及其库,这样 Windows 事件查看器能够清楚地显示事件日志消息。详见第 18.11 节。

logging_collector (boolean) #

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

注意

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

注意

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

log_directory (string) #

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

syslog_sequence_numbers (boolean) #

当日志被记录到 syslog 并且这个设置为 on(默认)时,每一个消息会被加上一个增长的序号作为前缀(例如[2])。这种行为避开了很多 syslog 实现默认采用的“--- 上一个消息重复 N 次 ---”形式。在现代 syslog 实现中,抑制重复消息是可以配置的(例如 rsyslog 中的 $RepeatedMsgReduction),因此这个参数可能不是必需的。此外,如果你真的想抑制重复消息,你可以把这个参数设置为 off。

这个参数只能在 postgresql.conf 文件或者服务器命令行上设置。

syslog_split_messages (boolean) #

当启用把日志记录到 syslog 时,这个参数决定消息如何送达 syslog。当设置为 on(默认)时,消息会被分成行,并且长的行也会被划分以便能够放到 1024 字节中,这是传统 syslog 实现的一种典型尺寸限制。当设置为 off 时,PostgreSQL 服务器日志消息会被原样送达 syslog 服务,而处理可能的大体量消息的任务由 syslog 服务负责。

如果 syslog 最终被记录到一个文本文件中,那么两种设置的效果是一样的,但最好设置为 on,因为大部分 syslog 实现要么不能处理大型消息,要么需要做特殊的配置以处理大型消息。但是如果 syslog 最终写入到某种其他媒介,让消息保持逻辑上的完整性可能是必要的,也可能更有用。

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

event_source (string) #

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

19.8.2. 什么时候记录日志 #

log_min_messages (enum) #

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

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 把语句消息链接到后来的持续时间消息。

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

表 19.2. 消息严重级别

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

19.8.3. 记录哪些内容 #

注意

你选择记录的内容可能会影响安全性;请参见第 24.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) #

记录每次尝试连接服务器的操作,以及客户端认证的成功完成。只有超级用户可以在会话开始时更改此参数,并且在会话中完全无法更改它。默认值为 off。

注意

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

log_disconnections (boolean) #

导致会话终止被记录。日志输出提供类似于 log_connections 的信息,以及会话的持续时间。只有超级用户可以在会话开始时更改此参数,而且在会话中根本无法更改。默认值为 off。

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 文件中或在服务器命令行上设置。默认值为'%m [%p] ',它会记录时间戳和进程 ID。

转义效果只限会话
%a应用名是
%u用户名是
%d数据库名是
%r远程主机名或 IP 地址,以及远程端口是
%h远程主机名或 IP 地址是
%p进程 ID否
%t无毫秒的时间戳否
%m带毫秒的时间戳否
%n带毫秒精度的 Unix 时间戳否
%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(trunc(EXTRACT(EPOCH FROM backend_start))::integer) || '.' ||
       to_hex(pid)
FROM pg_stat_activity;

提示

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

提示

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

提示

该 %q 转义在包含只有会话(后端)上下文才提供的信息时很有用,例如用户名或数据库名。比如:

log_line_prefix = '%m [%p] %q%u@%d/%a '

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_replication_commands (boolean) #

每个复制命令都会被记录在服务器日志中。有关复制命令的更多信息,请参见第 53.4 节。默认值为 off。只有超级用户能更改这个设置。

log_temp_files (integer) #

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

log_timezone (string) #

设置在服务器日志中写入的时间戳的时区。和 TimeZone 不同,这个值是集簇范围的,因此所有会话将报告一致的时间戳。内置默认值是 GMT,但是通常会被在 postgresql.conf 中覆盖。initdb 将安装一个对应于其系统环境的设置。详见第 8.5.3 节。这个参数只能在 postgresql.conf 文件中或在服务器命令行上设置。

19.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;

也可以作为外部表访问该文件,使用提供的 file_fdw 模块。

你可以做一些事情来简化导入 CSV 日志文件:

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

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

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

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

19.8.5. 进程标题

这些设置控制服务器进程的进程标题如何修改。通常可以通过 ps 等程序查看进程标题,在 Windows 上则可以使用 Process Explorer。详情参见第 28.1 节。

cluster_name (string) #

设置此集簇所有服务器进程的进程标题中显示的集簇名称。这个名称可以是任何长度少于 NAMEDATALEN 个字符(在标准编译中是 64 字符)的任何字符串。只有可打印的 ASCII 字符能被用在 cluster_name 值中。其他字符将被替换为问号(?)。如果这个参数被设置为空字符串''(也是默认值),将不会显示名称。这个参数只能在服务器启动时设置。

update_process_title (boolean) #

启用后,每次服务器接收到新的 SQL 命令时都会更新进程标题。在大多数平台上,默认情况下此设置为 on,但在 Windows 上默认为 off,因为该平台更新进程标题的开销较大。只有超级用户能更改这个设置。

报告文档问题

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